Created
November 29, 2024 18:31
-
-
Save Strajk/e87ad0888e8df0bd1bd7c60b764369f0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Name: Faker | |
// Description: Generate fake data with faker.js | |
// Author: Pavel 'Strajk' Dolecek | |
// Twitter: @straaajk | |
import "@johnlindquist/kit" | |
import { faker } from '@faker-js/faker'; | |
import { Choice } from "@johnlindquist/kit"; | |
const CACHE_EXPIRATION = 1000 * 60 * 60 * 24 * 30 // 1 month | |
// const CACHE_EXPIRATION = 1000 * 15 // 15 seconds // uncomment for debugging | |
// @ts-ignore kitCommand is defined, but it's not in types :( | |
const keyv = await store(kitCommand, {cachedChoices: null, cachedChoicesExpires: null}) | |
const maybeCachedChoices = await keyv.get('choices') as Choice[] | null | |
const maybeCachedChoicesExpires = await keyv.get('cachedChoicesExpires') as number | null | |
const EXAMPLES_MAX_COUNT = 5 | |
const EXAMPLES_MAX_CHARS = 120 | |
const modulesToIgnore = [ | |
"_defaultRefDate", | |
"_randomizer", | |
"datatype", // just boolean | |
"helpers", | |
"rawDefinitions", | |
"definitions", | |
] | |
const methodsToIgnore = [ | |
"faker", | |
] | |
const pairsToIgnore = [ | |
"internet.userName", // deprecated in favour of internet.username | |
"image.avatarLegacy", // deprecated in favour of image.avatar | |
// requires params, which would require special handling | |
"string.fromCharacters", | |
"date.between", | |
"date.betweens", | |
] | |
let choices = [] | |
if ( | |
maybeCachedChoices?.length > 0 | |
&& maybeCachedChoicesExpires > Date.now() | |
) { | |
// console.log("Using cached choices") | |
choices = maybeCachedChoices as Choice[] | |
} else { | |
// console.log("Generating choices") | |
for (const module in faker) { // date, number, string, finance, ... | |
if (modulesToIgnore.includes(module)) { | |
continue; | |
} | |
for (const method in faker[module]) { | |
if (methodsToIgnore.includes(method)) { | |
continue; | |
} | |
const pair = `${module}.${method}`; | |
if (pairsToIgnore.includes(pair)) { | |
continue; | |
} | |
let examplesCount = 0; | |
let examplesText = ""; | |
while (examplesText.length < EXAMPLES_MAX_CHARS && examplesCount < EXAMPLES_MAX_COUNT) { | |
const newExample = callFaker(module, method); | |
if (examplesText.length > 0) { | |
examplesText += " • " | |
} | |
examplesText += toString(newExample); | |
examplesCount++; | |
} | |
examplesText = examplesText.trim().substring(0, EXAMPLES_MAX_CHARS); | |
choices.push({ | |
name: `${module}: ${method}`, | |
value: pair, | |
description: examplesText, | |
}) | |
} | |
} | |
await keyv.set('choices', choices) | |
await keyv.set('cachedChoicesExpires', Date.now() + CACHE_EXPIRATION) | |
} | |
const selected = await arg({ | |
placeholder: "Select a Faker module and method", | |
choices: choices, | |
enter: "Copy to clipboard", | |
}) | |
let [module, method] = selected.split(".") | |
let value = toString(callFaker(module, method)) | |
await copy(value) | |
await notify(`Copied: ${value}`) | |
// Helpers | |
// === | |
function callFaker(module: string, method: string) { | |
try { | |
return faker[module][method]() | |
} catch (error) { | |
console.error(`Error calling faker method: ${module}.${method}`, error); | |
return | |
} | |
} | |
function toString(value: any): string { | |
if (typeof value === "string") { | |
return value | |
} else if (typeof value === "object") { | |
return JSON.stringify(value) | |
} else { | |
return value?.toString() || "❌" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment