commander 14.0.3 → 15.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 CHANGED
@@ -76,7 +76,7 @@ The two most used option types are a boolean option, and an option which takes i
76
76
  Example file: [split.js](./examples/split.js)
77
77
 
78
78
  ```js
79
- const { program } = require('commander');
79
+ import { program } from 'commander';
80
80
 
81
81
  program
82
82
  .option('--first')
@@ -91,10 +91,10 @@ console.log(program.args[0].split(options.separator, limit));
91
91
  ```
92
92
 
93
93
  ```console
94
- $ node split.js -s / --fits a/b/c
94
+ $ node split.js -s - --fits a-b-c
95
95
  error: unknown option '--fits'
96
96
  (Did you mean --first?)
97
- $ node split.js -s / --first a/b/c
97
+ $ node split.js -s - --first a-b-c
98
98
  [ 'a' ]
99
99
  ```
100
100
 
@@ -103,7 +103,7 @@ Here is a more complete program using a subcommand and with descriptions for the
103
103
  Example file: [string-util.js](./examples/string-util.js)
104
104
 
105
105
  ```js
106
- const { Command } = require('commander');
106
+ import { Command } from 'commander';
107
107
  const program = new Command();
108
108
 
109
109
  program
@@ -138,7 +138,7 @@ Options:
138
138
  -s, --separator <char> separator character (default: ",")
139
139
  -h, --help display help for command
140
140
 
141
- $ node string-util.js split --separator=/ a/b/c
141
+ $ node string-util.js split --separator=- a-b-c
142
142
  [ 'a', 'b', 'c' ]
143
143
  ```
144
144
 
