commander 11.1.0 → 12.0.0-1
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 +11 -5
- package/index.js +4 -6
- package/lib/argument.js +2 -2
- package/lib/command.js +272 -152
- package/lib/help.js +14 -19
- package/lib/option.js +6 -8
- package/package.json +8 -8
- package/typings/index.d.ts +23 -8
package/Readme.md
CHANGED
|
@@ -37,7 +37,7 @@ Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
|
|
|
37
37
|
- [.usage](#usage)
|
|
38
38
|
- [.description and .summary](#description-and-summary)
|
|
39
39
|
- [.helpOption(flags, description)](#helpoptionflags-description)
|
|
40
|
-
- [.
|
|
40
|
+
- [.helpCommand()](#helpcommand)
|
|
41
41
|
- [More configuration](#more-configuration-2)
|
|
42
42
|
- [Custom event listeners](#custom-event-listeners)
|
|
43
43
|
- [Bits and pieces](#bits-and-pieces)
|
|
@@ -904,16 +904,20 @@ program
|
|
|
904
904
|
.helpOption('-e, --HELP', 'read more information');
|
|
905
905
|
```
|
|
906
906
|
|
|
907
|
-
|
|
907
|
+
(Or use `.addHelpOption()` to add an option you construct yourself.)
|
|
908
908
|
|
|
909
|
-
|
|
909
|
+
### .helpCommand()
|
|
910
|
+
|
|
911
|
+
A help command is added by default if your command has subcommands. You can explicitly turn on or off the implicit help command with `.helpCommand(true)` and `.helpCommand(false)`.
|
|
910
912
|
|
|
911
913
|
You can both turn on and customise the help command by supplying the name and description:
|
|
912
914
|
|
|
913
915
|
```js
|
|
914
|
-
program.
|
|
916
|
+
program.helpCommand('assist [command]', 'show assistance');
|
|
915
917
|
```
|
|
916
918
|
|
|
919
|
+
(Or use `.addHelpCommand()` to add a command you construct yourself.)
|
|
920
|
+
|
|
917
921
|
### More configuration
|
|
918
922
|
|
|
919
923
|
The built-in help is formatted using the Help class.
|
|
@@ -967,6 +971,8 @@ program.parse(); // Implicit, and auto-detect electron
|
|
|
967
971
|
program.parse(['-f', 'filename'], { from: 'user' });
|
|
968
972
|
```
|
|
969
973
|
|
|
974
|
+
If you want to parse multiple times, create a new program each time. Calling parse does not clear out any previous state.
|
|
975
|
+
|
|
970
976
|
### Parsing Configuration
|
|
971
977
|
|
|
972
978
|
If the default parsing does not suit your needs, there are some behaviours to support other usage patterns.
|
|
@@ -1136,7 +1142,7 @@ There is more information available about:
|
|
|
1136
1142
|
|
|
1137
1143
|
## Support
|
|
1138
1144
|
|
|
1139
|
-
The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least
|
|
1145
|
+
The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v18.
|
|
1140
1146
|
(For older versions of Node.js, use an older version of Commander.)
|
|
1141
1147
|
|
|
1142
1148
|
The main forum for free and community support is the project [Issues](https://github.com/tj/commander.js/issues) on GitHub.
|
package/index.js
CHANGED
|
@@ -4,13 +4,11 @@ const { CommanderError, InvalidArgumentError } = require('./lib/error.js');
|
|
|
4
4
|
const { Help } = require('./lib/help.js');
|
|
5
5
|
const { Option } = require('./lib/option.js');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
* Expose the root command.
|
|
9
|
-
*/
|
|
7
|
+
exports.program = new Command();
|
|
10
8
|
|
|
11
|
-
exports =
|
|
12
|
-
exports.
|
|
13
|
-
|
|
9
|
+
exports.createCommand = (name) => new Command(name);
|
|
10
|
+
exports.createOption = (flags, description) => new Option(flags, description);
|
|
11
|
+
exports.createArgument = (name, description) => new Argument(name, description);
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* Expose classes
|
package/lib/argument.js
CHANGED
|
@@ -50,7 +50,7 @@ class Argument {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* @
|
|
53
|
+
* @package internal use only
|
|
54
54
|
*/
|
|
55
55
|
|
|
56
56
|
_concatValue(value, previous) {
|
|
@@ -130,7 +130,7 @@ class Argument {
|
|
|
130
130
|
*
|
|
131
131
|
* @param {Argument} arg
|
|
132
132
|
* @return {string}
|
|
133
|
-
* @
|
|
133
|
+
* @private
|
|
134
134
|
*/
|
|
135
135
|
|
|
136
136
|
function humanReadableArgName(arg) {
|
package/lib/command.js
CHANGED
|
@@ -7,7 +7,7 @@ const process = require('process');
|
|
|
7
7
|
const { Argument, humanReadableArgName } = require('./argument.js');
|
|
8
8
|
const { CommanderError } = require('./error.js');
|
|
9
9
|
const { Help } = require('./help.js');
|
|
10
|
-
const { Option,
|
|
10
|
+
const { Option, DualOptions } = require('./option.js');
|
|
11
11
|
const { suggestSimilar } = require('./suggestSimilar');
|
|
12
12
|
|
|
13
13
|
class Command extends EventEmitter {
|
|
@@ -52,7 +52,7 @@ class Command extends EventEmitter {
|
|
|
52
52
|
this._enablePositionalOptions = false;
|
|
53
53
|
this._passThroughOptions = false;
|
|
54
54
|
this._lifeCycleHooks = {}; // a hash of arrays
|
|
55
|
-
/** @type {boolean | string} */
|
|
55
|
+
/** @type {(boolean | string)} */
|
|
56
56
|
this._showHelpAfterError = false;
|
|
57
57
|
this._showSuggestionAfterError = true;
|
|
58
58
|
|
|
@@ -66,15 +66,11 @@ class Command extends EventEmitter {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
this._hidden = false;
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
72
|
-
|
|
73
|
-
this.
|
|
74
|
-
this._addImplicitHelpCommand = undefined; // Deliberately undefined, not decided whether true or false
|
|
75
|
-
this._helpCommandName = 'help';
|
|
76
|
-
this._helpCommandnameAndArgs = 'help [command]';
|
|
77
|
-
this._helpCommandDescription = 'display help for command';
|
|
69
|
+
/** @type {(Option | null | undefined)} */
|
|
70
|
+
this._helpOption = undefined; // Lazy created on demand. May be null if help option is disabled.
|
|
71
|
+
this._addImplicitHelpCommand = undefined; // undecided whether true or false yet, not inherited
|
|
72
|
+
/** @type {Command} */
|
|
73
|
+
this._helpCommand = undefined; // lazy initialised, inherited
|
|
78
74
|
this._helpConfiguration = {};
|
|
79
75
|
}
|
|
80
76
|
|
|
@@ -88,14 +84,8 @@ class Command extends EventEmitter {
|
|
|
88
84
|
*/
|
|
89
85
|
copyInheritedSettings(sourceCommand) {
|
|
90
86
|
this._outputConfiguration = sourceCommand._outputConfiguration;
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this._helpDescription = sourceCommand._helpDescription;
|
|
94
|
-
this._helpShortFlag = sourceCommand._helpShortFlag;
|
|
95
|
-
this._helpLongFlag = sourceCommand._helpLongFlag;
|
|
96
|
-
this._helpCommandName = sourceCommand._helpCommandName;
|
|
97
|
-
this._helpCommandnameAndArgs = sourceCommand._helpCommandnameAndArgs;
|
|
98
|
-
this._helpCommandDescription = sourceCommand._helpCommandDescription;
|
|
87
|
+
this._helpOption = sourceCommand._helpOption;
|
|
88
|
+
this._helpCommand = sourceCommand._helpCommand;
|
|
99
89
|
this._helpConfiguration = sourceCommand._helpConfiguration;
|
|
100
90
|
this._exitCallback = sourceCommand._exitCallback;
|
|
101
91
|
this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
|
|
@@ -110,7 +100,7 @@ class Command extends EventEmitter {
|
|
|
110
100
|
|
|
111
101
|
/**
|
|
112
102
|
* @returns {Command[]}
|
|
113
|
-
* @
|
|
103
|
+
* @private
|
|
114
104
|
*/
|
|
115
105
|
|
|
116
106
|
_getCommandAndAncestors() {
|
|
@@ -141,7 +131,7 @@ class Command extends EventEmitter {
|
|
|
141
131
|
* .command('stop [service]', 'stop named service, or all if no name supplied');
|
|
142
132
|
*
|
|
143
133
|
* @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
|
|
144
|
-
* @param {Object|string} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
|
|
134
|
+
* @param {(Object|string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
|
|
145
135
|
* @param {Object} [execOpts] - configuration options (for executable)
|
|
146
136
|
* @return {Command} returns new command for action handler, or `this` for executable command
|
|
147
137
|
*/
|
|
@@ -165,7 +155,7 @@ class Command extends EventEmitter {
|
|
|
165
155
|
cmd._hidden = !!(opts.noHelp || opts.hidden); // noHelp is deprecated old name for hidden
|
|
166
156
|
cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor
|
|
167
157
|
if (args) cmd.arguments(args);
|
|
168
|
-
this.
|
|
158
|
+
this._registerCommand(cmd);
|
|
169
159
|
cmd.parent = this;
|
|
170
160
|
cmd.copyInheritedSettings(this);
|
|
171
161
|
|
|
@@ -203,7 +193,7 @@ class Command extends EventEmitter {
|
|
|
203
193
|
* or with a subclass of Help by overriding createHelp().
|
|
204
194
|
*
|
|
205
195
|
* @param {Object} [configuration] - configuration options
|
|
206
|
-
* @return {Command|Object} `this` command for chaining, or stored configuration
|
|
196
|
+
* @return {(Command|Object)} `this` command for chaining, or stored configuration
|
|
207
197
|
*/
|
|
208
198
|
|
|
209
199
|
configureHelp(configuration) {
|
|
@@ -229,7 +219,7 @@ class Command extends EventEmitter {
|
|
|
229
219
|
* outputError(str, write) // used for displaying errors, and not used for displaying help
|
|
230
220
|
*
|
|
231
221
|
* @param {Object} [configuration] - configuration options
|
|
232
|
-
* @return {Command|Object} `this` command for chaining, or stored configuration
|
|
222
|
+
* @return {(Command|Object)} `this` command for chaining, or stored configuration
|
|
233
223
|
*/
|
|
234
224
|
|
|
235
225
|
configureOutput(configuration) {
|
|
@@ -242,7 +232,7 @@ class Command extends EventEmitter {
|
|
|
242
232
|
/**
|
|
243
233
|
* Display the help or a custom message after an error occurs.
|
|
244
234
|
*
|
|
245
|
-
* @param {boolean|string} [displayHelp]
|
|
235
|
+
* @param {(boolean|string)} [displayHelp]
|
|
246
236
|
* @return {Command} `this` command for chaining
|
|
247
237
|
*/
|
|
248
238
|
showHelpAfterError(displayHelp = true) {
|
|
@@ -282,8 +272,10 @@ class Command extends EventEmitter {
|
|
|
282
272
|
if (opts.isDefault) this._defaultCommandName = cmd._name;
|
|
283
273
|
if (opts.noHelp || opts.hidden) cmd._hidden = true; // modifying passed command due to existing implementation
|
|
284
274
|
|
|
285
|
-
this.
|
|
275
|
+
this._registerCommand(cmd);
|
|
286
276
|
cmd.parent = this;
|
|
277
|
+
cmd._checkForBrokenPassThrough();
|
|
278
|
+
|
|
287
279
|
return this;
|
|
288
280
|
}
|
|
289
281
|
|
|
@@ -314,7 +306,7 @@ class Command extends EventEmitter {
|
|
|
314
306
|
*
|
|
315
307
|
* @param {string} name
|
|
316
308
|
* @param {string} [description]
|
|
317
|
-
* @param {Function|*} [fn] - custom argument processing function
|
|
309
|
+
* @param {(Function|*)} [fn] - custom argument processing function
|
|
318
310
|
* @param {*} [defaultValue]
|
|
319
311
|
* @return {Command} `this` command for chaining
|
|
320
312
|
*/
|
|
@@ -367,39 +359,76 @@ class Command extends EventEmitter {
|
|
|
367
359
|
}
|
|
368
360
|
|
|
369
361
|
/**
|
|
370
|
-
*
|
|
362
|
+
* Customise or override default help command. By default a help command is automatically added if your command has subcommands.
|
|
371
363
|
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
364
|
+
* program.helpCommand('help [cmd]');
|
|
365
|
+
* program.helpCommand('help [cmd]', 'show help');
|
|
366
|
+
* program.helpCommand(false); // suppress default help command
|
|
367
|
+
* program.helpCommand(true); // add help command even if no subcommands
|
|
375
368
|
*
|
|
369
|
+
* @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
|
|
370
|
+
* @param {string} [description] - custom description
|
|
376
371
|
* @return {Command} `this` command for chaining
|
|
377
372
|
*/
|
|
378
373
|
|
|
379
|
-
|
|
380
|
-
if (enableOrNameAndArgs ===
|
|
381
|
-
this._addImplicitHelpCommand =
|
|
382
|
-
|
|
383
|
-
this._addImplicitHelpCommand = true;
|
|
384
|
-
if (typeof enableOrNameAndArgs === 'string') {
|
|
385
|
-
this._helpCommandName = enableOrNameAndArgs.split(' ')[0];
|
|
386
|
-
this._helpCommandnameAndArgs = enableOrNameAndArgs;
|
|
387
|
-
}
|
|
388
|
-
this._helpCommandDescription = description || this._helpCommandDescription;
|
|
374
|
+
helpCommand(enableOrNameAndArgs, description) {
|
|
375
|
+
if (typeof enableOrNameAndArgs === 'boolean') {
|
|
376
|
+
this._addImplicitHelpCommand = enableOrNameAndArgs;
|
|
377
|
+
return this;
|
|
389
378
|
}
|
|
379
|
+
|
|
380
|
+
enableOrNameAndArgs = enableOrNameAndArgs ?? 'help [command]';
|
|
381
|
+
const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
|
|
382
|
+
const helpDescription = description ?? 'display help for command';
|
|
383
|
+
|
|
384
|
+
const helpCommand = this.createCommand(helpName);
|
|
385
|
+
helpCommand.helpOption(false);
|
|
386
|
+
if (helpArgs) helpCommand.arguments(helpArgs);
|
|
387
|
+
if (helpDescription) helpCommand.description(helpDescription);
|
|
388
|
+
|
|
389
|
+
this._addImplicitHelpCommand = true;
|
|
390
|
+
this._helpCommand = helpCommand;
|
|
391
|
+
|
|
390
392
|
return this;
|
|
391
393
|
}
|
|
392
394
|
|
|
393
395
|
/**
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
+
* Add prepared custom help command.
|
|
397
|
+
*
|
|
398
|
+
* @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
|
|
399
|
+
* @param {string} [deprecatedDescription] - deprecated custom description used with custom name only
|
|
400
|
+
* @return {Command} `this` command for chaining
|
|
401
|
+
*/
|
|
402
|
+
addHelpCommand(helpCommand, deprecatedDescription) {
|
|
403
|
+
// If not passed an object, call through to helpCommand for backwards compatibility,
|
|
404
|
+
// as addHelpCommand was originally used like helpCommand is now.
|
|
405
|
+
if (typeof helpCommand !== 'object') {
|
|
406
|
+
this.helpCommand(helpCommand, deprecatedDescription);
|
|
407
|
+
return this;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
this._addImplicitHelpCommand = true;
|
|
411
|
+
this._helpCommand = helpCommand;
|
|
412
|
+
return this;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Lazy create help command.
|
|
417
|
+
*
|
|
418
|
+
* @return {(Command|null)}
|
|
419
|
+
* @package
|
|
396
420
|
*/
|
|
421
|
+
_getHelpCommand() {
|
|
422
|
+
const hasImplicitHelpCommand = this._addImplicitHelpCommand ??
|
|
423
|
+
(this.commands.length && !this._actionHandler && !this._findCommand('help'));
|
|
397
424
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
425
|
+
if (hasImplicitHelpCommand) {
|
|
426
|
+
if (this._helpCommand === undefined) {
|
|
427
|
+
this.helpCommand(undefined, undefined); // use default name and description
|
|
428
|
+
}
|
|
429
|
+
return this._helpCommand;
|
|
401
430
|
}
|
|
402
|
-
return
|
|
431
|
+
return null;
|
|
403
432
|
}
|
|
404
433
|
|
|
405
434
|
/**
|
|
@@ -453,7 +482,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
453
482
|
* @param {string} code an id string representing the error
|
|
454
483
|
* @param {string} message human-readable description of the error
|
|
455
484
|
* @return never
|
|
456
|
-
* @
|
|
485
|
+
* @private
|
|
457
486
|
*/
|
|
458
487
|
|
|
459
488
|
_exit(exitCode, code, message) {
|
|
@@ -515,11 +544,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
515
544
|
/**
|
|
516
545
|
* Wrap parseArgs to catch 'commander.invalidArgument'.
|
|
517
546
|
*
|
|
518
|
-
* @param {Option | Argument} target
|
|
547
|
+
* @param {(Option | Argument)} target
|
|
519
548
|
* @param {string} value
|
|
520
549
|
* @param {*} previous
|
|
521
550
|
* @param {string} invalidArgumentMessage
|
|
522
|
-
* @
|
|
551
|
+
* @private
|
|
523
552
|
*/
|
|
524
553
|
|
|
525
554
|
_callParseArg(target, value, previous, invalidArgumentMessage) {
|
|
@@ -534,6 +563,49 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
534
563
|
}
|
|
535
564
|
}
|
|
536
565
|
|
|
566
|
+
/**
|
|
567
|
+
* Check for option flag conflicts.
|
|
568
|
+
* Register option if no conflicts found, or throw on conflict.
|
|
569
|
+
*
|
|
570
|
+
* @param {Option} option
|
|
571
|
+
* @api private
|
|
572
|
+
*/
|
|
573
|
+
|
|
574
|
+
_registerOption(option) {
|
|
575
|
+
const matchingOption = (option.short && this._findOption(option.short)) ||
|
|
576
|
+
(option.long && this._findOption(option.long));
|
|
577
|
+
if (matchingOption) {
|
|
578
|
+
const matchingFlag = (option.long && this._findOption(option.long)) ? option.long : option.short;
|
|
579
|
+
throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
|
|
580
|
+
- already used by option '${matchingOption.flags}'`);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
this.options.push(option);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Check for command name and alias conflicts with existing commands.
|
|
588
|
+
* Register command if no conflicts found, or throw on conflict.
|
|
589
|
+
*
|
|
590
|
+
* @param {Command} command
|
|
591
|
+
* @api private
|
|
592
|
+
*/
|
|
593
|
+
|
|
594
|
+
_registerCommand(command) {
|
|
595
|
+
const knownBy = (cmd) => {
|
|
596
|
+
return [cmd.name()].concat(cmd.aliases());
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
|
|
600
|
+
if (alreadyUsed) {
|
|
601
|
+
const existingCmd = knownBy(this._findCommand(alreadyUsed)).join('|');
|
|
602
|
+
const newCmd = knownBy(command).join('|');
|
|
603
|
+
throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
this.commands.push(command);
|
|
607
|
+
}
|
|
608
|
+
|
|
537
609
|
/**
|
|
538
610
|
* Add an option.
|
|
539
611
|
*
|
|
@@ -541,6 +613,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
541
613
|
* @return {Command} `this` command for chaining
|
|
542
614
|
*/
|
|
543
615
|
addOption(option) {
|
|
616
|
+
this._registerOption(option);
|
|
617
|
+
|
|
544
618
|
const oname = option.name();
|
|
545
619
|
const name = option.attributeName();
|
|
546
620
|
|
|
@@ -555,9 +629,6 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
555
629
|
this.setOptionValueWithSource(name, option.defaultValue, 'default');
|
|
556
630
|
}
|
|
557
631
|
|
|
558
|
-
// register the option
|
|
559
|
-
this.options.push(option);
|
|
560
|
-
|
|
561
632
|
// handler for cli and env supplied values
|
|
562
633
|
const handleOptionValue = (val, invalidValueMessage, valueSource) => {
|
|
563
634
|
// val is null for optional option used without an optional-argument.
|
|
@@ -605,7 +676,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
605
676
|
/**
|
|
606
677
|
* Internal implementation shared by .option() and .requiredOption()
|
|
607
678
|
*
|
|
608
|
-
* @
|
|
679
|
+
* @private
|
|
609
680
|
*/
|
|
610
681
|
_optionEx(config, flags, description, fn, defaultValue) {
|
|
611
682
|
if (typeof flags === 'object' && flags instanceof Option) {
|
|
@@ -647,7 +718,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
647
718
|
*
|
|
648
719
|
* @param {string} flags
|
|
649
720
|
* @param {string} [description]
|
|
650
|
-
* @param {Function|*} [parseArg] - custom option processing function or default value
|
|
721
|
+
* @param {(Function|*)} [parseArg] - custom option processing function or default value
|
|
651
722
|
* @param {*} [defaultValue]
|
|
652
723
|
* @return {Command} `this` command for chaining
|
|
653
724
|
*/
|
|
@@ -664,7 +735,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
664
735
|
*
|
|
665
736
|
* @param {string} flags
|
|
666
737
|
* @param {string} [description]
|
|
667
|
-
* @param {Function|*} [parseArg] - custom option processing function or default value
|
|
738
|
+
* @param {(Function|*)} [parseArg] - custom option processing function or default value
|
|
668
739
|
* @param {*} [defaultValue]
|
|
669
740
|
* @return {Command} `this` command for chaining
|
|
670
741
|
*/
|
|
@@ -681,7 +752,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
681
752
|
* program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
|
|
682
753
|
* program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
|
|
683
754
|
*
|
|
684
|
-
* @param {
|
|
755
|
+
* @param {boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
|
|
685
756
|
*/
|
|
686
757
|
combineFlagAndOptionalValue(combine = true) {
|
|
687
758
|
this._combineFlagAndOptionalValue = !!combine;
|
|
@@ -691,7 +762,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
691
762
|
/**
|
|
692
763
|
* Allow unknown options on the command line.
|
|
693
764
|
*
|
|
694
|
-
* @param {
|
|
765
|
+
* @param {boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
|
|
695
766
|
* for unknown options.
|
|
696
767
|
*/
|
|
697
768
|
allowUnknownOption(allowUnknown = true) {
|
|
@@ -702,7 +773,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
702
773
|
/**
|
|
703
774
|
* Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
|
|
704
775
|
*
|
|
705
|
-
* @param {
|
|
776
|
+
* @param {boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
|
|
706
777
|
* for excess arguments.
|
|
707
778
|
*/
|
|
708
779
|
allowExcessArguments(allowExcess = true) {
|
|
@@ -715,7 +786,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
715
786
|
* subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
|
|
716
787
|
* The default behaviour is non-positional and global options may appear anywhere on the command line.
|
|
717
788
|
*
|
|
718
|
-
* @param {
|
|
789
|
+
* @param {boolean} [positional=true]
|
|
719
790
|
*/
|
|
720
791
|
enablePositionalOptions(positional = true) {
|
|
721
792
|
this._enablePositionalOptions = !!positional;
|
|
@@ -728,17 +799,25 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
728
799
|
* positional options to have been enabled on the program (parent commands).
|
|
729
800
|
* The default behaviour is non-positional and options may appear before or after command-arguments.
|
|
730
801
|
*
|
|
731
|
-
* @param {
|
|
802
|
+
* @param {boolean} [passThrough=true]
|
|
732
803
|
* for unknown options.
|
|
733
804
|
*/
|
|
734
805
|
passThroughOptions(passThrough = true) {
|
|
735
806
|
this._passThroughOptions = !!passThrough;
|
|
736
|
-
|
|
737
|
-
throw new Error('passThroughOptions can not be used without turning on enablePositionalOptions for parent command(s)');
|
|
738
|
-
}
|
|
807
|
+
this._checkForBrokenPassThrough();
|
|
739
808
|
return this;
|
|
740
809
|
}
|
|
741
810
|
|
|
811
|
+
/**
|
|
812
|
+
* @private
|
|
813
|
+
*/
|
|
814
|
+
|
|
815
|
+
_checkForBrokenPassThrough() {
|
|
816
|
+
if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
|
|
817
|
+
throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
742
821
|
/**
|
|
743
822
|
* Whether to store option values as properties on command object,
|
|
744
823
|
* or store separately (specify false). In both cases the option values can be accessed using .opts().
|
|
@@ -751,9 +830,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
751
830
|
if (this.options.length) {
|
|
752
831
|
throw new Error('call .storeOptionsAsProperties() before adding options');
|
|
753
832
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
833
|
+
if (Object.keys(this._optionValues).length) {
|
|
834
|
+
throw new Error('call .storeOptionsAsProperties() before setting option values');
|
|
835
|
+
}
|
|
757
836
|
this._storeOptionsAsProperties = !!storeAsProperties;
|
|
758
837
|
return this;
|
|
759
838
|
}
|
|
@@ -838,7 +917,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
838
917
|
* Get user arguments from implied or explicit arguments.
|
|
839
918
|
* Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
|
|
840
919
|
*
|
|
841
|
-
* @
|
|
920
|
+
* @private
|
|
842
921
|
*/
|
|
843
922
|
|
|
844
923
|
_prepareUserArgs(argv, parseOptions) {
|
|
@@ -941,7 +1020,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
941
1020
|
/**
|
|
942
1021
|
* Execute a sub-command executable.
|
|
943
1022
|
*
|
|
944
|
-
* @
|
|
1023
|
+
* @private
|
|
945
1024
|
*/
|
|
946
1025
|
|
|
947
1026
|
_executeSubCommand(subcommand, args) {
|
|
@@ -1028,15 +1107,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1028
1107
|
}
|
|
1029
1108
|
|
|
1030
1109
|
// By default terminate process when spawned process terminates.
|
|
1031
|
-
// Suppressing the exit if exitCallback defined is a bit messy and of limited use, but does allow process to stay running!
|
|
1032
1110
|
const exitCallback = this._exitCallback;
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1111
|
+
proc.on('close', (code, _signal) => {
|
|
1112
|
+
code = code ?? 1; // code is null if spawned process terminated due to a signal
|
|
1113
|
+
if (!exitCallback) {
|
|
1114
|
+
process.exit(code);
|
|
1115
|
+
} else {
|
|
1116
|
+
exitCallback(new CommanderError(code, 'commander.executeSubCommandAsync', '(close)'));
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1040
1119
|
proc.on('error', (err) => {
|
|
1041
1120
|
// @ts-ignore
|
|
1042
1121
|
if (err.code === 'ENOENT') {
|
|
@@ -1066,7 +1145,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1066
1145
|
}
|
|
1067
1146
|
|
|
1068
1147
|
/**
|
|
1069
|
-
* @
|
|
1148
|
+
* @private
|
|
1070
1149
|
*/
|
|
1071
1150
|
|
|
1072
1151
|
_dispatchSubcommand(commandName, operands, unknown) {
|
|
@@ -1089,7 +1168,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1089
1168
|
* Invoke help directly if possible, or dispatch if necessary.
|
|
1090
1169
|
* e.g. help foo
|
|
1091
1170
|
*
|
|
1092
|
-
* @
|
|
1171
|
+
* @private
|
|
1093
1172
|
*/
|
|
1094
1173
|
|
|
1095
1174
|
_dispatchHelpCommand(subcommandName) {
|
|
@@ -1103,14 +1182,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1103
1182
|
|
|
1104
1183
|
// Fallback to parsing the help flag to invoke the help.
|
|
1105
1184
|
return this._dispatchSubcommand(subcommandName, [], [
|
|
1106
|
-
this.
|
|
1185
|
+
this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? '--help'
|
|
1107
1186
|
]);
|
|
1108
1187
|
}
|
|
1109
1188
|
|
|
1110
1189
|
/**
|
|
1111
1190
|
* Check this.args against expected this.registeredArguments.
|
|
1112
1191
|
*
|
|
1113
|
-
* @
|
|
1192
|
+
* @private
|
|
1114
1193
|
*/
|
|
1115
1194
|
|
|
1116
1195
|
_checkNumberOfArguments() {
|
|
@@ -1132,7 +1211,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1132
1211
|
/**
|
|
1133
1212
|
* Process this.args using this.registeredArguments and save as this.processedArgs!
|
|
1134
1213
|
*
|
|
1135
|
-
* @
|
|
1214
|
+
* @private
|
|
1136
1215
|
*/
|
|
1137
1216
|
|
|
1138
1217
|
_processArguments() {
|
|
@@ -1177,10 +1256,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1177
1256
|
/**
|
|
1178
1257
|
* Once we have a promise we chain, but call synchronously until then.
|
|
1179
1258
|
*
|
|
1180
|
-
* @param {Promise|undefined} promise
|
|
1259
|
+
* @param {(Promise|undefined)} promise
|
|
1181
1260
|
* @param {Function} fn
|
|
1182
|
-
* @return {Promise|undefined}
|
|
1183
|
-
* @
|
|
1261
|
+
* @return {(Promise|undefined)}
|
|
1262
|
+
* @private
|
|
1184
1263
|
*/
|
|
1185
1264
|
|
|
1186
1265
|
_chainOrCall(promise, fn) {
|
|
@@ -1195,10 +1274,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1195
1274
|
|
|
1196
1275
|
/**
|
|
1197
1276
|
*
|
|
1198
|
-
* @param {Promise|undefined} promise
|
|
1277
|
+
* @param {(Promise|undefined)} promise
|
|
1199
1278
|
* @param {string} event
|
|
1200
|
-
* @return {Promise|undefined}
|
|
1201
|
-
* @
|
|
1279
|
+
* @return {(Promise|undefined)}
|
|
1280
|
+
* @private
|
|
1202
1281
|
*/
|
|
1203
1282
|
|
|
1204
1283
|
_chainOrCallHooks(promise, event) {
|
|
@@ -1226,11 +1305,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1226
1305
|
|
|
1227
1306
|
/**
|
|
1228
1307
|
*
|
|
1229
|
-
* @param {Promise|undefined} promise
|
|
1308
|
+
* @param {(Promise|undefined)} promise
|
|
1230
1309
|
* @param {Command} subCommand
|
|
1231
1310
|
* @param {string} event
|
|
1232
|
-
* @return {Promise|undefined}
|
|
1233
|
-
* @
|
|
1311
|
+
* @return {(Promise|undefined)}
|
|
1312
|
+
* @private
|
|
1234
1313
|
*/
|
|
1235
1314
|
|
|
1236
1315
|
_chainOrCallSubCommandHook(promise, subCommand, event) {
|
|
@@ -1249,7 +1328,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1249
1328
|
* Process arguments in context of this command.
|
|
1250
1329
|
* Returns action result, in case it is a promise.
|
|
1251
1330
|
*
|
|
1252
|
-
* @
|
|
1331
|
+
* @private
|
|
1253
1332
|
*/
|
|
1254
1333
|
|
|
1255
1334
|
_parseCommand(operands, unknown) {
|
|
@@ -1263,11 +1342,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1263
1342
|
if (operands && this._findCommand(operands[0])) {
|
|
1264
1343
|
return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
|
|
1265
1344
|
}
|
|
1266
|
-
if (this.
|
|
1345
|
+
if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
|
|
1267
1346
|
return this._dispatchHelpCommand(operands[1]);
|
|
1268
1347
|
}
|
|
1269
1348
|
if (this._defaultCommandName) {
|
|
1270
|
-
|
|
1349
|
+
this._outputHelpIfRequested(unknown); // Run the help for default command from parent rather than passing to default command
|
|
1271
1350
|
return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
|
|
1272
1351
|
}
|
|
1273
1352
|
if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
|
|
@@ -1275,7 +1354,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1275
1354
|
this.help({ error: true });
|
|
1276
1355
|
}
|
|
1277
1356
|
|
|
1278
|
-
|
|
1357
|
+
this._outputHelpIfRequested(parsed.unknown);
|
|
1279
1358
|
this._checkForMissingMandatoryOptions();
|
|
1280
1359
|
this._checkForConflictingOptions();
|
|
1281
1360
|
|
|
@@ -1333,7 +1412,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1333
1412
|
/**
|
|
1334
1413
|
* Find matching command.
|
|
1335
1414
|
*
|
|
1336
|
-
* @
|
|
1415
|
+
* @private
|
|
1337
1416
|
*/
|
|
1338
1417
|
_findCommand(name) {
|
|
1339
1418
|
if (!name) return undefined;
|
|
@@ -1345,7 +1424,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1345
1424
|
*
|
|
1346
1425
|
* @param {string} arg
|
|
1347
1426
|
* @return {Option}
|
|
1348
|
-
* @
|
|
1427
|
+
* @package internal use only
|
|
1349
1428
|
*/
|
|
1350
1429
|
|
|
1351
1430
|
_findOption(arg) {
|
|
@@ -1356,7 +1435,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1356
1435
|
* Display an error message if a mandatory option does not have a value.
|
|
1357
1436
|
* Called after checking for help flags in leaf subcommand.
|
|
1358
1437
|
*
|
|
1359
|
-
* @
|
|
1438
|
+
* @private
|
|
1360
1439
|
*/
|
|
1361
1440
|
|
|
1362
1441
|
_checkForMissingMandatoryOptions() {
|
|
@@ -1373,7 +1452,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1373
1452
|
/**
|
|
1374
1453
|
* Display an error message if conflicting options are used together in this.
|
|
1375
1454
|
*
|
|
1376
|
-
* @
|
|
1455
|
+
* @private
|
|
1377
1456
|
*/
|
|
1378
1457
|
_checkForConflictingLocalOptions() {
|
|
1379
1458
|
const definedNonDefaultOptions = this.options.filter(
|
|
@@ -1404,7 +1483,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1404
1483
|
* Display an error message if conflicting options are used together.
|
|
1405
1484
|
* Called after checking for help flags in leaf subcommand.
|
|
1406
1485
|
*
|
|
1407
|
-
* @
|
|
1486
|
+
* @private
|
|
1408
1487
|
*/
|
|
1409
1488
|
_checkForConflictingOptions() {
|
|
1410
1489
|
// Walk up hierarchy so can call in subcommand after checking for displaying help.
|
|
@@ -1425,8 +1504,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1425
1504
|
* sub --unknown uuu op => [sub], [--unknown uuu op]
|
|
1426
1505
|
* sub -- --unknown uuu op => [sub --unknown uuu op], []
|
|
1427
1506
|
*
|
|
1428
|
-
* @param {
|
|
1429
|
-
* @return {{operands:
|
|
1507
|
+
* @param {string[]} argv
|
|
1508
|
+
* @return {{operands: string[], unknown: string[]}}
|
|
1430
1509
|
*/
|
|
1431
1510
|
|
|
1432
1511
|
parseOptions(argv) {
|
|
@@ -1520,7 +1599,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1520
1599
|
operands.push(arg);
|
|
1521
1600
|
if (args.length > 0) unknown.push(...args);
|
|
1522
1601
|
break;
|
|
1523
|
-
} else if (
|
|
1602
|
+
} else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
|
|
1524
1603
|
operands.push(arg);
|
|
1525
1604
|
if (args.length > 0) operands.push(...args);
|
|
1526
1605
|
break;
|
|
@@ -1608,7 +1687,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1608
1687
|
* Apply any option related environment variables, if option does
|
|
1609
1688
|
* not have a value from cli or client code.
|
|
1610
1689
|
*
|
|
1611
|
-
* @
|
|
1690
|
+
* @private
|
|
1612
1691
|
*/
|
|
1613
1692
|
_parseOptionsEnv() {
|
|
1614
1693
|
this.options.forEach((option) => {
|
|
@@ -1631,7 +1710,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1631
1710
|
/**
|
|
1632
1711
|
* Apply any implied option values, if option is undefined or default value.
|
|
1633
1712
|
*
|
|
1634
|
-
* @
|
|
1713
|
+
* @private
|
|
1635
1714
|
*/
|
|
1636
1715
|
_parseOptionsImplied() {
|
|
1637
1716
|
const dualHelper = new DualOptions(this.options);
|
|
@@ -1655,7 +1734,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1655
1734
|
* Argument `name` is missing.
|
|
1656
1735
|
*
|
|
1657
1736
|
* @param {string} name
|
|
1658
|
-
* @
|
|
1737
|
+
* @private
|
|
1659
1738
|
*/
|
|
1660
1739
|
|
|
1661
1740
|
missingArgument(name) {
|
|
@@ -1667,7 +1746,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1667
1746
|
* `Option` is missing an argument.
|
|
1668
1747
|
*
|
|
1669
1748
|
* @param {Option} option
|
|
1670
|
-
* @
|
|
1749
|
+
* @private
|
|
1671
1750
|
*/
|
|
1672
1751
|
|
|
1673
1752
|
optionMissingArgument(option) {
|
|
@@ -1679,7 +1758,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1679
1758
|
* `Option` does not have a value, and is a mandatory option.
|
|
1680
1759
|
*
|
|
1681
1760
|
* @param {Option} option
|
|
1682
|
-
* @
|
|
1761
|
+
* @private
|
|
1683
1762
|
*/
|
|
1684
1763
|
|
|
1685
1764
|
missingMandatoryOptionValue(option) {
|
|
@@ -1692,7 +1771,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1692
1771
|
*
|
|
1693
1772
|
* @param {Option} option
|
|
1694
1773
|
* @param {Option} conflictingOption
|
|
1695
|
-
* @
|
|
1774
|
+
* @private
|
|
1696
1775
|
*/
|
|
1697
1776
|
_conflictingOption(option, conflictingOption) {
|
|
1698
1777
|
// The calling code does not know whether a negated option is the source of the
|
|
@@ -1729,7 +1808,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1729
1808
|
* Unknown option `flag`.
|
|
1730
1809
|
*
|
|
1731
1810
|
* @param {string} flag
|
|
1732
|
-
* @
|
|
1811
|
+
* @private
|
|
1733
1812
|
*/
|
|
1734
1813
|
|
|
1735
1814
|
unknownOption(flag) {
|
|
@@ -1758,7 +1837,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1758
1837
|
* Excess arguments, more than expected.
|
|
1759
1838
|
*
|
|
1760
1839
|
* @param {string[]} receivedArgs
|
|
1761
|
-
* @
|
|
1840
|
+
* @private
|
|
1762
1841
|
*/
|
|
1763
1842
|
|
|
1764
1843
|
_excessArguments(receivedArgs) {
|
|
@@ -1774,7 +1853,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1774
1853
|
/**
|
|
1775
1854
|
* Unknown command.
|
|
1776
1855
|
*
|
|
1777
|
-
* @
|
|
1856
|
+
* @private
|
|
1778
1857
|
*/
|
|
1779
1858
|
|
|
1780
1859
|
unknownCommand() {
|
|
@@ -1805,7 +1884,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1805
1884
|
* @param {string} [str]
|
|
1806
1885
|
* @param {string} [flags]
|
|
1807
1886
|
* @param {string} [description]
|
|
1808
|
-
* @return {this | string | undefined} `this` command for chaining, or version string if no arguments
|
|
1887
|
+
* @return {(this | string | undefined)} `this` command for chaining, or version string if no arguments
|
|
1809
1888
|
*/
|
|
1810
1889
|
|
|
1811
1890
|
version(str, flags, description) {
|
|
@@ -1814,8 +1893,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1814
1893
|
flags = flags || '-V, --version';
|
|
1815
1894
|
description = description || 'output the version number';
|
|
1816
1895
|
const versionOption = this.createOption(flags, description);
|
|
1817
|
-
this._versionOptionName = versionOption.attributeName();
|
|
1818
|
-
this.
|
|
1896
|
+
this._versionOptionName = versionOption.attributeName();
|
|
1897
|
+
this._registerOption(versionOption);
|
|
1898
|
+
|
|
1819
1899
|
this.on('option:' + versionOption.name(), () => {
|
|
1820
1900
|
this._outputConfiguration.writeOut(`${str}\n`);
|
|
1821
1901
|
this._exit(0, 'commander.version', str);
|
|
@@ -1828,7 +1908,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1828
1908
|
*
|
|
1829
1909
|
* @param {string} [str]
|
|
1830
1910
|
* @param {Object} [argsDescription]
|
|
1831
|
-
* @return {string|Command}
|
|
1911
|
+
* @return {(string|Command)}
|
|
1832
1912
|
*/
|
|
1833
1913
|
description(str, argsDescription) {
|
|
1834
1914
|
if (str === undefined && argsDescription === undefined) return this._description;
|
|
@@ -1843,7 +1923,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1843
1923
|
* Set the summary. Used when listed as subcommand of parent.
|
|
1844
1924
|
*
|
|
1845
1925
|
* @param {string} [str]
|
|
1846
|
-
* @return {string|Command}
|
|
1926
|
+
* @return {(string|Command)}
|
|
1847
1927
|
*/
|
|
1848
1928
|
summary(str) {
|
|
1849
1929
|
if (str === undefined) return this._summary;
|
|
@@ -1857,7 +1937,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1857
1937
|
* You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
|
|
1858
1938
|
*
|
|
1859
1939
|
* @param {string} [alias]
|
|
1860
|
-
* @return {string|Command}
|
|
1940
|
+
* @return {(string|Command)}
|
|
1861
1941
|
*/
|
|
1862
1942
|
|
|
1863
1943
|
alias(alias) {
|
|
@@ -1871,6 +1951,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1871
1951
|
}
|
|
1872
1952
|
|
|
1873
1953
|
if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');
|
|
1954
|
+
const matchingCommand = this.parent?._findCommand(alias);
|
|
1955
|
+
if (matchingCommand) {
|
|
1956
|
+
// c.f. _registerCommand
|
|
1957
|
+
const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join('|');
|
|
1958
|
+
throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
|
|
1959
|
+
}
|
|
1874
1960
|
|
|
1875
1961
|
command._aliases.push(alias);
|
|
1876
1962
|
return this;
|
|
@@ -1882,7 +1968,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1882
1968
|
* Only the first alias is shown in the auto-generated help.
|
|
1883
1969
|
*
|
|
1884
1970
|
* @param {string[]} [aliases]
|
|
1885
|
-
* @return {string[]|Command}
|
|
1971
|
+
* @return {(string[]|Command)}
|
|
1886
1972
|
*/
|
|
1887
1973
|
|
|
1888
1974
|
aliases(aliases) {
|
|
@@ -1897,7 +1983,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1897
1983
|
* Set / get the command usage `str`.
|
|
1898
1984
|
*
|
|
1899
1985
|
* @param {string} [str]
|
|
1900
|
-
* @return {
|
|
1986
|
+
* @return {(string|Command)}
|
|
1901
1987
|
*/
|
|
1902
1988
|
|
|
1903
1989
|
usage(str) {
|
|
@@ -1908,7 +1994,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1908
1994
|
return humanReadableArgName(arg);
|
|
1909
1995
|
});
|
|
1910
1996
|
return [].concat(
|
|
1911
|
-
(this.options.length || this.
|
|
1997
|
+
(this.options.length || (this._helpOption !== null) ? '[options]' : []),
|
|
1912
1998
|
(this.commands.length ? '[command]' : []),
|
|
1913
1999
|
(this.registeredArguments.length ? args : [])
|
|
1914
2000
|
).join(' ');
|
|
@@ -1922,7 +2008,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1922
2008
|
* Get or set the name of the command.
|
|
1923
2009
|
*
|
|
1924
2010
|
* @param {string} [str]
|
|
1925
|
-
* @return {string|Command}
|
|
2011
|
+
* @return {(string|Command)}
|
|
1926
2012
|
*/
|
|
1927
2013
|
|
|
1928
2014
|
name(str) {
|
|
@@ -1959,7 +2045,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1959
2045
|
* program.executableDir('subcommands');
|
|
1960
2046
|
*
|
|
1961
2047
|
* @param {string} [path]
|
|
1962
|
-
* @return {string|null|Command}
|
|
2048
|
+
* @return {(string|null|Command)}
|
|
1963
2049
|
*/
|
|
1964
2050
|
|
|
1965
2051
|
executableDir(path) {
|
|
@@ -1984,7 +2070,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1984
2070
|
}
|
|
1985
2071
|
|
|
1986
2072
|
/**
|
|
1987
|
-
* @
|
|
2073
|
+
* @private
|
|
1988
2074
|
*/
|
|
1989
2075
|
|
|
1990
2076
|
_getHelpContext(contextOptions) {
|
|
@@ -2029,38 +2115,72 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2029
2115
|
}
|
|
2030
2116
|
context.write(helpInformation);
|
|
2031
2117
|
|
|
2032
|
-
if (this.
|
|
2033
|
-
this.emit(this.
|
|
2118
|
+
if (this._getHelpOption()?.long) {
|
|
2119
|
+
this.emit(this._getHelpOption().long); // deprecated
|
|
2034
2120
|
}
|
|
2035
2121
|
this.emit('afterHelp', context);
|
|
2036
2122
|
this._getCommandAndAncestors().forEach(command => command.emit('afterAllHelp', context));
|
|
2037
2123
|
}
|
|
2038
2124
|
|
|
2039
2125
|
/**
|
|
2040
|
-
* You can pass in flags and a description to
|
|
2041
|
-
*
|
|
2042
|
-
*
|
|
2126
|
+
* You can pass in flags and a description to customise the built-in help option.
|
|
2127
|
+
* Pass in false to disable the built-in help option.
|
|
2128
|
+
*
|
|
2129
|
+
* @example
|
|
2130
|
+
* program.helpOption('-?, --help' 'show help'); // customise
|
|
2131
|
+
* program.helpOption(false); // disable
|
|
2043
2132
|
*
|
|
2044
|
-
* @param {string | boolean}
|
|
2133
|
+
* @param {(string | boolean)} flags
|
|
2045
2134
|
* @param {string} [description]
|
|
2046
2135
|
* @return {Command} `this` command for chaining
|
|
2047
2136
|
*/
|
|
2048
2137
|
|
|
2049
2138
|
helpOption(flags, description) {
|
|
2139
|
+
// Support disabling built-in help option.
|
|
2050
2140
|
if (typeof flags === 'boolean') {
|
|
2051
|
-
|
|
2141
|
+
if (flags) {
|
|
2142
|
+
this._helpOption = this._helpOption ?? undefined; // preserve existing option
|
|
2143
|
+
} else {
|
|
2144
|
+
this._helpOption = null; // disable
|
|
2145
|
+
}
|
|
2052
2146
|
return this;
|
|
2053
2147
|
}
|
|
2054
|
-
this._helpFlags = flags || this._helpFlags;
|
|
2055
|
-
this._helpDescription = description || this._helpDescription;
|
|
2056
2148
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2149
|
+
// Customise flags and description.
|
|
2150
|
+
flags = flags ?? '-h, --help';
|
|
2151
|
+
description = description ?? 'display help for command';
|
|
2152
|
+
this._helpOption = this.createOption(flags, description);
|
|
2060
2153
|
|
|
2061
2154
|
return this;
|
|
2062
2155
|
}
|
|
2063
2156
|
|
|
2157
|
+
/**
|
|
2158
|
+
* Lazy create help option.
|
|
2159
|
+
* Returns null if has been disabled with .helpOption(false).
|
|
2160
|
+
*
|
|
2161
|
+
* @returns {(Option | null)} the help option
|
|
2162
|
+
* @package internal use only
|
|
2163
|
+
*/
|
|
2164
|
+
_getHelpOption() {
|
|
2165
|
+
// Lazy create help option on demand.
|
|
2166
|
+
if (this._helpOption === undefined) {
|
|
2167
|
+
this.helpOption(undefined, undefined);
|
|
2168
|
+
}
|
|
2169
|
+
return this._helpOption;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
/**
|
|
2173
|
+
* Supply your own option to use for the built-in help option.
|
|
2174
|
+
* This is an alternative to using helpOption() to customise the flags and description etc.
|
|
2175
|
+
*
|
|
2176
|
+
* @param {Option} option
|
|
2177
|
+
* @return {Command} `this` command for chaining
|
|
2178
|
+
*/
|
|
2179
|
+
addHelpOption(option) {
|
|
2180
|
+
this._helpOption = option;
|
|
2181
|
+
return this;
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2064
2184
|
/**
|
|
2065
2185
|
* Output help information and exit.
|
|
2066
2186
|
*
|
|
@@ -2086,7 +2206,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2086
2206
|
* and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
|
|
2087
2207
|
*
|
|
2088
2208
|
* @param {string} position - before or after built-in help
|
|
2089
|
-
* @param {string | Function} text - string to add, or a function returning a string
|
|
2209
|
+
* @param {(string | Function)} text - string to add, or a function returning a string
|
|
2090
2210
|
* @return {Command} `this` command for chaining
|
|
2091
2211
|
*/
|
|
2092
2212
|
addHelpText(position, text) {
|
|
@@ -2110,22 +2230,22 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2110
2230
|
});
|
|
2111
2231
|
return this;
|
|
2112
2232
|
}
|
|
2113
|
-
}
|
|
2114
2233
|
|
|
2115
|
-
/**
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
*/
|
|
2234
|
+
/**
|
|
2235
|
+
* Output help information if help flags specified
|
|
2236
|
+
*
|
|
2237
|
+
* @param {Array} args - array of options to search for help flags
|
|
2238
|
+
* @private
|
|
2239
|
+
*/
|
|
2122
2240
|
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2241
|
+
_outputHelpIfRequested(args) {
|
|
2242
|
+
const helpOption = this._getHelpOption();
|
|
2243
|
+
const helpRequested = helpOption && args.find(arg => helpOption.is(arg));
|
|
2244
|
+
if (helpRequested) {
|
|
2245
|
+
this.outputHelp();
|
|
2246
|
+
// (Do not have all displayed text available so only passing placeholder.)
|
|
2247
|
+
this._exit(0, 'commander.helpDisplayed', '(outputHelp)');
|
|
2248
|
+
}
|
|
2129
2249
|
}
|
|
2130
2250
|
}
|
|
2131
2251
|
|
|
@@ -2134,7 +2254,7 @@ function outputHelpIfRequested(cmd, args) {
|
|
|
2134
2254
|
*
|
|
2135
2255
|
* @param {string[]} args - array of arguments from node.execArgv
|
|
2136
2256
|
* @returns {string[]}
|
|
2137
|
-
* @
|
|
2257
|
+
* @private
|
|
2138
2258
|
*/
|
|
2139
2259
|
|
|
2140
2260
|
function incrementNodeInspectorPort(args) {
|
package/lib/help.js
CHANGED
|
@@ -26,13 +26,8 @@ class Help {
|
|
|
26
26
|
|
|
27
27
|
visibleCommands(cmd) {
|
|
28
28
|
const visibleCommands = cmd.commands.filter(cmd => !cmd._hidden);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const [, helpName, helpArgs] = cmd._helpCommandnameAndArgs.match(/([^ ]+) *(.*)/);
|
|
32
|
-
const helpCommand = cmd.createCommand(helpName)
|
|
33
|
-
.helpOption(false);
|
|
34
|
-
helpCommand.description(cmd._helpCommandDescription);
|
|
35
|
-
if (helpArgs) helpCommand.arguments(helpArgs);
|
|
29
|
+
const helpCommand = cmd._getHelpCommand();
|
|
30
|
+
if (helpCommand && !helpCommand._hidden) {
|
|
36
31
|
visibleCommands.push(helpCommand);
|
|
37
32
|
}
|
|
38
33
|
if (this.sortSubcommands) {
|
|
@@ -68,19 +63,19 @@ class Help {
|
|
|
68
63
|
|
|
69
64
|
visibleOptions(cmd) {
|
|
70
65
|
const visibleOptions = cmd.options.filter((option) => !option.hidden);
|
|
71
|
-
//
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
// Built-in help option.
|
|
67
|
+
const helpOption = cmd._getHelpOption();
|
|
68
|
+
if (helpOption && !helpOption.hidden) {
|
|
69
|
+
// Automatically hide conflicting flags. Bit dubious but a historical behaviour that is convenient for single-command programs.
|
|
70
|
+
const removeShort = helpOption.short && cmd._findOption(helpOption.short);
|
|
71
|
+
const removeLong = helpOption.long && cmd._findOption(helpOption.long);
|
|
72
|
+
if (!removeShort && !removeLong) {
|
|
73
|
+
visibleOptions.push(helpOption); // no changes needed
|
|
74
|
+
} else if (helpOption.long && !removeLong) {
|
|
75
|
+
visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
|
|
76
|
+
} else if (helpOption.short && !removeShort) {
|
|
77
|
+
visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
|
|
82
78
|
}
|
|
83
|
-
visibleOptions.push(helpOption);
|
|
84
79
|
}
|
|
85
80
|
if (this.sortOptions) {
|
|
86
81
|
visibleOptions.sort(this.compareOptions);
|
package/lib/option.js
CHANGED
|
@@ -74,7 +74,7 @@ class Option {
|
|
|
74
74
|
* new Option('--rgb').conflicts('cmyk');
|
|
75
75
|
* new Option('--js').conflicts(['ts', 'jsx']);
|
|
76
76
|
*
|
|
77
|
-
* @param {string | string[]} names
|
|
77
|
+
* @param {(string | string[])} names
|
|
78
78
|
* @return {Option}
|
|
79
79
|
*/
|
|
80
80
|
|
|
@@ -158,7 +158,7 @@ class Option {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
|
-
* @
|
|
161
|
+
* @package internal use only
|
|
162
162
|
*/
|
|
163
163
|
|
|
164
164
|
_concatValue(value, previous) {
|
|
@@ -208,7 +208,6 @@ class Option {
|
|
|
208
208
|
* as a object attribute key.
|
|
209
209
|
*
|
|
210
210
|
* @return {string}
|
|
211
|
-
* @api private
|
|
212
211
|
*/
|
|
213
212
|
|
|
214
213
|
attributeName() {
|
|
@@ -220,7 +219,7 @@ class Option {
|
|
|
220
219
|
*
|
|
221
220
|
* @param {string} arg
|
|
222
221
|
* @return {boolean}
|
|
223
|
-
* @
|
|
222
|
+
* @package internal use only
|
|
224
223
|
*/
|
|
225
224
|
|
|
226
225
|
is(arg) {
|
|
@@ -233,7 +232,7 @@ class Option {
|
|
|
233
232
|
* Options are one of boolean, negated, required argument, or optional argument.
|
|
234
233
|
*
|
|
235
234
|
* @return {boolean}
|
|
236
|
-
* @
|
|
235
|
+
* @package internal use only
|
|
237
236
|
*/
|
|
238
237
|
|
|
239
238
|
isBoolean() {
|
|
@@ -293,7 +292,7 @@ class DualOptions {
|
|
|
293
292
|
*
|
|
294
293
|
* @param {string} str
|
|
295
294
|
* @return {string}
|
|
296
|
-
* @
|
|
295
|
+
* @private
|
|
297
296
|
*/
|
|
298
297
|
|
|
299
298
|
function camelcase(str) {
|
|
@@ -305,7 +304,7 @@ function camelcase(str) {
|
|
|
305
304
|
/**
|
|
306
305
|
* Split the short and long flag out of something like '-m,--mixed <value>'
|
|
307
306
|
*
|
|
308
|
-
* @
|
|
307
|
+
* @private
|
|
309
308
|
*/
|
|
310
309
|
|
|
311
310
|
function splitOptionFlags(flags) {
|
|
@@ -325,5 +324,4 @@ function splitOptionFlags(flags) {
|
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
exports.Option = Option;
|
|
328
|
-
exports.splitOptionFlags = splitOptionFlags;
|
|
329
327
|
exports.DualOptions = DualOptions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0-1",
|
|
4
4
|
"description": "the complete solution for node.js command-line programs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commander",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "https://github.com/tj/commander.js.git"
|
|
19
|
+
"url": "git+https://github.com/tj/commander.js.git"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"lint": "npm run lint:javascript && npm run lint:typescript",
|
|
@@ -58,23 +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": "^40.0.0",
|
|
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
76
|
"engines": {
|
|
77
|
-
"node": ">=
|
|
77
|
+
"node": ">=18"
|
|
78
78
|
},
|
|
79
79
|
"support": true
|
|
80
80
|
}
|
package/typings/index.d.ts
CHANGED
|
@@ -419,18 +419,27 @@ export class Command {
|
|
|
419
419
|
arguments(names: string): this;
|
|
420
420
|
|
|
421
421
|
/**
|
|
422
|
-
*
|
|
422
|
+
* Customise or override default help command. By default a help command is automatically added if your command has subcommands.
|
|
423
423
|
*
|
|
424
424
|
* @example
|
|
425
|
+
* ```ts
|
|
426
|
+
* program.helpCommand('help [cmd]');
|
|
427
|
+
* program.helpCommand('help [cmd]', 'show help');
|
|
428
|
+
* program.helpCommand(false); // suppress default help command
|
|
429
|
+
* program.helpCommand(true); // add help command even if no subcommands
|
|
425
430
|
* ```
|
|
426
|
-
* addHelpCommand() // force on
|
|
427
|
-
* addHelpCommand(false); // force off
|
|
428
|
-
* addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
|
|
429
|
-
* ```
|
|
430
|
-
*
|
|
431
|
-
* @returns `this` command for chaining
|
|
432
431
|
*/
|
|
433
|
-
|
|
432
|
+
helpCommand(nameAndArgs: string, description?: string): this;
|
|
433
|
+
helpCommand(enable: boolean): this;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Add prepared custom help command.
|
|
437
|
+
*/
|
|
438
|
+
addHelpCommand(cmd: Command): this;
|
|
439
|
+
/** @deprecated since v12, instead use helpCommand */
|
|
440
|
+
addHelpCommand(nameAndArgs: string, description?: string): this;
|
|
441
|
+
/** @deprecated since v12, instead use helpCommand */
|
|
442
|
+
addHelpCommand(enable?: boolean): this;
|
|
434
443
|
|
|
435
444
|
/**
|
|
436
445
|
* Add hook for life cycle event.
|
|
@@ -838,6 +847,12 @@ export class Command {
|
|
|
838
847
|
*/
|
|
839
848
|
helpOption(flags?: string | boolean, description?: string): this;
|
|
840
849
|
|
|
850
|
+
/**
|
|
851
|
+
* Supply your own option to use for the built-in help option.
|
|
852
|
+
* This is an alternative to using helpOption() to customise the flags and description etc.
|
|
853
|
+
*/
|
|
854
|
+
addHelpOption(option: Option): this;
|
|
855
|
+
|
|
841
856
|
/**
|
|
842
857
|
* Output help information and exit.
|
|
843
858
|
*
|