commander 14.0.0 → 14.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 CHANGED
@@ -943,7 +943,7 @@ You can configure the help by modifying data properties and methods using `.conf
943
943
 
944
944
  Simple properties include `sortSubcommands`, `sortOptions`, and `showGlobalOptions`. You can add color using the style methods like `styleTitle()`.
945
945
 
946
- For more detail and examples of changing the displayed text, color, and layout see (./docs/help-in-depth.md).
946
+ For more detail and examples of changing the displayed text, color, and layout see [help in depth](./docs/help-in-depth.md).
947
947
 
948
948
  ## Custom event listeners
949
949
 
@@ -1063,7 +1063,7 @@ customise the new subcommand (example file [custom-command-class.js](./examples/
1063
1063
  You can enable `--harmony` option in two ways:
1064
1064
 
1065
1065
  - Use `#! /usr/bin/env node --harmony` in the subcommands scripts. (Note Windows does not support this pattern.)
1066
- - Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning subcommand process.
1066
+ - Use the `--harmony` option when calling the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning subcommand processes.
1067
1067
 
1068
1068
  ### Debugging stand-alone executable subcommands
1069
1069
 
package/lib/argument.js CHANGED
@@ -33,7 +33,7 @@ class Argument {
33
33
  break;
34
34
  }
35
35
 