@@ -147,11 +147,10 @@ More samples can be found in the [examples](https://github.com/tj/commander.js/t
147
147
  ## Declaring _program_ variable
148
148
 
149
149
  Commander exports a global object which is convenient for quick programs.
150
- This is used in the examples in this README for brevity.
150
+ This is used in some examples in this README for brevity.
151
151
 
152
152
  ```js
153
- // CommonJS (.cjs)
154
- const { program } = require('commander');
153
+ import { program } from 'commander';
155
154
  ```
156
155
 
157
156
  For larger programs which may use commander in multiple ways, including unit testing, it is better to create a local `Command` object to use.
@@ -276,10 +275,7 @@ cheese: stilton
276
275
  ### Other option types, negatable boolean and boolean|value
277
276
 
278
277
  You can define a boolean option long name with a leading `no-` to set the option value to `false` when used.
279
- Defined alone, this also makes the option `true` by default.
280
-
281
- If you define `--foo` first, adding `--no-foo` does not change the default value from what it would
282
- otherwise be.
278
+ Defined alone without a matching positive option, this also makes the option `true` by default.
283
279
 
284
280
  Example file: [options-negatable.js](./examples/options-negatable.js)
285
281
 
@@ -558,7 +554,7 @@ Configuration options can be passed with the call to `.command()` and `.addComma
558
554
  remove the command from the generated help output. Specifying `isDefault: true` will run the subcommand if no other
559
555
  subcommand is specified. (Example file: [defaultCommand.js](./examples/defaultCommand.js).)
560
556
 
561
- You can add alternative names for a command with `.alias()`. (Example file: [alias.js](./examples/alias.js).)
557
+ You can add alternative names for a command with `.alias()`. (Example file: [alias.cjs](./examples/alias.cjs).)
562
558
 
563
559
  `.command()` automatically copies the inherited settings from the parent command to the newly created subcommand. This is only done during creation; any later setting changes to the parent are not inherited.
564
560
 
@@ -1060,7 +1056,7 @@ node -r ts-node/register pm.ts
1060
1056
  This factory function creates a new command. It is exported and may be used instead of using `new`, like:
1061
1057
 
1062
1058
  ```js
1063
- const { createCommand } = require('commander');
1059
+ import { createCommand } from 'commander';
1064
1060
  const program = createCommand();
1065
1061
  ```
1066
1062
 
@@ -1163,7 +1159,7 @@ There is more information available about:
1163
1159
 
1164
1160
  ## Support
1165
1161
 
1166
- The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v20.
1162
+ The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v22.12.0.
1167
1163
 
1168
1164
  Older major versions of Commander receive security updates for 12 months. For more see: [Release Policy](./docs/release-policy.md).
1169
1165
 
package/index.js CHANGED
@@ -1,24 +1,21 @@
1
- const { Argument } = require('./lib/argument.js');
2
- const { Command } = require('./lib/command.js');
3
- const { CommanderError, InvalidArgumentError } = require('./lib/error.js');
4
- const { Help } = require('./lib/help.js');
5
- const { Option } = require('./lib/option.js');
1
+ import { Argument } from './lib/argument.js';
2
+ import { Command } from './lib/command.js';
3
+ import { CommanderError, InvalidArgumentError } from './lib/error.js';
4
+ import { Help } from './lib/help.js';
5
+ import { Option } from './lib/option.js';
6
6
 
7
- exports.program = new Command();
7
+ export const program = new Command();
8
8
 
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);
9
+ export const createCommand = (name) => new Command(name);
10
+ export const createOption = (flags, description) =>
11
+ new Option(flags, description);
12
+ export const createArgument = (name, description) =>
13
+ new Argument(name, description);
12
14
 
13
15
  /**
14
16
  * Expose classes
15
17
  */
16
18
 
17
- exports.Command = Command;
18
- exports.Option = Option;
19
- exports.Argument = Argument;
20
- exports.Help = Help;
21
-
22
- exports.CommanderError = CommanderError;
23
- exports.InvalidArgumentError = InvalidArgumentError;
24
- exports.InvalidOptionArgumentError = InvalidArgumentError; // Deprecated
19
+ export { Command, Option, Argument, Help };
20
+ export { CommanderError, InvalidArgumentError };
21
+ export { InvalidArgumentError as InvalidOptionArgumentError }; // Deprecated
package/lib/argument.js CHANGED
@@ -1,6 +1,6 @@
1
- const { InvalidArgumentError } = require('./error.js');
1
+ import { InvalidArgumentError } from './error.js';
2
2
 
3
- class Argument {
3
+ export class Argument {
4
4
  /**
5
5
  * Initialize a new command argument with the given name and description.
6
6
  * The default is that the argument is required, and you can explicitly
@@ -140,11 +140,8 @@ class Argument {
140
140
  * @private
141
141
  */
142
142
 
143
- function humanReadableArgName(arg) {
143
+ export function humanReadableArgName(arg) {
144
144
  const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');
145
145
 
146
146
  return arg.required ? '<' + nameOutput + '>' : '[' + nameOutput + ']';
147
147
  }
148
-
149
- exports.Argument = Argument;
150
- exports.humanReadableArgName = humanReadableArgName;
package/lib/command.js CHANGED
@@ -1,16 +1,16 @@
1
- const EventEmitter = require('node:events').EventEmitter;
2
- const childProcess = require('node:child_process');
3
- const path = require('node:path');
4
- const fs = require('node:fs');
5
- const process = require('node:process');
1
+ import { EventEmitter } from 'node:events';
2
+ import childProcess from 'node:child_process';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ import process from 'node:process';
6
6
 
7
- const { Argument, humanReadableArgName } = require('./argument.js');
8
- const { CommanderError } = require('./error.js');
9
- const { Help, stripColor } = require('./help.js');
10
- const { Option, DualOptions } = require('./option.js');
11
- const { suggestSimilar } = require('./suggestSimilar');
7
+ import { Argument, humanReadableArgName } from './argument.js';
8
+ import { CommanderError } from './error.js';
9
+ import { Help, stripColor } from './help.js';
10
+ import { Option, DualOptions } from './option.js';
11
+ import { suggestSimilar } from './suggestSimilar.js';
12
12
 
13
- class Command extends EventEmitter {
13
+ export class Command extends EventEmitter {
14
14
  /**
15
15
  * Initialize a new `Command`.
16
16
  *
@@ -674,17 +674,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
674
674
  const name = option.attributeName();
675
675
 
676
676
  // store default value
677
- if (option.negate) {
678
- // --no-foo is special and defaults foo to true, unless a --foo option is already defined
679
- const positiveLongFlag = option.long.replace(/^--no-/, '--');
680
- if (!this._findOption(positiveLongFlag)) {
681
- this.setOptionValueWithSource(
682
- name,
683
- option.defaultValue === undefined ? true : option.defaultValue,
684
- 'default',
685
- );
686
- }
687
- } else if (option.defaultValue !== undefined) {
677
+ if (option.defaultValue !== undefined) {
688
678
  this.setOptionValueWithSource(name, option.defaultValue, 'default');
689
679
  }
690
680
 
@@ -1125,7 +1115,29 @@ Expecting one of '${allowedValues.join("', '")}'`);
1125
1115
  }
