commander 11.0.0 → 12.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/lib/error.js CHANGED
@@ -1,5 +1,3 @@
1
- // @ts-check
2
-
3
1
  /**
4
2
  * CommanderError class
5
3
  * @class
package/lib/help.js CHANGED
@@ -8,8 +8,6 @@ const { humanReadableArgName } = require('./argument.js');
8
8
  * @typedef { import("./option.js").Option } Option
9
9
  */
10
10
 
11
- // @ts-check
12
-
13
11
  // Although this is a class, methods are static in style to allow override using subclass or just functions.
14
12
  class Help {
15
13
  constructor() {
@@ -101,8 +99,8 @@ class Help {
101
99
  if (!this.showGlobalOptions) return [];
102
100
 
103
101
  const globalOptions = [];
104
- for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
105
- const visibleOptions = parentCmd.options.filter((option) => !option.hidden);
102
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
103
+ const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
106
104
  globalOptions.push(...visibleOptions);
107
105
  }
108
106
  if (this.sortOptions) {
@@ -121,14 +119,14 @@ class Help {
121
119
  visibleArguments(cmd) {
122
120
  // Side effect! Apply the legacy descriptions before the arguments are displayed.
123
121
  if (cmd._argsDescription) {
124
- cmd._args.forEach(argument => {
122
+ cmd.registeredArguments.forEach(argument => {
125
123
  argument.description = argument.description || cmd._argsDescription[argument.name()] || '';
126
124
  });
127
125
  }
128
126
 
129
127
  // If there are any arguments with a description then return all the arguments.
130
- if (cmd._args.find(argument => argument.description)) {
131
- return cmd._args;
128
+ if (cmd.registeredArguments.find(argument => argument.description)) {
129
+ return cmd.registeredArguments;
132
130
  }
133
131
  return [];
134
132
  }
@@ -142,7 +140,7 @@ class Help {
142
140
 
143
141
  subcommandTerm(cmd) {
144
142
  // Legacy. Ignores custom usage string, and nested commands.
145
- const args = cmd._args.map(arg => humanReadableArgName(arg)).join(' ');
143
+ const args = cmd.registeredArguments.map(arg => humanReadableArgName(arg)).join(' ');
146
144
  return cmd._name +
147
145
  (cmd._aliases[0] ? '|' + cmd._aliases[0] : '') +
148
146
  (cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option
@@ -240,11 +238,11 @@ class Help {
240
238
  if (cmd._aliases[0]) {
241
239
  cmdName = cmdName + '|' + cmd._aliases[0];
242
240
  }
243
- let parentCmdNames = '';
244
- for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
245
- parentCmdNames = parentCmd.name() + ' ' + parentCmdNames;
241
+ let ancestorCmdNames = '';
242
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
243
+ ancestorCmdNames = ancestorCmd.name() + ' ' + ancestorCmdNames;
246
244
  }
247
- return parentCmdNames + cmdName + ' ' + cmd.usage();
245
+ return ancestorCmdNames + cmdName + ' ' + cmd.usage();
248
246
  }
249
247
 
250
248
  /**
package/lib/option.js CHANGED
@@ -1,7 +1,5 @@
1
1
  const { InvalidArgumentError } = require('./error.js');
2
2
 
3
- // @ts-check
4
-
5
3
  class Option {
6
4
  /**
7
5
  * Initialize a new `Option` with the given `flags` and `description`.
@@ -40,7 +38,7 @@ class Option {
40
38
  /**
41
39
  * Set the default value, and optionally supply the description to be displayed in the help.
42
40
  *
43
- * @param {any} value
41
+ * @param {*} value
44
42
  * @param {string} [description]
45
43
  * @return {Option}
46
44
  */
@@ -59,7 +57,7 @@ class Option {
59
57
  * new Option('--color').default('GREYSCALE').preset('RGB');
60
58
  * new Option('--donate [amount]').preset('20').argParser(parseFloat);
61
59
  *
62
- * @param {any} arg
60
+ * @param {*} arg
63
61
  * @return {Option}
64
62
  */
65
63
 
@@ -160,7 +158,7 @@ class Option {
160
158
  }
161
159
 
162
160
  /**
163
- * @api private
161
+ * @package internal use only
164
162
  */
165
163
 
166
164
  _concatValue(value, previous) {
@@ -210,7 +208,6 @@ class Option {
210
208
  * as a object attribute key.
211
209
  *
212
210
  * @return {string}
213
- * @api private
214
211
  */
215
212
 
216
213
  attributeName() {
@@ -222,7 +219,7 @@ class Option {
222
219
  *
223
220
  * @param {string} arg
224
221
  * @return {boolean}
225
- * @api private
222
+ * @package internal use only
226
223
  */
227
224
 
228
225
  is(arg) {
@@ -235,7 +232,7 @@ class Option {
235
232
  * Options are one of boolean, negated, required argument, or optional argument.
236
233
  *
237
234
  * @return {boolean}
238
- * @api private
235
+ * @package internal use only
239
236
  */
240
237
 
241
238
  isBoolean() {
@@ -275,7 +272,7 @@ class DualOptions {
275
272
  /**
276
273
  * Did the value come from the option, and not from possible matching dual option?
277
274
  *
278
- * @param {any} value
275
+ * @param {*} value
279
276
  * @param {Option} option
280
277
  * @returns {boolean}
281
278
  */
@@ -295,7 +292,7 @@ class DualOptions {
295
292
  *
296
293
  * @param {string} str
297
294
  * @return {string}
298
- * @api private
295
+ * @private
299
296
  */
300
297
 
301
298
  function camelcase(str) {
@@ -307,7 +304,7 @@ function camelcase(str) {
307
304
  /**
308
305
  * Split the short and long flag out of something like '-m,--mixed <value>'
309
306
  *
310
- * @api private
307
+ * @private
311
308
  */
312
309
 
313
310
  function splitOptionFlags(flags) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commander",
3
- "version": "11.0.0",
3
+ "version": "12.0.0-0",
4
4
  "description": "the complete solution for node.js command-line programs",
5
5
  "keywords": [
6
6
  "commander",
@@ -22,11 +22,11 @@
22
22
  "lint": "npm run lint:javascript && npm run lint:typescript",
23
23
  "lint:javascript": "eslint index.js esm.mjs \"lib/*.js\" \"tests/**/*.js\"",
24
24
  "lint:typescript": "eslint typings/*.ts tests/*.ts",
25
- "test": "jest && npm run test-typings",
25
+ "test": "jest && npm run typecheck-ts",
26
26
  "test-esm": "node ./tests/esm-imports-test.mjs",
27
- "test-typings": "tsd",
28
- "typescript-checkJS": "tsc --allowJS --checkJS index.js lib/*.js --noEmit",
29
- "test-all": "npm run test && npm run lint && npm run typescript-checkJS && npm run test-esm"
27
+ "typecheck-ts": "tsd && tsc -p tsconfig.ts.json",
28
+ "typecheck-js": "tsc -p tsconfig.js.json",
29
+ "test-all": "npm run test && npm run lint && npm run typecheck-js && npm run test-esm"
30
30
  },
31
31
  "files": [
32
32
  "index.js",
@@ -58,33 +58,23 @@
58
58
  "devDependencies": {
59
59
  "@types/jest": "^29.2.4",
60
60
  "@types/node": "^20.2.5",
61
- "@typescript-eslint/eslint-plugin": "^5.47.1",
62
- "@typescript-eslint/parser": "^5.47.1",
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": "^33.0.0",
65
+ "eslint-config-standard-with-typescript": "^39.1.1",
66
66
  "eslint-plugin-import": "^2.26.0",
67
67
  "eslint-plugin-jest": "^27.1.7",
68
- "eslint-plugin-n": "^15.6.0",
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.28.1",
72
+ "tsd": "^0.29.0",
73
73
  "typescript": "^5.0.4"
74
74
  },
75
75
  "types": "typings/index.d.ts",
76
- "jest": {
77
- "testEnvironment": "node",
78
- "collectCoverage": true,
79
- "transform": {
80
- "^.+\\.tsx?$": "ts-jest"
81
- },
82
- "testPathIgnorePatterns": [
83
- "/node_modules/"
84
- ]
85
- },
86
76
  "engines": {
87
- "node": ">=16"
77
+ "node": ">=18"
88
78
  },
89
79
  "support": true
90
80
  }
@@ -5,6 +5,14 @@
5
5
  /* eslint-disable @typescript-eslint/method-signature-style */
6
6
  /* eslint-disable @typescript-eslint/no-explicit-any */
7
7
 
8
+ // This is a trick to encourage editor to suggest the known literals while still
9
+ // allowing any BaseType value.
10
+ // References:
11
+ // - https://github.com/microsoft/TypeScript/issues/29729
12
+ // - https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts
13
+ // - https://github.com/sindresorhus/type-fest/blob/main/source/primitive.d.ts
14
+ type LiteralUnion<LiteralType, BaseType extends string | number> = LiteralType | (BaseType & Record<never, never>);
15
+
8
16
  export class CommanderError extends Error {
9
17
  code: string;
10
18
  exitCode: number;
@@ -42,6 +50,9 @@ export class Argument {
42
50
  description: string;
43
51
  required: boolean;
44
52
  variadic: boolean;
53
+ defaultValue?: any;
54
+ defaultValueDescription?: string;
55
+ argChoices?: string[];
45
56
 
46
57
  /**
47
58
  * Initialize a new command argument with the given name and description.
@@ -94,6 +105,8 @@ export class Option {
94
105
  negate: boolean;
95
106
  defaultValue?: any;
96
107
  defaultValueDescription?: string;
108
+ presetArg?: unknown;
109
+ envVar?: string;
97
110
  parseArg?: <T>(value: string, previous: T) => T;
98
111
  hidden: boolean;
99
112
  argChoices?: string[];
@@ -272,7 +285,8 @@ export interface OutputConfiguration {
272
285
 
273
286
  export type AddHelpTextPosition = 'beforeAll' | 'before' | 'after' | 'afterAll';
274
287
  export type HookEvent = 'preSubcommand' | 'preAction' | 'postAction';
275
- export type OptionValueSource = 'default' | 'config' | 'env' | 'cli' | 'implied';
288
+ // The source is a string so author can define their own too.
289
+ export type OptionValueSource = LiteralUnion<'default' | 'config' | 'env' | 'cli' | 'implied', string> | undefined;
276
290
 
277
291
  export type OptionValues = Record<string, any>;
278
292
 
@@ -281,6 +295,7 @@ export class Command {
281
295
  processedArgs: any[];
282
296
  readonly commands: readonly Command[];
283
297
  readonly options: readonly Option[];
298
+ readonly registeredArguments: readonly Argument[];
284
299
  parent: Command | null;
285
300
 
286
301
  constructor(name?: string);
@@ -294,6 +309,10 @@ export class Command {
294
309
  * You can optionally supply the flags and description to override the defaults.
295
310
  */
296
311
  version(str: string, flags?: string, description?: string): this;
312
+ /**
313
+ * Get the program version.
314
+ */
315
+ version(): string | undefined;
297
316
 
298
317
  /**
299
318
  * Define a command, implemented using an action handler.
@@ -497,51 +516,27 @@ export class Command {
497
516
  action(fn: (...args: any[]) => void | Promise<void>): this;
498
517
 
499
518
  /**
500
- * Define option with `flags`, `description` and optional
501
- * coercion `fn`.
519
+ * Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
502
520
  *
503
- * The `flags` string contains the short and/or long flags,
504
- * separated by comma, a pipe or space. The following are all valid
505
- * all will output this way when `--help` is used.
521
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
522
+ * option-argument is indicated by `<>` and an optional option-argument by `[]`.
506
523
  *
507
- * "-p, --pepper"
508
- * "-p|--pepper"
509
- * "-p --pepper"
524
+ * See the README for more details, and see also addOption() and requiredOption().
510
525
  *
511
526
  * @example
512
- * ```
513
- * // simple boolean defaulting to false
514
- * program.option('-p, --pepper', 'add pepper');
515
527
  *
516
- * --pepper
517
- * program.pepper
518
- * // => Boolean
519
- *
520
- * // simple boolean defaulting to true
521
- * program.option('-C, --no-cheese', 'remove cheese');
522
- *
523
- * program.cheese
524
- * // => true
525
- *
526
- * --no-cheese
527
- * program.cheese
528
- * // => false
529
- *
530
- * // required argument
531
- * program.option('-C, --chdir <path>', 'change the working directory');
532
- *
533
- * --chdir /tmp
534
- * program.chdir
535
- * // => "/tmp"
536
- *
537
- * // optional argument
538
- * program.option('-c, --cheese [type]', 'add cheese [marble]');
528
+ * ```js
529
+ * program
530
+ * .option('-p, --pepper', 'add pepper')
531
+ * .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
532
+ * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
533
+ * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
539
534
  * ```
540
535
  *
541
536
  * @returns `this` command for chaining
542
537
  */
543
538
  option(flags: string, description?: string, defaultValue?: string | boolean | string[]): this;
544
- option<T>(flags: string, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): this;
539
+ option<T>(flags: string, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): this;
545
540
  /** @deprecated since v7, instead use choices or a custom function */
546
541
  option(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean | string[]): this;
547
542
 
@@ -552,7 +547,7 @@ export class Command {
552
547
  * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
553
548
  */
554
549
  requiredOption(flags: string, description?: string, defaultValue?: string | boolean | string[]): this;
555
- requiredOption<T>(flags: string, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): this;
550
+ requiredOption<T>(flags: string, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): this;
556
551
  /** @deprecated since v7, instead use choices or a custom function */
557
552
  requiredOption(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean | string[]): this;
558
553
 
@@ -819,7 +814,7 @@ export class Command {
819
814
  /**
820
815
  * Get the executable search directory.
821
816
  */
822
- executableDir(): string;
817
+ executableDir(): string | null;
823
818
 
824
819
  /**
825
820
  * Output help information for this command.