commander 13.0.0-0 → 13.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 +4 -4
- package/lib/command.js +85 -8
- package/package.json +2 -2
- package/typings/index.d.ts +18 -2
package/Readme.md
CHANGED
|
@@ -921,9 +921,11 @@ program.helpCommand('assist [command]', 'show assistance');
|
|
|
921
921
|
### More configuration
|
|
922
922
|
|
|
923
923
|
The built-in help is formatted using the Help class.
|
|
924
|
-
You can configure the
|
|
924
|
+
You can configure the help by modifying data properties and methods using `.configureHelp()`, or by subclassing Help using `.createHelp()` .
|
|
925
925
|
|
|
926
|
-
|
|
926
|
+
Simple properties include `sortSubcommands`, `sortOptions`, and `showGlobalOptions`. You can add color using the style methods like `styleTitle()`.
|
|
927
|
+
|
|
928
|
+
For more detail and examples of changing the displayed text, color, and layout see (./docs/help-in-depth.md)
|
|
927
929
|
|
|
928
930
|
## Custom event listeners
|
|
929
931
|
|
|
@@ -957,8 +959,6 @@ program.parse(['--port', '80'], { from: 'user' }); // just user supplied argumen
|
|
|
957
959
|
|
|
958
960
|
Use parseAsync instead of parse if any of your action handlers are async.
|
|
959
961
|
|
|
960
|
-
If you want to parse multiple times, create a new program each time. Calling parse does not clear out any previous state.
|
|
961
|
-
|
|
962
962
|
### Parsing Configuration
|
|
963
963
|
|
|
964
964
|
If the default parsing does not suit your needs, there are some behaviours to support other usage patterns.
|
package/lib/command.js
CHANGED
|
@@ -55,6 +55,7 @@ class Command extends EventEmitter {
|
|
|
55
55
|
/** @type {(boolean | string)} */
|
|
56
56
|
this._showHelpAfterError = false;
|
|
57
57
|
this._showSuggestionAfterError = true;
|
|
58
|
+
this._savedState = null; // used in save/restoreStateBeforeParse
|
|
58
59
|
|
|
59
60
|
// see configureOutput() for docs
|
|
60
61
|
this._outputConfiguration = {
|
|
@@ -1069,6 +1070,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1069
1070
|
*/
|
|
1070
1071
|
|
|
1071
1072
|
parse(argv, parseOptions) {
|
|
1073
|
+
this._prepareForParse();
|
|
1072
1074
|
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
|
1073
1075
|
this._parseCommand([], userArgs);
|
|
1074
1076
|
|
|
@@ -1097,12 +1099,82 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1097
1099
|
*/
|
|
1098
1100
|
|
|
1099
1101
|
async parseAsync(argv, parseOptions) {
|
|
1102
|
+
this._prepareForParse();
|
|
1100
1103
|
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
|
1101
1104
|
await this._parseCommand([], userArgs);
|
|
1102
1105
|
|
|
1103
1106
|
return this;
|
|
1104
1107
|
}
|
|
1105
1108
|
|
|
1109
|
+
_prepareForParse() {
|
|
1110
|
+
if (this._savedState === null) {
|
|
1111
|
+
this.saveStateBeforeParse();
|
|
1112
|
+
} else {
|
|
1113
|
+
this.restoreStateBeforeParse();
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
|
|
1119
|
+
* Not usually called directly, but available for subclasses to save their custom state.
|
|
1120
|
+
*
|
|
1121
|
+
* This is called in a lazy way. Only commands used in parsing chain will have state saved.
|
|
1122
|
+
*/
|
|
1123
|
+
saveStateBeforeParse() {
|
|
1124
|
+
this._savedState = {
|
|
1125
|
+
// name is stable if supplied by author, but may be unspecified for root command and deduced during parsing
|
|
1126
|
+
_name: this._name,
|
|
1127
|
+
// option values before parse have default values (including false for negated options)
|
|
1128
|
+
// shallow clones
|
|
1129
|
+
_optionValues: { ...this._optionValues },
|
|
1130
|
+
_optionValueSources: { ...this._optionValueSources },
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
/**
|
|
1135
|
+
* Restore state before parse for calls after the first.
|
|
1136
|
+
* Not usually called directly, but available for subclasses to save their custom state.
|
|
1137
|
+
*
|
|
1138
|
+
* This is called in a lazy way. Only commands used in parsing chain will have state restored.
|
|
1139
|
+
*/
|
|
1140
|
+
restoreStateBeforeParse() {
|
|
1141
|
+
if (this._storeOptionsAsProperties)
|
|
1142
|
+
throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
|
|
1143
|
+
- either make a new Command for each call to parse, or stop storing options as properties`);
|
|
1144
|
+
|
|
1145
|
+
// clear state from _prepareUserArgs
|
|
1146
|
+
this._name = this._savedState._name;
|
|
1147
|
+
this._scriptPath = null;
|
|
1148
|
+
this.rawArgs = [];
|
|
1149
|
+
// clear state from setOptionValueWithSource
|
|
1150
|
+
this._optionValues = { ...this._savedState._optionValues };
|
|
1151
|
+
this._optionValueSources = { ...this._savedState._optionValueSources };
|
|
1152
|
+
// clear state from _parseCommand
|
|
1153
|
+
this.args = [];
|
|
1154
|
+
// clear state from _processArguments
|
|
1155
|
+
this.processedArgs = [];
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
/**
|
|
1159
|
+
* Throw if expected executable is missing. Add lots of help for author.
|
|
1160
|
+
*
|
|
1161
|
+
* @param {string} executableFile
|
|
1162
|
+
* @param {string} executableDir
|
|
1163
|
+
* @param {string} subcommandName
|
|
1164
|
+
*/
|
|
1165
|
+
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
1166
|
+
if (fs.existsSync(executableFile)) return;
|
|
1167
|
+
|
|
1168
|
+
const executableDirMessage = executableDir
|
|
1169
|
+
? `searched for local subcommand relative to directory '${executableDir}'`
|
|
1170
|
+
: 'no directory for search for local subcommand, use .executableDir() to supply a custom directory';
|
|
1171
|
+
const executableMissing = `'${executableFile}' does not exist
|
|
1172
|
+
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
1173
|
+
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
1174
|
+
- ${executableDirMessage}`;
|
|
1175
|
+
throw new Error(executableMissing);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1106
1178
|
/**
|
|
1107
1179
|
* Execute a sub-command executable.
|
|
1108
1180
|
*
|
|
@@ -1186,6 +1258,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1186
1258
|
proc = childProcess.spawn(executableFile, args, { stdio: 'inherit' });
|
|
1187
1259
|
}
|
|
1188
1260
|
} else {
|
|
1261
|
+
this._checkForMissingExecutable(
|
|
1262
|
+
executableFile,
|
|
1263
|
+
executableDir,
|
|
1264
|
+
subcommand._name,
|
|
1265
|
+
);
|
|
1189
1266
|
args.unshift(executableFile);
|
|
1190
1267
|
// add executable arguments to spawn
|
|
1191
1268
|
args = incrementNodeInspectorPort(process.execArgv).concat(args);
|
|
@@ -1224,14 +1301,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1224
1301
|
proc.on('error', (err) => {
|
|
1225
1302
|
// @ts-ignore: because err.code is an unknown property
|
|
1226
1303
|
if (err.code === 'ENOENT') {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
1233
|
-
- ${executableDirMessage}`;
|
|
1234
|
-
throw new Error(executableMissing);
|
|
1304
|
+
this._checkForMissingExecutable(
|
|
1305
|
+
executableFile,
|
|
1306
|
+
executableDir,
|
|
1307
|
+
subcommand._name,
|
|
1308
|
+
);
|
|
1235
1309
|
// @ts-ignore: because err.code is an unknown property
|
|
1236
1310
|
} else if (err.code === 'EACCES') {
|
|
1237
1311
|
throw new Error(`'${executableFile}' not executable`);
|
|
@@ -1261,6 +1335,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1261
1335
|
const subCommand = this._findCommand(commandName);
|
|
1262
1336
|
if (!subCommand) this.help({ error: true });
|
|
1263
1337
|
|
|
1338
|
+
subCommand._prepareForParse();
|
|
1264
1339
|
let promiseChain;
|
|
1265
1340
|
promiseChain = this._chainOrCallSubCommandHook(
|
|
1266
1341
|
promiseChain,
|
|
@@ -1638,6 +1713,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1638
1713
|
* Parse options from `argv` removing known options,
|
|
1639
1714
|
* and return argv split into operands and unknown arguments.
|
|
1640
1715
|
*
|
|
1716
|
+
* Side effects: modifies command by storing options. Does not reset state if called again.
|
|
1717
|
+
*
|
|
1641
1718
|
* Examples:
|
|
1642
1719
|
*
|
|
1643
1720
|
* argv => operands, unknown
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander",
|
|
3
|
-
"version": "13.0.0
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "the complete solution for node.js command-line programs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commander",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"@eslint/js": "^9.4.0",
|
|
64
64
|
"@types/jest": "^29.2.4",
|
|
65
65
|
"@types/node": "^22.7.4",
|
|
66
|
-
"eslint": "^
|
|
66
|
+
"eslint": "^9.17.0",
|
|
67
67
|
"eslint-config-prettier": "^9.1.0",
|
|
68
68
|
"eslint-plugin-jest": "^28.3.0",
|
|
69
69
|
"globals": "^15.7.0",
|
package/typings/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Type definitions for commander
|
|
2
2
|
// Original definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>, Jules Randolph <https://github.com/sveinburne>
|
|
3
3
|
|
|
4
|
-
// Using method rather than property for method-signature-style, to document method overloads separately. Allow either.
|
|
5
|
-
/* eslint-disable @typescript-eslint/method-signature-style */
|
|
6
4
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
5
|
|
|
8
6
|
// This is a trick to encourage editor to suggest the known literals while still
|
|
@@ -823,10 +821,28 @@ export class Command {
|
|
|
823
821
|
parseOptions?: ParseOptions,
|
|
824
822
|
): Promise<this>;
|
|
825
823
|
|
|
824
|
+
/**
|
|
825
|
+
* Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
|
|
826
|
+
* Not usually called directly, but available for subclasses to save their custom state.
|
|
827
|
+
*
|
|
828
|
+
* This is called in a lazy way. Only commands used in parsing chain will have state saved.
|
|
829
|
+
*/
|
|
830
|
+
saveStateBeforeParse(): void;
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Restore state before parse for calls after the first.
|
|
834
|
+
* Not usually called directly, but available for subclasses to save their custom state.
|
|
835
|
+
*
|
|
836
|
+
* This is called in a lazy way. Only commands used in parsing chain will have state restored.
|
|
837
|
+
*/
|
|
838
|
+
restoreStateBeforeParse(): void;
|
|
839
|
+
|
|
826
840
|
/**
|
|
827
841
|
* Parse options from `argv` removing known options,
|
|
828
842
|
* and return argv split into operands and unknown arguments.
|
|
829
843
|
*
|
|
844
|
+
* Side effects: modifies command by storing options. Does not reset state if called again.
|
|
845
|
+
*
|
|
830
846
|
* argv => operands, unknown
|
|
831
847
|
* --known kkk op => [op], []
|
|
832
848
|
* op --known kkk => [op], []
|