1126
1116
 
1127
1117
  _prepareForParse() {
1118
+ // Save the state the first time, then restore the state before each subsequent parse.
1128
1119
  if (this._savedState === null) {
1120
+ // Do the special default of lone negated option to true, now that we have all the options.
1121
+ // Filter for negated options that have not been processed already.
1122
+ this.options
1123
+ .filter(
1124
+ (option) =>
1125
+ option.negate &&
1126
+ option.defaultValue === undefined &&
1127
+ this.getOptionValue(option.attributeName()) === undefined,
1128
+ )
1129
+ .forEach((option) => {
1130
+ // check for lone negated option: --no-foo without a --foo option
1131
+ const positiveLongFlag = option.long.replace(/^--no-/, '--');
1132
+ if (!this._findOption(positiveLongFlag)) {
1133
+ this.setOptionValueWithSource(
1134
+ option.attributeName(),
1135
+ true,
1136
+ 'default',
1137
+ );
1138
+ }
1139
+ });
1140
+
1129
1141
  this.saveStateBeforeParse();
1130
1142
  } else {
1131
1143
  this.restoreStateBeforeParse();
@@ -2148,8 +2160,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2148
2160
 
2149
2161
  const expected = this.registeredArguments.length;
2150
2162
  const s = expected === 1 ? '' : 's';
2163
+ const received = receivedArgs.length;
2151
2164
  const forSubcommand = this.parent ? ` for '${this.name()}'` : '';
2152
- const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
2165
+ const details = receivedArgs.join(', ');
2166
+ const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${received}: ${details}.`;
2153
2167
  this.error(message, { code: 'commander.excessArguments' });
2154
2168
  }
2155
2169
 
@@ -2405,12 +2419,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
2405
2419
 
2406
2420
  /**
2407
2421
  * Set the name of the command from script filename, such as process.argv[1],
2408
- * or require.main.filename, or __filename.
2422
+ * or import.meta.filename.
2409
2423
  *
2410
2424
  * (Used internally and public although not documented in README.)
2411
2425
  *
2412
2426
  * @example
2413
- * program.nameFromFilename(require.main.filename);
2427
+ * program.nameFromFilename(import.meta.filename);
2414
2428
  *
2415
2429
  * @param {string} filename
2416
2430
  * @return {Command}
@@ -2426,7 +2440,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2426
2440
  * Get or set the directory for searching for executable subcommands of this command.
2427
2441
  *
2428
2442
  * @example
2429
- * program.executableDir(__dirname);
2443
+ * program.executableDir(import.meta.dirname);
2430
2444
  * // or
2431
2445
  * program.executableDir('subcommands');
2432
2446
  *
@@ -2746,10 +2760,12 @@ function incrementNodeInspectorPort(args) {
2746
2760
  }
2747
2761
 
2748
2762
  /**
2763
+ * Exported for using from tests, not otherwise used outside this file.
2764
+ *
2749
2765
  * @returns {boolean | undefined}
2750
2766
  * @package
2751
2767
  */
2752
- function useColor() {
2768
+ export function useColor() {
2753
2769
  // Test for common conventions.
2754
2770
  // NB: the observed behaviour is in combination with how author adds color! For example:
2755
2771
  // - we do not test NODE_DISABLE_COLORS, but util:styletext does
@@ -2772,6 +2788,3 @@ function useColor() {
2772
2788
  return true;
2773
2789
  return undefined;
2774
2790
  }
2775
-
2776
- exports.Command = Command;
2777
- exports.useColor = useColor; // exporting for tests
package/lib/error.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * CommanderError class
3
3
  */
4
- class CommanderError extends Error {
4
+ export class CommanderError extends Error {
5
5
  /**
6
6
  * Constructs the CommanderError class
7
7
  * @param {number} exitCode suggested exit code which could be used with process.exit
@@ -22,7 +22,7 @@ class CommanderError extends Error {
22
22
  /**
23
23
  * InvalidArgumentError class
24
24
  */
25
- class InvalidArgumentError extends CommanderError {
25
+ export class InvalidArgumentError extends CommanderError {
26
26
  /**
27
27
  * Constructs the InvalidArgumentError class
28
28
  * @param {string} [message] explanation of why argument is invalid
@@ -34,6 +34,3 @@ class InvalidArgumentError extends CommanderError {
34
34
  this.name = this.constructor.name;
35
35
  }
36
36
  }
37
-
38
- exports.CommanderError = CommanderError;
39
- exports.InvalidArgumentError = InvalidArgumentError;
package/lib/help.js CHANGED
@@ -1,4 +1,4 @@
1
- const { humanReadableArgName } = require('./argument.js');
1
+ import { humanReadableArgName } from './argument.js';
2
2
 
3
3
  /**
4
4
  * TypeScript import types for JSDoc, used by Visual Studio Code IntelliSense and `npm run typescript-checkJS`
@@ -9,7 +9,7 @@ const { humanReadableArgName } = require('./argument.js');
9
9
  */
10
10
 
11
11
  // Although this is a class, methods are static in style to allow override using subclass or just functions.
12
- class Help {
12
+ export class Help {
13
13
  constructor() {
14
14
  this.helpWidth = undefined;
15
15
  this.minWidthToWrap = 40;
@@ -737,11 +737,8 @@ class Help {
737
737
  * @package
738
738
  */
739
739
 
740
- function stripColor(str) {
740
+ export function stripColor(str) {
741
741
  // eslint-disable-next-line no-control-regex
742
742
  const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
743
743
  return str.replace(sgrPattern, '');
744
744
  }
745
-
746
- exports.Help = Help;
747
- exports.stripColor = stripColor;
package/lib/option.js CHANGED
@@ -1,6 +1,6 @@
1
- const { InvalidArgumentError } = require('./error.js');
1
+ import { InvalidArgumentError } from './error.js';
2
2
 
3
- class Option {
3
+ export class Option {
4
4
  /**
5
5
  * Initialize a new `Option` with the given `flags` and `description`.
6
6
  *
@@ -265,7 +265,7 @@ class Option {
265
265
  * use cases, but is tricky for others where we want separate behaviours despite
266
266
  * the single shared option value.
267
267
  */
268
- class DualOptions {
268
+ export class DualOptions {
269
269
  /**
270
270
  * @param {Option[]} options
271
271
  */
@@ -375,6 +375,3 @@ function splitOptionFlags(flags) {
375
375
 
376
376
  return { shortFlag, longFlag };
377
377
  }
378
-
379
- exports.Option = Option;
380
- exports.DualOptions = DualOptions;
@@ -53,7 +53,7 @@ function editDistance(a, b) {
53
53
  * @returns {string}
54
54
  */
55
55
 
56
- function suggestSimilar(word, candidates) {
56
+ export function suggestSimilar(word, candidates) {
57
57
  if (!candidates || candidates.length === 0) return '';
58
58
  // remove possible duplicates
59
59
  candidates = Array.from(new Set(candidates));
@@ -97,5 +97,3 @@ function suggestSimilar(word, candidates) {
97
97
  }
98
98
  return '';
99
99
  }
100
-
101
- exports.suggestSimilar = suggestSimilar;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commander",
3
- "version": "14.0.3",
3
+ "version": "15.0.0-0",
4
4
  "description": "the complete solution for node.js command-line programs",
5
5
  "keywords": [
6
6
  "commander",
@@ -28,55 +28,37 @@
28
28
  "fix": "npm run fix:lint && npm run fix:format",
29
29
  "fix:format": "prettier --write .",
30
30
  "fix:lint": "eslint --fix .",
31
- "test": "jest && npm run check:type:ts",
32
- "test-all": "jest && npm run test-esm && npm run check",
33
- "test-esm": "node ./tests/esm-imports-test.mjs"
31
+ "test": "node --test && npm run check:type:ts",
32
+ "test-all": "node --test && npm run check"
34
33
  },
35
34
  "files": [
36
35
  "index.js",
37
36
  "lib/*.js",
38
- "esm.mjs",
39
37
  "typings/index.d.ts",
40
- "typings/esm.d.mts",
41
38
  "package-support.json"
42
39
  ],
43
- "type": "commonjs",
40
+ "type": "module",
44
41
  "main": "./index.js",
45
42
  "exports": {
46
43
  ".": {
47
- "require": {
48
- "types": "./typings/index.d.ts",
49
- "default": "./index.js"
50
- },
51
- "import": {
52
- "types": "./typings/esm.d.mts",
53
- "default": "./esm.mjs"
54
- },
44
+ "types": "./typings/index.d.ts",
55
45
  "default": "./index.js"
56
- },
57
- "./esm.mjs": {
58
- "types": "./typings/esm.d.mts",
59
- "import": "./esm.mjs"
60
46
  }
61
47
  },
62
48
  "devDependencies": {
63
49
  "@eslint/js": "^9.4.0",
64
- "@types/jest": "^30.0.0",
65
50
  "@types/node": "^22.7.4",
66
51
  "eslint": "^9.17.0",
67
52
  "eslint-config-prettier": "^10.0.1",
68
- "eslint-plugin-jest": "^29.0.1",
69
53
  "globals": "^16.0.0",
70
- "jest": "^30.0.3",
71
54
  "prettier": "^3.2.5",
72
- "ts-jest": "^29.0.3",
73
- "tsd": "^0.33.0",
55
+ "tsd": "^0.31.0",
74
56
  "typescript": "^5.0.4",
75
57
  "typescript-eslint": "^8.12.2"
76
58
  },
77
59
  "types": "typings/index.d.ts",
78
60
  "engines": {
79
- "node": ">=20"
61
+ "node": ">=22.12.0"
80
62
  },
81
63
  "support": true
82
64
  }
@@ -958,13 +958,13 @@ export class Command {
958
958
 
959
959
  /**
960
960
  * Set the name of the command from script filename, such as process.argv[1],
961
- * or require.main.filename, or __filename.
961
+ * or import.meta.filename.
962
962
  *
963
963
  * (Used internally and public although not documented in README.)
964
964
  *
965
965
  * @example
966
966
  * ```ts
967
- * program.nameFromFilename(require.main.filename);
967
+ * program.nameFromFilename(import.meta.filename);
968
968
  * ```
969
969
  *
970
970
  * @returns `this` command for chaining
@@ -976,7 +976,7 @@ export class Command {
976
976
  *
977
977
  * @example
978
978
  * ```ts
979
- * program.executableDir(__dirname);
979
+ * program.executableDir(import.meta.dirname);
980
980
  * // or
981
981
  * program.executableDir('subcommands');
982
982
  * ```
package/esm.mjs DELETED
@@ -1,16 +0,0 @@
1
- import commander from './index.js';
2
-
3
- // wrapper to provide named exports for ESM.
4
- export const {
5
- program,
6
- createCommand,
7
- createArgument,
8
- createOption,
9
- CommanderError,
10
- InvalidArgumentError,
11
- InvalidOptionArgumentError, // deprecated old name
12
- Command,
13
- Argument,
14
- Option,
15
- Help,
16
- } = commander;
package/typings/esm.d.mts DELETED
@@ -1,3 +0,0 @@
1
- // Just reexport the types from cjs
2
- // This is a bit indirect. There is not an index.js, but TypeScript will look for index.d.ts for types.
3
- export * from './index.js';