convoker 0.3.0 → 0.3.2

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.
@@ -0,0 +1,273 @@
1
+ import { DEFAULT_THEME } from "../color";
2
+ import { validate } from "../standard-schema";
3
+ import { InputValidationError } from "../error";
4
+ import { isDeno, isNode, isBun } from "../utils";
5
+ import * as raw from "./raw";
6
+ let theme = DEFAULT_THEME;
7
+ /**
8
+ * Sets the theme of the prompts.
9
+ * @param t The new theme.
10
+ */
11
+ export function setTheme(t) {
12
+ theme = t;
13
+ }
14
+ /**
15
+ * Prompts the user for text input.
16
+ * @param opts Options for text input.
17
+ * @returns The text the user typed in, or the default.
18
+ */
19
+ export async function text(opts) {
20
+ const th = opts.theme ?? theme;
21
+ const message = th.primary(opts.message) + " ";
22
+ const answer = await raw.readLine(message, opts.default);
23
+ if (opts.minLength && answer.length < opts.minLength)
24
+ throw new InputValidationError([
25
+ `Must be at least ${opts.minLength} characters`,
26
+ ]);
27
+ if (opts.maxLength && answer.length > opts.maxLength)
28
+ throw new InputValidationError([
29
+ `Must be at most ${opts.maxLength} characters`,
30
+ ]);
31
+ if (typeof opts.validate === "function") {
32
+ if (!opts.validate(answer))
33
+ throw new InputValidationError([
34
+ "Validation function returned a falsy value",
35
+ ]);
36
+ }
37
+ else if (opts.validate) {
38
+ validate(opts.validate, answer);
39
+ }
40
+ return answer;
41
+ }
42
+ /**
43
+ * Prompts the user for a password.
44
+ * @param opts Options for password input.
45
+ * @returns The password.
46
+ */
47
+ export async function password(opts) {
48
+ const th = opts.theme ?? theme;
49
+ const first = await raw.readLine(th.primary(opts.message) + " ", undefined, {
50
+ masked: true,
51
+ maskChar: opts.mask ?? "*",
52
+ });
53
+ if (opts.confirm) {
54
+ const second = await raw.readLine(th.secondary("Confirm password: "), undefined, {
55
+ masked: true,
56
+ maskChar: opts.mask ?? "*",
57
+ });
58
+ if (first !== second)
59
+ throw new Error(th.error("Passwords do not match"));
60
+ }
61
+ return first;
62
+ }
63
+ /**
64
+ * Prompts the user to select a single option.
65
+ * @param opts Options for select input.
66
+ * @returns The selected option's value.
67
+ */
68
+ export async function select(opts) {
69
+ const th = opts.theme ?? theme;
70
+ const options = opts.options;
71
+ let index = opts.initialIndex ?? 0;
72
+ const render = () => {
73
+ raw.clearLines(options.length + 1);
74
+ console.log(th.primary(opts.message));
75
+ for (let i = 0; i < options.length; i++) {
76
+ const o = options[i];
77
+ const prefix = i === index ? (th.accent?.("> ") ?? "> ") : " ";
78
+ const label = o.disabled
79
+ ? th.secondary(o.label)
80
+ : (th.foreground?.(o.label) ?? o.label);
81
+ console.log(prefix + label);
82
+ }
83
+ };
84
+ console.log(th.primary(opts.message));
85
+ options.forEach((o, i) => console.log(`${i === index ? "> " : " "}${o.label}`));
86
+ while (true) {
87
+ const key = await raw.readKey();
88
+ if (key === "up" && index > 0)
89
+ index--;
90
+ else if (key === "down" && index < options.length - 1)
91
+ index++;
92
+ else if (key === "enter") {
93
+ const choice = options[index];
94
+ if (choice.disabled)
95
+ continue;
96
+ raw.clearLines(options.length + 1);
97
+ console.log(th.success(`${th.symbols?.success ?? "✔"} ${choice.label}`));
98
+ return choice.value;
99
+ }
100
+ render();
101
+ }
102
+ }
103
+ /**
104
+ * Prompts the user to select multiple options.
105
+ * @param opts Options for select input.
106
+ * @returns The selected options.
107
+ */
108
+ export async function multiselect(opts) {
109
+ const th = opts.theme ?? theme;
110
+ const options = opts.options;
111
+ let index = opts.initialIndex ?? 0;
112
+ const selected = new Set();
113
+ const render = () => {
114
+ raw.clearLines();
115
+ console.log(th.primary(opts.message));
116
+ options.forEach((opt, i) => {
117
+ const prefix = i === index ? (th.accent?.("> ") ?? "> ") : " ";
118
+ const mark = selected.has(i) ? th.success("[x]") : "[ ]";
119
+ console.log(prefix + mark + " " + opt.label);
120
+ });
121
+ };
122
+ render();
123
+ while (true) {
124
+ const key = await raw.readKey();
125
+ if (key === "up" && index > 0)
126
+ index--;
127
+ else if (key === "down" && index < options.length - 1)
128
+ index++;
129
+ else if (key === "space") {
130
+ if (selected.has(index))
131
+ selected.delete(index);
132
+ else
133
+ selected.add(index);
134
+ }
135
+ else if (key === "return") {
136
+ const chosen = Array.from(selected).map((i) => options[i].value);
137
+ raw.clearLines(options.length + 1);
138
+ console.log(th.success(`${opts.message} ${chosen.length} selected`));
139
+ return chosen;
140
+ }
141
+ raw.cursorUp(options.length);
142
+ render();
143
+ }
144
+ }
145
+ /**
146
+ * Prompts the user to search through a list of options.
147
+ * @param opts Options for search input.
148
+ * @returns The selected option.
149
+ */
150
+ export async function search(opts) {
151
+ const th = opts.theme ?? theme;
152
+ let query = "";
153
+ const filter = opts.filter ?? ((q, o) => o.label.toLowerCase().includes(q.toLowerCase()));
154
+ while (true) {
155
+ raw.clearLines();
156
+ console.log(th.primary(opts.message));
157
+ const matches = opts.options.filter((o) => filter(query, o));
158
+ matches.forEach((o) => console.log(" " + (th.foreground?.(o.label) ?? o.label)));
159
+ const input = await raw.readLine(th.secondary(`Search: ${query}`));
160
+ if (input === "")
161
+ continue;
162
+ query = input;
163
+ if (matches.length === 1)
164
+ return matches[0].value;
165
+ }
166
+ }
167
+ /**
168
+ * Prompts the user to confirm an action.
169
+ * @param opts Options for confirm input.
170
+ * @returns If the user picked Yes.
171
+ */
172
+ export async function confirm(opts) {
173
+ const th = opts.theme ?? theme;
174
+ const yes = opts.yesLabel ?? "y";
175
+ const no = opts.noLabel ?? "n";
176
+ const def = opts.default ? yes : no;
177
+ const res = await raw.readLine(`${th.primary(opts.message)} ${th.secondary(`[${yes}/${no}] (default: ${def})`)} `);
178
+ if (!res)
179
+ return !!opts.default;
180
+ return /^y/i.test(res.trim());
181
+ }
182
+ /**
183
+ * Opens the system editor, or asks for input in the terminal as fallback.
184
+ * @param opts Options for opening the system editor.
185
+ * @returns The result of the system editor.
186
+ */
187
+ export async function editor(opts) {
188
+ const th = opts.theme ?? {
189
+ primary: (s) => s,
190
+ secondary: (s) => s,
191
+ };
192
+ console.log(th.primary(opts.message ?? "Please enter text:"));
193
+ console.log(th.secondary("Press Ctrl+D (or save & close editor) when done."));
194
+ try {
195
+ const result = await openSystemEditor(opts.initial ?? "");
196
+ if (opts.required && !result.trim())
197
+ throw new Error("Input required.");
198
+ return result;
199
+ }
200
+ catch {
201
+ // fallback: cross-runtime multiline input
202
+ const value = await raw.readLine("", opts.initial, { multiline: true });
203
+ if (opts.required && !value.trim())
204
+ throw new Error("Input required.");
205
+ return value;
206
+ }
207
+ }
208
+ /**
209
+ * Opens the system editor on a temporary file.
210
+ * @param initial Initial contents of the file.
211
+ * @returns The contents of the file after saving.
212
+ */
213
+ async function openSystemEditor(initial) {
214
+ const tmpFile = `edit-${Date.now()}.txt`;
215
+ if (isDeno) {
216
+ const tmpDir = Deno.env.get("TMPDIR") ?? "/tmp";
217
+ const path = `${tmpDir}/${tmpFile}`;
218
+ await Deno.writeTextFile(path, initial ?? "");
219
+ const editor = Deno.env.get("EDITOR") ?? "vi";
220
+ const p = new Deno.Command(editor, {
221
+ args: [path],
222
+ stdin: "inherit",
223
+ stdout: "inherit",
224
+ stderr: "inherit",
225
+ }).spawn();
226
+ const status = await p.status;
227
+ if (!status.success)
228
+ throw new Error(`${editor} exited with ${status.code}`);
229
+ const text = await Deno.readTextFile(path);
230
+ await Deno.remove(path).catch(() => { });
231
+ return text;
232
+ }
233
+ if (isBun) {
234
+ const { $ } = await import("bun");
235
+ const path = `/tmp/${tmpFile}`;
236
+ await Bun.write(path, initial ?? "");
237
+ const editor = process.env.EDITOR ?? "vi";
238
+ await $ `${editor} ${path}`;
239
+ const text = await Bun.file(path).text();
240
+ await Bun.write(path, ""); // or remove if supported
241
+ return text;
242
+ }
243
+ if (isNode) {
244
+ const { tmpdir } = await import("node:os");
245
+ const { join } = await import("node:path");
246
+ const { promises: fs } = await import("node:fs");
247
+ const { spawn } = await import("node:child_process");
248
+ const path = join(tmpdir(), tmpFile);
249
+ await fs.writeFile(path, initial ?? "", "utf8");
250
+ const editor = process.env.EDITOR ||
251
+ process.env.VISUAL ||
252
+ (process.platform === "win32" ? "notepad" : "vi");
253
+ return new Promise((resolve, reject) => {
254
+ const child = spawn(editor, [path], { stdio: "inherit" });
255
+ child.on("exit", async (code) => {
256
+ if (code !== 0) {
257
+ reject(new Error(`${editor} exited with code ${code}`));
258
+ return;
259
+ }
260
+ try {
261
+ const data = await fs.readFile(path, "utf8");
262
+ await fs.unlink(path).catch(() => { });
263
+ resolve(data);
264
+ }
265
+ catch (err) {
266
+ reject(err);
267
+ }
268
+ });
269
+ });
270
+ }
271
+ throw new Error("Unsupported runtime for system editor.");
272
+ }
273
+ export { raw };
@@ -1,9 +1,105 @@
1
- import "../chunks/utils-DdmSEjLc.js";
2
- import { c as s, e as o, b as c, a as i, r as n } from "../chunks/__vite-browser-external-DQYBmsno.js";
3
- export {
4
- s as clearLines,
5
- o as cursorDown,
6
- c as cursorUp,
7
- i as readKey,
8
- n as readLine
9
- };
1
+ import { isDeno } from "../utils";
2
+ /**
3
+ * Reads a line from standard input.
4
+ * @param message The message.
5
+ * @param def Default value.
6
+ * @param opts Options for reading a line.
7
+ * @returns The line that was read.
8
+ */
9
+ export async function readLine(message = "", def, opts) {
10
+ // Deno
11
+ if (isDeno) {
12
+ await Deno.stdout.write(new TextEncoder().encode(message));
13
+ const decoder = new TextDecoder();
14
+ const buf = new Uint8Array(1024);
15
+ let input = "";
16
+ while (true) {
17
+ const n = await Deno.stdin.read(buf);
18
+ if (!n)
19
+ break;
20
+ const chunk = decoder.decode(buf.subarray(0, n));
21
+ if (chunk.includes("\n")) {
22
+ input += chunk.split("\n")[0];
23
+ break;
24
+ }
25
+ input += chunk;
26
+ }
27
+ return input.trim() || def || "";
28
+ }
29
+ // Node / Bun
30
+ const readline = await import("node:readline");
31
+ return new Promise((resolve) => {
32
+ const rl = readline.createInterface({
33
+ input: process.stdin,
34
+ output: process.stdout,
35
+ terminal: true,
36
+ });
37
+ if (opts?.masked) {
38
+ const write = rl._writeToOutput.bind(rl);
39
+ rl._writeToOutput = (str) => {
40
+ if (str.match(/^\x1b/))
41
+ return write(str);
42
+ if (str.endsWith("\n") || str.endsWith("\r"))
43
+ return write(str);
44
+ const mask = opts.maskChar ?? "*";
45
+ write(mask.repeat(str.length));
46
+ };
47
+ }
48
+ rl.question(message, (answer) => {
49
+ rl.close();
50
+ resolve(answer || def || "");
51
+ });
52
+ });
53
+ }
54
+ /**
55
+ * Reads a single key from stdin.
56
+ * @returns The key that was read.
57
+ */
58
+ export async function readKey() {
59
+ return new Promise((resolve) => {
60
+ const stdin = process.stdin;
61
+ stdin.setRawMode(true);
62
+ stdin.resume();
63
+ stdin.once("data", (data) => {
64
+ const s = data.toString();
65
+ stdin.setRawMode(false);
66
+ stdin.pause();
67
+ if (s === "\r" || s === "\n")
68
+ return resolve("enter");
69
+ if (s === " ")
70
+ return resolve("space");
71
+ if (s === "\u001b[A")
72
+ return resolve("up");
73
+ if (s === "\u001b[B")
74
+ return resolve("down");
75
+ if (s === "\u001b[C")
76
+ return resolve("right");
77
+ if (s === "\u001b[D")
78
+ return resolve("left");
79
+ return resolve(s);
80
+ });
81
+ });
82
+ }
83
+ /**
84
+ * Clears `lines` amount of lines.
85
+ * @param lines Amount of lines to clear.
86
+ */
87
+ export function clearLines(lines = 1) {
88
+ for (let i = 0; i < lines; i++)
89
+ process.stdout.write("\x1b[2K\x1b[1A");
90
+ process.stdout.write("\x1b[2K\r");
91
+ }
92
+ /**
93
+ * Moves the cursor up `n` times.
94
+ * @param n The amount of steps to move.
95
+ */
96
+ export function cursorUp(n = 1) {
97
+ process.stdout.write(`\x1b[${n}A`);
98
+ }
99
+ /**
100
+ * Moves the cursor down `n` times.
101
+ * @param n The amount of steps to move.
102
+ */
103
+ export function cursorDown(n = 1) {
104
+ process.stdout.write(`\x1b[${n}B`);
105
+ }
@@ -0,0 +1,62 @@
1
+ /** The Standard Schema interface. */
2
+ export interface StandardSchemaV1<Input = unknown, Output = Input> {
3
+ /** The Standard Schema properties. */
4
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
5
+ }
6
+ export declare namespace StandardSchemaV1 {
7
+ /** The Standard Schema properties interface. */
8
+ interface Props<Input = unknown, Output = Input> {
9
+ /** The version number of the standard. */
10
+ readonly version: 1;
11
+ /** The vendor name of the schema library. */
12
+ readonly vendor: string;
13
+ /** Validates unknown input values. */
14
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
15
+ /** Inferred types associated with the schema. */
16
+ readonly types?: Types<Input, Output> | undefined;
17
+ }
18
+ /** The result interface of the validate function. */
19
+ type Result<Output> = SuccessResult<Output> | FailureResult;
20
+ /** The result interface if validation succeeds. */
21
+ interface SuccessResult<Output> {
22
+ /** The typed output value. */
23
+ readonly value: Output;
24
+ /** The non-existent issues. */
25
+ readonly issues?: undefined;
26
+ }
27
+ /** The result interface if validation fails. */
28
+ interface FailureResult {
29
+ /** The issues of failed validation. */
30
+ readonly issues: ReadonlyArray<Issue>;
31
+ }
32
+ /** The issue interface of the failure output. */
33
+ interface Issue {
34
+ /** The error message of the issue. */
35
+ readonly message: string;
36
+ /** The path of the issue, if any. */
37
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
38
+ }
39
+ /** The path segment interface of the issue. */
40
+ interface PathSegment {
41
+ /** The key representing a path segment. */
42
+ readonly key: PropertyKey;
43
+ }
44
+ /** The Standard Schema types interface. */
45
+ interface Types<Input = unknown, Output = Input> {
46
+ /** The input type of the schema. */
47
+ readonly input: Input;
48
+ /** The output type of the schema. */
49
+ readonly output: Output;
50
+ }
51
+ /** Infers the input type of a Standard Schema. */
52
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
53
+ /** Infers the output type of a Standard Schema. */
54
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
55
+ }
56
+ /**
57
+ * Validates a value.
58
+ * @param entry The Standard Schema validator.
59
+ * @param value The value to validate.
60
+ * @returns The validated value.
61
+ */
62
+ export declare function validate<T extends StandardSchemaV1<any, any>>(entry: T, value: any): Promise<T extends StandardSchemaV1<any, infer Out> ? Out : never>;
@@ -0,0 +1,16 @@
1
+ // * https://standardschema.dev * //
2
+ import { InputValidationError } from "./error";
3
+ /**
4
+ * Validates a value.
5
+ * @param entry The Standard Schema validator.
6
+ * @param value The value to validate.
7
+ * @returns The validated value.
8
+ */
9
+ export async function validate(entry, value) {
10
+ const result = await entry["~standard"].validate(value);
11
+ if (result.issues) {
12
+ const msgs = result.issues.map((i) => i.message);
13
+ throw new InputValidationError(msgs);
14
+ }
15
+ return result.value;
16
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * If the runtime is Node.js.
3
+ */
4
+ export declare const isNode: boolean;
5
+ /**
6
+ * If the runtime is Deno.
7
+ */
8
+ export declare const isDeno: boolean;
9
+ /**
10
+ * If the runtime is Bun.
11
+ */
12
+ export declare const isBun: boolean;
13
+ /**
14
+ * All TypeScript primitive types.
15
+ */
16
+ type Primitive = string | number | boolean | symbol | null | undefined | bigint;
17
+ /**
18
+ * Merges two objects deeply.
19
+ */
20
+ export type DeepMerge<T, U> = T extends Primitive ? U : U extends Primitive ? U : T extends Array<infer TItem> ? U extends Array<infer UItem> ? Array<DeepMerge<TItem, UItem>> : U : T extends object ? U extends object ? {
21
+ [K in keyof T | keyof U]: K extends keyof U ? K extends keyof T ? DeepMerge<T[K], U[K]> : U[K] : K extends keyof T ? T[K] : never;
22
+ } : U : U;
23
+ /**
24
+ * Merges two objects deeply.
25
+ * @param source The source object.
26
+ * @param target The target object.
27
+ * @returns The merged objects.
28
+ */
29
+ export declare function merge<T, U>(source: T, target: U): DeepMerge<T, U>;
30
+ export {};
package/dist/utils.js ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * If the runtime is Node.js.
3
+ */
4
+ export const isNode = typeof process !== "undefined" &&
5
+ process.versions != null &&
6
+ process.versions.node != null;
7
+ /**
8
+ * If the runtime is Deno.
9
+ */
10
+ export const isDeno = typeof Deno !== "undefined" && typeof Deno.version?.deno === "string";
11
+ /**
12
+ * If the runtime is Bun.
13
+ */
14
+ export const isBun = typeof Bun !== "undefined" && typeof Bun.version === "string";
15
+ /**
16
+ * Checks if a value is a plain object.
17
+ * @param value The value to check.
18
+ * @returns If the value is a plain object.
19
+ */
20
+ function isPlainObject(value) {
21
+ return (value !== null &&
22
+ typeof value === "object" &&
23
+ Object.getPrototypeOf(value) === Object.prototype);
24
+ }
25
+ /**
26
+ * Merges two objects deeply.
27
+ * @param source The source object.
28
+ * @param target The target object.
29
+ * @returns The merged objects.
30
+ */
31
+ export function merge(source, target) {
32
+ if (Array.isArray(source) && Array.isArray(target)) {
33
+ // Replace arrays
34
+ return target;
35
+ }
36
+ if (isPlainObject(source) && isPlainObject(target)) {
37
+ const result = {};
38
+ const keys = new Set([...Object.keys(source), ...Object.keys(target)]);
39
+ keys.forEach((key) => {
40
+ const sourceVal = source[key];
41
+ const targetVal = target[key];
42
+ if (sourceVal !== undefined && targetVal !== undefined) {
43
+ result[key] = merge(sourceVal, targetVal);
44
+ }
45
+ else if (targetVal !== undefined) {
46
+ result[key] = targetVal;
47
+ }
48
+ else {
49
+ result[key] = sourceVal;
50
+ }
51
+ });
52
+ return result;
53
+ }
54
+ // For class instances or primitives, always use target
55
+ return target;
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convoker",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "A simple, type safe CLI framework for TypeScript.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "default": "./dist/color.js"
23
23
  },
24
24
  "./prompt": {
25
- "types": "./dist/prompt.js",
25
+ "types": "./dist/prompt/index.d.ts",
26
26
  "default": "./dist/prompt/index.js"
27
27
  },
28
28
  "./prompt/raw": {
@@ -52,16 +52,15 @@
52
52
  "eslint": "^9.36.0",
53
53
  "globals": "^16.4.0",
54
54
  "prettier": "^3.6.2",
55
+ "tsc-alias": "^1.8.16",
55
56
  "typescript": "^5.9.2",
56
57
  "typescript-eslint": "^8.45.0",
57
58
  "valibot": "^1.1.0",
58
- "vite": "^7.1.12",
59
- "vite-plugin-dts": "^4.5.4",
60
59
  "vitest": "^3.2.4"
61
60
  },
62
61
  "scripts": {
63
62
  "test": "vitest tests",
64
- "build": "tsc -b && vite build",
63
+ "build": "tsc -b tsconfig.app.json && tsc-alias -p tsconfig.app.json",
65
64
  "format": "prettier --check .",
66
65
  "format!": "prettier --write .",
67
66
  "lint": "eslint .",
@@ -1,80 +0,0 @@
1
- import { i as c } from "./utils-DdmSEjLc.js";
2
- async function d(e = "", t, u) {
3
- if (c) {
4
- await Deno.stdout.write(new TextEncoder().encode(e));
5
- const a = new TextDecoder(), i = new Uint8Array(1024);
6
- let n = "";
7
- for (; ; ) {
8
- const o = await Deno.stdin.read(i);
9
- if (!o) break;
10
- const s = a.decode(i.subarray(0, o));
11
- if (s.includes(`
12
- `)) {
13
- n += s.split(`
14
- `)[0];
15
- break;
16
- }
17
- n += s;
18
- }
19
- return n.trim() || t || "";
20
- }
21
- const r = await Promise.resolve().then(() => x);
22
- return new Promise((a) => {
23
- const i = r.createInterface({
24
- input: process.stdin,
25
- output: process.stdout,
26
- terminal: !0
27
- });
28
- if (u?.masked) {
29
- const n = i._writeToOutput.bind(i);
30
- i._writeToOutput = (o) => {
31
- if (o.match(/^\x1b/) || o.endsWith(`
32
- `) || o.endsWith("\r")) return n(o);
33
- const s = u.maskChar ?? "*";
34
- n(s.repeat(o.length));
35
- };
36
- }
37
- i.question(e, (n) => {
38
- i.close(), a(n || t || "");
39
- });
40
- });
41
- }
42
- async function f() {
43
- return new Promise((e) => {
44
- const t = process.stdin;
45
- t.setRawMode(!0), t.resume(), t.once("data", (u) => {
46
- const r = u.toString();
47
- return t.setRawMode(!1), t.pause(), e(r === "\r" || r === `
48
- ` ? "enter" : r === " " ? "space" : r === "\x1B[A" ? "up" : r === "\x1B[B" ? "down" : r === "\x1B[C" ? "right" : r === "\x1B[D" ? "left" : r);
49
- });
50
- });
51
- }
52
- function p(e = 1) {
53
- for (let t = 0; t < e; t++) process.stdout.write("\x1B[2K\x1B[1A");
54
- process.stdout.write("\x1B[2K\r");
55
- }
56
- function w(e = 1) {
57
- process.stdout.write(`\x1B[${e}A`);
58
- }
59
- function l(e = 1) {
60
- process.stdout.write(`\x1B[${e}B`);
61
- }
62
- const m = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
63
- __proto__: null,
64
- clearLines: p,
65
- cursorDown: l,
66
- cursorUp: w,
67
- readKey: f,
68
- readLine: d
69
- }, Symbol.toStringTag, { value: "Module" })), x = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
70
- __proto__: null
71
- }, Symbol.toStringTag, { value: "Module" }));
72
- export {
73
- x as _,
74
- f as a,
75
- w as b,
76
- p as c,
77
- m as d,
78
- l as e,
79
- d as r
80
- };