commander 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -1
- package/Readme.md +18 -15
- package/esm.mjs +4 -0
- package/index.js +36 -19
- package/package.json +10 -6
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
8
8
|
<!-- markdownlint-disable MD024 -->
|
|
9
9
|
<!-- markdownlint-disable MD004 -->
|
|
10
10
|
|
|
11
|
+
## [7.1.0] (2021-02-15)
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- support for named imports from ECMAScript modules ([#1440])
|
|
16
|
+
- add `.cjs` to list of expected script file extensions ([#1449])
|
|
17
|
+
- allow using option choices and variadic together ([#1454])
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- replace use of deprecated `process.mainModule` ([#1448])
|
|
22
|
+
- regression for legacy `command('*')` and call when command line includes options ([#1464])
|
|
23
|
+
- regression for `on('command:*', ...)` and call when command line includes unknown options ([#1464])
|
|
24
|
+
- display best error for combination of unknown command and unknown option (i.e. unknown command) ([#1464])
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- make TypeScript typings tests stricter ([#1453])
|
|
29
|
+
- improvements to README and tests
|
|
30
|
+
|
|
11
31
|
## [7.0.0] (2021-01-15)
|
|
12
32
|
|
|
13
33
|
### Added
|
|
@@ -53,7 +73,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
53
73
|
- *Breaking:* `.passCommandToAction()` ([#1409])
|
|
54
74
|
- no longer needed as action handler is passed options and command
|
|
55
75
|
- *Breaking:* "extra arguments" parameter to action handler ([#1409])
|
|
56
|
-
- if being used to detect excess arguments, there is now an error
|
|
76
|
+
- if being used to detect excess arguments, there is now an error available by setting `.allowExcessArguments(false)`
|
|
57
77
|
|
|
58
78
|
### Migration Tips
|
|
59
79
|
|
|
@@ -376,8 +396,17 @@ to expand `-fb` to `-f -b` rather than `-f b`.
|
|
|
376
396
|
[#1403]: https://github.com/tj/commander.js/pull/1403
|
|
377
397
|
[#1409]: https://github.com/tj/commander.js/pull/1409
|
|
378
398
|
[#1427]: https://github.com/tj/commander.js/pull/1427
|
|
399
|
+
[#1440]: https://github.com/tj/commander.js/pull/1440
|
|
400
|
+
[#1448]: https://github.com/tj/commander.js/pull/1448
|
|
401
|
+
[#1449]: https://github.com/tj/commander.js/pull/1449
|
|
402
|
+
[#1453]: https://github.com/tj/commander.js/pull/1453
|
|
403
|
+
[#1454]: https://github.com/tj/commander.js/pull/1454
|
|
404
|
+
[#1464]: https://github.com/tj/commander.js/pull/1464
|
|
405
|
+
|
|
406
|
+
|
|
379
407
|
|
|
380
408
|
[Unreleased]: https://github.com/tj/commander.js/compare/master...develop
|
|
409
|
+
[7.1.0]: https://github.com/tj/commander.js/compare/v7.0.0...v7.1.0
|
|
381
410
|
[7.0.0]: https://github.com/tj/commander.js/compare/v6.2.1...v7.0.0
|
|
382
411
|
[7.0.0-2]: https://github.com/tj/commander.js/compare/v7.0.0-1...v7.0.0-2
|
|
383
412
|
[7.0.0-1]: https://github.com/tj/commander.js/compare/v7.0.0-0...v7.0.0-1
|
package/Readme.md
CHANGED
|
@@ -39,7 +39,6 @@ Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
|
|
|
39
39
|
- [Legacy options as properties](#legacy-options-as-properties)
|
|
40
40
|
- [TypeScript](#typescript)
|
|
41
41
|
- [createCommand()](#createcommand)
|
|
42
|
-
- [Import into ECMAScript Module](#import-into-ecmascript-module)
|
|
43
42
|
- [Node options such as `--harmony`](#node-options-such-as---harmony)
|
|
44
43
|
- [Debugging stand-alone executable subcommands](#debugging-stand-alone-executable-subcommands)
|
|
45
44
|
- [Override exit and output handling](#override-exit-and-output-handling)
|
|
@@ -74,6 +73,23 @@ const program = new Command();
|
|
|
74
73
|
program.version('0.0.1');
|
|
75
74
|
```
|
|
76
75
|
|
|
76
|
+
For named imports in ECMAScript modules, import from `commander/esm.mjs`.
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
// index.mjs
|
|
80
|
+
import { Command } from 'commander/esm.mjs';
|
|
81
|
+
const program = new Command();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
And in TypeScript:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
// index.ts
|
|
88
|
+
import { Command } from 'commander';
|
|
89
|
+
const program = new Command();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
77
93
|
## Options
|
|
78
94
|
|
|
79
95
|
Options are defined with the `.option()` method, also serving as documentation for the options. Each option can have a short flag (single character) and a long name, separated by a comma or space or vertical bar ('|').
|
|
@@ -655,7 +671,7 @@ You can execute custom actions by listening to command and option events.
|
|
|
655
671
|
|
|
656
672
|
```js
|
|
657
673
|
program.on('option:verbose', function () {
|
|
658
|
-
process.env.VERBOSE = this.verbose;
|
|
674
|
+
process.env.VERBOSE = this.opts().verbose;
|
|
659
675
|
});
|
|
660
676
|
|
|
661
677
|
program.on('command:*', function (operands) {
|
|
@@ -740,8 +756,6 @@ program
|
|
|
740
756
|
|
|
741
757
|
### TypeScript
|
|
742
758
|
|
|
743
|
-
The Commander package includes its TypeScript Definition file.
|
|
744
|
-
|
|
745
759
|
If you use `ts-node` and stand-alone executable subcommands written as `.ts` files, you need to call your program through node to get the subcommands called correctly. e.g.
|
|
746
760
|
|
|
747
761
|
```bash
|
|
@@ -761,17 +775,6 @@ const program = createCommand();
|
|
|
761
775
|
when creating subcommands using `.command()`, and you may override it to
|
|
762
776
|
customise the new subcommand (example file [custom-command-class.js](./examples/custom-command-class.js)).
|
|
763
777
|
|
|
764
|
-
### Import into ECMAScript Module
|
|
765
|
-
|
|
766
|
-
Commander is currently a CommonJS package, and the default export can be imported into an ES Module:
|
|
767
|
-
|
|
768
|
-
```js
|
|
769
|
-
// index.mjs
|
|
770
|
-
import commander from 'commander';
|
|
771
|
-
const program = commander.program;
|
|
772
|
-
const newCommand = new commander.Command();
|
|
773
|
-
```
|
|
774
|
-
|
|
775
778
|
### Node options such as `--harmony`
|
|
776
779
|
|
|
777
780
|
You can enable `--harmony` option in two ways:
|
package/esm.mjs
ADDED
package/index.js
CHANGED
|
@@ -425,6 +425,18 @@ class Option {
|
|
|
425
425
|
return this;
|
|
426
426
|
};
|
|
427
427
|
|
|
428
|
+
/**
|
|
429
|
+
* @api private
|
|
430
|
+
*/
|
|
431
|
+
|
|
432
|
+
_concatValue(value, previous) {
|
|
433
|
+
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
434
|
+
return [value];
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return previous.concat(value);
|
|
438
|
+
}
|
|
439
|
+
|
|
428
440
|
/**
|
|
429
441
|
* Only allow option value to be one of choices.
|
|
430
442
|
*
|
|
@@ -434,10 +446,13 @@ class Option {
|
|
|
434
446
|
|
|
435
447
|
choices(values) {
|
|
436
448
|
this.argChoices = values;
|
|
437
|
-
this.parseArg = (arg) => {
|
|
449
|
+
this.parseArg = (arg, previous) => {
|
|
438
450
|
if (!values.includes(arg)) {
|
|
439
451
|
throw new InvalidOptionArgumentError(`Allowed choices are ${values.join(', ')}.`);
|
|
440
452
|
}
|
|
453
|
+
if (this.variadic) {
|
|
454
|
+
return this._concatValue(arg, previous);
|
|
455
|
+
}
|
|
441
456
|
return arg;
|
|
442
457
|
};
|
|
443
458
|
return this;
|
|
@@ -976,11 +991,7 @@ class Command extends EventEmitter {
|
|
|
976
991
|
throw err;
|
|
977
992
|
}
|
|
978
993
|
} else if (val !== null && option.variadic) {
|
|
979
|
-
|
|
980
|
-
val = [val];
|
|
981
|
-
} else {
|
|
982
|
-
val = oldValue.concat(val);
|
|
983
|
-
}
|
|
994
|
+
val = option._concatValue(val, oldValue);
|
|
984
995
|
}
|
|
985
996
|
|
|
986
997
|
// unassigned or boolean value
|
|
@@ -1270,10 +1281,8 @@ class Command extends EventEmitter {
|
|
|
1270
1281
|
default:
|
|
1271
1282
|
throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
|
|
1272
1283
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
// @ts-ignore: unknown property
|
|
1276
|
-
this._scriptPath = process.mainModule.filename;
|
|
1284
|
+
if (!this._scriptPath && require.main) {
|
|
1285
|
+
this._scriptPath = require.main.filename;
|
|
1277
1286
|
}
|
|
1278
1287
|
|
|
1279
1288
|
// Guess name, used in usage in help.
|
|
@@ -1319,7 +1328,7 @@ class Command extends EventEmitter {
|
|
|
1319
1328
|
_executeSubCommand(subcommand, args) {
|
|
1320
1329
|
args = args.slice();
|
|
1321
1330
|
let launchWithNode = false; // Use node for source targets so do not need to get permissions correct, and on Windows.
|
|
1322
|
-
const sourceExt = ['.js', '.ts', '.tsx', '.mjs'];
|
|
1331
|
+
const sourceExt = ['.js', '.ts', '.tsx', '.mjs', '.cjs'];
|
|
1323
1332
|
|
|
1324
1333
|
// Not checking for help first. Unlikely to have mandatory and executable, and can't robustly test for help flags in external command.
|
|
1325
1334
|
this._checkForMissingMandatoryOptions();
|
|
@@ -1327,10 +1336,8 @@ class Command extends EventEmitter {
|
|
|
1327
1336
|
// Want the entry script as the reference for command name and directory for searching for other files.
|
|
1328
1337
|
let scriptPath = this._scriptPath;
|
|
1329
1338
|
// Fallback in case not set, due to how Command created or called.
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
// @ts-ignore: unknown property
|
|
1333
|
-
scriptPath = process.mainModule.filename;
|
|
1339
|
+
if (!scriptPath && require.main) {
|
|
1340
|
+
scriptPath = require.main.filename;
|
|
1334
1341
|
}
|
|
1335
1342
|
|
|
1336
1343
|
let baseDir;
|
|
@@ -1468,12 +1475,17 @@ class Command extends EventEmitter {
|
|
|
1468
1475
|
|
|
1469
1476
|
outputHelpIfRequested(this, parsed.unknown);
|
|
1470
1477
|
this._checkForMissingMandatoryOptions();
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1478
|
+
|
|
1479
|
+
// We do not always call this check to avoid masking a "better" error, like unknown command.
|
|
1480
|
+
const checkForUnknownOptions = () => {
|
|
1481
|
+
if (parsed.unknown.length > 0) {
|
|
1482
|
+
this.unknownOption(parsed.unknown[0]);
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1474
1485
|
|
|
1475
1486
|
const commandEvent = `command:${this.name()}`;
|
|
1476
1487
|
if (this._actionHandler) {
|
|
1488
|
+
checkForUnknownOptions();
|
|
1477
1489
|
// Check expected arguments and collect variadic together.
|
|
1478
1490
|
const args = this.args.slice();
|
|
1479
1491
|
this._args.forEach((arg, i) => {
|
|
@@ -1491,19 +1503,24 @@ class Command extends EventEmitter {
|
|
|
1491
1503
|
this._actionHandler(args);
|
|
1492
1504
|
if (this.parent) this.parent.emit(commandEvent, operands, unknown); // legacy
|
|
1493
1505
|
} else if (this.parent && this.parent.listenerCount(commandEvent)) {
|
|
1506
|
+
checkForUnknownOptions();
|
|
1494
1507
|
this.parent.emit(commandEvent, operands, unknown); // legacy
|
|
1495
1508
|
} else if (operands.length) {
|
|
1496
|
-
if (this._findCommand('*')) { // legacy
|
|
1509
|
+
if (this._findCommand('*')) { // legacy default command
|
|
1497
1510
|
this._dispatchSubcommand('*', operands, unknown);
|
|
1498
1511
|
} else if (this.listenerCount('command:*')) {
|
|
1512
|
+
// skip option check, emit event for possible misspelling suggestion
|
|
1499
1513
|
this.emit('command:*', operands, unknown);
|
|
1500
1514
|
} else if (this.commands.length) {
|
|
1501
1515
|
this.unknownCommand();
|
|
1516
|
+
} else {
|
|
1517
|
+
checkForUnknownOptions();
|
|
1502
1518
|
}
|
|
1503
1519
|
} else if (this.commands.length) {
|
|
1504
1520
|
// This command has subcommands and nothing hooked up at this level, so display help.
|
|
1505
1521
|
this.help({ error: true });
|
|
1506
1522
|
} else {
|
|
1523
|
+
checkForUnknownOptions();
|
|
1507
1524
|
// fall through for caller to handle after calling .parse()
|
|
1508
1525
|
}
|
|
1509
1526
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "the complete solution for node.js command-line programs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commander",
|
|
@@ -19,18 +19,21 @@
|
|
|
19
19
|
"url": "https://github.com/tj/commander.js.git"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"lint": "eslint index.js \"tests/**/*.js\"",
|
|
22
|
+
"lint": "eslint index.js esm.mjs \"tests/**/*.js\"",
|
|
23
23
|
"typescript-lint": "eslint typings/*.ts",
|
|
24
24
|
"test": "jest && npm run test-typings",
|
|
25
|
-
"test-
|
|
25
|
+
"test-esm": "node --experimental-modules ./tests/esm-test.mjs",
|
|
26
|
+
"test-typings": "tsd",
|
|
26
27
|
"typescript-checkJS": "tsc --allowJS --checkJS index.js --noEmit",
|
|
27
|
-
"test-all": "npm run test && npm run lint && npm run typescript-lint && npm run typescript-checkJS"
|
|
28
|
+
"test-all": "npm run test && npm run lint && npm run typescript-lint && npm run typescript-checkJS && npm run test-esm"
|
|
28
29
|
},
|
|
29
|
-
"main": "index",
|
|
30
|
+
"main": "./index.js",
|
|
30
31
|
"files": [
|
|
31
32
|
"index.js",
|
|
33
|
+
"esm.mjs",
|
|
32
34
|
"typings/index.d.ts"
|
|
33
35
|
],
|
|
36
|
+
"type": "commonjs",
|
|
34
37
|
"dependencies": {},
|
|
35
38
|
"devDependencies": {
|
|
36
39
|
"@types/jest": "^26.0.20",
|
|
@@ -42,9 +45,10 @@
|
|
|
42
45
|
"eslint-plugin-jest": "^24.1.3",
|
|
43
46
|
"jest": "^26.6.3",
|
|
44
47
|
"standard": "^16.0.3",
|
|
48
|
+
"tsd": "^0.14.0",
|
|
45
49
|
"typescript": "^4.1.2"
|
|
46
50
|
},
|
|
47
|
-
"
|
|
51
|
+
"types": "typings/index.d.ts",
|
|
48
52
|
"jest": {
|
|
49
53
|
"collectCoverage": true
|
|
50
54
|
},
|