@mudah-cli/console 0.1.0
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/dist/command.d.ts +53 -0
- package/dist/command.js +76 -0
- package/dist/command.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/help.d.ts +9 -0
- package/dist/help.js +69 -0
- package/dist/help.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel.d.ts +37 -0
- package/dist/kernel.js +100 -0
- package/dist/kernel.js.map +1 -0
- package/dist/prompts.d.ts +27 -0
- package/dist/prompts.js +65 -0
- package/dist/prompts.js.map +1 -0
- package/dist/signature.d.ts +37 -0
- package/dist/signature.js +99 -0
- package/dist/signature.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UsageError, type Application } from '@mudah-cli/core';
|
|
2
|
+
import type { Output } from '@mudah-cli/ui';
|
|
3
|
+
import { Prompts } from './prompts.js';
|
|
4
|
+
import { type ParsedInput, type ParsedSignature } from './signature.js';
|
|
5
|
+
/**
|
|
6
|
+
* Base class for all Mudah commands.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* class Greet extends Command {
|
|
10
|
+
* signature = 'greet {name?} [--shout]';
|
|
11
|
+
* description = 'Say hello.';
|
|
12
|
+
*
|
|
13
|
+
* async handle() {
|
|
14
|
+
* this.output.success(`Hello, ${this.arg('name') ?? 'world'}!`);
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* The kernel injects `app`, `output`, and `input` before calling
|
|
20
|
+
* `handle()`, which returns the process exit code (void = 0).
|
|
21
|
+
*/
|
|
22
|
+
export declare abstract class Command {
|
|
23
|
+
/** Signature string: `name {arg?} [--flag=]`. */
|
|
24
|
+
signature: string;
|
|
25
|
+
/** One-line description for help output. */
|
|
26
|
+
description: string;
|
|
27
|
+
/** The application (container, config, events). */
|
|
28
|
+
app: Application;
|
|
29
|
+
/** Styled output for the user. */
|
|
30
|
+
output: Output;
|
|
31
|
+
/** Parsed positional args and options. */
|
|
32
|
+
input: ParsedInput;
|
|
33
|
+
private prompts;
|
|
34
|
+
protected parsedSignature(): ParsedSignature;
|
|
35
|
+
/** The kernel sets this before `handle()`. */
|
|
36
|
+
__inject(app: Application, output: Output, input: ParsedInput): void;
|
|
37
|
+
/** Abstract entry point. Return an exit code, or void for 0. */
|
|
38
|
+
abstract handle(): Promise<number | void> | number | void;
|
|
39
|
+
/** A positional argument value (or its signature default). */
|
|
40
|
+
arg(name: string): string | undefined;
|
|
41
|
+
/** An option value: boolean for flags, string for `--opt=value`. */
|
|
42
|
+
option<T extends string | boolean>(name: string): T | undefined;
|
|
43
|
+
protected promptsInstance(): Prompts;
|
|
44
|
+
protected ask(question: string, defaultValue?: string): Promise<string>;
|
|
45
|
+
protected confirm(question: string, defaultValue?: boolean): Promise<boolean>;
|
|
46
|
+
protected select(question: string, choices: string[]): Promise<string>;
|
|
47
|
+
/**
|
|
48
|
+
* Render a usage error with this command's usage line. Commands call this
|
|
49
|
+
* when their own validation fails.
|
|
50
|
+
*/
|
|
51
|
+
protected usageError(message: string, hint?: string): UsageError;
|
|
52
|
+
}
|
|
53
|
+
export { parseInput, parseSignature, ArgumentParseError, type ParsedInput, type ParsedSignature } from './signature.js';
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { UsageError } from '@mudah-cli/core';
|
|
2
|
+
import { Prompts } from './prompts.js';
|
|
3
|
+
import { parseInput, parseSignature } from './signature.js';
|
|
4
|
+
/**
|
|
5
|
+
* Base class for all Mudah commands.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* class Greet extends Command {
|
|
9
|
+
* signature = 'greet {name?} [--shout]';
|
|
10
|
+
* description = 'Say hello.';
|
|
11
|
+
*
|
|
12
|
+
* async handle() {
|
|
13
|
+
* this.output.success(`Hello, ${this.arg('name') ?? 'world'}!`);
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* The kernel injects `app`, `output`, and `input` before calling
|
|
19
|
+
* `handle()`, which returns the process exit code (void = 0).
|
|
20
|
+
*/
|
|
21
|
+
export class Command {
|
|
22
|
+
/** Signature string: `name {arg?} [--flag=]`. */
|
|
23
|
+
signature = '';
|
|
24
|
+
/** One-line description for help output. */
|
|
25
|
+
description = '';
|
|
26
|
+
/** The application (container, config, events). */
|
|
27
|
+
app;
|
|
28
|
+
/** Styled output for the user. */
|
|
29
|
+
output;
|
|
30
|
+
/** Parsed positional args and options. */
|
|
31
|
+
input;
|
|
32
|
+
prompts = null;
|
|
33
|
+
parsedSignature() {
|
|
34
|
+
return parseSignature(this.signature);
|
|
35
|
+
}
|
|
36
|
+
/** The kernel sets this before `handle()`. */
|
|
37
|
+
__inject(app, output, input) {
|
|
38
|
+
this.app = app;
|
|
39
|
+
this.output = output;
|
|
40
|
+
this.input = input;
|
|
41
|
+
}
|
|
42
|
+
/** A positional argument value (or its signature default). */
|
|
43
|
+
arg(name) {
|
|
44
|
+
return this.input.args[name];
|
|
45
|
+
}
|
|
46
|
+
/** An option value: boolean for flags, string for `--opt=value`. */
|
|
47
|
+
option(name) {
|
|
48
|
+
return this.input.options[name];
|
|
49
|
+
}
|
|
50
|
+
promptsInstance() {
|
|
51
|
+
if (!this.prompts)
|
|
52
|
+
this.prompts = new Prompts();
|
|
53
|
+
return this.prompts;
|
|
54
|
+
}
|
|
55
|
+
ask(question, defaultValue) {
|
|
56
|
+
return this.promptsInstance().ask(question, { defaultValue });
|
|
57
|
+
}
|
|
58
|
+
confirm(question, defaultValue) {
|
|
59
|
+
return this.promptsInstance().confirm(question, { defaultValue });
|
|
60
|
+
}
|
|
61
|
+
select(question, choices) {
|
|
62
|
+
return this.promptsInstance().select(question, choices);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Render a usage error with this command's usage line. Commands call this
|
|
66
|
+
* when their own validation fails.
|
|
67
|
+
*/
|
|
68
|
+
usageError(message, hint) {
|
|
69
|
+
return new UsageError(message, {
|
|
70
|
+
hint,
|
|
71
|
+
usage: this.signature,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export { parseInput, parseSignature, ArgumentParseError } from './signature.js';
|
|
76
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoB,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAA0C,MAAM,gBAAgB,CAAC;AAEpG;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAgB,OAAO;IAC3B,iDAAiD;IACjD,SAAS,GAAG,EAAE,CAAC;IAEf,4CAA4C;IAC5C,WAAW,GAAG,EAAE,CAAC;IAEjB,mDAAmD;IACnD,GAAG,CAAe;IAClB,kCAAkC;IAClC,MAAM,CAAU;IAChB,0CAA0C;IAC1C,KAAK,CAAe;IAEZ,OAAO,GAAmB,IAAI,CAAC;IAE7B,eAAe;QACvB,OAAO,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,8CAA8C;IAC9C,QAAQ,CAAC,GAAgB,EAAE,MAAc,EAAE,KAAkB;QAC3D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAKD,8DAA8D;IAC9D,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,oEAAoE;IACpE,MAAM,CAA6B,IAAY;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAkB,CAAC;IACnD,CAAC;IAES,eAAe;QACvB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAES,GAAG,CAAC,QAAgB,EAAE,YAAqB;QACnD,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IAChE,CAAC;IAES,OAAO,CAAC,QAAgB,EAAE,YAAsB;QACxD,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IACpE,CAAC;IAES,MAAM,CAAC,QAAgB,EAAE,OAAiB;QAClD,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACO,UAAU,CAAC,OAAe,EAAE,IAAa;QACjD,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE;YAC7B,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,SAAS;SACtB,CAAC,CAAC;IACL,CAAC;CACF;AAED,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAA0C,MAAM,gBAAgB,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Output } from '@mudah-cli/ui';
|
|
2
|
+
/**
|
|
3
|
+
* Render a thrown error through the styled output and return the process
|
|
4
|
+
* exit code it maps to. Shared by the `@mudah-cli/mudah` umbrella and the test harness
|
|
5
|
+
* so both render failures identically.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderError(error: unknown, output: Output): number;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CommandCancelled, ExitError, UsageError } from '@mudah-cli/core';
|
|
2
|
+
/**
|
|
3
|
+
* Render a thrown error through the styled output and return the process
|
|
4
|
+
* exit code it maps to. Shared by the `@mudah-cli/mudah` umbrella and the test harness
|
|
5
|
+
* so both render failures identically.
|
|
6
|
+
*/
|
|
7
|
+
export function renderError(error, output) {
|
|
8
|
+
if (error instanceof UsageError) {
|
|
9
|
+
output.error(error.message);
|
|
10
|
+
if (error.usage)
|
|
11
|
+
output.hint(`Usage: ${error.usage}`);
|
|
12
|
+
if (error.hint)
|
|
13
|
+
output.hint(error.hint);
|
|
14
|
+
return 2;
|
|
15
|
+
}
|
|
16
|
+
if (error instanceof CommandCancelled) {
|
|
17
|
+
return 130;
|
|
18
|
+
}
|
|
19
|
+
if (error instanceof ExitError) {
|
|
20
|
+
if (error.message)
|
|
21
|
+
output.error(error.message);
|
|
22
|
+
return error.code;
|
|
23
|
+
}
|
|
24
|
+
output.error(error instanceof Error ? error.message : String(error));
|
|
25
|
+
if (process.env['MUDAH_DEBUG']) {
|
|
26
|
+
output.error(error instanceof Error ? (error.stack ?? '') : '');
|
|
27
|
+
}
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG1E;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,MAAc;IACxD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,KAAK,CAAC,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,OAAO;YAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/help.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CommandEntry } from './kernel.js';
|
|
2
|
+
/** The full invocation string for a command: `name {args} [options]`. */
|
|
3
|
+
export declare function formatUsage(entry: CommandEntry): string;
|
|
4
|
+
/** One-line command row for the command list. */
|
|
5
|
+
export declare function formatCommandRow(entry: CommandEntry, width: number): string;
|
|
6
|
+
/** Render the full command list. */
|
|
7
|
+
export declare function renderCommandList(appName: string, version: string, entries: CommandEntry[], lines: string[]): void;
|
|
8
|
+
/** Render single-command help. */
|
|
9
|
+
export declare function renderCommandHelp(appName: string, entry: CommandEntry, lines: string[]): void;
|
package/dist/help.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { visibleLength } from '@mudah-cli/ui';
|
|
2
|
+
/** The full invocation string for a command: `name {args} [options]`. */
|
|
3
|
+
export function formatUsage(entry) {
|
|
4
|
+
const parts = [entry.signature.name];
|
|
5
|
+
for (const arg of entry.signature.args) {
|
|
6
|
+
if (arg.optional) {
|
|
7
|
+
parts.push(arg.defaultValue !== undefined ? `{${arg.name}=${arg.defaultValue}}` : `{${arg.name}?}`);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
parts.push(arg.defaultValue !== undefined ? `{${arg.name}=${arg.defaultValue}}` : `{${arg.name}}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (entry.signature.options.length > 0) {
|
|
14
|
+
parts.push(entry.signature.options
|
|
15
|
+
.map((o) => (o.takesValue ? `--${o.name}=` : `--${o.name}`))
|
|
16
|
+
.join(' '));
|
|
17
|
+
}
|
|
18
|
+
return parts.join(' ');
|
|
19
|
+
}
|
|
20
|
+
/** One-line command row for the command list. */
|
|
21
|
+
export function formatCommandRow(entry, width) {
|
|
22
|
+
const padded = entry.name + ' '.repeat(Math.max(1, width - visibleLength(entry.name)));
|
|
23
|
+
return ` ${padded} ${entry.description}`;
|
|
24
|
+
}
|
|
25
|
+
/** Render the full command list. */
|
|
26
|
+
export function renderCommandList(appName, version, entries, lines) {
|
|
27
|
+
lines.push(`${appName} v${version}`, '');
|
|
28
|
+
if (entries.length === 0) {
|
|
29
|
+
lines.push('No commands registered.');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
lines.push('Commands:');
|
|
33
|
+
const width = Math.max(...entries.map((e) => visibleLength(e.name))) + 2;
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
lines.push(formatCommandRow(entry, width));
|
|
36
|
+
}
|
|
37
|
+
lines.push('', `Use "${appName} <command> --help" for command details.`);
|
|
38
|
+
}
|
|
39
|
+
/** Render single-command help. */
|
|
40
|
+
export function renderCommandHelp(appName, entry, lines) {
|
|
41
|
+
lines.push(`Usage: ${appName} ${formatUsage(entry)}`, '');
|
|
42
|
+
if (entry.description) {
|
|
43
|
+
lines.push('Description');
|
|
44
|
+
lines.push(` ${entry.description}`, '');
|
|
45
|
+
}
|
|
46
|
+
if (entry.signature.args.length > 0) {
|
|
47
|
+
lines.push('Arguments:');
|
|
48
|
+
const width = Math.max(...entry.signature.args.map((a) => a.name.length)) + 2;
|
|
49
|
+
for (const arg of entry.signature.args) {
|
|
50
|
+
const kind = arg.optional ? (arg.defaultValue !== undefined ? `optional (default: ${arg.defaultValue})` : 'optional') : 'required';
|
|
51
|
+
lines.push(` ${arg.name + ' '.repeat(Math.max(1, width - arg.name.length))} ${kind}`);
|
|
52
|
+
}
|
|
53
|
+
lines.push('');
|
|
54
|
+
}
|
|
55
|
+
if (entry.signature.options.length > 0) {
|
|
56
|
+
lines.push('Options:');
|
|
57
|
+
for (const option of entry.signature.options) {
|
|
58
|
+
const flag = option.takesValue ? `--${option.name}=` : `--${option.name}`;
|
|
59
|
+
const note = option.takesValue
|
|
60
|
+
? option.defaultValue !== undefined
|
|
61
|
+
? `(default: ${option.defaultValue})`
|
|
62
|
+
: ''
|
|
63
|
+
: '';
|
|
64
|
+
lines.push(` ${flag} ${note}`.trimEnd());
|
|
65
|
+
}
|
|
66
|
+
lines.push(' --help Show this help');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=help.js.map
|
package/dist/help.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Command } from './command.js';
|
|
2
|
+
export { renderError } from './errors.js';
|
|
3
|
+
export { formatCommandRow, formatUsage, renderCommandHelp, renderCommandList } from './help.js';
|
|
4
|
+
export { ConsoleKernel, type CommandEntry, type CommandModule } from './kernel.js';
|
|
5
|
+
export { Prompts, type PromptOptions } from './prompts.js';
|
|
6
|
+
export { ArgumentParseError, parseInput, parseSignature, type ParsedArg, type ParsedInput, type ParsedOption, type ParsedSignature, } from './signature.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Command } from './command.js';
|
|
2
|
+
export { renderError } from './errors.js';
|
|
3
|
+
export { formatCommandRow, formatUsage, renderCommandHelp, renderCommandList } from './help.js';
|
|
4
|
+
export { ConsoleKernel } from './kernel.js';
|
|
5
|
+
export { Prompts } from './prompts.js';
|
|
6
|
+
export { ArgumentParseError, parseInput, parseSignature, } from './signature.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,aAAa,EAAyC,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,OAAO,EAAsB,MAAM,cAAc,CAAC;AAC3D,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,cAAc,GAKf,MAAM,gBAAgB,CAAC"}
|
package/dist/kernel.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Application, type CommandModule } from '@mudah-cli/core';
|
|
2
|
+
import type { Output } from '@mudah-cli/ui';
|
|
3
|
+
import { Command, type ParsedSignature } from './command.js';
|
|
4
|
+
export type { CommandModule } from '@mudah-cli/core';
|
|
5
|
+
export interface CommandEntry {
|
|
6
|
+
name: string;
|
|
7
|
+
signature: ParsedSignature;
|
|
8
|
+
description: string;
|
|
9
|
+
factory: () => Command;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The console kernel: command registry and dispatcher.
|
|
13
|
+
*
|
|
14
|
+
* Flow for `dispatch(argv)`:
|
|
15
|
+
* 1. Resolve the command by name (UsageError when unknown/missing).
|
|
16
|
+
* 2. Emit `command.before`, boot lazy providers for this command.
|
|
17
|
+
* 3. Parse argv against the command's signature.
|
|
18
|
+
* 4. Inject app/output/input and call `handle()`.
|
|
19
|
+
* 5. Emit `command.after` with the exit code and duration.
|
|
20
|
+
*
|
|
21
|
+
* Errors propagate to the caller (the `@mudah-cli/mudah` umbrella renders them and
|
|
22
|
+
* maps them to exit codes).
|
|
23
|
+
*/
|
|
24
|
+
export declare class ConsoleKernel {
|
|
25
|
+
private readonly app;
|
|
26
|
+
private readonly output;
|
|
27
|
+
private readonly commands;
|
|
28
|
+
constructor(app: Application, output: Output);
|
|
29
|
+
/** Register a command module (default export is the command class). */
|
|
30
|
+
register(module: CommandModule): this;
|
|
31
|
+
/** All registered commands, sorted by name. */
|
|
32
|
+
list(): CommandEntry[];
|
|
33
|
+
has(name: string): boolean;
|
|
34
|
+
get(name: string): CommandEntry | undefined;
|
|
35
|
+
/** Dispatch argv (command name + arguments). Returns the exit code. */
|
|
36
|
+
dispatch(argv: string[]): Promise<number>;
|
|
37
|
+
}
|
package/dist/kernel.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { UsageError } from '@mudah-cli/core';
|
|
2
|
+
import { Command, ArgumentParseError, parseInput, parseSignature, } from './command.js';
|
|
3
|
+
/**
|
|
4
|
+
* The console kernel: command registry and dispatcher.
|
|
5
|
+
*
|
|
6
|
+
* Flow for `dispatch(argv)`:
|
|
7
|
+
* 1. Resolve the command by name (UsageError when unknown/missing).
|
|
8
|
+
* 2. Emit `command.before`, boot lazy providers for this command.
|
|
9
|
+
* 3. Parse argv against the command's signature.
|
|
10
|
+
* 4. Inject app/output/input and call `handle()`.
|
|
11
|
+
* 5. Emit `command.after` with the exit code and duration.
|
|
12
|
+
*
|
|
13
|
+
* Errors propagate to the caller (the `@mudah-cli/mudah` umbrella renders them and
|
|
14
|
+
* maps them to exit codes).
|
|
15
|
+
*/
|
|
16
|
+
export class ConsoleKernel {
|
|
17
|
+
app;
|
|
18
|
+
output;
|
|
19
|
+
commands = new Map();
|
|
20
|
+
constructor(app, output) {
|
|
21
|
+
this.app = app;
|
|
22
|
+
this.output = output;
|
|
23
|
+
}
|
|
24
|
+
/** Register a command module (default export is the command class). */
|
|
25
|
+
register(module) {
|
|
26
|
+
const Ctor = module.default;
|
|
27
|
+
// Metadata is read from an instance: `signature`/`description` are
|
|
28
|
+
// instance fields (not prototype properties).
|
|
29
|
+
const instance = new Ctor();
|
|
30
|
+
if (typeof instance.signature !== 'string' || instance.signature.length === 0) {
|
|
31
|
+
throw new Error(`[console] Command ${Ctor.name} has no signature.`);
|
|
32
|
+
}
|
|
33
|
+
if (typeof instance.handle !== 'function') {
|
|
34
|
+
throw new Error(`[console] Command ${Ctor.name} has no handle() method.`);
|
|
35
|
+
}
|
|
36
|
+
const signature = parseSignature(instance.signature);
|
|
37
|
+
if (this.commands.has(signature.name)) {
|
|
38
|
+
throw new Error(`[console] Duplicate command name "${signature.name}".`);
|
|
39
|
+
}
|
|
40
|
+
this.commands.set(signature.name, {
|
|
41
|
+
name: signature.name,
|
|
42
|
+
signature,
|
|
43
|
+
description: instance.description ?? '',
|
|
44
|
+
factory: () => new Ctor(),
|
|
45
|
+
});
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
/** All registered commands, sorted by name. */
|
|
49
|
+
list() {
|
|
50
|
+
return [...this.commands.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
51
|
+
}
|
|
52
|
+
has(name) {
|
|
53
|
+
return this.commands.has(name);
|
|
54
|
+
}
|
|
55
|
+
get(name) {
|
|
56
|
+
return this.commands.get(name);
|
|
57
|
+
}
|
|
58
|
+
/** Dispatch argv (command name + arguments). Returns the exit code. */
|
|
59
|
+
async dispatch(argv) {
|
|
60
|
+
const name = argv[0];
|
|
61
|
+
if (name === undefined) {
|
|
62
|
+
throw new UsageError('No command specified.', {
|
|
63
|
+
hint: 'Run with --help to see available commands.',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const entry = this.commands.get(name);
|
|
67
|
+
if (!entry) {
|
|
68
|
+
throw new UsageError(`Unknown command "${name}".`, {
|
|
69
|
+
hint: 'Run with --help to see available commands.',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
await this.app.events().emit('command.before', { command: name, argv });
|
|
73
|
+
await this.app.bootLazyForCommand(name);
|
|
74
|
+
let input;
|
|
75
|
+
try {
|
|
76
|
+
input = parseInput(entry.signature, argv.slice(1));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error instanceof ArgumentParseError) {
|
|
80
|
+
throw new UsageError(error.message, { usage: entry.signature.name });
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
const command = entry.factory();
|
|
85
|
+
command.__inject(this.app, this.output, input);
|
|
86
|
+
const startedAt = performance.now();
|
|
87
|
+
let exitCode;
|
|
88
|
+
try {
|
|
89
|
+
exitCode = (await command.handle()) ?? 0;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
await this.app.events().emit('command.error', { command: name, error });
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
const durationMs = Math.round(performance.now() - startedAt);
|
|
96
|
+
await this.app.events().emit('command.after', { command: name, exitCode, durationMs });
|
|
97
|
+
return exitCode;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=kernel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel.js","sourceRoot":"","sources":["../src/kernel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface PromptOptions {
|
|
2
|
+
input?: NodeJS.ReadStream;
|
|
3
|
+
output?: NodeJS.WritableStream;
|
|
4
|
+
/** Bypasses the raw-mode UI entirely (used in tests and non-interactive runs). */
|
|
5
|
+
forcedValue?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Minimal interactive prompts built on `node:readline` (text/confirm) and a
|
|
9
|
+
* numbered fallback for selects. Raw-mode arrow-key selection lands in v0.2;
|
|
10
|
+
* the interface is already designed for it.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Prompts {
|
|
13
|
+
private rl;
|
|
14
|
+
private makeReader;
|
|
15
|
+
/** Ask a free-text question. Returns the default when the user presses enter. */
|
|
16
|
+
ask(question: string, options?: PromptOptions & {
|
|
17
|
+
defaultValue?: string;
|
|
18
|
+
}): Promise<string>;
|
|
19
|
+
/** Ask a yes/no question. */
|
|
20
|
+
confirm(question: string, options?: PromptOptions & {
|
|
21
|
+
defaultValue?: boolean;
|
|
22
|
+
}): Promise<boolean>;
|
|
23
|
+
/** Pick one of the choices by index (1-based). Returns the choice value. */
|
|
24
|
+
select(question: string, choices: string[], options?: PromptOptions): Promise<string>;
|
|
25
|
+
/** Close the underlying readline interface. */
|
|
26
|
+
dispose(): void;
|
|
27
|
+
}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as readline from 'node:readline';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal interactive prompts built on `node:readline` (text/confirm) and a
|
|
4
|
+
* numbered fallback for selects. Raw-mode arrow-key selection lands in v0.2;
|
|
5
|
+
* the interface is already designed for it.
|
|
6
|
+
*/
|
|
7
|
+
export class Prompts {
|
|
8
|
+
rl = null;
|
|
9
|
+
makeReader() {
|
|
10
|
+
if (!this.rl) {
|
|
11
|
+
this.rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: process.stdin.isTTY === true });
|
|
12
|
+
}
|
|
13
|
+
return this.rl;
|
|
14
|
+
}
|
|
15
|
+
/** Ask a free-text question. Returns the default when the user presses enter. */
|
|
16
|
+
async ask(question, options = {}) {
|
|
17
|
+
if (options.forcedValue !== undefined)
|
|
18
|
+
return options.forcedValue;
|
|
19
|
+
const rl = this.makeReader();
|
|
20
|
+
const suffix = options.defaultValue !== undefined ? ` (${options.defaultValue})` : '';
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
rl.question(`${question}${suffix} `, (answer) => {
|
|
23
|
+
resolve(answer.trim() === '' && options.defaultValue !== undefined ? options.defaultValue : answer.trim());
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Ask a yes/no question. */
|
|
28
|
+
async confirm(question, options = {}) {
|
|
29
|
+
if (options.forcedValue !== undefined) {
|
|
30
|
+
const value = options.forcedValue.trim().toLowerCase();
|
|
31
|
+
return value === 'y' || value === 'yes' || value === 'true' || value === '1';
|
|
32
|
+
}
|
|
33
|
+
const def = options.defaultValue ?? false;
|
|
34
|
+
const answer = await this.ask(`${question} [${def ? 'Y/n' : 'y/N'}]`, { ...options, defaultValue: undefined });
|
|
35
|
+
if (answer === '')
|
|
36
|
+
return def;
|
|
37
|
+
return answer.toLowerCase().startsWith('y');
|
|
38
|
+
}
|
|
39
|
+
/** Pick one of the choices by index (1-based). Returns the choice value. */
|
|
40
|
+
async select(question, choices, options = {}) {
|
|
41
|
+
if (options.forcedValue !== undefined) {
|
|
42
|
+
const choice = choices[Number(options.forcedValue) - 1];
|
|
43
|
+
if (!choice)
|
|
44
|
+
throw new Error(`[console] Forced select value "${options.forcedValue}" is out of range.`);
|
|
45
|
+
return choice;
|
|
46
|
+
}
|
|
47
|
+
process.stderr.write(`\n${question}\n`);
|
|
48
|
+
choices.forEach((choice, i) => {
|
|
49
|
+
process.stderr.write(` ${i + 1}. ${choice}\n`);
|
|
50
|
+
});
|
|
51
|
+
const answer = await this.ask('Choose', options);
|
|
52
|
+
const index = Number(answer) - 1;
|
|
53
|
+
const choice = choices[index];
|
|
54
|
+
if (!choice) {
|
|
55
|
+
throw new Error(`[console] Invalid selection "${answer}".`);
|
|
56
|
+
}
|
|
57
|
+
return choice;
|
|
58
|
+
}
|
|
59
|
+
/** Close the underlying readline interface. */
|
|
60
|
+
dispose() {
|
|
61
|
+
this.rl?.close();
|
|
62
|
+
this.rl = null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAS1C;;;;GAIG;AACH,MAAM,OAAO,OAAO;IACV,EAAE,GAA8B,IAAI,CAAC;IAErC,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC;QAC/H,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,GAAG,CAAC,QAAgB,EAAE,OAAO,GAA8C,EAAE;QACjF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,WAAW,CAAC;QAClE,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC9C,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7G,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,6BAA6B;IAC7B,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,OAAO,GAA+C,EAAE;QACtF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACvD,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC;QAC/E,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/G,IAAI,MAAM,KAAK,EAAE;YAAE,OAAO,GAAG,CAAC;QAC9B,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED,4EAA4E;IAC5E,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,OAAiB,EAAE,OAAO,GAAkB,EAAE;QAC3E,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,CAAC,WAAW,oBAAoB,CAAC,CAAC;YACxG,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,IAAI,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+CAA+C;IAC/C,OAAO;QACL,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface ParsedArg {
|
|
2
|
+
name: string;
|
|
3
|
+
optional: boolean;
|
|
4
|
+
defaultValue?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ParsedOption {
|
|
7
|
+
name: string;
|
|
8
|
+
/** Takes a value (`--env=production`). */
|
|
9
|
+
takesValue: boolean;
|
|
10
|
+
defaultValue?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ParsedSignature {
|
|
13
|
+
name: string;
|
|
14
|
+
args: ParsedArg[];
|
|
15
|
+
options: ParsedOption[];
|
|
16
|
+
}
|
|
17
|
+
export interface ParsedInput {
|
|
18
|
+
args: Record<string, string>;
|
|
19
|
+
options: Record<string, string | boolean>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a command signature string:
|
|
23
|
+
*
|
|
24
|
+
* ```
|
|
25
|
+
* deploy {branch?} {ref=main} [--force] [--env=production]
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseSignature(signature: string): ParsedSignature;
|
|
29
|
+
/**
|
|
30
|
+
* Parse raw argv (everything after the command name) against a parsed
|
|
31
|
+
* signature. Positional values fill args in order; `--name` / `--name=value`
|
|
32
|
+
* fill options. Throws `ArgumentParseError` on violations.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseInput(signature: ParsedSignature, argv: string[]): ParsedInput;
|
|
35
|
+
export declare class ArgumentParseError extends Error {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a command signature string:
|
|
3
|
+
*
|
|
4
|
+
* ```
|
|
5
|
+
* deploy {branch?} {ref=main} [--force] [--env=production]
|
|
6
|
+
* ```
|
|
7
|
+
*/
|
|
8
|
+
export function parseSignature(signature) {
|
|
9
|
+
const result = { name: '', args: [], options: [] };
|
|
10
|
+
const trimmed = signature.trim();
|
|
11
|
+
const firstSpace = trimmed.search(/\s/);
|
|
12
|
+
result.name = firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace);
|
|
13
|
+
for (const match of trimmed.matchAll(/\{([^{}]+)\}/g)) {
|
|
14
|
+
const inner = match[1];
|
|
15
|
+
const parsed = /^([a-zA-Z][\w:.-]*)(\?)?(?:=(.*))?$/.exec(inner);
|
|
16
|
+
if (!parsed) {
|
|
17
|
+
throw new Error(`[console] Invalid argument syntax "{${inner}}" in signature "${signature}".`);
|
|
18
|
+
}
|
|
19
|
+
result.args.push({
|
|
20
|
+
name: parsed[1],
|
|
21
|
+
optional: parsed[2] === '?',
|
|
22
|
+
defaultValue: parsed[3],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
for (const match of trimmed.matchAll(/\[-{2}([a-zA-Z][\w-]*)(?:=([^}\]]*))?\]/g)) {
|
|
26
|
+
const name = match[1];
|
|
27
|
+
const takesValue = match[2] !== undefined;
|
|
28
|
+
result.options.push({
|
|
29
|
+
name,
|
|
30
|
+
takesValue,
|
|
31
|
+
defaultValue: takesValue ? match[2] : undefined,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse raw argv (everything after the command name) against a parsed
|
|
38
|
+
* signature. Positional values fill args in order; `--name` / `--name=value`
|
|
39
|
+
* fill options. Throws `ArgumentParseError` on violations.
|
|
40
|
+
*/
|
|
41
|
+
export function parseInput(signature, argv) {
|
|
42
|
+
const input = { args: {}, options: {} };
|
|
43
|
+
const positionals = [];
|
|
44
|
+
for (let i = 0; i < argv.length; i++) {
|
|
45
|
+
const token = argv[i];
|
|
46
|
+
if (token === '--') {
|
|
47
|
+
positionals.push(...argv.slice(i + 1));
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (token.startsWith('--')) {
|
|
51
|
+
const eq = token.indexOf('=');
|
|
52
|
+
if (eq === -1) {
|
|
53
|
+
input.options[token.slice(2)] = true;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
input.options[token.slice(2, eq)] = token.slice(eq + 1);
|
|
57
|
+
}
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
positionals.push(token);
|
|
61
|
+
}
|
|
62
|
+
// Validate unknown options.
|
|
63
|
+
const knownOptions = new Set(signature.options.map((o) => o.name));
|
|
64
|
+
for (const name of Object.keys(input.options)) {
|
|
65
|
+
if (!knownOptions.has(name)) {
|
|
66
|
+
throw new ArgumentParseError(`Unknown option "--${name}" for command "${signature.name}".`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Fill args.
|
|
70
|
+
if (positionals.length > signature.args.length) {
|
|
71
|
+
throw new ArgumentParseError(`Too many arguments for "${signature.name}": expected at most ${signature.args.length}.`);
|
|
72
|
+
}
|
|
73
|
+
signature.args.forEach((arg, index) => {
|
|
74
|
+
const value = positionals[index];
|
|
75
|
+
if (value !== undefined) {
|
|
76
|
+
input.args[arg.name] = value;
|
|
77
|
+
}
|
|
78
|
+
else if (arg.defaultValue !== undefined) {
|
|
79
|
+
input.args[arg.name] = arg.defaultValue;
|
|
80
|
+
}
|
|
81
|
+
else if (!arg.optional) {
|
|
82
|
+
throw new ArgumentParseError(`Missing required argument "${arg.name}" for command "${signature.name}".`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// Fill options with defaults.
|
|
86
|
+
for (const option of signature.options) {
|
|
87
|
+
if (input.options[option.name] === undefined) {
|
|
88
|
+
input.options[option.name] = option.takesValue ? (option.defaultValue ?? '') : false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return input;
|
|
92
|
+
}
|
|
93
|
+
export class ArgumentParseError extends Error {
|
|
94
|
+
constructor(message) {
|
|
95
|
+
super(message);
|
|
96
|
+
this.name = 'ArgumentParseError';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=signature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.js","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mudah-cli/console",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Command system: string signatures, typed dispatch, interactive prompts, and help rendering.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=26"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@mudah-cli/animation": "^0.1.0",
|
|
22
|
+
"@mudah-cli/core": "^0.1.0",
|
|
23
|
+
"@mudah-cli/terminal": "^0.1.0",
|
|
24
|
+
"@mudah-cli/ui": "^0.1.0"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
}
|
|
29
|
+
}
|