@guanghechen/commander 3.2.0 → 4.0.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/CHANGELOG.md +19 -0
- package/README.md +2 -5
- package/lib/cjs/index.cjs +501 -597
- package/lib/esm/index.mjs +501 -597
- package/lib/types/index.d.ts +152 -79
- package/package.json +1 -1
package/lib/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
7
|
* Reporter interface for logging.
|
|
8
|
-
*
|
|
8
|
+
* Provided by @guanghechen/reporter or user implementation.
|
|
9
9
|
*/
|
|
10
10
|
interface IReporter {
|
|
11
11
|
debug(message: string, ...args: unknown[]): void;
|
|
@@ -13,129 +13,193 @@ interface IReporter {
|
|
|
13
13
|
warn(message: string, ...args: unknown[]): void;
|
|
14
14
|
error(message: string, ...args: unknown[]): void;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
type
|
|
16
|
+
/** Token type: long option, short option, or positional */
|
|
17
|
+
type ICommandTokenType = 'long' | 'short' | 'none';
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Command token after preprocessing.
|
|
20
|
+
*
|
|
21
|
+
* - original: raw input for error messages (e.g., --LOG-LEVEL=info, -v)
|
|
22
|
+
* - resolved: normalized form (e.g., --logLevel=info, -v)
|
|
23
|
+
* - name: option name for matching (e.g., logLevel, v, '')
|
|
24
|
+
* - type: token type (long/short/none)
|
|
25
|
+
*/
|
|
26
|
+
interface ICommandToken {
|
|
27
|
+
/** Raw input, used for error display */
|
|
28
|
+
original: string;
|
|
29
|
+
/** Normalized form, used for parsing */
|
|
30
|
+
resolved: string;
|
|
31
|
+
/** Option name for matching: camelCase for long, single char for short, '' for positional */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Token type */
|
|
34
|
+
type: ICommandTokenType;
|
|
35
|
+
}
|
|
36
|
+
/** Option value type */
|
|
37
|
+
type ICommandOptionType = 'boolean' | 'number' | 'string';
|
|
38
|
+
/** Option argument mode */
|
|
39
|
+
type ICommandOptionArgs = 'none' | 'required' | 'variadic';
|
|
40
|
+
/**
|
|
41
|
+
* Option configuration.
|
|
42
|
+
*
|
|
43
|
+
* `type` and `args` must be specified together. Valid combinations:
|
|
44
|
+
* - boolean + none → boolean
|
|
45
|
+
* - string + required → string
|
|
46
|
+
* - number + required → number
|
|
47
|
+
* - string + variadic → string[]
|
|
48
|
+
* - number + variadic → number[]
|
|
49
|
+
*
|
|
20
50
|
* @template T - The type of the option value
|
|
21
51
|
*/
|
|
22
|
-
interface
|
|
23
|
-
/** Long option (
|
|
52
|
+
interface ICommandOptionConfig<T = unknown> {
|
|
53
|
+
/** Long option name (camelCase, required) */
|
|
24
54
|
long: string;
|
|
25
|
-
/** Short option (single character
|
|
55
|
+
/** Short option (single character) */
|
|
26
56
|
short?: string;
|
|
27
|
-
/** Value type
|
|
28
|
-
type
|
|
57
|
+
/** Value type (required) */
|
|
58
|
+
type: ICommandOptionType;
|
|
59
|
+
/** Argument mode (required) */
|
|
60
|
+
args: ICommandOptionArgs;
|
|
29
61
|
/** Description for help text */
|
|
30
|
-
|
|
31
|
-
/** Whether this option is required (
|
|
62
|
+
desc: string;
|
|
63
|
+
/** Whether this option is required (mutually exclusive with default) */
|
|
32
64
|
required?: boolean;
|
|
33
65
|
/** Default value when not provided */
|
|
34
66
|
default?: T;
|
|
35
67
|
/** Allowed values for validation and completion */
|
|
36
68
|
choices?: T extends Array<infer U> ? U[] : T[];
|
|
37
|
-
/** Single value transformation (
|
|
69
|
+
/** Single value transformation (called for each value, before choices validation) */
|
|
38
70
|
coerce?: (rawValue: string) => T extends Array<infer U> ? U : T;
|
|
39
|
-
/** Custom resolver that fully replaces builtin parsing (ignores type/coerce) */
|
|
40
|
-
resolver?: (argv: string[]) => {
|
|
41
|
-
value: T;
|
|
42
|
-
remaining: string[];
|
|
43
|
-
};
|
|
44
71
|
/** Callback after parsing, applies value to context */
|
|
45
72
|
apply?: (value: T, ctx: ICommandContext) => void;
|
|
46
73
|
}
|
|
47
74
|
/** Argument kind */
|
|
48
|
-
type
|
|
75
|
+
type ICommandArgumentKind = 'required' | 'optional' | 'variadic';
|
|
49
76
|
/** Argument value type */
|
|
50
|
-
type
|
|
77
|
+
type ICommandArgumentType = 'string' | 'number';
|
|
51
78
|
/**
|
|
52
|
-
* Positional argument
|
|
79
|
+
* Positional argument configuration.
|
|
80
|
+
*
|
|
81
|
+
* Constraints:
|
|
82
|
+
* - required arguments must come before optional
|
|
83
|
+
* - variadic can only appear once, and must be last
|
|
84
|
+
* - required cannot have default
|
|
85
|
+
*
|
|
53
86
|
* @template T - The type of the argument value
|
|
54
87
|
*/
|
|
55
|
-
interface
|
|
88
|
+
interface ICommandArgumentConfig<T = unknown> {
|
|
56
89
|
/** Argument name */
|
|
57
90
|
name: string;
|
|
58
91
|
/** Argument description */
|
|
59
|
-
|
|
92
|
+
desc: string;
|
|
60
93
|
/** Argument kind: required / optional / variadic */
|
|
61
|
-
kind:
|
|
94
|
+
kind: ICommandArgumentKind;
|
|
62
95
|
/** Value type, defaults to 'string' */
|
|
63
|
-
type?:
|
|
64
|
-
/** Default value when not provided (only
|
|
96
|
+
type?: ICommandArgumentType;
|
|
97
|
+
/** Default value when not provided (only for optional arguments) */
|
|
65
98
|
default?: T;
|
|
66
99
|
/** Custom value transformation (takes precedence over type conversion) */
|
|
67
100
|
coerce?: (rawValue: string) => T;
|
|
68
101
|
}
|
|
69
102
|
/** Command configuration */
|
|
70
103
|
interface ICommandConfig {
|
|
71
|
-
/** Command name (only
|
|
104
|
+
/** Command name (only for root command) */
|
|
72
105
|
name?: string;
|
|
73
106
|
/** Command description */
|
|
74
|
-
|
|
75
|
-
/** Version (
|
|
107
|
+
desc: string;
|
|
108
|
+
/** Version (for root --version) */
|
|
76
109
|
version?: string;
|
|
77
|
-
/** Enable built-in "help" subcommand
|
|
110
|
+
/** Enable built-in "help" subcommand */
|
|
78
111
|
help?: boolean;
|
|
112
|
+
/** Default reporter for this command */
|
|
113
|
+
reporter?: IReporter;
|
|
79
114
|
}
|
|
80
|
-
/**
|
|
115
|
+
/** Command interface */
|
|
81
116
|
interface ICommand {
|
|
82
|
-
readonly name: string;
|
|
117
|
+
readonly name: string | undefined;
|
|
83
118
|
readonly description: string;
|
|
84
119
|
readonly version: string | undefined;
|
|
85
|
-
readonly
|
|
86
|
-
readonly
|
|
120
|
+
readonly parent: ICommand | undefined;
|
|
121
|
+
readonly options: ICommandOptionConfig[];
|
|
122
|
+
readonly arguments: ICommandArgumentConfig[];
|
|
123
|
+
readonly subcommands: Map<string, ICommand>;
|
|
87
124
|
}
|
|
88
125
|
/** Execution context */
|
|
89
126
|
interface ICommandContext {
|
|
90
127
|
/** Current command node */
|
|
91
128
|
cmd: ICommand;
|
|
92
|
-
/** Environment variables
|
|
129
|
+
/** Environment variables */
|
|
93
130
|
envs: Record<string, string | undefined>;
|
|
94
131
|
/** Reporter instance */
|
|
95
132
|
reporter: IReporter;
|
|
96
133
|
/** Original argv */
|
|
97
134
|
argv: string[];
|
|
98
135
|
}
|
|
99
|
-
/** Action parameters */
|
|
100
|
-
interface
|
|
136
|
+
/** Action callback parameters */
|
|
137
|
+
interface ICommandActionParams {
|
|
101
138
|
/** Execution context */
|
|
102
139
|
ctx: ICommandContext;
|
|
103
|
-
/** Parsed options */
|
|
104
|
-
opts:
|
|
140
|
+
/** Parsed options (keyed by long name) */
|
|
141
|
+
opts: ICommandParsedOpts;
|
|
105
142
|
/** Parsed positional arguments (keyed by argument name) */
|
|
106
|
-
args:
|
|
143
|
+
args: ICommandParsedArgs;
|
|
107
144
|
/** Raw positional argument strings (before type conversion) */
|
|
108
145
|
rawArgs: string[];
|
|
109
146
|
}
|
|
110
147
|
/** Action handler function */
|
|
111
|
-
type
|
|
112
|
-
/** run() method parameters */
|
|
113
|
-
interface
|
|
148
|
+
type ICommandAction = (params: ICommandActionParams) => void | Promise<void>;
|
|
149
|
+
/** run() / parse() method parameters */
|
|
150
|
+
interface ICommandRunParams {
|
|
114
151
|
/** Command line arguments (usually process.argv.slice(2)) */
|
|
115
152
|
argv: string[];
|
|
116
153
|
/** Environment variables (usually process.env) */
|
|
117
154
|
envs: Record<string, string | undefined>;
|
|
118
|
-
/** Optional reporter
|
|
155
|
+
/** Optional reporter override */
|
|
119
156
|
reporter?: IReporter;
|
|
120
157
|
}
|
|
121
|
-
/**
|
|
122
|
-
|
|
158
|
+
/** Parsed options record */
|
|
159
|
+
type ICommandParsedOpts = Record<string, unknown>;
|
|
160
|
+
/** Parsed arguments record */
|
|
161
|
+
type ICommandParsedArgs = Record<string, unknown>;
|
|
162
|
+
/** Route stage result */
|
|
163
|
+
interface ICommandRouteResult {
|
|
164
|
+
/** Command chain from root to leaf */
|
|
165
|
+
chain: ICommand[];
|
|
166
|
+
/** Remaining argv after routing */
|
|
167
|
+
remaining: string[];
|
|
168
|
+
}
|
|
169
|
+
/** Tokenize stage result */
|
|
170
|
+
interface ICommandTokenizeResult {
|
|
171
|
+
/** Option tokens (before --) */
|
|
172
|
+
optionTokens: ICommandToken[];
|
|
173
|
+
/** Arguments after -- */
|
|
174
|
+
restArgs: string[];
|
|
175
|
+
}
|
|
176
|
+
/** Resolve stage result */
|
|
177
|
+
interface ICommandResolveResult {
|
|
178
|
+
/** Tokens consumed by each command */
|
|
179
|
+
consumedTokens: Map<ICommand, ICommandToken[]>;
|
|
180
|
+
/** Argument tokens (non-option tokens) */
|
|
181
|
+
argTokens: ICommandToken[];
|
|
182
|
+
}
|
|
183
|
+
/** shift() method result (internal) */
|
|
184
|
+
interface ICommandShiftResult {
|
|
185
|
+
/** Tokens consumed by this command */
|
|
186
|
+
consumed: ICommandToken[];
|
|
187
|
+
/** Remaining tokens to pass to parent */
|
|
188
|
+
remaining: ICommandToken[];
|
|
189
|
+
}
|
|
190
|
+
/** Parse stage result */
|
|
191
|
+
interface ICommandParseResult {
|
|
192
|
+
/** Execution context */
|
|
193
|
+
ctx: ICommandContext;
|
|
123
194
|
/** Parsed options */
|
|
124
|
-
opts:
|
|
125
|
-
/** Parsed
|
|
126
|
-
args:
|
|
127
|
-
/** Raw
|
|
195
|
+
opts: ICommandParsedOpts;
|
|
196
|
+
/** Parsed arguments */
|
|
197
|
+
args: ICommandParsedArgs;
|
|
198
|
+
/** Raw argument strings */
|
|
128
199
|
rawArgs: string[];
|
|
129
200
|
}
|
|
130
|
-
/** shift() method result */
|
|
131
|
-
interface IShiftResult {
|
|
132
|
-
/** Options consumed by this command */
|
|
133
|
-
opts: Record<string, unknown>;
|
|
134
|
-
/** Tokens not consumed, to be passed to parent */
|
|
135
|
-
remaining: string[];
|
|
136
|
-
}
|
|
137
201
|
/** Error kinds for command parsing */
|
|
138
|
-
type ICommanderErrorKind = 'UnknownOption' | 'UnexpectedArgument' | 'MissingValue' | 'InvalidType' | 'UnsupportedShortSyntax' | 'OptionConflict' | 'MissingRequired' | 'InvalidChoice' | 'InvalidBooleanValue' | 'MissingRequiredArgument' | 'TooManyArguments' | 'ConfigurationError';
|
|
202
|
+
type ICommanderErrorKind = 'InvalidOptionFormat' | 'InvalidNegativeOption' | 'NegativeOptionWithValue' | 'NegativeOptionType' | 'UnknownOption' | 'UnexpectedArgument' | 'MissingValue' | 'InvalidType' | 'UnsupportedShortSyntax' | 'OptionConflict' | 'MissingRequired' | 'InvalidChoice' | 'InvalidBooleanValue' | 'MissingRequiredArgument' | 'TooManyArguments' | 'ConfigurationError';
|
|
139
203
|
/** Commander error with structured information */
|
|
140
204
|
declare class CommanderError extends Error {
|
|
141
205
|
readonly kind: ICommanderErrorKind;
|
|
@@ -145,65 +209,74 @@ declare class CommanderError extends Error {
|
|
|
145
209
|
format(): string;
|
|
146
210
|
}
|
|
147
211
|
/** Shell type for completion */
|
|
148
|
-
type
|
|
212
|
+
type ICompletionShellType = 'bash' | 'fish' | 'pwsh';
|
|
149
213
|
/** Option metadata for completion */
|
|
150
214
|
interface ICompletionOptionMeta {
|
|
215
|
+
/** Long option name (camelCase) */
|
|
151
216
|
long: string;
|
|
217
|
+
/** Short option */
|
|
152
218
|
short?: string;
|
|
153
|
-
|
|
219
|
+
/** Description */
|
|
220
|
+
desc: string;
|
|
221
|
+
/** Whether option takes value (args !== 'none') */
|
|
154
222
|
takesValue: boolean;
|
|
223
|
+
/** Allowed values */
|
|
155
224
|
choices?: string[];
|
|
156
225
|
}
|
|
157
226
|
/** Command metadata for completion */
|
|
158
227
|
interface ICompletionMeta {
|
|
228
|
+
/** Command name */
|
|
159
229
|
name: string;
|
|
160
|
-
|
|
230
|
+
/** Description */
|
|
231
|
+
desc: string;
|
|
232
|
+
/** Command aliases */
|
|
161
233
|
aliases: string[];
|
|
234
|
+
/** Options */
|
|
162
235
|
options: ICompletionOptionMeta[];
|
|
236
|
+
/** Subcommands */
|
|
163
237
|
subcommands: ICompletionMeta[];
|
|
164
238
|
}
|
|
165
239
|
/** Shell completion paths configuration */
|
|
166
240
|
interface ICompletionPaths {
|
|
167
|
-
/** Bash completion file path
|
|
241
|
+
/** Bash completion file path */
|
|
168
242
|
bash: string;
|
|
169
|
-
/** Fish completion file path
|
|
243
|
+
/** Fish completion file path */
|
|
170
244
|
fish: string;
|
|
171
|
-
/** PowerShell completion file path
|
|
245
|
+
/** PowerShell completion file path */
|
|
172
246
|
pwsh: string;
|
|
173
247
|
}
|
|
174
248
|
/** CompletionCommand configuration */
|
|
175
249
|
interface ICompletionCommandConfig {
|
|
176
250
|
/** Program name for completion scripts (defaults to root.name) */
|
|
177
251
|
programName?: string;
|
|
178
|
-
/** Default completion file paths for each shell
|
|
252
|
+
/** Default completion file paths for each shell */
|
|
179
253
|
paths: ICompletionPaths;
|
|
180
254
|
}
|
|
181
255
|
|
|
182
256
|
/**
|
|
183
257
|
* Command class - CLI command builder with fluent API
|
|
184
258
|
*
|
|
259
|
+
* Execution flow: route → tokenize → resolve → parse → run
|
|
260
|
+
*
|
|
185
261
|
* @module @guanghechen/commander
|
|
186
262
|
*/
|
|
187
263
|
|
|
188
264
|
declare class Command implements ICommand {
|
|
189
265
|
#private;
|
|
190
266
|
constructor(config: ICommandConfig);
|
|
191
|
-
get name(): string;
|
|
267
|
+
get name(): string | undefined;
|
|
192
268
|
get description(): string;
|
|
193
269
|
get version(): string | undefined;
|
|
194
|
-
get
|
|
195
|
-
get
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
270
|
+
get parent(): Command | undefined;
|
|
271
|
+
get options(): ICommandOptionConfig[];
|
|
272
|
+
get arguments(): ICommandArgumentConfig[];
|
|
273
|
+
get subcommands(): Map<string, ICommand>;
|
|
274
|
+
option<T>(opt: ICommandOptionConfig<T>): this;
|
|
275
|
+
argument<T>(arg: ICommandArgumentConfig<T>): this;
|
|
276
|
+
action(fn: ICommandAction): this;
|
|
199
277
|
subcommand(name: string, cmd: Command): this;
|
|
200
|
-
run(params:
|
|
201
|
-
parse(
|
|
202
|
-
/**
|
|
203
|
-
* Shift options from tokens that this command recognizes.
|
|
204
|
-
* Unrecognized tokens are returned in `remaining` for parent commands.
|
|
205
|
-
*/
|
|
206
|
-
shift(tokens: string[]): IShiftResult;
|
|
278
|
+
run(params: ICommandRunParams): Promise<void>;
|
|
279
|
+
parse(params: ICommandRunParams): ICommandParseResult;
|
|
207
280
|
formatHelp(): string;
|
|
208
281
|
getCompletionMeta(): ICompletionMeta;
|
|
209
282
|
}
|
|
@@ -219,7 +292,7 @@ declare class Command implements ICommand {
|
|
|
219
292
|
*
|
|
220
293
|
* @example
|
|
221
294
|
* ```typescript
|
|
222
|
-
* const root = new Command({ name: 'mycli',
|
|
295
|
+
* const root = new Command({ name: 'mycli', desc: 'My CLI' })
|
|
223
296
|
* root.subcommand('completion', new CompletionCommand(root, {
|
|
224
297
|
* paths: {
|
|
225
298
|
* bash: `~/.local/share/bash-completion/completions/mycli`,
|
|
@@ -254,4 +327,4 @@ declare class PwshCompletion {
|
|
|
254
327
|
}
|
|
255
328
|
|
|
256
329
|
export { BashCompletion, Command, CommanderError, CompletionCommand, FishCompletion, PwshCompletion };
|
|
257
|
-
export type {
|
|
330
|
+
export type { ICommand, ICommandAction, ICommandActionParams, ICommandArgumentConfig, ICommandArgumentKind, ICommandArgumentType, ICommandConfig, ICommandContext, ICommandOptionArgs, ICommandOptionConfig, ICommandOptionType, ICommandParseResult, ICommandParsedArgs, ICommandParsedOpts, ICommandResolveResult, ICommandRouteResult, ICommandRunParams, ICommandShiftResult, ICommandToken, ICommandTokenType, ICommandTokenizeResult, ICommanderErrorKind, ICompletionCommandConfig, ICompletionMeta, ICompletionOptionMeta, ICompletionPaths, ICompletionShellType, IReporter };
|