// Name: JSON to TypeScript// Description: Convert some JSON to TypeScript modelsimport "@johnlindquist/kit"import jsonToTS from "json-to-ts"import { submitShortcut } from "@johnlindquist/kit/core/utils"import { refreshable } from "@josxa/kit-utils"import { crudArg } from "@josxa/kit-utils"import ModernError from "modern-errors"let json = args[0]if (!json) {json = await editor({language: "json",validate(input: string): true | string {try {JSON.parse(input)return true} catch (err) {return ModernError.normalize(err).message}},shortcuts: [submitShortcut],})}const rootName = await crudArg("Name of the root type?")const options: Parameters<typeof jsonToTS>[1] = {rootName,useTypeAlias: true,}await refreshable(async ({ refresh }) => {let types = ""try {types = `${jsonToTS(JSON.parse(json), options).join("\n\n")}\n`} catch (error) {const hint = ModernError.normalize(error).messagesetHint(hint)exit()}if (options.useTypeAlias) {types = types.replaceAll(/^type /g, "export type ")} else {types = types.replaceAll(/^interface /g, "export interface ")}await editor({value: types,language: "ts",shortcuts: [{key: `${cmd}+shift+t`,name: `Use ${options.useTypeAlias ? "Interfaces" : "Types"}`,onPress: () => {options.useTypeAlias = !options.useTypeAliasrefresh()},visible: true,bar: "right",},{name: "Copy to Clipboard",key: `${cmd}+shift+c`,onPress: async (input) => {await clipboard.writeText(input)setHint("Copied to clipboard")},visible: true,bar: "right",},],})})
// Name: Cron Expression Validator// Description: Validates and helps you build Crontab expressions// Shortcode: cron// Author: @JosXa, loosely based on Ricardo Gonçalves Bassete's versionimport "@johnlindquist/kit"import { computed, effect, signal } from "@preact/signals-core"import cronstrue from "cronstrue"import { markdownTable } from "markdown-table"const FONT_SIZE = "0.8em"const allowedCharsTable = markdownTable([["Character", "Meaning"],["`*`", "any value"],["`,`", "value list separator"],["`-`", "range of values"],["`/`", 'step values (e.g. `*/5 * * * *` for "every 5 minutes")'],],{ align: "l" },)const tableHtml = md(allowedCharsTable).replace('<th align="left">', '<th align="left" style="width: 17%">')const input = signal("* * * * *")const parts = computed(() => input.value.split(" "))const parsedExpression = computed(() => {try {return cronstrue.toString(input.value)} catch (err) {return undefined}})const isValid = computed(() => !!parsedExpression.value)const asciiHint = computed(() => {if (!input.value) {return `| | | | || | | | +----- day of the week (0 - 7) (Sunday = 0 or 7)| | | +------- month (1 - 12)| | +--------- day of the month (1 - 31)| +----------- hour (0 - 23)+------------- minute (0 - 59)`.trim()}const hasSecond = parts.value.length >= 6const names = ["second (0 - 59)","minute (0 - 59)","hour (0 - 23)","day of the month (1 - 31)","month (1 - 12)","day of the week (0 - 7) (Sunday = 0 or 7)",]if (!hasSecond) {names.splice(0, 1)}/*0 1 2 3 4 5 👉 partIdx0 | | | | | +----- day of the week (0 - 7) (Sunday = 0 or 7)1 | | | | +------- month (1 - 12)2 | | | +--------- day of the month (1 - 31)3 | | +----------- hour (0 - 23)4 | +------------- minute (0 - 59)5 +--------------- second (0 - 59)👇lineIdx*/const columns = parts.value.reduce((agg, part, partIdx) => {const prev = agg[partIdx - 1]const startCol = prev ? prev.endCol + 1 : 0const endCol = startCol + part.lengthconst name = names[partIdx]!agg.push({partIdx,startCol,endCol,part,gapToPrevious: Math.max(0, endCol - startCol),name,})return agg},[] as Array<{startCol: numberendCol: numberpart: stringgapToPrevious: numberpartIdx: numbername: string}>,)const lines: string[] = []const maxLen = columns.slice(-1)[0]!.endCol + 5for (let lineIdx = -1; lineIdx < columns.length; lineIdx++) {let line = ""for (const { gapToPrevious, partIdx, name } of columns) {if (lineIdx === -1) {line += "|"line += " ".repeat(gapToPrevious)continue}if (partIdx + lineIdx === columns.length - 1) {line += "+"line = line.padEnd(maxLen, "-")line += ` ${name}`break}line += "|"line += " ".repeat(gapToPrevious)}lines.push(line)}return lines.join("\n")})const asciiHintHtml = computed(() =>`<div style="font-size: ${FONT_SIZE};" class="px-4"><pre>${asciiHint}</pre></div>`.trim(),)const resultMessage = computed(() => {if (!input.value) {return ""}return ("<br>" +(parsedExpression.value? `<h3 class="px-4" style="color: rgba(var(--color-primary), var(--tw-text-opacity))">👉 ${parsedExpression.value}</h3>`: `<h3 class="px-4" style="color: #f65671">❌ The expression "${input.value}" cannot be parsed.</h3>`))})const enter = computed(() => (isValid.value ? "Copy" : ""))const panel = computed(() => `<div>${asciiHintHtml.value}${resultMessage.value}<br><hr>${tableHtml}</div>`)const cleanup: Array<() => void> = []await arg({placeholder: "Type a Crontab expression",input: input.value,className: "p-0",inputClassName: "font-mono",css: `#input {min-width: 250px !important;font-size: ${FONT_SIZE} !important;}`,onInit() {cleanup.push(effect(() => setEnter(enter.value)))cleanup.push(effect(() => setPanel(panel.value)))},onInput(val) {if (!val) {input.value = ""return}let sanitized = val// Replace duplicate spaces.replaceAll(/\s{2,}/g, " ")// Leading whitespace.replaceAll(/^\s+/g, "")const s = sanitized.split(" ")// Ensure maximum of 6 partsif (s.length > 6) {sanitized = s.slice(0, 6).join(" ")}if (val !== sanitized) {setInput(sanitized)}input.value = sanitized},enter: enter.value,alwaysOnTop: true,})cleanup.forEach((fn) => fn())await clipboard.writeText(input.value)
// Name: Urban Dictionary// Keyword: udimport "@johnlindquist/kit"import type { Choice } from "@johnlindquist/kit"import { DateTime } from "luxon"import { escapeHTML } from "../../.kit/core/utils"await setInput("")const debouncedOnInput = debounce(async (input) => {if (!input) {return}try {const choices = await getResultsAsChoices(input)await setChoices(choices)} finally {setHint("")}}, 500)const link = await arg({placeholder: "Search a word definition",onInput: (input) => {setHint("Searching...")debouncedOnInput(input)},})await clipboard.writeText(link)notify({ title: "Urban Dictionary", message: "Definition URL copied to clipboard." })await wait(200) // Somehow the notify function needs some time to complete...type Definition = {definition: stringpermalink: stringthumbs_up: numberauthor: stringword: stringdefid: numbercurrent_vote: stringwritten_on: stringexample: stringthumbs_down: number}async function getResultsAsChoices(query: string) {const response = await get<{ list: Definition[] }>(`https://api.urbandictionary.com/v0/define?term=${encodeURI(query)}`,)return response.data.list.map((e) =>({name: e.word,description: e.definition.replaceAll(/[\[\]]/g, ""),preview: formatMdDefinition(e),value: e.permalink,}) as Choice<string>,)}function formatMdDefinition(def: Definition) {const parts: string[] = []parts.push(`# ${def.word}`)parts.push(f(def.definition))parts.push("<br><br>")parts.push(`<i>${f(def.example)}</i>`)parts.push("<br><br>")const timestamp = DateTime.fromISO(def.written_on).toFormat("MMMM d, yyyy")const author =def.author && `by [${def.author}](https://www.urbandictionary.com/author.php?author=${encodeURI(def.author)})`parts.push(`<b>${author ? `${author} ` : ""}${timestamp}</b>`)parts.push("<br>")parts.push(`👍 ${def.thumbs_up} | 👎 ${def.thumbs_down}`)return md(parts.join("\n"))}function f(val: string) {const result = val.replaceAll("\r\n", "\n")return result.replaceAll(/\[(.*?)]/g, (substring: string, ...args: any[]) => {const term = escapeHTML(args[0])return `[${term}](https://www.urbandictionary.com/define.php?term=${encodeURI(term)})`})}
// Name: Generate scripts.d.ts// Description: Enables autocompletion for the `run` commandimport "@johnlindquist/kit"import { writeFile } from "node:fs/promises"const scripts = await getScripts()const availableScripts = scripts.map((x) => ` | "${x.command}"`).join("\n")const body = `// Do not edit. Autogenerated by generate-scripts-declarations.tsimport type { Run } from "../../.kit/types/kit"type AvailableScript =${availableScripts};declare module "@johnlindquist/kit/types/kit" {export interface Run {// biome-ignore lint/style/useShorthandFunctionType: <explanation>(command?: AvailableScript, ...args: string[]): Promise<any>}}declare global {var run: Run}`await ensureDir(kenvPath("@types"))await writeFile(kenvPath("@types", "scripts.d.ts"), body, { encoding: "utf-8" })
**/.idea/GitLink.xml
**/.idea/deploymentTargetDropDown.xml
**/.idea/gbrowser_project.xml
**/.idea/highlightedFiles.xml
**/.idea/discord.xml
**/.idea/developer-tools.xml
**/.idea/CustomInspectionsConfig.xml
// Name: Edit global .gitignore// Description: Opens an editor with the global .gitignore file and sets it up if it doesn't existimport "@johnlindquist/kit"import { writeFile } from "node:fs/promises"import { startSpinner } from "@josxa/kit-utils"const cache = await db({ defaultEntries: [] as string[] })const DESIRED_IGNORE_PATH = home(".global.gitignore")const ensureGlobalGitIgnorePathConfigured = async () => {try {const existing = await exec("git config --global core.excludesfile")debuggerif (existing.stdout.toString() !== DESIRED_IGNORE_PATH) {await exec(`git config --global core.excludesfile "${DESIRED_IGNORE_PATH}"`)await div(`Global gitconfig file configured to be at ${DESIRED_IGNORE_PATH}`)}} catch (err) {await exec(`git config --global core.excludesfile "${DESIRED_IGNORE_PATH}"`)await div(`Global gitconfig file configured to be at ${DESIRED_IGNORE_PATH}`)}}await ensureGlobalGitIgnorePathConfigured()const content = await ensureReadFile(DESIRED_IGNORE_PATH, "", { encoding: "utf-8" })const updated = ensureDefaultEntriesPresent(content).trim()if (updated !== content) {await writeFile(DESIRED_IGNORE_PATH, updated, { encoding: "utf-8" })await div("Inserted default entries and wrote to file!")}const edited = (await editor({ value: updated })).trim()if (edited !== updated) {await writeFile(DESIRED_IGNORE_PATH, edited, { encoding: "utf-8" })startSpinner("dots", { initialMessage: "Writing..." })await wait(1200)await submit("done")}cache.defaultEntries = edited.split("\n")await cache.write()function ensureDefaultEntriesPresent(content: string): string {const lines = content.split("\n")for (const x of cache.defaultEntries) {if (!lines.includes(x)) {lines.unshift(x)}}return lines.join("\n")}
// Name: Kill// Description: Immediately terminates a Windows process using `taskkill /F /im <name.exe>`// Keyword: kill// Pass: trueimport '@johnlindquist/kit'import { Choice } from '@johnlindquist/kit'const cache = await db({ recents: ["node.exe"] as string[] })const exe = arg.pass ?? await arg('Type the name of a .exe to kill', cache.recents.map(x => {if (x === 'node.exe') {return {name: x,description: "CAUTION: This will stop all Kit Scripts (including this one, so there won't be an output)",value: x} as Choice}return x}))cache.recents = Array.from(new Set(cache.recents).add(exe))cache.write().then()try {const res = await exec(`taskkill /F /im "${exe}"`)await div(res.stdout + res.stderr)} catch (err) {if (err.exitCode === 128) {await div('No process was active.')}console.error(err);exit()}