convoker 0.3.4 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/color/index.d.mts +2 -0
- package/dist/color/index.mjs +3 -0
- package/dist/{color-OlJQTTxb.mjs → color-s-N9yh90.mjs} +7 -41
- package/dist/color-s-N9yh90.mjs.map +1 -0
- package/dist/command/index.d.mts +5 -0
- package/dist/command/index.mjs +9 -0
- package/dist/{command-D2UiQBNA.mjs → command-C9QIG--8.mjs} +187 -148
- package/dist/command-C9QIG--8.mjs.map +1 -0
- package/dist/{index-Dikc5KAP.d.mts → index-C0cH9MIP.d.mts} +4 -3
- package/dist/{input-B12iaqb8.d.mts → index-C6iJZTo3.d.mts} +20 -5
- package/dist/index-CCQ6jz54.d.mts +58 -0
- package/dist/{command-BXmfoT-l.d.mts → index-OUlP1L9o.d.mts} +10 -25
- package/dist/index.d.mts +62 -43
- package/dist/index.mjs +8 -9
- package/dist/input/index.d.mts +3 -0
- package/dist/input/index.mjs +4 -0
- package/dist/{input-DRy_sVxZ.mjs → input-li13L1uf.mjs} +5 -3
- package/dist/input-li13L1uf.mjs.map +1 -0
- package/dist/prompt/index.d.mts +3 -3
- package/dist/prompt/index.mjs +5 -6
- package/dist/prompt/raw.mjs +1 -2
- package/dist/{prompt-Cvufljin.mjs → prompt-OXGrAkDf.mjs} +30 -58
- package/dist/prompt-OXGrAkDf.mjs.map +1 -0
- package/dist/raw-BqvlveTU.d.mts +2 -1
- package/dist/{raw--889icsd.mjs → raw-DVT5lw11.mjs} +4 -21
- package/dist/raw-DVT5lw11.mjs.map +1 -0
- package/dist/{standard-schema-DLeKaehR.d.mts → standard-schema-D1sStgzy.d.mts} +3 -2
- package/dist/standard-schema-WhGEzW0C.mjs +32 -0
- package/dist/standard-schema-WhGEzW0C.mjs.map +1 -0
- package/dist/{utils-ChmY93uA.mjs → theme-Chg3mOhZ.mjs} +36 -13
- package/dist/theme-Chg3mOhZ.mjs.map +1 -0
- package/dist/theme-EERPMtQU.d.mts +115 -0
- package/dist/theme.d.mts +2 -0
- package/dist/theme.mjs +4 -0
- package/package.json +18 -17
- package/dist/color-BuHvMolk.d.mts +0 -158
- package/dist/color.d.mts +0 -2
- package/dist/color.mjs +0 -4
- package/dist/command.d.mts +0 -5
- package/dist/command.mjs +0 -10
- package/dist/error-C1S1gs8L.mjs +0 -115
- package/dist/error.d.mts +0 -5
- package/dist/error.mjs +0 -3
- package/dist/input.d.mts +0 -3
- package/dist/input.mjs +0 -5
- package/dist/standard-schema-DBXbMy6L.mjs +0 -17
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { t as __export } from "./chunk-z5eko27R.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import { r as
|
|
5
|
-
import
|
|
6
|
-
import
|
|
2
|
+
import { t as DEFAULT_THEME } from "./theme-Chg3mOhZ.mjs";
|
|
3
|
+
import { n as InputValidationError, t as validate } from "./standard-schema-WhGEzW0C.mjs";
|
|
4
|
+
import { a as readKey, i as raw_exports, o as readLine, r as cursorUp, t as clearLines } from "./raw-DVT5lw11.mjs";
|
|
5
|
+
import childProcess from "node:child_process";
|
|
6
|
+
import fs from "node:fs/promises";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import os from "node:os";
|
|
7
9
|
|
|
8
10
|
//#region src/prompt/index.ts
|
|
9
11
|
var prompt_exports = /* @__PURE__ */ __export({
|
|
@@ -37,7 +39,7 @@ async function text(opts) {
|
|
|
37
39
|
if (opts.maxLength && answer.length > opts.maxLength) throw new InputValidationError([`Must be at most ${opts.maxLength} characters`]);
|
|
38
40
|
if (typeof opts.validate === "function") {
|
|
39
41
|
if (!opts.validate(answer)) throw new InputValidationError(["Validation function returned a falsy value"]);
|
|
40
|
-
} else if (opts.validate) validate(opts.validate, answer);
|
|
42
|
+
} else if (opts.validate) await validate(opts.validate, answer);
|
|
41
43
|
return answer;
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
@@ -120,7 +122,7 @@ async function multiselect(opts) {
|
|
|
120
122
|
else if (key === "down" && index < options.length - 1) index++;
|
|
121
123
|
else if (key === "space") if (selected.has(index)) selected.delete(index);
|
|
122
124
|
else selected.add(index);
|
|
123
|
-
else if (key === "
|
|
125
|
+
else if (key === "enter") {
|
|
124
126
|
const chosen = Array.from(selected).map((i) => options[i].value);
|
|
125
127
|
clearLines(options.length + 1);
|
|
126
128
|
console.log(th.success(`${opts.message} ${chosen.length} selected`));
|
|
@@ -144,10 +146,10 @@ async function search(opts) {
|
|
|
144
146
|
console.log(th.primary(opts.message));
|
|
145
147
|
const matches = opts.options.filter((o) => filter(query, o));
|
|
146
148
|
matches.forEach((o) => console.log(" " + (th.foreground?.(o.label) ?? o.label)));
|
|
149
|
+
if (matches.length === 1) return matches[0].value;
|
|
147
150
|
const input = await readLine(th.secondary(`Search: ${query}`));
|
|
148
|
-
if (input
|
|
151
|
+
if (!input) continue;
|
|
149
152
|
query = input;
|
|
150
|
-
if (matches.length === 1) return matches[0].value;
|
|
151
153
|
}
|
|
152
154
|
}
|
|
153
155
|
/**
|
|
@@ -193,56 +195,26 @@ async function editor(opts) {
|
|
|
193
195
|
*/
|
|
194
196
|
async function openSystemEditor(initial) {
|
|
195
197
|
const tmpFile = `edit-${Date.now()}.txt`;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const { $ } = await import("bun");
|
|
213
|
-
const path = `/tmp/${tmpFile}`;
|
|
214
|
-
await Bun.write(path, initial ?? "");
|
|
215
|
-
await $`${process.env.EDITOR ?? "vi"} ${path}`;
|
|
216
|
-
const text$1 = await Bun.file(path).text();
|
|
217
|
-
await Bun.write(path, "");
|
|
218
|
-
return text$1;
|
|
219
|
-
}
|
|
220
|
-
if (isNode) {
|
|
221
|
-
const { tmpdir } = await import("node:os");
|
|
222
|
-
const { join } = await import("node:path");
|
|
223
|
-
const { promises: fs } = await import("node:fs");
|
|
224
|
-
const { spawn } = await import("node:child_process");
|
|
225
|
-
const path = join(tmpdir(), tmpFile);
|
|
226
|
-
await fs.writeFile(path, initial ?? "", "utf8");
|
|
227
|
-
const editor$1 = process.env.EDITOR || process.env.VISUAL || (process.platform === "win32" ? "notepad" : "vi");
|
|
228
|
-
return new Promise((resolve, reject) => {
|
|
229
|
-
spawn(editor$1, [path], { stdio: "inherit" }).on("exit", async (code) => {
|
|
230
|
-
if (code !== 0) {
|
|
231
|
-
reject(/* @__PURE__ */ new Error(`${editor$1} exited with code ${code}`));
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
try {
|
|
235
|
-
const data = await fs.readFile(path, "utf8");
|
|
236
|
-
await fs.unlink(path).catch(() => {});
|
|
237
|
-
resolve(data);
|
|
238
|
-
} catch (err) {
|
|
239
|
-
reject(err);
|
|
240
|
-
}
|
|
241
|
-
});
|
|
198
|
+
const filePath = path.join(os.tmpdir(), tmpFile);
|
|
199
|
+
await fs.writeFile(filePath, initial ?? "", "utf8");
|
|
200
|
+
const editor$1 = process.env.EDITOR || process.env.VISUAL || (process.platform === "win32" ? "notepad" : "vi");
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
childProcess.spawn(editor$1, [filePath], { stdio: "inherit" }).on("exit", async (code) => {
|
|
203
|
+
if (code !== 0) {
|
|
204
|
+
reject(/* @__PURE__ */ new Error(`${editor$1} exited with code ${code}`));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const data = await fs.readFile(filePath, "utf8");
|
|
209
|
+
await fs.unlink(filePath).catch(() => {});
|
|
210
|
+
resolve(data);
|
|
211
|
+
} catch (err) {
|
|
212
|
+
reject(err);
|
|
213
|
+
}
|
|
242
214
|
});
|
|
243
|
-
}
|
|
244
|
-
throw new Error("Unsupported runtime for system editor.");
|
|
215
|
+
});
|
|
245
216
|
}
|
|
246
217
|
|
|
247
218
|
//#endregion
|
|
248
|
-
export { prompt_exports as a, setTheme as c, password as i, text as l, editor as n, search as o, multiselect as r, select as s, confirm as t };
|
|
219
|
+
export { prompt_exports as a, setTheme as c, password as i, text as l, editor as n, search as o, multiselect as r, select as s, confirm as t };
|
|
220
|
+
//# sourceMappingURL=prompt-OXGrAkDf.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-OXGrAkDf.mjs","names":["theme: Theme","raw.readLine","raw.readKey","editor"],"sources":["../src/prompt/index.ts"],"sourcesContent":["import childProcess from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nimport { DEFAULT_THEME, type Theme } from \"@/theme\";\nimport { validate, type StandardSchemaV1 } from \"@/input/standard-schema\";\nimport { InputValidationError } from \"@/input/error\";\nimport * as raw from \"./raw\";\n\nlet theme: Theme = DEFAULT_THEME;\n\n/**\n * Sets the theme of the prompts.\n * @param t The new theme.\n */\nexport function setTheme(t: Theme) {\n theme = t;\n}\n\n/**\n * Base options for prompts.\n */\nexport interface BaseOpts<T> {\n /**\n * The message of the prompt.\n */\n message: string;\n /**\n * An `AbortSignal` to cancel the prompt.\n */\n signal?: AbortSignal;\n /**\n * The default value.\n */\n default?: T;\n /**\n * The theme of the prompt.\n */\n theme?: Theme;\n /**\n * A validator function, or a Standard Schema validator.\n */\n validate?: StandardSchemaV1<any, T> | ((value: T) => boolean | T);\n}\n\n// -- text -- //\n\n/**\n * Options for text input.\n */\nexport interface TextOpts extends BaseOpts<string> {\n /**\n * A placeholder, displayed when the user hasn't typed anything yet.\n */\n placeholder?: string;\n /**\n * Minimum length of the input.\n */\n minLength?: number;\n /**\n * Maximum length of the input.\n */\n maxLength?: number;\n}\n\n/**\n * Prompts the user for text input.\n * @param opts Options for text input.\n * @returns The text the user typed in, or the default.\n */\nexport async function text(opts: TextOpts): Promise<string> {\n const th = opts.theme ?? theme;\n const message = th.primary(opts.message) + \" \";\n const answer = await raw.readLine(message, opts.default);\n\n if (opts.minLength && answer.length < opts.minLength)\n throw new InputValidationError([\n `Must be at least ${opts.minLength} characters`,\n ]);\n if (opts.maxLength && answer.length > opts.maxLength)\n throw new InputValidationError([\n `Must be at most ${opts.maxLength} characters`,\n ]);\n\n if (typeof opts.validate === \"function\") {\n if (!opts.validate(answer))\n throw new InputValidationError([\n \"Validation function returned a falsy value\",\n ]);\n } else if (opts.validate) {\n await validate(opts.validate, answer);\n }\n return answer;\n}\n\n// -- password -- //\n\n/**\n * Options for password input.\n */\nexport interface PasswordOpts extends TextOpts {\n /**\n * The mask for the password input.\n */\n mask?: string;\n /**\n * If the user should be asked to confirm the password, by typing it again.\n */\n confirm?: boolean;\n}\n\n/**\n * Prompts the user for a password.\n * @param opts Options for password input.\n * @returns The password.\n */\nexport async function password(opts: PasswordOpts): Promise<string> {\n const th = opts.theme ?? theme;\n const first = await raw.readLine(th.primary(opts.message) + \" \", undefined, {\n masked: true,\n maskChar: opts.mask ?? \"*\",\n });\n if (opts.confirm) {\n const second = await raw.readLine(\n th.secondary(\"Confirm password: \"),\n undefined,\n {\n masked: true,\n maskChar: opts.mask ?? \"*\",\n },\n );\n if (first !== second) throw new Error(th.error(\"Passwords do not match\"));\n }\n return first;\n}\n\n// -- select -- //\n\n/**\n * An option for select input.\n */\nexport interface SelectOption<T> {\n /**\n * The label (what gets displayed) of the select option.\n */\n label: string;\n /**\n * The value (what gets returned) of the select option.\n */\n value: T;\n /**\n * A description of the option.\n */\n hint?: string;\n /**\n * If this option is disabled.\n */\n disabled?: boolean;\n}\n\n/**\n * Options for select input.\n */\nexport interface SelectOpts<T> extends BaseOpts<T> {\n /**\n * Every option the user can pick from.\n */\n options: SelectOption<T>[];\n /**\n * The initial option selected.\n */\n initialIndex?: number;\n}\n\n/**\n * Prompts the user to select a single option.\n * @param opts Options for select input.\n * @returns The selected option's value.\n */\nexport async function select<T>(opts: SelectOpts<T>): Promise<T> {\n const th = opts.theme ?? theme;\n const options = opts.options;\n let index = opts.initialIndex ?? 0;\n\n const render = () => {\n raw.clearLines(options.length + 1);\n console.log(th.primary(opts.message));\n for (let i = 0; i < options.length; i++) {\n const o = options[i];\n const prefix = i === index ? (th.accent?.(\"> \") ?? \"> \") : \" \";\n const label = o.disabled\n ? th.secondary(o.label)\n : (th.foreground?.(o.label) ?? o.label);\n console.log(prefix + label);\n }\n };\n\n console.log(th.primary(opts.message));\n options.forEach((o, i) =>\n console.log(`${i === index ? \"> \" : \" \"}${o.label}`),\n );\n\n while (true) {\n const key = await raw.readKey();\n if (key === \"up\" && index > 0) index--;\n else if (key === \"down\" && index < options.length - 1) index++;\n else if (key === \"enter\") {\n const choice = options[index];\n if (choice.disabled) continue;\n raw.clearLines(options.length + 1);\n console.log(th.success(`${th.symbols?.success ?? \"✔\"} ${choice.label}`));\n return choice.value;\n }\n render();\n }\n}\n\n/**\n * Prompts the user to select multiple options.\n * @param opts Options for select input.\n * @returns The selected options.\n */\nexport async function multiselect<T>(opts: SelectOpts<T>): Promise<T[]> {\n const th = opts.theme ?? theme;\n const options = opts.options;\n let index = opts.initialIndex ?? 0;\n const selected = new Set<number>();\n\n const render = () => {\n raw.clearLines();\n console.log(th.primary(opts.message));\n options.forEach((opt, i) => {\n const prefix = i === index ? (th.accent?.(\"> \") ?? \"> \") : \" \";\n const mark = selected.has(i) ? th.success(\"[x]\") : \"[ ]\";\n console.log(prefix + mark + \" \" + opt.label);\n });\n };\n\n render();\n while (true) {\n const key = await raw.readKey();\n if (key === \"up\" && index > 0) index--;\n else if (key === \"down\" && index < options.length - 1) index++;\n else if (key === \"space\") {\n if (selected.has(index)) selected.delete(index);\n else selected.add(index);\n } else if (key === \"enter\") {\n const chosen = Array.from(selected).map((i) => options[i].value);\n raw.clearLines(options.length + 1);\n console.log(th.success(`${opts.message} ${chosen.length} selected`));\n return chosen;\n }\n raw.cursorUp(options.length);\n render();\n }\n}\n\n// -- search -- //\n\n/**\n * Options for search input.\n */\nexport interface SearchOpts<T> extends BaseOpts<T> {\n /**\n * Every option the user can search through.\n */\n options: SelectOption<T>[];\n /**\n * Placeholder for the search input.\n */\n placeholder?: string;\n /**\n * Minimum length for a query string.\n */\n minQueryLength?: number;\n /**\n * Filters a single option.\n * @param query The search query.\n * @param option The option to filter.\n */\n filter?(query: string, option: SelectOption<T>): boolean;\n}\n\n/**\n * Prompts the user to search through a list of options.\n * @param opts Options for search input.\n * @returns The selected option.\n */\nexport async function search<T>(opts: SearchOpts<T>): Promise<T> {\n const th = opts.theme ?? theme;\n let query = \"\";\n const filter =\n opts.filter ?? ((q, o) => o.label.toLowerCase().includes(q.toLowerCase()));\n while (true) {\n raw.clearLines();\n console.log(th.primary(opts.message));\n\n const matches = opts.options.filter((o) => filter(query, o));\n matches.forEach((o) =>\n console.log(\" \" + (th.foreground?.(o.label) ?? o.label)),\n );\n\n if (matches.length === 1) {\n return matches[0].value;\n }\n\n const input = await raw.readLine(th.secondary(`Search: ${query}`));\n if (!input) continue;\n\n query = input;\n }\n}\n\n// -- confirm -- //\n\n/**\n * Options for confirm input.\n */\nexport interface ConfirmOpts extends BaseOpts<boolean> {\n /**\n * What gets displayed for the Yes option.\n */\n yesLabel?: string;\n /**\n * What gets displayed for the No option.\n */\n noLabel?: string;\n}\n\n/**\n * Prompts the user to confirm an action.\n * @param opts Options for confirm input.\n * @returns If the user picked Yes.\n */\nexport async function confirm(opts: ConfirmOpts): Promise<boolean> {\n const th = opts.theme ?? theme;\n const yes = opts.yesLabel ?? \"y\";\n const no = opts.noLabel ?? \"n\";\n const def = opts.default ? yes : no;\n const res = await raw.readLine(\n `${th.primary(opts.message)} ${th.secondary(`[${yes}/${no}] (default: ${def})`)} `,\n );\n if (!res) return !!opts.default;\n return /^y/i.test(res.trim());\n}\n\n// -- editor -- //\n\n/**\n * Options for opening the system editor.\n */\nexport interface EditorOpts extends BaseOpts<string> {\n /**\n * The initial value.\n */\n initial?: string;\n /**\n * The language of the value.\n */\n language?: string;\n /**\n * If the input is required for continuing or not.\n */\n required?: boolean;\n}\n\n/**\n * Opens the system editor, or asks for input in the terminal as fallback.\n * @param opts Options for opening the system editor.\n * @returns The result of the system editor.\n */\nexport async function editor(opts: EditorOpts): Promise<string> {\n const th = opts.theme ?? {\n primary: (s: string) => s,\n secondary: (s: string) => s,\n };\n\n console.log(th.primary(opts.message ?? \"Please enter text:\"));\n console.log(th.secondary(\"Press Ctrl+D (or save & close editor) when done.\"));\n\n try {\n const result = await openSystemEditor(opts.initial ?? \"\");\n if (opts.required && !result.trim()) throw new Error(\"Input required.\");\n return result;\n } catch {\n // fallback: cross-runtime multiline input\n const value = await raw.readLine(\"\", opts.initial, { multiline: true });\n if (opts.required && !value.trim()) throw new Error(\"Input required.\");\n return value;\n }\n}\n\n/**\n * Opens the system editor on a temporary file.\n * @param initial Initial contents of the file.\n * @returns The contents of the file after saving.\n */\nasync function openSystemEditor(initial: string): Promise<string> {\n const tmpFile = `edit-${Date.now()}.txt`;\n const filePath = path.join(os.tmpdir(), tmpFile);\n await fs.writeFile(filePath, initial ?? \"\", \"utf8\");\n\n const editor =\n process.env.EDITOR ||\n process.env.VISUAL ||\n (process.platform === \"win32\" ? \"notepad\" : \"vi\");\n\n return new Promise((resolve, reject) => {\n const child = childProcess.spawn(editor, [filePath], { stdio: \"inherit\" });\n child.on(\"exit\", async (code: number) => {\n if (code !== 0) {\n reject(new Error(`${editor} exited with code ${code}`));\n return;\n }\n try {\n const data = await fs.readFile(filePath, \"utf8\");\n await fs.unlink(filePath).catch(() => {});\n resolve(data);\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\nexport { raw };\n"],"mappings":"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"}
|
package/dist/raw-BqvlveTU.d.mts
CHANGED
|
@@ -34,4 +34,5 @@ declare function cursorUp(n?: number): void;
|
|
|
34
34
|
*/
|
|
35
35
|
declare function cursorDown(n?: number): void;
|
|
36
36
|
//#endregion
|
|
37
|
-
export { readKey as a, raw_d_exports as i, cursorDown as n, readLine as o, cursorUp as r, clearLines as t };
|
|
37
|
+
export { readKey as a, raw_d_exports as i, cursorDown as n, readLine as o, cursorUp as r, clearLines as t };
|
|
38
|
+
//# sourceMappingURL=raw-BqvlveTU.d.mts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __export } from "./chunk-z5eko27R.mjs";
|
|
2
|
-
import
|
|
2
|
+
import readline from "node:readline";
|
|
3
3
|
|
|
4
4
|
//#region src/prompt/raw.ts
|
|
5
5
|
var raw_exports = /* @__PURE__ */ __export({
|
|
@@ -16,25 +16,7 @@ var raw_exports = /* @__PURE__ */ __export({
|
|
|
16
16
|
* @param opts Options for reading a line.
|
|
17
17
|
* @returns The line that was read.
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
|
-
if (isDeno) {
|
|
21
|
-
await Deno.stdout.write(new TextEncoder().encode(message));
|
|
22
|
-
const decoder = new TextDecoder();
|
|
23
|
-
const buf = new Uint8Array(1024);
|
|
24
|
-
let input = "";
|
|
25
|
-
while (true) {
|
|
26
|
-
const n = await Deno.stdin.read(buf);
|
|
27
|
-
if (!n) break;
|
|
28
|
-
const chunk = decoder.decode(buf.subarray(0, n));
|
|
29
|
-
if (chunk.includes("\n")) {
|
|
30
|
-
input += chunk.split("\n")[0];
|
|
31
|
-
break;
|
|
32
|
-
}
|
|
33
|
-
input += chunk;
|
|
34
|
-
}
|
|
35
|
-
return input.trim() || def || "";
|
|
36
|
-
}
|
|
37
|
-
const readline = await import("node:readline");
|
|
19
|
+
function readLine(message = "", def, opts) {
|
|
38
20
|
return new Promise((resolve) => {
|
|
39
21
|
const rl = readline.createInterface({
|
|
40
22
|
input: process.stdin,
|
|
@@ -102,4 +84,5 @@ function cursorDown(n = 1) {
|
|
|
102
84
|
}
|
|
103
85
|
|
|
104
86
|
//#endregion
|
|
105
|
-
export { readKey as a, raw_exports as i, cursorDown as n, readLine as o, cursorUp as r, clearLines as t };
|
|
87
|
+
export { readKey as a, raw_exports as i, cursorDown as n, readLine as o, cursorUp as r, clearLines as t };
|
|
88
|
+
//# sourceMappingURL=raw-DVT5lw11.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-DVT5lw11.mjs","names":[],"sources":["../src/prompt/raw.ts"],"sourcesContent":["import readline from \"node:readline\";\n\n/**\n * Reads a line from standard input.\n * @param message The message.\n * @param def Default value.\n * @param opts Options for reading a line.\n * @returns The line that was read.\n */\nexport function readLine(\n message = \"\",\n def?: string,\n opts?: { masked?: boolean; maskChar?: string; multiline?: boolean },\n): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n\n if (opts?.masked) {\n const write = (rl as any)._writeToOutput.bind(rl);\n (rl as any)._writeToOutput = (str: string) => {\n if (str.match(/^\\x1b/)) return write(str);\n if (str.endsWith(\"\\n\") || str.endsWith(\"\\r\")) return write(str);\n const mask = opts.maskChar ?? \"*\";\n write(mask.repeat(str.length));\n };\n }\n\n rl.question(message, (answer: string) => {\n rl.close();\n resolve(answer || def || \"\");\n });\n });\n}\n\n/**\n * Reads a single key from stdin.\n * @returns The key that was read.\n */\nexport async function readKey(): Promise<string> {\n return new Promise((resolve) => {\n const stdin = process.stdin;\n stdin.setRawMode(true);\n stdin.resume();\n stdin.once(\"data\", (data: Buffer) => {\n const s = data.toString();\n stdin.setRawMode(false);\n stdin.pause();\n if (s === \"\\r\" || s === \"\\n\") return resolve(\"enter\");\n if (s === \" \") return resolve(\"space\");\n if (s === \"\\u001b[A\") return resolve(\"up\");\n if (s === \"\\u001b[B\") return resolve(\"down\");\n if (s === \"\\u001b[C\") return resolve(\"right\");\n if (s === \"\\u001b[D\") return resolve(\"left\");\n return resolve(s);\n });\n });\n}\n\n/**\n * Clears `lines` amount of lines.\n * @param lines Amount of lines to clear.\n */\nexport function clearLines(lines = 1) {\n for (let i = 0; i < lines; i++) process.stdout.write(\"\\x1b[2K\\x1b[1A\");\n process.stdout.write(\"\\x1b[2K\\r\");\n}\n\n/**\n * Moves the cursor up `n` times.\n * @param n The amount of steps to move.\n */\nexport function cursorUp(n = 1) {\n process.stdout.write(`\\x1b[${n}A`);\n}\n\n/**\n * Moves the cursor down `n` times.\n * @param n The amount of steps to move.\n */\nexport function cursorDown(n = 1) {\n process.stdout.write(`\\x1b[${n}B`);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AASA,SAAgB,SACd,UAAU,IACV,KACA,MACiB;AACjB,QAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,KAAK,SAAS,gBAAgB;GAClC,OAAO,QAAQ;GACf,QAAQ,QAAQ;GAChB,UAAU;GACX,CAAC;AAEF,MAAI,MAAM,QAAQ;GAChB,MAAM,QAAS,GAAW,eAAe,KAAK,GAAG;AACjD,GAAC,GAAW,kBAAkB,QAAgB;AAC5C,QAAI,IAAI,MAAM,QAAQ,CAAE,QAAO,MAAM,IAAI;AACzC,QAAI,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,CAAE,QAAO,MAAM,IAAI;AAE/D,WADa,KAAK,YAAY,KACnB,OAAO,IAAI,OAAO,CAAC;;;AAIlC,KAAG,SAAS,UAAU,WAAmB;AACvC,MAAG,OAAO;AACV,WAAQ,UAAU,OAAO,GAAG;IAC5B;GACF;;;;;;AAOJ,eAAsB,UAA2B;AAC/C,QAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,QAAQ,QAAQ;AACtB,QAAM,WAAW,KAAK;AACtB,QAAM,QAAQ;AACd,QAAM,KAAK,SAAS,SAAiB;GACnC,MAAM,IAAI,KAAK,UAAU;AACzB,SAAM,WAAW,MAAM;AACvB,SAAM,OAAO;AACb,OAAI,MAAM,QAAQ,MAAM,KAAM,QAAO,QAAQ,QAAQ;AACrD,OAAI,MAAM,IAAK,QAAO,QAAQ,QAAQ;AACtC,OAAI,MAAM,SAAY,QAAO,QAAQ,KAAK;AAC1C,OAAI,MAAM,SAAY,QAAO,QAAQ,OAAO;AAC5C,OAAI,MAAM,SAAY,QAAO,QAAQ,QAAQ;AAC7C,OAAI,MAAM,SAAY,QAAO,QAAQ,OAAO;AAC5C,UAAO,QAAQ,EAAE;IACjB;GACF;;;;;;AAOJ,SAAgB,WAAW,QAAQ,GAAG;AACpC,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,IAAK,SAAQ,OAAO,MAAM,iBAAiB;AACtE,SAAQ,OAAO,MAAM,YAAY;;;;;;AAOnC,SAAgB,SAAS,IAAI,GAAG;AAC9B,SAAQ,OAAO,MAAM,QAAQ,EAAE,GAAG;;;;;;AAOpC,SAAgB,WAAW,IAAI,GAAG;AAChC,SAAQ,OAAO,MAAM,QAAQ,EAAE,GAAG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/standard-schema.d.ts
|
|
1
|
+
//#region src/input/standard-schema.d.ts
|
|
2
2
|
/** The Standard Schema interface. */
|
|
3
3
|
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
4
4
|
/** The Standard Schema properties. */
|
|
@@ -55,4 +55,5 @@ declare namespace StandardSchemaV1 {
|
|
|
55
55
|
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
|
-
export { StandardSchemaV1 as t };
|
|
58
|
+
export { StandardSchemaV1 as t };
|
|
59
|
+
//# sourceMappingURL=standard-schema-D1sStgzy.d.mts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/input/error.ts
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when the command fails to validate an input.
|
|
4
|
+
*/
|
|
5
|
+
var InputValidationError = class extends Error {
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new input validation error.
|
|
8
|
+
* @param messages The messages.
|
|
9
|
+
*/
|
|
10
|
+
constructor(messages) {
|
|
11
|
+
super(`Validation failed: ${messages.join(", ")}`);
|
|
12
|
+
this.messages = messages;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/input/standard-schema.ts
|
|
18
|
+
/**
|
|
19
|
+
* Validates a value.
|
|
20
|
+
* @param entry The Standard Schema validator.
|
|
21
|
+
* @param value The value to validate.
|
|
22
|
+
* @returns The validated value.
|
|
23
|
+
*/
|
|
24
|
+
async function validate(entry, value) {
|
|
25
|
+
const result = await entry["~standard"].validate(value);
|
|
26
|
+
if (result.issues) throw new InputValidationError(result.issues.map((i) => i.message));
|
|
27
|
+
return result.value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { InputValidationError as n, validate as t };
|
|
32
|
+
//# sourceMappingURL=standard-schema-WhGEzW0C.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-schema-WhGEzW0C.mjs","names":[],"sources":["../src/input/error.ts","../src/input/standard-schema.ts"],"sourcesContent":["/**\n * Thrown when the command fails to validate an input.\n */\nexport class InputValidationError extends Error {\n /**\n * A list of messages.\n */\n messages: string[];\n\n /**\n * Creates a new input validation error.\n * @param messages The messages.\n */\n constructor(messages: string[]) {\n super(`Validation failed: ${messages.join(\", \")}`);\n this.messages = messages;\n }\n}\n","// * https://standardschema.dev * //\n\nimport { InputValidationError } from \"./error\";\n\n/** The Standard Schema interface. */\nexport interface StandardSchemaV1<Input = unknown, Output = Input> {\n /** The Standard Schema properties. */\n readonly \"~standard\": StandardSchemaV1.Props<Input, Output>;\n}\n\n// eslint-disable-next-line -- this is Standard Schema\nexport declare namespace StandardSchemaV1 {\n /** The Standard Schema properties interface. */\n export interface Props<Input = unknown, Output = Input> {\n /** The version number of the standard. */\n readonly version: 1;\n /** The vendor name of the schema library. */\n readonly vendor: string;\n /** Validates unknown input values. */\n readonly validate: (\n value: unknown,\n ) => Result<Output> | Promise<Result<Output>>;\n /** Inferred types associated with the schema. */\n readonly types?: Types<Input, Output> | undefined;\n }\n\n /** The result interface of the validate function. */\n export type Result<Output> = SuccessResult<Output> | FailureResult;\n\n /** The result interface if validation succeeds. */\n export interface SuccessResult<Output> {\n /** The typed output value. */\n readonly value: Output;\n /** The non-existent issues. */\n readonly issues?: undefined;\n }\n\n /** The result interface if validation fails. */\n export interface FailureResult {\n /** The issues of failed validation. */\n readonly issues: ReadonlyArray<Issue>;\n }\n\n /** The issue interface of the failure output. */\n export interface Issue {\n /** The error message of the issue. */\n readonly message: string;\n /** The path of the issue, if any. */\n readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;\n }\n\n /** The path segment interface of the issue. */\n export interface PathSegment {\n /** The key representing a path segment. */\n readonly key: PropertyKey;\n }\n\n /** The Standard Schema types interface. */\n export interface Types<Input = unknown, Output = Input> {\n /** The input type of the schema. */\n readonly input: Input;\n /** The output type of the schema. */\n readonly output: Output;\n }\n\n /** Infers the input type of a Standard Schema. */\n export type InferInput<Schema extends StandardSchemaV1> = NonNullable<\n Schema[\"~standard\"][\"types\"]\n >[\"input\"];\n\n /** Infers the output type of a Standard Schema. */\n export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<\n Schema[\"~standard\"][\"types\"]\n >[\"output\"];\n}\n\n/**\n * Validates a value.\n * @param entry The Standard Schema validator.\n * @param value The value to validate.\n * @returns The validated value.\n */\nexport async function validate<T extends StandardSchemaV1<any, any>>(\n entry: T,\n value: any,\n): Promise<T extends StandardSchemaV1<any, infer Out> ? Out : never> {\n const result = await entry[\"~standard\"].validate(value);\n if (result.issues) {\n const msgs = result.issues.map((i) => i.message);\n throw new InputValidationError(msgs);\n }\n\n return result.value;\n}\n"],"mappings":";;;;AAGA,IAAa,uBAAb,cAA0C,MAAM;;;;;CAU9C,YAAY,UAAoB;AAC9B,QAAM,sBAAsB,SAAS,KAAK,KAAK,GAAG;AAClD,OAAK,WAAW;;;;;;;;;;;;ACmEpB,eAAsB,SACpB,OACA,OACmE;CACnE,MAAM,SAAS,MAAM,MAAM,aAAa,SAAS,MAAM;AACvD,KAAI,OAAO,OAET,OAAM,IAAI,qBADG,OAAO,OAAO,KAAK,MAAM,EAAE,QAAQ,CACZ;AAGtC,QAAO,OAAO"}
|
|
@@ -1,17 +1,7 @@
|
|
|
1
|
+
import { B as underline, C as cyan, D as green, E as gray, F as red, U as yellow, b as bold, j as italic } from "./color-s-N9yh90.mjs";
|
|
2
|
+
|
|
1
3
|
//#region src/utils.ts
|
|
2
4
|
/**
|
|
3
|
-
* If the runtime is Node.js.
|
|
4
|
-
*/
|
|
5
|
-
const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
6
|
-
/**
|
|
7
|
-
* If the runtime is Deno.
|
|
8
|
-
*/
|
|
9
|
-
const isDeno = typeof Deno !== "undefined" && typeof Deno.version?.deno === "string";
|
|
10
|
-
/**
|
|
11
|
-
* If the runtime is Bun.
|
|
12
|
-
*/
|
|
13
|
-
const isBun = typeof Bun !== "undefined" && typeof Bun.version === "string";
|
|
14
|
-
/**
|
|
15
5
|
* Checks if a value is a plain object.
|
|
16
6
|
* @param value The value to check.
|
|
17
7
|
* @returns If the value is a plain object.
|
|
@@ -42,4 +32,37 @@ function merge(source, target) {
|
|
|
42
32
|
}
|
|
43
33
|
|
|
44
34
|
//#endregion
|
|
45
|
-
|
|
35
|
+
//#region src/theme.ts
|
|
36
|
+
/**
|
|
37
|
+
* The default theme.
|
|
38
|
+
*/
|
|
39
|
+
const DEFAULT_THEME = {
|
|
40
|
+
primary: cyan,
|
|
41
|
+
secondary: gray,
|
|
42
|
+
success: green,
|
|
43
|
+
warning: yellow,
|
|
44
|
+
error: red,
|
|
45
|
+
symbols: {
|
|
46
|
+
success: "✔",
|
|
47
|
+
error: "✖",
|
|
48
|
+
fatal: "✖",
|
|
49
|
+
warning: "⚠"
|
|
50
|
+
},
|
|
51
|
+
styles: {
|
|
52
|
+
bold,
|
|
53
|
+
italic,
|
|
54
|
+
underline
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Defines a theme.
|
|
59
|
+
* @param theme The (partial) theme.
|
|
60
|
+
* @returns The theme, merged with the default theme.
|
|
61
|
+
*/
|
|
62
|
+
function defineTheme(theme) {
|
|
63
|
+
return merge(DEFAULT_THEME, theme);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { defineTheme as n, merge as r, DEFAULT_THEME as t };
|
|
68
|
+
//# sourceMappingURL=theme-Chg3mOhZ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-Chg3mOhZ.mjs","names":["result: any","DEFAULT_THEME: Theme","color.cyan","color.gray","color.green","color.yellow","color.red","color.bold","color.italic","color.underline"],"sources":["../src/utils.ts","../src/theme.ts"],"sourcesContent":["/**\n * Deep `Partial<T>`.\n */\nexport type DeepPartial<T> = {\n [P in keyof T]?: DeepPartial<T[P]>;\n};\n\n/**\n * All TypeScript primitive types.\n */\ntype Primitive = string | number | boolean | symbol | null | undefined | bigint;\n\n/**\n * A plain TypeScript object.\n */\ntype PlainObject = Record<string | number | symbol, unknown>;\n\n/**\n * Merges two objects deeply.\n */\nexport type DeepMerge<T, U> = U extends Primitive\n ? T\n : T extends Primitive\n ? T\n : U extends readonly (infer TItem)[]\n ? T extends readonly (infer UItem)[]\n ? Array<DeepMerge<TItem, UItem>>\n : T\n : U extends PlainObject\n ? T extends PlainObject\n ? {\n [K in keyof U | keyof T]: K extends keyof T\n ? K extends keyof U\n ? DeepMerge<U[K], T[K]>\n : T[K]\n : K extends keyof U\n ? U[K]\n : never;\n }\n : T\n : T;\n\n/**\n * Checks if a value is a plain object.\n * @param value The value to check.\n * @returns If the value is a plain object.\n */\nfunction isPlainObject(value: any): value is Record<string, any> {\n return (\n value !== null &&\n typeof value === \"object\" &&\n Object.getPrototypeOf(value) === Object.prototype\n );\n}\n\n/**\n * Merges two objects deeply.\n * @param source The source object.\n * @param target The target object.\n * @returns The merged objects.\n */\nexport function merge<T, U>(source: T, target: U): DeepMerge<T, U> {\n if (Array.isArray(source) && Array.isArray(target)) {\n // Replace arrays\n return target as any;\n }\n\n if (isPlainObject(source) && isPlainObject(target)) {\n const result: any = {};\n const keys = new Set([...Object.keys(source), ...Object.keys(target)]);\n keys.forEach((key) => {\n const sourceVal = (source as any)[key];\n const targetVal = (target as any)[key];\n\n if (sourceVal !== undefined && targetVal !== undefined) {\n result[key] = merge(sourceVal, targetVal);\n } else if (targetVal !== undefined) {\n result[key] = targetVal;\n } else {\n result[key] = sourceVal;\n }\n });\n return result;\n }\n\n // For class instances or primitives, always use target\n return target as any;\n}\n","import { merge, type DeepPartial } from \"@/utils\";\nimport * as color from \"@/color\";\n\n/**\n * A theme.\n */\nexport interface Theme {\n /**\n * Wraps a string in a background ANSI code.\n * @param a The string to wrap.\n */\n background?(a: string): string;\n /**\n * Wraps a string in a foreground ANSI code.\n * @param a The string to wrap.\n */\n foreground?(a: string): string;\n /**\n * Wraps a string in a primary ANSI code.\n * @param a The string to wrap.\n */\n primary(a: string): string;\n /**\n * Wraps a string in a secondary ANSI code.\n * @param a The string to wrap.\n */\n secondary(a: string): string;\n /**\n * Wraps a string in a accent ANSI code.\n * @param a The string to wrap.\n */\n accent?(a: string): string;\n\n /**\n * Wraps a string in a success ANSI code.\n * @param a The string to wrap.\n */\n success(a: string): string;\n /**\n * Wraps a string in a warning ANSI code.\n * @param a The string to wrap.\n */\n warning(a: string): string;\n /**\n * Wraps a string in a error ANSI code.\n * @param a The string to wrap.\n */\n error(a: string): string;\n /**\n * Wraps a string in a info ANSI code.\n * @param a The string to wrap.\n */\n info?(a: string): string;\n\n /**\n * Set of symbols for logging.\n */\n symbols?: {\n /**\n * Success message symbol.\n */\n success: string;\n /**\n * Error message symbol.\n */\n error: string;\n /**\n * Fatal error message symbol.\n */\n fatal: string;\n /**\n * Warning message symbol.\n */\n warning: string;\n /**\n * Information message symbol.\n */\n info?: string;\n };\n\n /**\n * Optional styles.\n */\n styles?: {\n /**\n * Wraps a string in a bold ANSI code.\n * @param a The string to wrap.\n */\n bold?(a: string): string;\n /**\n * Wraps a string in an italic ANSI code.\n * @param a The string to wrap.\n */\n italic?(a: string): string;\n /**\n * Wraps a string in an underline ANSI code.\n * @param a The string to wrap.\n */\n underline?(a: string): string;\n };\n}\n\n/**\n * The default theme.\n */\nexport const DEFAULT_THEME: Theme = {\n primary: color.cyan,\n secondary: color.gray,\n\n success: color.green,\n warning: color.yellow,\n error: color.red,\n\n symbols: {\n success: \"✔\",\n error: \"✖\",\n fatal: \"✖\",\n warning: \"⚠\",\n },\n\n styles: {\n bold: color.bold,\n italic: color.italic,\n underline: color.underline,\n },\n};\n\n/**\n * Defines a theme.\n * @param theme The (partial) theme.\n * @returns The theme, merged with the default theme.\n */\nexport function defineTheme(theme: DeepPartial<Theme>): Theme {\n return merge(DEFAULT_THEME, theme);\n}\n"],"mappings":";;;;;;;;AA+CA,SAAS,cAAc,OAA0C;AAC/D,QACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,eAAe,MAAM,KAAK,OAAO;;;;;;;;AAU5C,SAAgB,MAAY,QAAW,QAA4B;AACjE,KAAI,MAAM,QAAQ,OAAO,IAAI,MAAM,QAAQ,OAAO,CAEhD,QAAO;AAGT,KAAI,cAAc,OAAO,IAAI,cAAc,OAAO,EAAE;EAClD,MAAMA,SAAc,EAAE;AAEtB,EADa,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,OAAO,EAAE,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,CACjE,SAAS,QAAQ;GACpB,MAAM,YAAa,OAAe;GAClC,MAAM,YAAa,OAAe;AAElC,OAAI,cAAc,UAAa,cAAc,OAC3C,QAAO,OAAO,MAAM,WAAW,UAAU;YAChC,cAAc,OACvB,QAAO,OAAO;OAEd,QAAO,OAAO;IAEhB;AACF,SAAO;;AAIT,QAAO;;;;;;;;ACmBT,MAAaC,gBAAuB;CAClC,SAASC;CACT,WAAWC;CAEX,SAASC;CACT,SAASC;CACT,OAAOC;CAEP,SAAS;EACP,SAAS;EACT,OAAO;EACP,OAAO;EACP,SAAS;EACV;CAED,QAAQ;EACAC;EACEC;EACGC;EACZ;CACF;;;;;;AAOD,SAAgB,YAAY,OAAkC;AAC5D,QAAO,MAAM,eAAe,MAAM"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
//#region src/utils.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Deep `Partial<T>`.
|
|
4
|
+
*/
|
|
5
|
+
type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]> };
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/theme.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* A theme.
|
|
10
|
+
*/
|
|
11
|
+
interface Theme {
|
|
12
|
+
/**
|
|
13
|
+
* Wraps a string in a background ANSI code.
|
|
14
|
+
* @param a The string to wrap.
|
|
15
|
+
*/
|
|
16
|
+
background?(a: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Wraps a string in a foreground ANSI code.
|
|
19
|
+
* @param a The string to wrap.
|
|
20
|
+
*/
|
|
21
|
+
foreground?(a: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Wraps a string in a primary ANSI code.
|
|
24
|
+
* @param a The string to wrap.
|
|
25
|
+
*/
|
|
26
|
+
primary(a: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Wraps a string in a secondary ANSI code.
|
|
29
|
+
* @param a The string to wrap.
|
|
30
|
+
*/
|
|
31
|
+
secondary(a: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Wraps a string in a accent ANSI code.
|
|
34
|
+
* @param a The string to wrap.
|
|
35
|
+
*/
|
|
36
|
+
accent?(a: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Wraps a string in a success ANSI code.
|
|
39
|
+
* @param a The string to wrap.
|
|
40
|
+
*/
|
|
41
|
+
success(a: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Wraps a string in a warning ANSI code.
|
|
44
|
+
* @param a The string to wrap.
|
|
45
|
+
*/
|
|
46
|
+
warning(a: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Wraps a string in a error ANSI code.
|
|
49
|
+
* @param a The string to wrap.
|
|
50
|
+
*/
|
|
51
|
+
error(a: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Wraps a string in a info ANSI code.
|
|
54
|
+
* @param a The string to wrap.
|
|
55
|
+
*/
|
|
56
|
+
info?(a: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Set of symbols for logging.
|
|
59
|
+
*/
|
|
60
|
+
symbols?: {
|
|
61
|
+
/**
|
|
62
|
+
* Success message symbol.
|
|
63
|
+
*/
|
|
64
|
+
success: string;
|
|
65
|
+
/**
|
|
66
|
+
* Error message symbol.
|
|
67
|
+
*/
|
|
68
|
+
error: string;
|
|
69
|
+
/**
|
|
70
|
+
* Fatal error message symbol.
|
|
71
|
+
*/
|
|
72
|
+
fatal: string;
|
|
73
|
+
/**
|
|
74
|
+
* Warning message symbol.
|
|
75
|
+
*/
|
|
76
|
+
warning: string;
|
|
77
|
+
/**
|
|
78
|
+
* Information message symbol.
|
|
79
|
+
*/
|
|
80
|
+
info?: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Optional styles.
|
|
84
|
+
*/
|
|
85
|
+
styles?: {
|
|
86
|
+
/**
|
|
87
|
+
* Wraps a string in a bold ANSI code.
|
|
88
|
+
* @param a The string to wrap.
|
|
89
|
+
*/
|
|
90
|
+
bold?(a: string): string;
|
|
91
|
+
/**
|
|
92
|
+
* Wraps a string in an italic ANSI code.
|
|
93
|
+
* @param a The string to wrap.
|
|
94
|
+
*/
|
|
95
|
+
italic?(a: string): string;
|
|
96
|
+
/**
|
|
97
|
+
* Wraps a string in an underline ANSI code.
|
|
98
|
+
* @param a The string to wrap.
|
|
99
|
+
*/
|
|
100
|
+
underline?(a: string): string;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The default theme.
|
|
105
|
+
*/
|
|
106
|
+
declare const DEFAULT_THEME: Theme;
|
|
107
|
+
/**
|
|
108
|
+
* Defines a theme.
|
|
109
|
+
* @param theme The (partial) theme.
|
|
110
|
+
* @returns The theme, merged with the default theme.
|
|
111
|
+
*/
|
|
112
|
+
declare function defineTheme(theme: DeepPartial<Theme>): Theme;
|
|
113
|
+
//#endregion
|
|
114
|
+
export { DeepPartial as i, Theme as n, defineTheme as r, DEFAULT_THEME as t };
|
|
115
|
+
//# sourceMappingURL=theme-EERPMtQU.d.mts.map
|
package/dist/theme.d.mts
ADDED
package/dist/theme.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "convoker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "A simple, type safe CLI framework for TypeScript.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/
|
|
7
|
+
"url": "git+https://github.com/sprucepad/convoker"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.mjs",
|
|
10
10
|
"types": "./dist/index.d.mts",
|
|
@@ -14,16 +14,20 @@
|
|
|
14
14
|
"import": "./dist/index.mjs"
|
|
15
15
|
},
|
|
16
16
|
"./command": {
|
|
17
|
-
"types": "./dist/command.d.mts",
|
|
18
|
-
"import": "./dist/command.mjs"
|
|
17
|
+
"types": "./dist/command/index.d.mts",
|
|
18
|
+
"import": "./dist/command/index.mjs"
|
|
19
|
+
},
|
|
20
|
+
"./theme": {
|
|
21
|
+
"types": "./dist/theme.d.mts",
|
|
22
|
+
"import": "./dist/theme.mjs"
|
|
19
23
|
},
|
|
20
24
|
"./input": {
|
|
21
|
-
"types": "./dist/
|
|
22
|
-
"import": "./dist/input.mjs"
|
|
25
|
+
"types": "./dist/input/index.d.mts",
|
|
26
|
+
"import": "./dist/input/index.mjs"
|
|
23
27
|
},
|
|
24
28
|
"./color": {
|
|
25
|
-
"types": "./dist/color.d.mts",
|
|
26
|
-
"import": "./dist/color.mjs"
|
|
29
|
+
"types": "./dist/color/index.d.mts",
|
|
30
|
+
"import": "./dist/color/index.mjs"
|
|
27
31
|
},
|
|
28
32
|
"./prompt": {
|
|
29
33
|
"types": "./dist/prompt/index.d.mts",
|
|
@@ -32,10 +36,6 @@
|
|
|
32
36
|
"./prompt/raw": {
|
|
33
37
|
"types": "./dist/prompt/raw.d.mts",
|
|
34
38
|
"import": "./dist/prompt/raw.mjs"
|
|
35
|
-
},
|
|
36
|
-
"./error": {
|
|
37
|
-
"types": "./dist/error.d.mts",
|
|
38
|
-
"import": "./dist/error.mjs"
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"type": "module",
|
|
@@ -49,10 +49,11 @@
|
|
|
49
49
|
"argv",
|
|
50
50
|
"option"
|
|
51
51
|
],
|
|
52
|
-
"author": "
|
|
52
|
+
"author": "sprucepad",
|
|
53
53
|
"license": "MIT",
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@eslint/js": "^9.36.0",
|
|
56
|
+
"@types/node": "~20.19.30",
|
|
56
57
|
"eslint": "^9.36.0",
|
|
57
58
|
"globals": "^16.4.0",
|
|
58
59
|
"prettier": "^3.6.2",
|
|
@@ -63,12 +64,12 @@
|
|
|
63
64
|
"vitest": "^3.2.4"
|
|
64
65
|
},
|
|
65
66
|
"scripts": {
|
|
66
|
-
"test": "vitest
|
|
67
|
+
"test": "vitest",
|
|
67
68
|
"build": "tsdown",
|
|
68
|
-
"check": "tsc
|
|
69
|
+
"check": "tsc",
|
|
69
70
|
"format": "prettier --check .",
|
|
70
|
-
"format
|
|
71
|
+
"format:fix": "prettier --write .",
|
|
71
72
|
"lint": "eslint .",
|
|
72
|
-
"lint
|
|
73
|
+
"lint:fix": "eslint --fix ."
|
|
73
74
|
}
|
|
74
75
|
}
|