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