clap-ts 0.3.0 → 0.4.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/parser.js +5 -5
- package/dist/types.d.ts +14 -1
- package/package.json +17 -1
- package/src/__tests__/arg-options.test.ts +687 -0
- package/src/__tests__/argfile.test.ts +127 -0
- package/src/__tests__/clap-parity.test.ts +682 -0
- package/src/__tests__/command-options.test.ts +713 -0
- package/src/__tests__/completions.test.ts +423 -0
- package/src/__tests__/config.test.ts +261 -0
- package/src/__tests__/deprecation.test.ts +104 -0
- package/src/__tests__/help.test.ts +312 -0
- package/src/__tests__/install.test.ts +120 -0
- package/src/__tests__/log.test.ts +189 -0
- package/src/__tests__/man.test.ts +135 -0
- package/src/__tests__/markdown.test.ts +114 -0
- package/src/__tests__/output.test.ts +249 -0
- package/src/__tests__/parser.test.ts +627 -0
- package/src/__tests__/plugins.test.ts +182 -0
- package/src/__tests__/progress.test.ts +221 -0
- package/src/__tests__/prompt.test.ts +265 -0
- package/src/__tests__/runner.test.ts +459 -0
- package/src/__tests__/spec.test.ts +107 -0
- package/src/__tests__/testing.test.ts +93 -0
- package/src/__tests__/validation.test.ts +267 -0
- package/src/argfile.ts +188 -0
- package/src/completions.ts +865 -0
- package/src/config.ts +184 -0
- package/src/help.ts +779 -0
- package/src/index.ts +58 -0
- package/src/install.ts +226 -0
- package/src/log.ts +225 -0
- package/src/man.ts +289 -0
- package/src/markdown.ts +210 -0
- package/src/output.ts +453 -0
- package/src/parser.ts +1240 -0
- package/src/plugins.ts +193 -0
- package/src/progress.ts +295 -0
- package/src/prompt.ts +388 -0
- package/src/runner.ts +769 -0
- package/src/spec.ts +197 -0
- package/src/testing.ts +159 -0
- package/src/types.ts +618 -0
- package/src/validation.ts +627 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for the clap-ts CLI framework.
|
|
3
|
+
* Matches clap's feature set with TypeScript type safety.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ---- Argument Types ----
|
|
7
|
+
|
|
8
|
+
/** Argument value type - matches clap's value_parser types. */
|
|
9
|
+
export type ArgType = 'boolean' | 'string' | 'number' | 'enum' | 'positional';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* How an argument collects values.
|
|
13
|
+
* - set: replace (default)
|
|
14
|
+
* - append: collect into an array
|
|
15
|
+
* - count: number of occurrences
|
|
16
|
+
* - setTrue / setFalse: force a boolean regardless of the flag's polarity
|
|
17
|
+
* - help / helpShort / helpLong / version: trigger the built-in output
|
|
18
|
+
*/
|
|
19
|
+
export type ArgAction =
|
|
20
|
+
| 'set'
|
|
21
|
+
| 'append'
|
|
22
|
+
| 'count'
|
|
23
|
+
| 'setTrue'
|
|
24
|
+
| 'setFalse'
|
|
25
|
+
| 'help'
|
|
26
|
+
| 'helpShort'
|
|
27
|
+
| 'helpLong'
|
|
28
|
+
| 'version';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Where a parsed value came from. Extends clap's ValueSource with 'config',
|
|
32
|
+
* which sits between an environment variable and a default, and 'prompt' for a
|
|
33
|
+
* value the user typed when asked.
|
|
34
|
+
*/
|
|
35
|
+
export type ValueSource = 'cli' | 'env' | 'config' | 'prompt' | 'default';
|
|
36
|
+
|
|
37
|
+
/** Min/max constraint for number of values an argument accepts. */
|
|
38
|
+
export interface NumArgs {
|
|
39
|
+
readonly min: number;
|
|
40
|
+
readonly max: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Custom value parser function. Receives raw string, returns parsed value or throws. */
|
|
44
|
+
export type ValueParserFn = (value: string) => unknown;
|
|
45
|
+
|
|
46
|
+
/** One allowed value for an argument, with optional help text and aliases. */
|
|
47
|
+
export interface PossibleValue {
|
|
48
|
+
/** The canonical value as it appears in help and completions. */
|
|
49
|
+
readonly name: string;
|
|
50
|
+
/** Description shown next to the value in long help. */
|
|
51
|
+
readonly help?: string;
|
|
52
|
+
/** Additional accepted spellings, not shown in help. */
|
|
53
|
+
readonly aliases?: readonly string[];
|
|
54
|
+
/** Accept the value but keep it out of help and completions. */
|
|
55
|
+
readonly hidden?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Hint for shell completion behavior -- guides what kind of values to complete. */
|
|
59
|
+
export type ValueHint =
|
|
60
|
+
| 'unknown'
|
|
61
|
+
| 'other'
|
|
62
|
+
| 'filePath'
|
|
63
|
+
| 'dirPath'
|
|
64
|
+
| 'anyPath'
|
|
65
|
+
| 'executablePath'
|
|
66
|
+
| 'commandName'
|
|
67
|
+
| 'commandString'
|
|
68
|
+
| 'commandWithArguments'
|
|
69
|
+
| 'hostname'
|
|
70
|
+
| 'username'
|
|
71
|
+
| 'url'
|
|
72
|
+
| 'emailAddress';
|
|
73
|
+
|
|
74
|
+
/** When to colourise help and error output. */
|
|
75
|
+
export type ColorChoice = 'auto' | 'always' | 'never';
|
|
76
|
+
|
|
77
|
+
/** Supported shells for completion script generation. */
|
|
78
|
+
export type Shell = 'bash' | 'zsh' | 'fish' | 'powershell' | 'elvish' | 'nushell';
|
|
79
|
+
|
|
80
|
+
/** Full argument definition - matches clap::Arg. */
|
|
81
|
+
export interface ArgDef {
|
|
82
|
+
/** Value type for this argument. */
|
|
83
|
+
readonly type: ArgType;
|
|
84
|
+
/** Human-readable description shown in help. */
|
|
85
|
+
readonly description?: string;
|
|
86
|
+
/** Extended description shown with --help but not with -h. */
|
|
87
|
+
readonly longDescription?: string;
|
|
88
|
+
/** Sort key within the arg's help section; lower values come first. */
|
|
89
|
+
readonly displayOrder?: number;
|
|
90
|
+
/** Render the description on its own line beneath the flag. */
|
|
91
|
+
readonly nextLineHelp?: boolean;
|
|
92
|
+
/** Short flag character (e.g., 'v' for -v). */
|
|
93
|
+
readonly short?: string;
|
|
94
|
+
/** Long flag name (e.g., 'verbose' for --verbose). Defaults to the arg key. */
|
|
95
|
+
readonly long?: string;
|
|
96
|
+
/** Additional aliases (hidden from help). Single-char treated as short, multi-char as long. */
|
|
97
|
+
readonly alias?: readonly string[];
|
|
98
|
+
/** Visible aliases shown in help output. Registered as working aliases at parse time. */
|
|
99
|
+
readonly visibleAlias?: readonly string[];
|
|
100
|
+
/** Default value when the argument is not provided. */
|
|
101
|
+
readonly default?: string | number | boolean | readonly string[];
|
|
102
|
+
/** Value to use when the flag is present but no value given (e.g., --port vs --port=8080). */
|
|
103
|
+
readonly defaultMissingValue?: string | number | boolean;
|
|
104
|
+
/** Values to use for a multi-value arg present without values. */
|
|
105
|
+
readonly defaultMissingValues?: readonly string[];
|
|
106
|
+
/**
|
|
107
|
+
* Conditional default: [otherArgName, otherArgValue, defaultValue].
|
|
108
|
+
* If the other arg equals the given value, this default is applied.
|
|
109
|
+
*/
|
|
110
|
+
readonly defaultValueIf?: readonly [string, string, string | number | boolean];
|
|
111
|
+
/** Several conditional defaults; the first whose condition holds is applied. */
|
|
112
|
+
readonly defaultValueIfs?: readonly (readonly [
|
|
113
|
+
string,
|
|
114
|
+
string,
|
|
115
|
+
string | number | boolean,
|
|
116
|
+
])[];
|
|
117
|
+
/** Whether this argument is required. */
|
|
118
|
+
readonly required?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Required unless the named arg(s) are present.
|
|
121
|
+
* Overrides `required: true` when the specified arg(s) are set.
|
|
122
|
+
*/
|
|
123
|
+
readonly requiredUnlessPresent?: string | readonly string[];
|
|
124
|
+
/**
|
|
125
|
+
* Required if another arg equals a specific value: [argName, argValue].
|
|
126
|
+
* Makes this arg required when the condition is met.
|
|
127
|
+
*/
|
|
128
|
+
readonly requiredIfEq?: readonly [string, string];
|
|
129
|
+
/** Required when ANY of these [argName, argValue] conditions holds. */
|
|
130
|
+
readonly requiredIfEqAny?: readonly (readonly [string, string])[];
|
|
131
|
+
/** Required when ALL of these [argName, argValue] conditions hold. */
|
|
132
|
+
readonly requiredIfEqAll?: readonly (readonly [string, string])[];
|
|
133
|
+
/** Required unless ALL of the named args are present. */
|
|
134
|
+
readonly requiredUnlessPresentAll?: readonly string[];
|
|
135
|
+
/** Cannot be used with ANY other argument. */
|
|
136
|
+
readonly exclusive?: boolean;
|
|
137
|
+
/** Global arg -- inherited by all subcommands. */
|
|
138
|
+
readonly global?: boolean;
|
|
139
|
+
/** Environment variable fallback (checked if arg not provided on CLI). */
|
|
140
|
+
readonly env?: string;
|
|
141
|
+
/** Display name for the value in help (e.g., "PATH", "PORT"). */
|
|
142
|
+
readonly valueName?: string;
|
|
143
|
+
/** Per-value display names for a multi-value arg (e.g., ['X', 'Y', 'Z']). */
|
|
144
|
+
readonly valueNames?: readonly string[];
|
|
145
|
+
/**
|
|
146
|
+
* Value validation/parsing. Either:
|
|
147
|
+
* - An array of allowed values, each a plain string or a PossibleValue, or
|
|
148
|
+
* - A function that parses/validates the raw string value (throw to reject).
|
|
149
|
+
*/
|
|
150
|
+
readonly valueParser?: readonly (string | PossibleValue)[] | ValueParserFn;
|
|
151
|
+
/** Match allowed values case-insensitively. The input is kept as typed. */
|
|
152
|
+
readonly ignoreCase?: boolean;
|
|
153
|
+
/** Character to split values on (e.g., ',' for --tags=a,b,c). */
|
|
154
|
+
readonly valueDelimiter?: string;
|
|
155
|
+
/** Require `--flag=value` form; reject `--flag value`. */
|
|
156
|
+
readonly requireEquals?: boolean;
|
|
157
|
+
/** Token that ends value collection for a multi-value arg (e.g., ';'). */
|
|
158
|
+
readonly valueTerminator?: string;
|
|
159
|
+
/** Min/max number of values this arg accepts. */
|
|
160
|
+
readonly numArgs?: NumArgs;
|
|
161
|
+
/** Names of args that conflict with this one (mutually exclusive). */
|
|
162
|
+
readonly conflictsWith?: readonly string[];
|
|
163
|
+
/** Names of args that must also be present when this one is used. */
|
|
164
|
+
readonly requires?: readonly string[];
|
|
165
|
+
/** Names of args this one overrides. The argument given later wins. */
|
|
166
|
+
readonly overridesWith?: readonly string[];
|
|
167
|
+
/** Requires the named arg only when this one equals a value: [value, argName]. */
|
|
168
|
+
readonly requiresIf?: readonly [string, string];
|
|
169
|
+
/** Several conditional requirements, each [thisValue, requiredArgName]. */
|
|
170
|
+
readonly requiresIfs?: readonly (readonly [string, string])[];
|
|
171
|
+
/** Argument group name this arg belongs to. */
|
|
172
|
+
readonly group?: string;
|
|
173
|
+
/** Argument group names this arg belongs to. */
|
|
174
|
+
readonly groups?: readonly string[];
|
|
175
|
+
/** How values are collected: set (replace), append (collect into array), count. */
|
|
176
|
+
readonly action?: ArgAction;
|
|
177
|
+
/** Hide this argument from all help output. */
|
|
178
|
+
readonly hidden?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* Mark the argument deprecated. Using it warns on stderr and help labels it.
|
|
181
|
+
* A string is used as the warning's reason.
|
|
182
|
+
*/
|
|
183
|
+
readonly deprecated?: boolean | string;
|
|
184
|
+
/**
|
|
185
|
+
* Name of the argument that supersedes this one. Named in the warning, and
|
|
186
|
+
* the value is forwarded there when that argument was not given itself.
|
|
187
|
+
*/
|
|
188
|
+
readonly replacedBy?: string;
|
|
189
|
+
/** Hide this argument from short help (-h) only. */
|
|
190
|
+
readonly hideShortHelp?: boolean;
|
|
191
|
+
/** Hide this argument from long help (--help) only. */
|
|
192
|
+
readonly hideLongHelp?: boolean;
|
|
193
|
+
/** Hide possible values list from help (when valueParser is an array). */
|
|
194
|
+
readonly hidePossibleValues?: boolean;
|
|
195
|
+
/** Hide the [default: ...] note from help. */
|
|
196
|
+
readonly hideDefaultValue?: boolean;
|
|
197
|
+
/** Hide the [env: ...] note from help. */
|
|
198
|
+
readonly hideEnv?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Treat the value as sensitive: masked when prompted for, and its
|
|
201
|
+
* environment variable's value kept out of help.
|
|
202
|
+
*/
|
|
203
|
+
readonly secret?: boolean;
|
|
204
|
+
/** Show [env: VAR] in help without the variable's current value. */
|
|
205
|
+
readonly hideEnvValues?: boolean;
|
|
206
|
+
/** Description for the --no-X variant of boolean flags. */
|
|
207
|
+
readonly negativeDescription?: string;
|
|
208
|
+
/** Accept values that start with a hyphen (e.g., --grep -pattern). */
|
|
209
|
+
readonly allowHyphenValues?: boolean;
|
|
210
|
+
/** Accept negative numbers as values (e.g., --offset -10). */
|
|
211
|
+
readonly allowNegativeNumbers?: boolean;
|
|
212
|
+
/** Mark as trailing var arg -- last positional consumes all remaining args. */
|
|
213
|
+
readonly trailingVarArg?: boolean;
|
|
214
|
+
/** Positional that requires -- before it (like clap's last()). */
|
|
215
|
+
readonly last?: boolean;
|
|
216
|
+
/** Explicit 1-based position for a positional arg. */
|
|
217
|
+
readonly index?: number;
|
|
218
|
+
/** Custom section heading in help output (groups args under this heading). */
|
|
219
|
+
readonly helpHeading?: string;
|
|
220
|
+
/** Hint for shell completion -- guides what kind of values to suggest (files, dirs, hosts, etc.). */
|
|
221
|
+
readonly valueHint?: ValueHint;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** Record of argument name to definition. */
|
|
225
|
+
export type ArgsDef = Record<string, ArgDef>;
|
|
226
|
+
|
|
227
|
+
// ---- Style Customization ----
|
|
228
|
+
|
|
229
|
+
/** Style function that applies formatting to a string. */
|
|
230
|
+
export type StyleFn = (s: string) => string;
|
|
231
|
+
|
|
232
|
+
/** Customizable style definitions for help and error output. */
|
|
233
|
+
export interface StylesDef {
|
|
234
|
+
/** Bold text (used for error prefix). */
|
|
235
|
+
readonly bold: StyleFn;
|
|
236
|
+
/** Yellow text. */
|
|
237
|
+
readonly yellow: StyleFn;
|
|
238
|
+
/** Green text. */
|
|
239
|
+
readonly green: StyleFn;
|
|
240
|
+
/** Cyan text. */
|
|
241
|
+
readonly cyan: StyleFn;
|
|
242
|
+
/** Section headings (e.g., "Usage:", "Options:"). */
|
|
243
|
+
readonly heading: StyleFn;
|
|
244
|
+
/** Flag names (e.g., --verbose, -v). */
|
|
245
|
+
readonly flag: StyleFn;
|
|
246
|
+
/** Value placeholders (e.g., <PORT>, <ENV>). */
|
|
247
|
+
readonly value: StyleFn;
|
|
248
|
+
/** Command/subcommand names. */
|
|
249
|
+
readonly command: StyleFn;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ---- Command Types ----
|
|
253
|
+
|
|
254
|
+
/** Command metadata - matches clap::Command attributes. */
|
|
255
|
+
export interface CommandMeta {
|
|
256
|
+
/** Command name (used in usage line). */
|
|
257
|
+
readonly name: string;
|
|
258
|
+
/** Name shown in the usage line, when the binary differs from the command. */
|
|
259
|
+
readonly binName?: string;
|
|
260
|
+
/** Name shown in the help header and version output. */
|
|
261
|
+
readonly displayName?: string;
|
|
262
|
+
/** Version string (shown with --version). */
|
|
263
|
+
readonly version?: string;
|
|
264
|
+
/** Longer version text, shown with --version where -V shows `version`. */
|
|
265
|
+
readonly longVersion?: string;
|
|
266
|
+
/** Give subcommands this command's version, as clap's propagate_version does. */
|
|
267
|
+
readonly propagateVersion?: boolean;
|
|
268
|
+
/** Author line, available to help templates as {author}. */
|
|
269
|
+
readonly author?: string;
|
|
270
|
+
/** Short description (one line, shown in parent's subcommand list). */
|
|
271
|
+
readonly description?: string;
|
|
272
|
+
/** Longer "about" text (shown at top of this command's help). */
|
|
273
|
+
readonly about?: string;
|
|
274
|
+
/** Extended help text (shown with --help, not -h). */
|
|
275
|
+
readonly longAbout?: string;
|
|
276
|
+
/** Text prepended before the help output. */
|
|
277
|
+
readonly beforeHelp?: string;
|
|
278
|
+
/** Text appended after the help output. */
|
|
279
|
+
readonly afterHelp?: string;
|
|
280
|
+
/** Text prepended before long help only (--help, not -h). */
|
|
281
|
+
readonly beforeLongHelp?: string;
|
|
282
|
+
/** Text appended after long help only (--help, not -h). */
|
|
283
|
+
readonly afterLongHelp?: string;
|
|
284
|
+
/** Hide this command from parent's help subcommand list. */
|
|
285
|
+
readonly hidden?: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* Mark the command deprecated. Running it warns on stderr and help labels it.
|
|
288
|
+
* A string is used as the warning's reason.
|
|
289
|
+
*/
|
|
290
|
+
readonly deprecated?: boolean | string;
|
|
291
|
+
/** Name of the command that supersedes this one, named in the warning. */
|
|
292
|
+
readonly replacedBy?: string;
|
|
293
|
+
/** Visible aliases shown next to the command name in help. */
|
|
294
|
+
readonly aliases?: readonly string[];
|
|
295
|
+
/** Aliases that work but stay out of help. */
|
|
296
|
+
readonly hiddenAliases?: readonly string[];
|
|
297
|
+
/** Invoke this subcommand with a short flag, as in `pacman -S`. */
|
|
298
|
+
readonly shortFlag?: string;
|
|
299
|
+
/** Invoke this subcommand with a long flag, as in `pacman --sync`. */
|
|
300
|
+
readonly longFlag?: string;
|
|
301
|
+
/** Extra short flag forms for this subcommand, kept out of help. */
|
|
302
|
+
readonly shortFlagAliases?: readonly string[];
|
|
303
|
+
/** Extra long flag forms for this subcommand, kept out of help. */
|
|
304
|
+
readonly longFlagAliases?: readonly string[];
|
|
305
|
+
/** Extra short flag forms shown in help. */
|
|
306
|
+
readonly visibleShortFlagAliases?: readonly string[];
|
|
307
|
+
/** Extra long flag forms shown in help. */
|
|
308
|
+
readonly visibleLongFlagAliases?: readonly string[];
|
|
309
|
+
/** Sort key among sibling subcommands in help; lower comes first. */
|
|
310
|
+
readonly displayOrder?: number;
|
|
311
|
+
/** Require a subcommand to be provided. */
|
|
312
|
+
readonly subcommandRequired?: boolean;
|
|
313
|
+
/** Accept partial subcommand names (e.g., 'ser' matches 'serve'). */
|
|
314
|
+
readonly inferSubcommands?: boolean;
|
|
315
|
+
/** Accept partial long arg names (e.g., '--verb' matches '--verbose'). */
|
|
316
|
+
readonly inferLongArgs?: boolean;
|
|
317
|
+
/** Parent args and subcommands are mutually exclusive. */
|
|
318
|
+
readonly argsConflictsWithSubcommands?: boolean;
|
|
319
|
+
/** Accept subcommands not defined in subCommands. Passed to parent run handler. */
|
|
320
|
+
readonly allowExternalSubcommands?: boolean;
|
|
321
|
+
/** When a subcommand is present, parent's required args are waived. */
|
|
322
|
+
readonly subcommandNegatesReqs?: boolean;
|
|
323
|
+
/** Show help if no arguments are provided (instead of running). */
|
|
324
|
+
readonly argRequiredElseHelp?: boolean;
|
|
325
|
+
/** Do not add the built-in -h/--help flag. */
|
|
326
|
+
readonly disableHelpFlag?: boolean;
|
|
327
|
+
/** Do not add the built-in -V/--version flag. */
|
|
328
|
+
readonly disableVersionFlag?: boolean;
|
|
329
|
+
/** Do not add the built-in `help` subcommand. */
|
|
330
|
+
readonly disableHelpSubcommand?: boolean;
|
|
331
|
+
/** Render help without colour even on a capable terminal. */
|
|
332
|
+
readonly disableColoredHelp?: boolean;
|
|
333
|
+
/** When to colourise output. 'never' matches disableColoredHelp. */
|
|
334
|
+
readonly color?: ColorChoice;
|
|
335
|
+
/** Summarise each subcommand's own args inside this command's help. */
|
|
336
|
+
readonly flattenHelp?: boolean;
|
|
337
|
+
/** Collect parse errors on ParseResult instead of throwing. */
|
|
338
|
+
readonly ignoreErrors?: boolean;
|
|
339
|
+
/** Default help heading for args that set none. */
|
|
340
|
+
readonly nextHelpHeading?: string;
|
|
341
|
+
/** Starting display order for args that set none. */
|
|
342
|
+
readonly nextDisplayOrder?: number;
|
|
343
|
+
/** Do not split values after `--` on their valueDelimiter. */
|
|
344
|
+
readonly dontDelimitTrailingValues?: boolean;
|
|
345
|
+
/** Reject at build time any visible arg that has no description. */
|
|
346
|
+
readonly helpExpected?: boolean;
|
|
347
|
+
/** Fixed width for help output, overriding the terminal width. */
|
|
348
|
+
readonly termWidth?: number;
|
|
349
|
+
/** Upper bound on the terminal width used for help output. */
|
|
350
|
+
readonly maxTermWidth?: number;
|
|
351
|
+
/** Replace the generated usage line. */
|
|
352
|
+
readonly overrideUsage?: string;
|
|
353
|
+
/** Replace the whole help output. */
|
|
354
|
+
readonly overrideHelp?: string;
|
|
355
|
+
/** Heading for the subcommand list (default "Commands"). */
|
|
356
|
+
readonly subcommandHelpHeading?: string;
|
|
357
|
+
/** Placeholder for the subcommand in the usage line (default "COMMAND"). */
|
|
358
|
+
readonly subcommandValueName?: string;
|
|
359
|
+
/** Let every arg of this command accept values starting with a hyphen. */
|
|
360
|
+
readonly allowHyphenValues?: boolean;
|
|
361
|
+
/** Let every arg of this command accept negative numbers as values. */
|
|
362
|
+
readonly allowNegativeNumbers?: boolean;
|
|
363
|
+
/** Allow the first positional to be omitted when later ones are given. */
|
|
364
|
+
readonly allowMissingPositional?: boolean;
|
|
365
|
+
/** Repeating a single-value arg replaces it instead of being an error. */
|
|
366
|
+
readonly argsOverrideSelf?: boolean;
|
|
367
|
+
/** A subcommand name ends value collection for a multi-value arg. */
|
|
368
|
+
readonly subcommandPrecedenceOverArg?: boolean;
|
|
369
|
+
/** Dispatch on the invoked binary name, busybox style. */
|
|
370
|
+
readonly multicall?: boolean;
|
|
371
|
+
/** argv holds no binary name, so nothing is stripped from the front. */
|
|
372
|
+
readonly noBinaryName?: boolean;
|
|
373
|
+
/**
|
|
374
|
+
* Custom help template with placeholders:
|
|
375
|
+
* {name}, {version}, {author}, {about}, {usage}, {all-args}, {arguments},
|
|
376
|
+
* {options}, {commands}, {before-help}, {after-help}
|
|
377
|
+
*/
|
|
378
|
+
readonly helpTemplate?: string;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** Argument group - for organizing related args (like clap's ArgGroup). */
|
|
382
|
+
export interface ArgGroup {
|
|
383
|
+
/** Group name (for display). */
|
|
384
|
+
readonly name: string;
|
|
385
|
+
/** Arg names in this group. */
|
|
386
|
+
readonly args: readonly string[];
|
|
387
|
+
/** Whether the group is required (at least one must be set). */
|
|
388
|
+
readonly required?: boolean;
|
|
389
|
+
/** Whether args in the group are mutually exclusive. */
|
|
390
|
+
readonly multiple?: boolean;
|
|
391
|
+
/** Args that cannot be used when any member of this group is present. */
|
|
392
|
+
readonly conflictsWith?: readonly string[];
|
|
393
|
+
/** Args that must be present when any member of this group is present. */
|
|
394
|
+
readonly requires?: readonly string[];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* The value one arg parses to, given its action and its type.
|
|
399
|
+
*
|
|
400
|
+
* Taken apart from `InferArgValue` so that both unions reach a naked type
|
|
401
|
+
* parameter and the conditional distributes over them. `A['action']` is an
|
|
402
|
+
* indexed access, and a conditional on one of those tests the whole union at
|
|
403
|
+
* once: for a literal arg definition that is the same answer either way, but
|
|
404
|
+
* for `ArgDef` itself it is the difference between `string` and every value an
|
|
405
|
+
* arg can actually hold.
|
|
406
|
+
*/
|
|
407
|
+
type ArgValueOf<Act, Ty> = Act extends 'append'
|
|
408
|
+
? string[]
|
|
409
|
+
: Act extends 'count'
|
|
410
|
+
? number
|
|
411
|
+
: Ty extends 'boolean'
|
|
412
|
+
? boolean
|
|
413
|
+
: Ty extends 'number'
|
|
414
|
+
? number
|
|
415
|
+
: string;
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Infer the parsed type from an ArgDef.
|
|
419
|
+
* - boolean -> boolean
|
|
420
|
+
* - number -> number
|
|
421
|
+
* - string/enum/positional -> string
|
|
422
|
+
* - action: 'append' -> string[]
|
|
423
|
+
* - action: 'count' -> number
|
|
424
|
+
* - ArgDef itself -> string | number | boolean | string[]
|
|
425
|
+
*/
|
|
426
|
+
export type InferArgValue<A extends ArgDef> = ArgValueOf<A['action'], A['type']>;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Infer whether an arg is optional based on required/default.
|
|
430
|
+
* Args with `required: true` are always non-optional.
|
|
431
|
+
* Args with a default are always non-optional.
|
|
432
|
+
* All others may be undefined.
|
|
433
|
+
*/
|
|
434
|
+
export type InferArgOptional<A extends ArgDef, V> = A['required'] extends true
|
|
435
|
+
? V
|
|
436
|
+
: A['default'] extends undefined
|
|
437
|
+
? V | undefined
|
|
438
|
+
: V;
|
|
439
|
+
|
|
440
|
+
/** Map an ArgsDef record to parsed argument types. */
|
|
441
|
+
export type ParsedArgs<T extends ArgsDef> = {
|
|
442
|
+
[K in keyof T]: InferArgOptional<T[K], InferArgValue<T[K]>>;
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
/** Context passed to command hooks. */
|
|
446
|
+
export interface CommandContext<T extends ArgsDef = ArgsDef> {
|
|
447
|
+
/** Raw argv that was parsed. */
|
|
448
|
+
readonly rawArgs: readonly string[];
|
|
449
|
+
/** Parsed and validated arguments. */
|
|
450
|
+
readonly args: ParsedArgs<T>;
|
|
451
|
+
/** The command definition being executed. */
|
|
452
|
+
readonly cmd: CommandDef<T>;
|
|
453
|
+
/** Name of the resolved subcommand, if any. */
|
|
454
|
+
readonly subCommand?: string;
|
|
455
|
+
/**
|
|
456
|
+
* Where each argument's value came from, by arg key. Absent means the arg has
|
|
457
|
+
* no value at all.
|
|
458
|
+
*/
|
|
459
|
+
readonly valueSources: ReadonlyMap<string, ValueSource>;
|
|
460
|
+
/**
|
|
461
|
+
* Where the handler should write. Defaults to process.stdout/stderr; the
|
|
462
|
+
* testing helpers swap them so a run can be asserted without spawning.
|
|
463
|
+
*/
|
|
464
|
+
readonly stdout: OutputSink;
|
|
465
|
+
readonly stderr: OutputSink;
|
|
466
|
+
/** Arbitrary user data (for passing state between setup/run/cleanup). */
|
|
467
|
+
data: Record<string, unknown>;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/** Full command definition - matches clap::Command. */
|
|
471
|
+
export interface CommandDef<T extends ArgsDef = ArgsDef> {
|
|
472
|
+
/** Command metadata. */
|
|
473
|
+
readonly meta: CommandMeta;
|
|
474
|
+
/** Argument definitions. */
|
|
475
|
+
readonly args?: T;
|
|
476
|
+
/** Subcommand definitions (name -> command). */
|
|
477
|
+
// CommandDef needs to accept any args type for subcommands
|
|
478
|
+
readonly subCommands?: Record<string, CommandDef<any>>;
|
|
479
|
+
/**
|
|
480
|
+
* Subcommands built on first use rather than at definition time, so a CLI
|
|
481
|
+
* with many heavy subcommands does not pay for all of them at startup.
|
|
482
|
+
* Merged with `subCommands`, which wins on a name collision.
|
|
483
|
+
*/
|
|
484
|
+
readonly lazySubCommands?: () => Record<string, CommandDef<any>>;
|
|
485
|
+
/** Parse each argument of an external subcommand before handing it on. */
|
|
486
|
+
readonly externalSubcommandValueParser?: ValueParserFn;
|
|
487
|
+
/** Argument groups for validation and help grouping. */
|
|
488
|
+
readonly groups?: readonly ArgGroup[];
|
|
489
|
+
// Method syntax, not arrow properties: it makes the parameter bivariant, so a
|
|
490
|
+
// CommandDef<{port: ...}> from defineCommand can still be passed to parseArgs,
|
|
491
|
+
// validate and renderHelp, which take CommandDef<ArgsDef>.
|
|
492
|
+
/** Called before run. Return value is ignored; throw to abort. */
|
|
493
|
+
setup?(ctx: CommandContext<T>): void | Promise<void>;
|
|
494
|
+
/** Main command handler. */
|
|
495
|
+
run?(ctx: CommandContext<T>): void | Promise<void>;
|
|
496
|
+
/** Called after run (even on error). */
|
|
497
|
+
cleanup?(ctx: CommandContext<T>): void | Promise<void>;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/** Options for man page generation. */
|
|
501
|
+
export interface ManOptions {
|
|
502
|
+
/** Page name; defaults to the command's binName, displayName or name. */
|
|
503
|
+
readonly name?: string;
|
|
504
|
+
/** Man section number (default '1'). */
|
|
505
|
+
readonly section?: string;
|
|
506
|
+
/** Manual title shown in the page header. */
|
|
507
|
+
readonly manual?: string;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/** Options for markdown documentation output. */
|
|
511
|
+
export interface MarkdownOptions {
|
|
512
|
+
/** Command name used in headings and usage; defaults to binName or name. */
|
|
513
|
+
readonly name?: string;
|
|
514
|
+
/** Document title rendered above the command, as a level-1 heading. */
|
|
515
|
+
readonly title?: string;
|
|
516
|
+
/** Text appended after the last command section. */
|
|
517
|
+
readonly footer?: string;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// ---- Options ----
|
|
521
|
+
|
|
522
|
+
/** Somewhere to write output. `process.stdout` satisfies this. */
|
|
523
|
+
export interface OutputSink {
|
|
524
|
+
write(chunk: string): void;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/** Options for runMain / runCommand. */
|
|
528
|
+
export interface RunOptions {
|
|
529
|
+
/** Override argv (defaults to Bun.argv / process.argv). */
|
|
530
|
+
readonly argv?: readonly string[];
|
|
531
|
+
/** Exit process on error (default: true). */
|
|
532
|
+
readonly exit?: boolean;
|
|
533
|
+
/** Show help on empty args when command has subcommands (default: true). */
|
|
534
|
+
readonly showHelpOnEmpty?: boolean;
|
|
535
|
+
/** Custom styles for help and error output. */
|
|
536
|
+
readonly styles?: Partial<StylesDef>;
|
|
537
|
+
/** Where help and version output goes (default: process.stdout). */
|
|
538
|
+
readonly stdout?: OutputSink;
|
|
539
|
+
/** Where errors go (default: process.stderr). */
|
|
540
|
+
readonly stderr?: OutputSink;
|
|
541
|
+
/**
|
|
542
|
+
* Called with the exit code the run settled on, before `process.exit`. Set
|
|
543
|
+
* alongside `exit: false` to observe the code without ending the process.
|
|
544
|
+
*/
|
|
545
|
+
readonly onExit?: (code: number) => void;
|
|
546
|
+
/**
|
|
547
|
+
* Values from a configuration file, filling args that the command line and
|
|
548
|
+
* environment left alone. A nested object keyed by a subcommand name scopes
|
|
549
|
+
* its contents to that command; scalar keys apply at every level.
|
|
550
|
+
*
|
|
551
|
+
* `loadConfig` from `clap-ts/config` produces this shape.
|
|
552
|
+
*
|
|
553
|
+
* Pass a thunk to defer the file search: it runs only if some argument is
|
|
554
|
+
* still sitting on its default, so a fully specified command line reads
|
|
555
|
+
* nothing from disk.
|
|
556
|
+
*/
|
|
557
|
+
readonly config?:
|
|
558
|
+
| Record<string, unknown>
|
|
559
|
+
| (() => Record<string, unknown> | undefined);
|
|
560
|
+
/**
|
|
561
|
+
* Supply values for required arguments still missing after argv, the
|
|
562
|
+
* environment and the config have had their turn. Returning a record fills
|
|
563
|
+
* them in with source 'prompt'; returning undefined leaves validation to
|
|
564
|
+
* fail as it would have.
|
|
565
|
+
*
|
|
566
|
+
* `promptMissing` from `clap-ts/prompt` is the intended implementation.
|
|
567
|
+
*/
|
|
568
|
+
readonly fillMissing?: (
|
|
569
|
+
missing: readonly MissingArg[],
|
|
570
|
+
command: CommandDef<any>,
|
|
571
|
+
) => Promise<Record<string, unknown> | undefined>;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** A required argument that nothing has supplied yet. */
|
|
575
|
+
export interface MissingArg {
|
|
576
|
+
/** Key in the command's `args`. */
|
|
577
|
+
readonly key: string;
|
|
578
|
+
/** The argument's definition. */
|
|
579
|
+
readonly def: ArgDef;
|
|
580
|
+
/** How it reads in a message: `--port` or `<FILE>`. */
|
|
581
|
+
readonly label: string;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// ---- Parser Result ----
|
|
585
|
+
|
|
586
|
+
/** Result of parsing arguments. */
|
|
587
|
+
export interface ParseResult {
|
|
588
|
+
/** Parsed argument values (key -> value). */
|
|
589
|
+
readonly args: Record<string, string | number | boolean | string[]>;
|
|
590
|
+
/** Positional arguments in order. */
|
|
591
|
+
readonly positionals: readonly string[];
|
|
592
|
+
/** Arguments after -- separator. */
|
|
593
|
+
readonly rest: readonly string[];
|
|
594
|
+
/** The subcommand name if one was matched. */
|
|
595
|
+
readonly subCommand?: string;
|
|
596
|
+
/** Whether the matched subcommand was accepted via allowExternalSubcommands. */
|
|
597
|
+
readonly subCommandIsExternal: boolean;
|
|
598
|
+
/** Tokens following the matched subcommand, to be parsed against it. */
|
|
599
|
+
readonly subCommandArgs: readonly string[];
|
|
600
|
+
/** Whether --help / -h was requested. */
|
|
601
|
+
readonly helpRequested: boolean;
|
|
602
|
+
/** Whether -h (short) was used vs --help (long). */
|
|
603
|
+
readonly helpIsShort: boolean;
|
|
604
|
+
/** Whether --version / -V was requested. */
|
|
605
|
+
readonly versionRequested: boolean;
|
|
606
|
+
/** Whether -V (short) was used rather than --version. */
|
|
607
|
+
readonly versionIsShort: boolean;
|
|
608
|
+
/** Unknown flags that were passed. */
|
|
609
|
+
readonly unknown: readonly string[];
|
|
610
|
+
/** Errors collected instead of thrown, when meta.ignoreErrors is set. */
|
|
611
|
+
readonly errors: readonly string[];
|
|
612
|
+
/** Notices to show the user without failing, such as deprecation warnings. */
|
|
613
|
+
readonly warnings: readonly string[];
|
|
614
|
+
/** Set of arg keys that were explicitly provided (not defaults or env). */
|
|
615
|
+
readonly explicitlySet: ReadonlySet<string>;
|
|
616
|
+
/** Where each parsed value came from, by arg key. */
|
|
617
|
+
readonly valueSources: ReadonlyMap<string, ValueSource>;
|
|
618
|
+
}
|