commander 11.0.0 → 12.0.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/Readme.md +26 -22
- package/index.js +8 -11
- package/lib/argument.js +3 -5
- package/lib/command.js +222 -181
- package/lib/error.js +0 -2
- package/lib/help.js +10 -12
- package/lib/option.js +8 -11
- package/package.json +11 -21
- package/typings/index.d.ts +33 -38
package/lib/error.js
CHANGED
package/lib/help.js
CHANGED
|
@@ -8,8 +8,6 @@ const { humanReadableArgName } = require('./argument.js');
|
|
|
8
8
|
* @typedef { import("./option.js").Option } Option
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
// @ts-check
|
|
12
|
-
|
|
13
11
|
// Although this is a class, methods are static in style to allow override using subclass or just functions.
|
|
14
12
|
class Help {
|
|
15
13
|
constructor() {
|
|
@@ -101,8 +99,8 @@ class Help {
|
|
|
101
99
|
if (!this.showGlobalOptions) return [];
|
|
102
100
|
|
|
103
101
|
const globalOptions = [];
|
|
104
|
-
for (let
|
|
105
|
-
const visibleOptions =
|
|
102
|
+
for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
103
|
+
const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
|
|
106
104
|
globalOptions.push(...visibleOptions);
|
|
107
105
|
}
|
|
108
106
|
if (this.sortOptions) {
|
|
@@ -121,14 +119,14 @@ class Help {
|
|
|
121
119
|
visibleArguments(cmd) {
|
|
122
120
|
// Side effect! Apply the legacy descriptions before the arguments are displayed.
|
|
123
121
|
if (cmd._argsDescription) {
|
|
124
|
-
cmd.
|
|
122
|
+
cmd.registeredArguments.forEach(argument => {
|
|
125
123
|
argument.description = argument.description || cmd._argsDescription[argument.name()] || '';
|
|
126
124
|
});
|
|
127
125
|
}
|
|
128
126
|
|
|
129
127
|
// If there are any arguments with a description then return all the arguments.
|
|
130
|
-
if (cmd.
|
|
131
|
-
return cmd.
|
|
128
|
+
if (cmd.registeredArguments.find(argument => argument.description)) {
|
|
129
|
+
return cmd.registeredArguments;
|
|
132
130
|
}
|
|
133
131
|
return [];
|
|
134
132
|
}
|
|
@@ -142,7 +140,7 @@ class Help {
|
|
|
142
140
|
|
|
143
141
|
subcommandTerm(cmd) {
|
|
144
142
|
// Legacy. Ignores custom usage string, and nested commands.
|
|
145
|
-
const args = cmd.
|
|
143
|
+
const args = cmd.registeredArguments.map(arg => humanReadableArgName(arg)).join(' ');
|
|
146
144
|
return cmd._name +
|
|
147
145
|
(cmd._aliases[0] ? '|' + cmd._aliases[0] : '') +
|
|
148
146
|
(cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option
|
|
@@ -240,11 +238,11 @@ class Help {
|
|
|
240
238
|
if (cmd._aliases[0]) {
|
|
241
239
|
cmdName = cmdName + '|' + cmd._aliases[0];
|
|
242
240
|
}
|
|
243
|
-
let
|
|
244
|
-
for (let
|
|
245
|
-
|
|
241
|
+
let ancestorCmdNames = '';
|
|
242
|
+
for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
243
|
+
ancestorCmdNames = ancestorCmd.name() + ' ' + ancestorCmdNames;
|
|
246
244
|
}
|
|
247
|
-
return
|
|
245
|
+
return ancestorCmdNames + cmdName + ' ' + cmd.usage();
|
|
248
246
|
}
|
|
249
247
|
|
|
250
248
|
/**
|
package/lib/option.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const { InvalidArgumentError } = require('./error.js');
|
|
2
2
|
|
|
3
|
-
// @ts-check
|
|
4
|
-
|
|
5
3
|
class Option {
|
|
6
4
|
/**
|
|
7
5
|
* Initialize a new `Option` with the given `flags` and `description`.
|
|
@@ -40,7 +38,7 @@ class Option {
|
|
|
40
38
|
/**
|
|
41
39
|
* Set the default value, and optionally supply the description to be displayed in the help.
|
|
42
40
|
*
|
|
43
|
-
* @param {
|
|
41
|
+
* @param {*} value
|
|
44
42
|
* @param {string} [description]
|
|
45
43
|
* @return {Option}
|
|
46
44
|
*/
|
|
@@ -59,7 +57,7 @@ class Option {
|
|
|
59
57
|
* new Option('--color').default('GREYSCALE').preset('RGB');
|
|
60
58
|
* new Option('--donate [amount]').preset('20').argParser(parseFloat);
|
|
61
59
|
*
|
|
62
|
-
* @param {
|
|
60
|
+
* @param {*} arg
|
|
63
61
|
* @return {Option}
|
|
64
62
|
*/
|
|
65
63
|
|
|
@@ -160,7 +158,7 @@ class Option {
|
|
|
160
158
|
}
|
|
161
159
|
|
|
162
160
|
/**
|
|
163
|
-
* @
|
|
161
|
+
* @package internal use only
|
|
164
162
|
*/
|
|
165
163
|
|
|
166
164
|
_concatValue(value, previous) {
|
|
@@ -210,7 +208,6 @@ class Option {
|
|
|
210
208
|
* as a object attribute key.
|
|
211
209
|
*
|
|
212
210
|
* @return {string}
|
|
213
|
-
* @api private
|
|
214
211
|
*/
|
|
215
212
|
|
|
216
213
|
attributeName() {
|
|
@@ -222,7 +219,7 @@ class Option {
|
|
|
222
219
|
*
|
|
223
220
|
* @param {string} arg
|
|
224
221
|
* @return {boolean}
|
|
225
|
-
* @
|
|
222
|
+
* @package internal use only
|
|
226
223
|
*/
|
|
227
224
|
|
|
228
225
|
is(arg) {
|
|
@@ -235,7 +232,7 @@ class Option {
|
|
|
235
232
|
* Options are one of boolean, negated, required argument, or optional argument.
|
|
236
233
|
*
|
|
237
234
|
* @return {boolean}
|
|
238
|
-
* @
|
|
235
|
+
* @package internal use only
|
|
239
236
|
*/
|
|
240
237
|
|
|
241
238
|
isBoolean() {
|
|
@@ -275,7 +272,7 @@ class DualOptions {
|
|
|
275
272
|
/**
|
|
276
273
|
* Did the value come from the option, and not from possible matching dual option?
|
|
277
274
|
*
|
|
278
|
-
* @param {
|
|
275
|
+
* @param {*} value
|
|
279
276
|
* @param {Option} option
|
|
280
277
|
* @returns {boolean}
|
|
281
278
|
*/
|
|
@@ -295,7 +292,7 @@ class DualOptions {
|
|
|
295
292
|
*
|
|
296
293
|
* @param {string} str
|
|
297
294
|
* @return {string}
|
|
298
|
-
* @
|
|
295
|
+
* @private
|
|
299
296
|
*/
|
|
300
297
|
|
|
301
298
|
function camelcase(str) {
|
|
@@ -307,7 +304,7 @@ function camelcase(str) {
|
|
|
307
304
|
/**
|
|
308
305
|
* Split the short and long flag out of something like '-m,--mixed <value>'
|
|
309
306
|
*
|
|
310
|
-
* @
|
|
307
|
+
* @private
|
|
311
308
|
*/
|
|
312
309
|
|
|
313
310
|
function splitOptionFlags(flags) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0-0",
|
|
4
4
|
"description": "the complete solution for node.js command-line programs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commander",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"lint": "npm run lint:javascript && npm run lint:typescript",
|
|
23
23
|
"lint:javascript": "eslint index.js esm.mjs \"lib/*.js\" \"tests/**/*.js\"",
|
|
24
24
|
"lint:typescript": "eslint typings/*.ts tests/*.ts",
|
|
25
|
-
"test": "jest && npm run
|
|
25
|
+
"test": "jest && npm run typecheck-ts",
|
|
26
26
|
"test-esm": "node ./tests/esm-imports-test.mjs",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"test-all": "npm run test && npm run lint && npm run
|
|
27
|
+
"typecheck-ts": "tsd && tsc -p tsconfig.ts.json",
|
|
28
|
+
"typecheck-js": "tsc -p tsconfig.js.json",
|
|
29
|
+
"test-all": "npm run test && npm run lint && npm run typecheck-js && npm run test-esm"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
32
|
"index.js",
|
|
@@ -58,33 +58,23 @@
|
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/jest": "^29.2.4",
|
|
60
60
|
"@types/node": "^20.2.5",
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
62
|
-
"@typescript-eslint/parser": "^
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
|
62
|
+
"@typescript-eslint/parser": "^6.7.5",
|
|
63
63
|
"eslint": "^8.30.0",
|
|
64
64
|
"eslint-config-standard": "^17.0.0",
|
|
65
|
-
"eslint-config-standard-with-typescript": "^
|
|
65
|
+
"eslint-config-standard-with-typescript": "^39.1.1",
|
|
66
66
|
"eslint-plugin-import": "^2.26.0",
|
|
67
67
|
"eslint-plugin-jest": "^27.1.7",
|
|
68
|
-
"eslint-plugin-n": "^
|
|
68
|
+
"eslint-plugin-n": "^16.2.0",
|
|
69
69
|
"eslint-plugin-promise": "^6.1.1",
|
|
70
70
|
"jest": "^29.3.1",
|
|
71
71
|
"ts-jest": "^29.0.3",
|
|
72
|
-
"tsd": "^0.
|
|
72
|
+
"tsd": "^0.29.0",
|
|
73
73
|
"typescript": "^5.0.4"
|
|
74
74
|
},
|
|
75
75
|
"types": "typings/index.d.ts",
|
|
76
|
-
"jest": {
|
|
77
|
-
"testEnvironment": "node",
|
|
78
|
-
"collectCoverage": true,
|
|
79
|
-
"transform": {
|
|
80
|
-
"^.+\\.tsx?$": "ts-jest"
|
|
81
|
-
},
|
|
82
|
-
"testPathIgnorePatterns": [
|
|
83
|
-
"/node_modules/"
|
|
84
|
-
]
|
|
85
|
-
},
|
|
86
76
|
"engines": {
|
|
87
|
-
"node": ">=
|
|
77
|
+
"node": ">=18"
|
|
88
78
|
},
|
|
89
79
|
"support": true
|
|
90
80
|
}
|
package/typings/index.d.ts
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/method-signature-style */
|
|
6
6
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
7
|
|
|
8
|
+
// This is a trick to encourage editor to suggest the known literals while still
|
|
9
|
+
// allowing any BaseType value.
|
|
10
|
+
// References:
|
|
11
|
+
// - https://github.com/microsoft/TypeScript/issues/29729
|
|
12
|
+
// - https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts
|
|
13
|
+
// - https://github.com/sindresorhus/type-fest/blob/main/source/primitive.d.ts
|
|
14
|
+
type LiteralUnion<LiteralType, BaseType extends string | number> = LiteralType | (BaseType & Record<never, never>);
|
|
15
|
+
|
|
8
16
|
export class CommanderError extends Error {
|
|
9
17
|
code: string;
|
|
10
18
|
exitCode: number;
|
|
@@ -42,6 +50,9 @@ export class Argument {
|
|
|
42
50
|
description: string;
|
|
43
51
|
required: boolean;
|
|
44
52
|
variadic: boolean;
|
|
53
|
+
defaultValue?: any;
|
|
54
|
+
defaultValueDescription?: string;
|
|
55
|
+
argChoices?: string[];
|
|
45
56
|
|
|
46
57
|
/**
|
|
47
58
|
* Initialize a new command argument with the given name and description.
|
|
@@ -94,6 +105,8 @@ export class Option {
|
|
|
94
105
|
negate: boolean;
|
|
95
106
|
defaultValue?: any;
|
|
96
107
|
defaultValueDescription?: string;
|
|
108
|
+
presetArg?: unknown;
|
|
109
|
+
envVar?: string;
|
|
97
110
|
parseArg?: <T>(value: string, previous: T) => T;
|
|
98
111
|
hidden: boolean;
|
|
99
112
|
argChoices?: string[];
|
|
@@ -272,7 +285,8 @@ export interface OutputConfiguration {
|
|
|
272
285
|
|
|
273
286
|
export type AddHelpTextPosition = 'beforeAll' | 'before' | 'after' | 'afterAll';
|
|
274
287
|
export type HookEvent = 'preSubcommand' | 'preAction' | 'postAction';
|
|
275
|
-
|
|
288
|
+
// The source is a string so author can define their own too.
|
|
289
|
+
export type OptionValueSource = LiteralUnion<'default' | 'config' | 'env' | 'cli' | 'implied', string> | undefined;
|
|
276
290
|
|
|
277
291
|
export type OptionValues = Record<string, any>;
|
|
278
292
|
|
|
@@ -281,6 +295,7 @@ export class Command {
|
|
|
281
295
|
processedArgs: any[];
|
|
282
296
|
readonly commands: readonly Command[];
|
|
283
297
|
readonly options: readonly Option[];
|
|
298
|
+
readonly registeredArguments: readonly Argument[];
|
|
284
299
|
parent: Command | null;
|
|
285
300
|
|
|
286
301
|
constructor(name?: string);
|
|
@@ -294,6 +309,10 @@ export class Command {
|
|
|
294
309
|
* You can optionally supply the flags and description to override the defaults.
|
|
295
310
|
*/
|
|
296
311
|
version(str: string, flags?: string, description?: string): this;
|
|
312
|
+
/**
|
|
313
|
+
* Get the program version.
|
|
314
|
+
*/
|
|
315
|
+
version(): string | undefined;
|
|
297
316
|
|
|
298
317
|
/**
|
|
299
318
|
* Define a command, implemented using an action handler.
|
|
@@ -497,51 +516,27 @@ export class Command {
|
|
|
497
516
|
action(fn: (...args: any[]) => void | Promise<void>): this;
|
|
498
517
|
|
|
499
518
|
/**
|
|
500
|
-
* Define option with `flags`, `description
|
|
501
|
-
* coercion `fn`.
|
|
519
|
+
* Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
|
|
502
520
|
*
|
|
503
|
-
* The `flags` string contains the short and/or long flags,
|
|
504
|
-
*
|
|
505
|
-
* all will output this way when `--help` is used.
|
|
521
|
+
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
|
|
522
|
+
* option-argument is indicated by `<>` and an optional option-argument by `[]`.
|
|
506
523
|
*
|
|
507
|
-
*
|
|
508
|
-
* "-p|--pepper"
|
|
509
|
-
* "-p --pepper"
|
|
524
|
+
* See the README for more details, and see also addOption() and requiredOption().
|
|
510
525
|
*
|
|
511
526
|
* @example
|
|
512
|
-
* ```
|
|
513
|
-
* // simple boolean defaulting to false
|
|
514
|
-
* program.option('-p, --pepper', 'add pepper');
|
|
515
527
|
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
* program.cheese
|
|
524
|
-
* // => true
|
|
525
|
-
*
|
|
526
|
-
* --no-cheese
|
|
527
|
-
* program.cheese
|
|
528
|
-
* // => false
|
|
529
|
-
*
|
|
530
|
-
* // required argument
|
|
531
|
-
* program.option('-C, --chdir <path>', 'change the working directory');
|
|
532
|
-
*
|
|
533
|
-
* --chdir /tmp
|
|
534
|
-
* program.chdir
|
|
535
|
-
* // => "/tmp"
|
|
536
|
-
*
|
|
537
|
-
* // optional argument
|
|
538
|
-
* program.option('-c, --cheese [type]', 'add cheese [marble]');
|
|
528
|
+
* ```js
|
|
529
|
+
* program
|
|
530
|
+
* .option('-p, --pepper', 'add pepper')
|
|
531
|
+
* .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
|
|
532
|
+
* .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
|
|
533
|
+
* .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
|
|
539
534
|
* ```
|
|
540
535
|
*
|
|
541
536
|
* @returns `this` command for chaining
|
|
542
537
|
*/
|
|
543
538
|
option(flags: string, description?: string, defaultValue?: string | boolean | string[]): this;
|
|
544
|
-
option<T>(flags: string, description: string,
|
|
539
|
+
option<T>(flags: string, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): this;
|
|
545
540
|
/** @deprecated since v7, instead use choices or a custom function */
|
|
546
541
|
option(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean | string[]): this;
|
|
547
542
|
|
|
@@ -552,7 +547,7 @@ export class Command {
|
|
|
552
547
|
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
|
|
553
548
|
*/
|
|
554
549
|
requiredOption(flags: string, description?: string, defaultValue?: string | boolean | string[]): this;
|
|
555
|
-
requiredOption<T>(flags: string, description: string,
|
|
550
|
+
requiredOption<T>(flags: string, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): this;
|
|
556
551
|
/** @deprecated since v7, instead use choices or a custom function */
|
|
557
552
|
requiredOption(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean | string[]): this;
|
|
558
553
|
|
|
@@ -819,7 +814,7 @@ export class Command {
|
|
|
819
814
|
/**
|
|
820
815
|
* Get the executable search directory.
|
|
821
816
|
*/
|
|
822
|
-
executableDir(): string;
|
|
817
|
+
executableDir(): string | null;
|
|
823
818
|
|
|
824
819
|
/**
|
|
825
820
|
* Output help information for this command.
|