36
- if (this._name.length > 3 && this._name.slice(-3) === '...') {
36
+ if (this._name.endsWith('...')) {
37
37
  this.variadic = true;
38
38
  this._name = this._name.slice(0, -3);
39
39
  }
@@ -53,12 +53,13 @@ class Argument {
53
53
  * @package
54
54
  */
55
55
 
56
- _concatValue(value, previous) {
56
+ _collectValue(value, previous) {
57
57
  if (previous === this.defaultValue || !Array.isArray(previous)) {
58
58
  return [value];
59
59
  }
60
60
 
61
- return previous.concat(value);
61
+ previous.push(value);
62
+ return previous;
62
63
  }
63
64
 
64
65
  /**
@@ -103,7 +104,7 @@ class Argument {
103
104
  );
104
105
  }
105
106
  if (this.variadic) {
106
- return this._concatValue(arg, previous);
107
+ return this._collectValue(arg, previous);
107
108
  }
108
109
  return arg;
109
110
  };
package/lib/command.js CHANGED
@@ -245,11 +245,10 @@ class Command extends EventEmitter {
245
245
  configureOutput(configuration) {
246
246
  if (configuration === undefined) return this._outputConfiguration;
247
247
 
248
- this._outputConfiguration = Object.assign(
249
- {},
250
- this._outputConfiguration,
251
- configuration,
252
- );
248
+ this._outputConfiguration = {
249
+ ...this._outputConfiguration,
250
+ ...configuration,
251
+ };
253
252
  return this;
254
253
  }
255
254
 
@@ -375,7 +374,7 @@ class Command extends EventEmitter {
375
374
  */
376
375
  addArgument(argument) {
377
376
  const previousArgument = this.registeredArguments.slice(-1)[0];
378
- if (previousArgument && previousArgument.variadic) {
377
+ if (previousArgument?.variadic) {
379
378
  throw new Error(
380
379
  `only the last argument can be variadic '${previousArgument.name()}'`,
381
380
  );
@@ -702,7 +701,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
702
701
  if (val !== null && option.parseArg) {
703
702
  val = this._callParseArg(option, val, oldValue, invalidValueMessage);
704
703
  } else if (val !== null && option.variadic) {
705
- val = option._concatValue(val, oldValue);
704
+ val = option._collectValue(val, oldValue);
706
705
  }
707
706
 
708
707
  // Fill-in appropriate missing values. Long winded but easy to follow.
@@ -1481,7 +1480,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1481
1480
 
1482
1481
  _chainOrCall(promise, fn) {
1483
1482
  // thenable
1484
- if (promise && promise.then && typeof promise.then === 'function') {
1483
+ if (promise?.then && typeof promise.then === 'function') {
1485
1484
  // already have a promise, chain callback
1486
1485
  return promise.then(() => fn());
1487
1486
  }
@@ -1612,7 +1611,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1612
1611
  promiseChain = this._chainOrCallHooks(promiseChain, 'postAction');
1613
1612
  return promiseChain;
1614
1613
  }
1615
- if (this.parent && this.parent.listenerCount(commandEvent)) {
1614
+ if (this.parent?.listenerCount(commandEvent)) {
1616
1615
  checkForUnknownOptions();
1617
1616
  this._processArguments();
1618
1617
  this.parent.emit(commandEvent, operands, unknown); // legacy
@@ -1742,15 +1741,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
1742
1741
  * sub --unknown uuu op => [sub], [--unknown uuu op]
1743
1742
  * sub -- --unknown uuu op => [sub --unknown uuu op], []
1744
1743
  *
1745
- * @param {string[]} argv
1744
+ * @param {string[]} args
1746
1745
  * @return {{operands: string[], unknown: string[]}}
1747
1746
  */
1748
1747
 
1749
- parseOptions(argv) {
1748
+ parseOptions(args) {
1750
1749
  const operands = []; // operands, not options or values
1751
1750
  const unknown = []; // first unknown option and remaining unknown args
1752
1751
  let dest = operands;
1753
- const args = argv.slice();
1754
1752
 
1755
1753
  function maybeOption(arg) {
1756
1754
  return arg.length > 1 && arg[0] === '-';
@@ -1769,13 +1767,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
1769
1767
 
1770
1768
  // parse options
1771
1769
  let activeVariadicOption = null;
1772
- while (args.length) {
1773
- const arg = args.shift();
1770
+ let activeGroup = null; // working through group of short options, like -abc
1771
+ let i = 0;
1772
+ while (i < args.length || activeGroup) {
1773
+ const arg = activeGroup ?? args[i++];
1774
+ activeGroup = null;
1774
1775
 
1775
1776
  // literal
1776
1777
  if (arg === '--') {
1777
1778
  if (dest === unknown) dest.push(arg);
1778
- dest.push(...args);
1779
+ dest.push(...args.slice(i));
1779
1780
  break;
1780
1781
  }
1781
1782
 
@@ -1793,17 +1794,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
1793
1794
  // recognised option, call listener to assign value with possible custom processing
1794
1795
  if (option) {
1795
1796
  if (option.required) {
1796
- const value = args.shift();
1797
+ const value = args[i++];
1797
1798
  if (value === undefined) this.optionMissingArgument(option);
1798
1799
  this.emit(`option:${option.name()}`, value);
1799
1800
  } else if (option.optional) {
1800
1801
  let value = null;
1801
1802
  // historical behaviour is optional value is following arg unless an option
1802
1803
  if (
1803
- args.length > 0 &&
1804
- (!maybeOption(args[0]) || negativeNumberArg(args[0]))
1804
+ i < args.length &&
1805
+ (!maybeOption(args[i]) || negativeNumberArg(args[i]))
1805
1806
  ) {
1806
- value = args.shift();
1807
+ value = args[i++];
1807
1808
  }
1808
1809
  this.emit(`option:${option.name()}`, value);
1809
1810
  } else {
@@ -1826,9 +1827,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1826
1827
  // option with value following in same argument
1827
1828
  this.emit(`option:${option.name()}`, arg.slice(2));
1828
1829
  } else {
1829
- // boolean option, emit and put back remainder of arg for further processing
1830
+ // boolean option
1830
1831
  this.emit(`option:${option.name()}`);
1831
- args.unshift(`-${arg.slice(2)}`);
1832
+ // remove the processed option and keep processing group
1833
+ activeGroup = `-${arg.slice(2)}`;
1832
1834
  }
1833
1835
  continue;
1834
1836
  }
@@ -1865,26 +1867,23 @@ Expecting one of '${allowedValues.join("', '")}'`);
1865
1867
  ) {
1866
1868
  if (this._findCommand(arg)) {
1867
1869
  operands.push(arg);
1868
- if (args.length > 0) unknown.push(...args);
1870
+ unknown.push(...args.slice(i));
1869
1871
  break;
1870
1872
  } else if (
1871
1873
  this._getHelpCommand() &&
1872
1874
  arg === this._getHelpCommand().name()
1873
1875
  ) {
1874
- operands.push(arg);
1875
- if (args.length > 0) operands.push(...args);
1876
+ operands.push(arg, ...args.slice(i));
1876
1877
  break;
1877
1878
  } else if (this._defaultCommandName) {
1878
- unknown.push(arg);
1879
- if (args.length > 0) unknown.push(...args);
1879
+ unknown.push(arg, ...args.slice(i));
1880
1880
  break;
1881
1881
  }
1882
1882
  }
1883
1883
 
1884
1884
  // If using passThroughOptions, stop processing options at first command-argument.
1885
1885
  if (this._passThroughOptions) {
1886
- dest.push(arg);
1887
- if (args.length > 0) dest.push(...args);
1886
+ dest.push(arg, ...args.slice(i));
1888
1887
  break;
1889
1888
  }
1890
1889
 
package/lib/option.js CHANGED
@@ -162,12 +162,13 @@ class Option {
162
162
  * @package
163
163
  */
164
164
 
165
- _concatValue(value, previous) {
165
+ _collectValue(value, previous) {
166
166
  if (previous === this.defaultValue || !Array.isArray(previous)) {
167
167
  return [value];
168
168
  }
169
169
 
170
- return previous.concat(value);
170
+ previous.push(value);
171
+ return previous;
171
172
  }
172
173
 
173
174
  /**
@@ -186,7 +187,7 @@ class Option {
186
187
  );
187
188
  }
188
189
  if (this.variadic) {
189
- return this._concatValue(arg, previous);
190
+ return this._collectValue(arg, previous);
190
191
  }
191
192
  return arg;
192
193
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commander",
3
- "version": "14.0.0",
3
+ "version": "14.0.1",
4
4
  "description": "the complete solution for node.js command-line programs",
5
5
  "keywords": [
6
6
  "commander",
@@ -61,16 +61,16 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@eslint/js": "^9.4.0",
64
- "@types/jest": "^29.2.4",
64
+ "@types/jest": "^30.0.0",
65
65
  "@types/node": "^22.7.4",
66
66
  "eslint": "^9.17.0",
67
67
  "eslint-config-prettier": "^10.0.1",
68
- "eslint-plugin-jest": "^28.3.0",
68
+ "eslint-plugin-jest": "^29.0.1",
69
69
  "globals": "^16.0.0",
70
- "jest": "^29.3.1",
70
+ "jest": "^30.0.3",
71
71
  "prettier": "^3.2.5",
72
72
  "ts-jest": "^29.0.3",
73
- "tsd": "^0.31.0",
73
+ "tsd": "^0.33.0",
74
74
  "typescript": "^5.0.4",
75
75
  "typescript-eslint": "^8.12.2"
76
76
  },