commander 12.0.0 → 12.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/lib/command.js CHANGED
@@ -1,8 +1,8 @@
1
- const EventEmitter = require('events').EventEmitter;
2
- const childProcess = require('child_process');
3
- const path = require('path');
4
- const fs = require('fs');
5
- const process = require('process');
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');
6
6
 
7
7
  const { Argument, humanReadableArgName } = require('./argument.js');
8
8
  const { CommanderError } = require('./error.js');
@@ -60,9 +60,11 @@ class Command extends EventEmitter {
60
60
  this._outputConfiguration = {
61
61
  writeOut: (str) => process.stdout.write(str),
62
62
  writeErr: (str) => process.stderr.write(str),
63
- getOutHelpWidth: () => process.stdout.isTTY ? process.stdout.columns : undefined,
64
- getErrHelpWidth: () => process.stderr.isTTY ? process.stderr.columns : undefined,
65
- outputError: (str, write) => write(str)
63
+ getOutHelpWidth: () =>
64
+ process.stdout.isTTY ? process.stdout.columns : undefined,
65
+ getErrHelpWidth: () =>
66
+ process.stderr.isTTY ? process.stderr.columns : undefined,
67
+ outputError: (str, write) => write(str),
66
68
  };
67
69
 
68
70
  this._hidden = false;
@@ -89,7 +91,8 @@ class Command extends EventEmitter {
89
91
  this._helpConfiguration = sourceCommand._helpConfiguration;
90
92
  this._exitCallback = sourceCommand._exitCallback;
91
93
  this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
92
- this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
94
+ this._combineFlagAndOptionalValue =
95
+ sourceCommand._combineFlagAndOptionalValue;
93
96
  this._allowExcessArguments = sourceCommand._allowExcessArguments;
94
97
  this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
95
98
  this._showHelpAfterError = sourceCommand._showHelpAfterError;
@@ -105,6 +108,7 @@ class Command extends EventEmitter {
105
108
 
106
109
  _getCommandAndAncestors() {
107
110
  const result = [];
111
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
108
112
  for (let command = this; command; command = command.parent) {
109
113
  result.push(command);
110
114
  }
@@ -131,8 +135,8 @@ class Command extends EventEmitter {
131
135
  * .command('stop [service]', 'stop named service, or all if no name supplied');
132
136
  *
133
137
  * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
134
- * @param {(Object|string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
135
- * @param {Object} [execOpts] - configuration options (for executable)
138
+ * @param {(object | string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
139
+ * @param {object} [execOpts] - configuration options (for executable)
136
140
  * @return {Command} returns new command for action handler, or `this` for executable command
137
141
  */
138
142
 
@@ -192,8 +196,8 @@ class Command extends EventEmitter {
192
196
  * You can customise the help by overriding Help properties using configureHelp(),
193
197
  * or with a subclass of Help by overriding createHelp().
194
198
  *
195
- * @param {Object} [configuration] - configuration options
196
- * @return {(Command|Object)} `this` command for chaining, or stored configuration
199
+ * @param {object} [configuration] - configuration options
200
+ * @return {(Command | object)} `this` command for chaining, or stored configuration
197
201
  */
198
202
 
199
203
  configureHelp(configuration) {
@@ -218,8 +222,8 @@ class Command extends EventEmitter {
218
222
  * // functions based on what is being written out
219
223
  * outputError(str, write) // used for displaying errors, and not used for displaying help
220
224
  *
221
- * @param {Object} [configuration] - configuration options
222
- * @return {(Command|Object)} `this` command for chaining, or stored configuration
225
+ * @param {object} [configuration] - configuration options
226
+ * @return {(Command | object)} `this` command for chaining, or stored configuration
223
227
  */
224
228
 
225
229
  configureOutput(configuration) {
@@ -258,7 +262,7 @@ class Command extends EventEmitter {
258
262
  * See .command() for creating an attached subcommand which inherits settings from its parent.
259
263
  *
260
264
  * @param {Command} cmd - new subcommand
261
- * @param {Object} [opts] - configuration options
265
+ * @param {object} [opts] - configuration options
262
266
  * @return {Command} `this` command for chaining
263
267
  */
264
268
 
@@ -334,9 +338,12 @@ class Command extends EventEmitter {
334
338
  */
335
339
 
336
340
  arguments(names) {
337
- names.trim().split(/ +/).forEach((detail) => {
338
- this.argument(detail);
339
- });
341
+ names
342
+ .trim()
343
+ .split(/ +/)
344
+ .forEach((detail) => {
345
+ this.argument(detail);
346
+ });
340
347
  return this;
341
348
  }
342
349
 
@@ -349,10 +356,18 @@ class Command extends EventEmitter {
349
356
  addArgument(argument) {
350
357
  const previousArgument = this.registeredArguments.slice(-1)[0];
351
358
  if (previousArgument && previousArgument.variadic) {
352
- throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
359
+ throw new Error(
360
+ `only the last argument can be variadic '${previousArgument.name()}'`,
361
+ );
353
362
  }
354
- if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
355
- throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
363
+ if (
364
+ argument.required &&
365
+ argument.defaultValue !== undefined &&
366
+ argument.parseArg === undefined
367
+ ) {
368
+ throw new Error(
369
+ `a default value for a required argument is never used: '${argument.name()}'`,
370
+ );
356
371
  }
357
372
  this.registeredArguments.push(argument);
358
373
  return this;
@@ -361,6 +376,7 @@ class Command extends EventEmitter {
361
376
  /**
362
377
  * Customise or override default help command. By default a help command is automatically added if your command has subcommands.
363
378
  *
379
+ * @example
364
380
  * program.helpCommand('help [cmd]');
365
381
  * program.helpCommand('help [cmd]', 'show help');
366
382
  * program.helpCommand(false); // suppress default help command
@@ -419,8 +435,11 @@ class Command extends EventEmitter {
419
435
  * @package
420
436
  */
421
437
  _getHelpCommand() {
422
- const hasImplicitHelpCommand = this._addImplicitHelpCommand ??
423
- (this.commands.length && !this._actionHandler && !this._findCommand('help'));
438
+ const hasImplicitHelpCommand =
439
+ this._addImplicitHelpCommand ??
440
+ (this.commands.length &&
441
+ !this._actionHandler &&
442
+ !this._findCommand('help'));
424
443
 
425
444
  if (hasImplicitHelpCommand) {
426
445
  if (this._helpCommand === undefined) {
@@ -568,14 +587,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
568
587
  * Register option if no conflicts found, or throw on conflict.
569
588
  *
570
589
  * @param {Option} option
571
- * @api private
590
+ * @private
572
591
  */
573
592
 
574
593
  _registerOption(option) {
575
- const matchingOption = (option.short && this._findOption(option.short)) ||
594
+ const matchingOption =
595
+ (option.short && this._findOption(option.short)) ||
576
596
  (option.long && this._findOption(option.long));
577
597
  if (matchingOption) {
578
- const matchingFlag = (option.long && this._findOption(option.long)) ? option.long : option.short;
598
+ const matchingFlag =
599
+ option.long && this._findOption(option.long)
600
+ ? option.long
601
+ : option.short;
579
602
  throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
580
603
  - already used by option '${matchingOption.flags}'`);
581
604
  }
@@ -588,7 +611,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
588
611
  * Register command if no conflicts found, or throw on conflict.
589
612
  *
590
613
  * @param {Command} command
591
- * @api private
614
+ * @private
592
615
  */
593
616
 
594
617
  _registerCommand(command) {
@@ -596,11 +619,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
596
619
  return [cmd.name()].concat(cmd.aliases());
597
620
  };
598
621
 
599
- const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
622
+ const alreadyUsed = knownBy(command).find((name) =>
623
+ this._findCommand(name),
624
+ );
600
625
  if (alreadyUsed) {
601
626
  const existingCmd = knownBy(this._findCommand(alreadyUsed)).join('|');
602
627
  const newCmd = knownBy(command).join('|');
603
- throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
628
+ throw new Error(
629
+ `cannot add command '${newCmd}' as already have command '${existingCmd}'`,
630
+ );
604
631
  }
605
632
 
606
633
  this.commands.push(command);
@@ -623,7 +650,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
623
650
  // --no-foo is special and defaults foo to true, unless a --foo option is already defined
624
651
  const positiveLongFlag = option.long.replace(/^--no-/, '--');
625
652
  if (!this._findOption(positiveLongFlag)) {
626
- this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, 'default');
653
+ this.setOptionValueWithSource(
654
+ name,
655
+ option.defaultValue === undefined ? true : option.defaultValue,
656
+ 'default',
657
+ );
627
658
  }
628
659
  } else if (option.defaultValue !== undefined) {
629
660
  this.setOptionValueWithSource(name, option.defaultValue, 'default');
@@ -676,11 +707,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
676
707
  /**
677
708
  * Internal implementation shared by .option() and .requiredOption()
678
709
  *
710
+ * @return {Command} `this` command for chaining
679
711
  * @private
680
712
  */
681
713
  _optionEx(config, flags, description, fn, defaultValue) {
682
714
  if (typeof flags === 'object' && flags instanceof Option) {
683
- throw new Error('To add an Option object use addOption() instead of option() or requiredOption()');
715
+ throw new Error(
716
+ 'To add an Option object use addOption() instead of option() or requiredOption()',
717
+ );
684
718
  }
685
719
  const option = this.createOption(flags, description);
686
720
  option.makeOptionMandatory(!!config.mandatory);
@@ -728,20 +762,26 @@ Expecting one of '${allowedValues.join("', '")}'`);
728
762
  }
729
763
 
730
764
  /**
731
- * Add a required option which must have a value after parsing. This usually means
732
- * the option must be specified on the command line. (Otherwise the same as .option().)
733
- *
734
- * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
735
- *
736
- * @param {string} flags
737
- * @param {string} [description]
738
- * @param {(Function|*)} [parseArg] - custom option processing function or default value
739
- * @param {*} [defaultValue]
740
- * @return {Command} `this` command for chaining
741
- */
765
+ * Add a required option which must have a value after parsing. This usually means
766
+ * the option must be specified on the command line. (Otherwise the same as .option().)
767
+ *
768
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
769
+ *
770
+ * @param {string} flags
771
+ * @param {string} [description]
772
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
773
+ * @param {*} [defaultValue]
774
+ * @return {Command} `this` command for chaining
775
+ */
742
776
 
743
777
  requiredOption(flags, description, parseArg, defaultValue) {
744
- return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
778
+ return this._optionEx(
779
+ { mandatory: true },
780
+ flags,
781
+ description,
782
+ parseArg,
783
+ defaultValue,
784
+ );
745
785
  }
746
786
 
747
787
  /**
@@ -752,7 +792,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
752
792
  * program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
753
793
  * program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
754
794
  *
755
- * @param {boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
795
+ * @param {boolean} [combine] - if `true` or omitted, an optional value can be specified directly after the flag.
796
+ * @return {Command} `this` command for chaining
756
797
  */
757
798
  combineFlagAndOptionalValue(combine = true) {
758
799
  this._combineFlagAndOptionalValue = !!combine;
@@ -762,8 +803,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
762
803
  /**
763
804
  * Allow unknown options on the command line.
764
805
  *
765
- * @param {boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
766
- * for unknown options.
806
+ * @param {boolean} [allowUnknown] - if `true` or omitted, no error will be thrown for unknown options.
807
+ * @return {Command} `this` command for chaining
767
808
  */
768
809
  allowUnknownOption(allowUnknown = true) {
769
810
  this._allowUnknownOption = !!allowUnknown;
@@ -773,8 +814,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
773
814
  /**
774
815
  * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
775
816
  *
776
- * @param {boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
777
- * for excess arguments.
817
+ * @param {boolean} [allowExcess] - if `true` or omitted, no error will be thrown for excess arguments.
818
+ * @return {Command} `this` command for chaining
778
819
  */
779
820
  allowExcessArguments(allowExcess = true) {
780
821
  this._allowExcessArguments = !!allowExcess;
@@ -786,7 +827,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
786
827
  * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
787
828
  * The default behaviour is non-positional and global options may appear anywhere on the command line.
788
829
  *
789
- * @param {boolean} [positional=true]
830
+ * @param {boolean} [positional]
831
+ * @return {Command} `this` command for chaining
790
832
  */
791
833
  enablePositionalOptions(positional = true) {
792
834
  this._enablePositionalOptions = !!positional;
@@ -799,8 +841,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
799
841
  * positional options to have been enabled on the program (parent commands).
800
842
  * The default behaviour is non-positional and options may appear before or after command-arguments.
801
843
  *
802
- * @param {boolean} [passThrough=true]
803
- * for unknown options.
844
+ * @param {boolean} [passThrough] for unknown options.
845
+ * @return {Command} `this` command for chaining
804
846
  */
805
847
  passThroughOptions(passThrough = true) {
806
848
  this._passThroughOptions = !!passThrough;
@@ -813,25 +855,33 @@ Expecting one of '${allowedValues.join("', '")}'`);
813
855
  */
814
856
 
815
857
  _checkForBrokenPassThrough() {
816
- if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
817
- throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
858
+ if (
859
+ this.parent &&
860
+ this._passThroughOptions &&
861
+ !this.parent._enablePositionalOptions
862
+ ) {
863
+ throw new Error(
864
+ `passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`,
865
+ );
818
866
  }
819
867
  }
820
868
 
821
869
  /**
822
- * Whether to store option values as properties on command object,
823
- * or store separately (specify false). In both cases the option values can be accessed using .opts().
824
- *
825
- * @param {boolean} [storeAsProperties=true]
826
- * @return {Command} `this` command for chaining
827
- */
870
+ * Whether to store option values as properties on command object,
871
+ * or store separately (specify false). In both cases the option values can be accessed using .opts().
872
+ *
873
+ * @param {boolean} [storeAsProperties=true]
874
+ * @return {Command} `this` command for chaining
875
+ */
828
876
 
829
877
  storeOptionsAsProperties(storeAsProperties = true) {
830
878
  if (this.options.length) {
831
879
  throw new Error('call .storeOptionsAsProperties() before adding options');
832
880
  }
833
881
  if (Object.keys(this._optionValues).length) {
834
- throw new Error('call .storeOptionsAsProperties() before setting option values');
882
+ throw new Error(
883
+ 'call .storeOptionsAsProperties() before setting option values',
884
+ );
835
885
  }
836
886
  this._storeOptionsAsProperties = !!storeAsProperties;
837
887
  return this;
@@ -841,7 +891,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
841
891
  * Retrieve option value.
842
892
  *
843
893
  * @param {string} key
844
- * @return {Object} value
894
+ * @return {object} value
845
895
  */
846
896
 
847
897
  getOptionValue(key) {
@@ -855,7 +905,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
855
905
  * Store option value.
856
906
  *
857
907
  * @param {string} key
858
- * @param {Object} value
908
+ * @param {object} value
859
909
  * @return {Command} `this` command for chaining
860
910
  */
861
911
 
@@ -864,13 +914,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
864
914
  }
865
915
 
866
916
  /**
867
- * Store option value and where the value came from.
868
- *
869
- * @param {string} key
870
- * @param {Object} value
871
- * @param {string} source - expected values are default/config/env/cli/implied
872
- * @return {Command} `this` command for chaining
873
- */
917
+ * Store option value and where the value came from.
918
+ *
919
+ * @param {string} key
920
+ * @param {object} value
921
+ * @param {string} source - expected values are default/config/env/cli/implied
922
+ * @return {Command} `this` command for chaining
923
+ */
874
924
 
875
925
  setOptionValueWithSource(key, value, source) {
876
926
  if (this._storeOptionsAsProperties) {
@@ -883,24 +933,24 @@ Expecting one of '${allowedValues.join("', '")}'`);
883
933
  }
884
934
 
885
935
  /**
886
- * Get source of option value.
887
- * Expected values are default | config | env | cli | implied
888
- *
889
- * @param {string} key
890
- * @return {string}
891
- */
936
+ * Get source of option value.
937
+ * Expected values are default | config | env | cli | implied
938
+ *
939
+ * @param {string} key
940
+ * @return {string}
941
+ */
892
942
 
893
943
  getOptionValueSource(key) {
894
944
  return this._optionValueSources[key];
895
945
  }
896
946
 
897
947
  /**
898
- * Get source of option value. See also .optsWithGlobals().
899
- * Expected values are default | config | env | cli | implied
900
- *
901
- * @param {string} key
902
- * @return {string}
903
- */
948
+ * Get source of option value. See also .optsWithGlobals().
949
+ * Expected values are default | config | env | cli | implied
950
+ *
951
+ * @param {string} key
952
+ * @return {string}
953
+ */
904
954
 
905
955
  getOptionValueSourceWithGlobals(key) {
906
956
  // global overwrites local, like optsWithGlobals
@@ -926,17 +976,30 @@ Expecting one of '${allowedValues.join("', '")}'`);
926
976
  }
927
977
  parseOptions = parseOptions || {};
928
978
 
929
- // Default to using process.argv
930
- if (argv === undefined) {
931
- argv = process.argv;
932
- // @ts-ignore: unknown property
933
- if (process.versions && process.versions.electron) {
979
+ // auto-detect argument conventions if nothing supplied
980
+ if (argv === undefined && parseOptions.from === undefined) {
981
+ if (process.versions?.electron) {
934
982
  parseOptions.from = 'electron';
935
983
  }
984
+ // check node specific options for scenarios where user CLI args follow executable without scriptname
985
+ const execArgv = process.execArgv ?? [];
986
+ if (
987
+ execArgv.includes('-e') ||
988
+ execArgv.includes('--eval') ||
989
+ execArgv.includes('-p') ||
990
+ execArgv.includes('--print')
991
+ ) {
992
+ parseOptions.from = 'eval'; // internal usage, not documented
993
+ }
994
+ }
995
+
996
+ // default to using process.argv
997
+ if (argv === undefined) {
998
+ argv = process.argv;
936
999
  }
937
1000
  this.rawArgs = argv.slice();
938
1001
 
939
- // make it a little easier for callers by supporting various argv conventions
1002
+ // extract the user args and scriptPath
940
1003
  let userArgs;
941
1004
  switch (parseOptions.from) {
942
1005
  case undefined:
@@ -945,7 +1008,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
945
1008
  userArgs = argv.slice(2);
946
1009
  break;
947
1010
  case 'electron':
948
- // @ts-ignore: unknown property
1011
+ // @ts-ignore: because defaultApp is an unknown property
949
1012
  if (process.defaultApp) {
950
1013
  this._scriptPath = argv[1];
951
1014
  userArgs = argv.slice(2);
@@ -956,12 +1019,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
956
1019
  case 'user':
957
1020
  userArgs = argv.slice(0);
958
1021
  break;
1022
+ case 'eval':
1023
+ userArgs = argv.slice(1);
1024
+ break;
959
1025
  default:
960
- throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
1026
+ throw new Error(
1027
+ `unexpected parse option { from: '${parseOptions.from}' }`,
1028
+ );
961
1029
  }
962
1030
 
963
1031
  // Find default name for program from arguments.
964
- if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath);
1032
+ if (!this._name && this._scriptPath)
1033
+ this.nameFromFilename(this._scriptPath);
965
1034
  this._name = this._name || 'program';
966
1035
 
967
1036
  return userArgs;
@@ -970,16 +1039,22 @@ Expecting one of '${allowedValues.join("', '")}'`);
970
1039
  /**
971
1040
  * Parse `argv`, setting options and invoking commands when defined.
972
1041
  *
973
- * The default expectation is that the arguments are from node and have the application as argv[0]
974
- * and the script being run in argv[1], with user parameters after that.
1042
+ * Use parseAsync instead of parse if any of your action handlers are async.
1043
+ *
1044
+ * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
1045
+ *
1046
+ * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
1047
+ * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
1048
+ * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
1049
+ * - `'user'`: just user arguments
975
1050
  *
976
1051
  * @example
977
- * program.parse(process.argv);
978
- * program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
1052
+ * program.parse(); // parse process.argv and auto-detect electron and special node flags
1053
+ * program.parse(process.argv); // assume argv[0] is app and argv[1] is script
979
1054
  * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
980
1055
  *
981
1056
  * @param {string[]} [argv] - optional, defaults to process.argv
982
- * @param {Object} [parseOptions] - optionally specify style of options with from: node/user/electron
1057
+ * @param {object} [parseOptions] - optionally specify style of options with from: node/user/electron
983
1058
  * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
984
1059
  * @return {Command} `this` command for chaining
985
1060
  */
@@ -994,18 +1069,20 @@ Expecting one of '${allowedValues.join("', '")}'`);
994
1069
  /**
995
1070
  * Parse `argv`, setting options and invoking commands when defined.
996
1071
  *
997
- * Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
1072
+ * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
998
1073
  *
999
- * The default expectation is that the arguments are from node and have the application as argv[0]
1000
- * and the script being run in argv[1], with user parameters after that.
1074
+ * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
1075
+ * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
1076
+ * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
1077
+ * - `'user'`: just user arguments
1001
1078
  *
1002
1079
  * @example
1003
- * await program.parseAsync(process.argv);
1004
- * await program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
1080
+ * await program.parseAsync(); // parse process.argv and auto-detect electron and special node flags
1081
+ * await program.parseAsync(process.argv); // assume argv[0] is app and argv[1] is script
1005
1082
  * await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
1006
1083
  *
1007
1084
  * @param {string[]} [argv]
1008
- * @param {Object} [parseOptions]
1085
+ * @param {object} [parseOptions]
1009
1086
  * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
1010
1087
  * @return {Promise}
1011
1088
  */
@@ -1037,7 +1114,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
1037
1114
  if (sourceExt.includes(path.extname(baseName))) return undefined;
1038
1115
 
1039
1116
  // Try all the extensions.
1040
- const foundExt = sourceExt.find(ext => fs.existsSync(`${localBin}${ext}`));
1117
+ const foundExt = sourceExt.find((ext) =>
1118
+ fs.existsSync(`${localBin}${ext}`),
1119
+ );
1041
1120
  if (foundExt) return `${localBin}${foundExt}`;
1042
1121
 
1043
1122
  return undefined;
@@ -1048,7 +1127,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1048
1127
  this._checkForConflictingOptions();
1049
1128
 
1050
1129
  // executableFile and executableDir might be full path, or just a name
1051
- let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
1130
+ let executableFile =
1131
+ subcommand._executableFile || `${this._name}-${subcommand._name}`;
1052
1132
  let executableDir = this._executableDir || '';
1053
1133
  if (this._scriptPath) {
1054
1134
  let resolvedScriptPath; // resolve possible symlink for installed npm binary
@@ -1057,7 +1137,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1057
1137
  } catch (err) {
1058
1138
  resolvedScriptPath = this._scriptPath;
1059
1139
  }
1060
- executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
1140
+ executableDir = path.resolve(
1141
+ path.dirname(resolvedScriptPath),
1142
+ executableDir,
1143
+ );
1061
1144
  }
1062
1145
 
1063
1146
  // Look for a local file in preference to a command in PATH.
@@ -1066,9 +1149,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
1066
1149
 
1067
1150
  // Legacy search using prefix of script name instead of command name
1068
1151
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1069
- const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
1152
+ const legacyName = path.basename(
1153
+ this._scriptPath,
1154
+ path.extname(this._scriptPath),
1155
+ );
1070
1156
  if (legacyName !== this._name) {
1071
- localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
1157
+ localFile = findFile(
1158
+ executableDir,
1159
+ `${legacyName}-${subcommand._name}`,
1160
+ );
1072
1161
  }
1073
1162
  }
1074
1163
  executableFile = localFile || executableFile;
@@ -1094,12 +1183,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1094
1183
  proc = childProcess.spawn(process.execPath, args, { stdio: 'inherit' });
1095
1184
  }
1096
1185
 
1097
- if (!proc.killed) { // testing mainly to avoid leak warnings during unit tests with mocked spawn
1186
+ if (!proc.killed) {
1187
+ // testing mainly to avoid leak warnings during unit tests with mocked spawn
1098
1188
  const signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];
1099
1189
  signals.forEach((signal) => {
1100
- // @ts-ignore
1101
1190
  process.on(signal, () => {
1102
1191
  if (proc.killed === false && proc.exitCode === null) {
1192
+ // @ts-ignore because signals not typed to known strings
1103
1193
  proc.kill(signal);
1104
1194
  }
1105
1195
  });
@@ -1108,16 +1198,22 @@ Expecting one of '${allowedValues.join("', '")}'`);
1108
1198
 
1109
1199
  // By default terminate process when spawned process terminates.
1110
1200
  const exitCallback = this._exitCallback;
1111
- proc.on('close', (code, _signal) => {
1201
+ proc.on('close', (code) => {
1112
1202
  code = code ?? 1; // code is null if spawned process terminated due to a signal
1113
1203
  if (!exitCallback) {
1114
1204
  process.exit(code);
1115
1205
  } else {
1116
- exitCallback(new CommanderError(code, 'commander.executeSubCommandAsync', '(close)'));
1206
+ exitCallback(
1207
+ new CommanderError(
1208
+ code,
1209
+ 'commander.executeSubCommandAsync',
1210
+ '(close)',
1211
+ ),
1212
+ );
1117
1213
  }
1118
1214
  });
1119
1215
  proc.on('error', (err) => {
1120
- // @ts-ignore
1216
+ // @ts-ignore: because err.code is an unknown property
1121
1217
  if (err.code === 'ENOENT') {
1122
1218
  const executableDirMessage = executableDir
1123
1219
  ? `searched for local subcommand relative to directory '${executableDir}'`
@@ -1127,14 +1223,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
1127
1223
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1128
1224
  - ${executableDirMessage}`;
1129
1225
  throw new Error(executableMissing);
1130
- // @ts-ignore
1226
+ // @ts-ignore: because err.code is an unknown property
1131
1227
  } else if (err.code === 'EACCES') {
1132
1228
  throw new Error(`'${executableFile}' not executable`);
1133
1229
  }
1134
1230
  if (!exitCallback) {
1135
1231
  process.exit(1);
1136
1232
  } else {
1137
- const wrappedError = new CommanderError(1, 'commander.executeSubCommandAsync', '(error)');
1233
+ const wrappedError = new CommanderError(
1234
+ 1,
1235
+ 'commander.executeSubCommandAsync',
1236
+ '(error)',
1237
+ );
1138
1238
  wrappedError.nestedError = err;
1139
1239
  exitCallback(wrappedError);
1140
1240
  }
@@ -1153,7 +1253,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1153
1253
  if (!subCommand) this.help({ error: true });
1154
1254
 
1155
1255
  let promiseChain;
1156
- promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, 'preSubcommand');
1256
+ promiseChain = this._chainOrCallSubCommandHook(
1257
+ promiseChain,
1258
+ subCommand,
1259
+ 'preSubcommand',
1260
+ );
1157
1261
  promiseChain = this._chainOrCall(promiseChain, () => {
1158
1262
  if (subCommand._executableHandler) {
1159
1263
  this._executeSubCommand(subCommand, operands.concat(unknown));
@@ -1181,9 +1285,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1181
1285
  }
1182
1286
 
1183
1287
  // Fallback to parsing the help flag to invoke the help.
1184
- return this._dispatchSubcommand(subcommandName, [], [
1185
- this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? '--help'
1186
- ]);
1288
+ return this._dispatchSubcommand(
1289
+ subcommandName,
1290
+ [],
1291
+ [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? '--help'],
1292
+ );
1187
1293
  }
1188
1294
 
1189
1295
  /**
@@ -1200,7 +1306,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1200
1306
  }
1201
1307
  });
1202
1308
  // too many
1203
- if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
1309
+ if (
1310
+ this.registeredArguments.length > 0 &&
1311
+ this.registeredArguments[this.registeredArguments.length - 1].variadic
1312
+ ) {
1204
1313
  return;
1205
1314
  }
1206
1315
  if (this.args.length > this.registeredArguments.length) {
@@ -1220,7 +1329,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
1220
1329
  let parsedValue = value;
1221
1330
  if (value !== null && argument.parseArg) {
1222
1331
  const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
1223
- parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
1332
+ parsedValue = this._callParseArg(
1333
+ argument,
1334
+ value,
1335
+ previous,
1336
+ invalidValueMessage,
1337
+ );
1224
1338
  }
1225
1339
  return parsedValue;
1226
1340
  };
@@ -1285,8 +1399,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1285
1399
  const hooks = [];
1286
1400
  this._getCommandAndAncestors()
1287
1401
  .reverse()
1288
- .filter(cmd => cmd._lifeCycleHooks[event] !== undefined)
1289
- .forEach(hookedCommand => {
1402
+ .filter((cmd) => cmd._lifeCycleHooks[event] !== undefined)
1403
+ .forEach((hookedCommand) => {
1290
1404
  hookedCommand._lifeCycleHooks[event].forEach((callback) => {
1291
1405
  hooks.push({ hookedCommand, callback });
1292
1406
  });
@@ -1342,14 +1456,26 @@ Expecting one of '${allowedValues.join("', '")}'`);
1342
1456
  if (operands && this._findCommand(operands[0])) {
1343
1457
  return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
1344
1458
  }
1345
- if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
1459
+ if (
1460
+ this._getHelpCommand() &&
1461
+ operands[0] === this._getHelpCommand().name()
1462
+ ) {
1346
1463
  return this._dispatchHelpCommand(operands[1]);
1347
1464
  }
1348
1465
  if (this._defaultCommandName) {
1349
1466
  this._outputHelpIfRequested(unknown); // Run the help for default command from parent rather than passing to default command
1350
- return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
1467
+ return this._dispatchSubcommand(
1468
+ this._defaultCommandName,
1469
+ operands,
1470
+ unknown,
1471
+ );
1351
1472
  }
1352
- if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
1473
+ if (
1474
+ this.commands.length &&
1475
+ this.args.length === 0 &&
1476
+ !this._actionHandler &&
1477
+ !this._defaultCommandName
1478
+ ) {
1353
1479
  // probably missing subcommand and no handler, user needs help (and exit)
1354
1480
  this.help({ error: true });
1355
1481
  }
@@ -1372,7 +1498,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
1372
1498
 
1373
1499
  let promiseChain;
1374
1500
  promiseChain = this._chainOrCallHooks(promiseChain, 'preAction');
1375
- promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
1501
+ promiseChain = this._chainOrCall(promiseChain, () =>
1502
+ this._actionHandler(this.processedArgs),
1503
+ );
1376
1504
  if (this.parent) {
1377
1505
  promiseChain = this._chainOrCall(promiseChain, () => {
1378
1506
  this.parent.emit(commandEvent, operands, unknown); // legacy
@@ -1386,7 +1514,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1386
1514
  this._processArguments();
1387
1515
  this.parent.emit(commandEvent, operands, unknown); // legacy
1388
1516
  } else if (operands.length) {
1389
- if (this._findCommand('*')) { // legacy default command
1517
+ if (this._findCommand('*')) {
1518
+ // legacy default command
1390
1519
  return this._dispatchSubcommand('*', operands, unknown);
1391
1520
  }
1392
1521
  if (this.listenerCount('command:*')) {
@@ -1413,10 +1542,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1413
1542
  * Find matching command.
1414
1543
  *
1415
1544
  * @private
1545
+ * @return {Command | undefined}
1416
1546
  */
1417
1547
  _findCommand(name) {
1418
1548
  if (!name) return undefined;
1419
- return this.commands.find(cmd => cmd._name === name || cmd._aliases.includes(name));
1549
+ return this.commands.find(
1550
+ (cmd) => cmd._name === name || cmd._aliases.includes(name),
1551
+ );
1420
1552
  }
1421
1553
 
1422
1554
  /**
@@ -1424,11 +1556,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1424
1556
  *
1425
1557
  * @param {string} arg
1426
1558
  * @return {Option}
1427
- * @package internal use only
1559
+ * @package
1428
1560
  */
1429
1561
 
1430
1562
  _findOption(arg) {
1431
- return this.options.find(option => option.is(arg));
1563
+ return this.options.find((option) => option.is(arg));
1432
1564
  }
1433
1565
 
1434
1566
  /**
@@ -1442,7 +1574,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1442
1574
  // Walk up hierarchy so can call in subcommand after checking for displaying help.
1443
1575
  this._getCommandAndAncestors().forEach((cmd) => {
1444
1576
  cmd.options.forEach((anOption) => {
1445
- if (anOption.mandatory && (cmd.getOptionValue(anOption.attributeName()) === undefined)) {
1577
+ if (
1578
+ anOption.mandatory &&
1579
+ cmd.getOptionValue(anOption.attributeName()) === undefined
1580
+ ) {
1446
1581
  cmd.missingMandatoryOptionValue(anOption);
1447
1582
  }
1448
1583
  });
@@ -1455,23 +1590,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1455
1590
  * @private
1456
1591
  */
1457
1592
  _checkForConflictingLocalOptions() {
1458
- const definedNonDefaultOptions = this.options.filter(
1459
- (option) => {
1460
- const optionKey = option.attributeName();
1461
- if (this.getOptionValue(optionKey) === undefined) {
1462
- return false;
1463
- }
1464
- return this.getOptionValueSource(optionKey) !== 'default';
1593
+ const definedNonDefaultOptions = this.options.filter((option) => {
1594
+ const optionKey = option.attributeName();
1595
+ if (this.getOptionValue(optionKey) === undefined) {
1596
+ return false;
1465
1597
  }
1466
- );
1598
+ return this.getOptionValueSource(optionKey) !== 'default';
1599
+ });
1467
1600
 
1468
1601
  const optionsWithConflicting = definedNonDefaultOptions.filter(
1469
- (option) => option.conflictsWith.length > 0
1602
+ (option) => option.conflictsWith.length > 0,
1470
1603
  );
1471
1604
 
1472
1605
  optionsWithConflicting.forEach((option) => {
1473
1606
  const conflictingAndDefined = definedNonDefaultOptions.find((defined) =>
1474
- option.conflictsWith.includes(defined.attributeName())
1607
+ option.conflictsWith.includes(defined.attributeName()),
1475
1608
  );
1476
1609
  if (conflictingAndDefined) {
1477
1610
  this._conflictingOption(option, conflictingAndDefined);
@@ -1551,7 +1684,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1551
1684
  value = args.shift();
1552
1685
  }
1553
1686
  this.emit(`option:${option.name()}`, value);
1554
- } else { // boolean flag
1687
+ } else {
1688
+ // boolean flag
1555
1689
  this.emit(`option:${option.name()}`);
1556
1690
  }
1557
1691
  activeVariadicOption = option.variadic ? option : null;
@@ -1563,7 +1697,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1563
1697
  if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {
1564
1698
  const option = this._findOption(`-${arg[1]}`);
1565
1699
  if (option) {
1566
- if (option.required || (option.optional && this._combineFlagAndOptionalValue)) {
1700
+ if (
1701
+ option.required ||
1702
+ (option.optional && this._combineFlagAndOptionalValue)
1703
+ ) {
1567
1704
  // option with value following in same argument
1568
1705
  this.emit(`option:${option.name()}`, arg.slice(2));
1569
1706
  } else {
@@ -1594,12 +1731,19 @@ Expecting one of '${allowedValues.join("', '")}'`);
1594
1731
  }
1595
1732
 
1596
1733
  // If using positionalOptions, stop processing our options at subcommand.
1597
- if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
1734
+ if (
1735
+ (this._enablePositionalOptions || this._passThroughOptions) &&
1736
+ operands.length === 0 &&
1737
+ unknown.length === 0
1738
+ ) {
1598
1739
  if (this._findCommand(arg)) {
1599
1740
  operands.push(arg);
1600
1741
  if (args.length > 0) unknown.push(...args);
1601
1742
  break;
1602
- } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
1743
+ } else if (
1744
+ this._getHelpCommand() &&
1745
+ arg === this._getHelpCommand().name()
1746
+ ) {
1603
1747
  operands.push(arg);
1604
1748
  if (args.length > 0) operands.push(...args);
1605
1749
  break;
@@ -1627,7 +1771,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1627
1771
  /**
1628
1772
  * Return an object containing local option values as key-value pairs.
1629
1773
  *
1630
- * @return {Object}
1774
+ * @return {object}
1631
1775
  */
1632
1776
  opts() {
1633
1777
  if (this._storeOptionsAsProperties) {
@@ -1637,7 +1781,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1637
1781
 
1638
1782
  for (let i = 0; i < len; i++) {
1639
1783
  const key = this.options[i].attributeName();
1640
- result[key] = key === this._versionOptionName ? this._version : this[key];
1784
+ result[key] =
1785
+ key === this._versionOptionName ? this._version : this[key];
1641
1786
  }
1642
1787
  return result;
1643
1788
  }
@@ -1648,13 +1793,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1648
1793
  /**
1649
1794
  * Return an object containing merged local and global option values as key-value pairs.
1650
1795
  *
1651
- * @return {Object}
1796
+ * @return {object}
1652
1797
  */
1653
1798
  optsWithGlobals() {
1654
1799
  // globals overwrite locals
1655
1800
  return this._getCommandAndAncestors().reduce(
1656
1801
  (combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()),
1657
- {}
1802
+ {},
1658
1803
  );
1659
1804
  }
1660
1805
 
@@ -1662,13 +1807,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
1662
1807
  * Display error message and exit (or call exitOverride).
1663
1808
  *
1664
1809
  * @param {string} message
1665
- * @param {Object} [errorOptions]
1810
+ * @param {object} [errorOptions]
1666
1811
  * @param {string} [errorOptions.code] - an id string representing the error
1667
1812
  * @param {number} [errorOptions.exitCode] - used with process.exit
1668
1813
  */
1669
1814
  error(message, errorOptions) {
1670
1815
  // output handling
1671
- this._outputConfiguration.outputError(`${message}\n`, this._outputConfiguration.writeErr);
1816
+ this._outputConfiguration.outputError(
1817
+ `${message}\n`,
1818
+ this._outputConfiguration.writeErr,
1819
+ );
1672
1820
  if (typeof this._showHelpAfterError === 'string') {
1673
1821
  this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`);
1674
1822
  } else if (this._showHelpAfterError) {
@@ -1694,11 +1842,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
1694
1842
  if (option.envVar && option.envVar in process.env) {
1695
1843
  const optionKey = option.attributeName();
1696
1844
  // Priority check. Do not overwrite cli or options from unknown source (client-code).
1697
- if (this.getOptionValue(optionKey) === undefined || ['default', 'config', 'env'].includes(this.getOptionValueSource(optionKey))) {
1698
- if (option.required || option.optional) { // option can take a value
1845
+ if (
1846
+ this.getOptionValue(optionKey) === undefined ||
1847
+ ['default', 'config', 'env'].includes(
1848
+ this.getOptionValueSource(optionKey),
1849
+ )
1850
+ ) {
1851
+ if (option.required || option.optional) {
1852
+ // option can take a value
1699
1853
  // keep very simple, optional always takes value
1700
1854
  this.emit(`optionEnv:${option.name()}`, process.env[option.envVar]);
1701
- } else { // boolean
1855
+ } else {
1856
+ // boolean
1702
1857
  // keep very simple, only care that envVar defined and not the value
1703
1858
  this.emit(`optionEnv:${option.name()}`);
1704
1859
  }
@@ -1715,17 +1870,30 @@ Expecting one of '${allowedValues.join("', '")}'`);
1715
1870
  _parseOptionsImplied() {
1716
1871
  const dualHelper = new DualOptions(this.options);
1717
1872
  const hasCustomOptionValue = (optionKey) => {
1718
- return this.getOptionValue(optionKey) !== undefined && !['default', 'implied'].includes(this.getOptionValueSource(optionKey));
1873
+ return (
1874
+ this.getOptionValue(optionKey) !== undefined &&
1875
+ !['default', 'implied'].includes(this.getOptionValueSource(optionKey))
1876
+ );
1719
1877
  };
1720
1878
  this.options
1721
- .filter(option => (option.implied !== undefined) &&
1722
- hasCustomOptionValue(option.attributeName()) &&
1723
- dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option))
1879
+ .filter(
1880
+ (option) =>
1881
+ option.implied !== undefined &&
1882
+ hasCustomOptionValue(option.attributeName()) &&
1883
+ dualHelper.valueFromOption(
1884
+ this.getOptionValue(option.attributeName()),
1885
+ option,
1886
+ ),
1887
+ )
1724
1888
  .forEach((option) => {
1725
1889
  Object.keys(option.implied)
1726
- .filter(impliedKey => !hasCustomOptionValue(impliedKey))
1727
- .forEach(impliedKey => {
1728
- this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], 'implied');
1890
+ .filter((impliedKey) => !hasCustomOptionValue(impliedKey))
1891
+ .forEach((impliedKey) => {
1892
+ this.setOptionValueWithSource(
1893
+ impliedKey,
1894
+ option.implied[impliedKey],
1895
+ 'implied',
1896
+ );
1729
1897
  });
1730
1898
  });
1731
1899
  }
@@ -1779,12 +1947,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
1779
1947
  const findBestOptionFromValue = (option) => {
1780
1948
  const optionKey = option.attributeName();
1781
1949
  const optionValue = this.getOptionValue(optionKey);
1782
- const negativeOption = this.options.find(target => target.negate && optionKey === target.attributeName());
1783
- const positiveOption = this.options.find(target => !target.negate && optionKey === target.attributeName());
1784
- if (negativeOption && (
1785
- (negativeOption.presetArg === undefined && optionValue === false) ||
1786
- (negativeOption.presetArg !== undefined && optionValue === negativeOption.presetArg)
1787
- )) {
1950
+ const negativeOption = this.options.find(
1951
+ (target) => target.negate && optionKey === target.attributeName(),
1952
+ );
1953
+ const positiveOption = this.options.find(
1954
+ (target) => !target.negate && optionKey === target.attributeName(),
1955
+ );
1956
+ if (
1957
+ negativeOption &&
1958
+ ((negativeOption.presetArg === undefined && optionValue === false) ||
1959
+ (negativeOption.presetArg !== undefined &&
1960
+ optionValue === negativeOption.presetArg))
1961
+ ) {
1788
1962
  return negativeOption;
1789
1963
  }
1790
1964
  return positiveOption || option;
@@ -1818,11 +1992,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
1818
1992
  if (flag.startsWith('--') && this._showSuggestionAfterError) {
1819
1993
  // Looping to pick up the global options too
1820
1994
  let candidateFlags = [];
1995
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1821
1996
  let command = this;
1822
1997
  do {
1823
- const moreFlags = command.createHelp().visibleOptions(command)
1824
- .filter(option => option.long)
1825
- .map(option => option.long);
1998
+ const moreFlags = command
1999
+ .createHelp()
2000
+ .visibleOptions(command)
2001
+ .filter((option) => option.long)
2002
+ .map((option) => option.long);
1826
2003
  candidateFlags = candidateFlags.concat(moreFlags);
1827
2004
  command = command.parent;
1828
2005
  } while (command && !command._enablePositionalOptions);
@@ -1844,7 +2021,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1844
2021
  if (this._allowExcessArguments) return;
1845
2022
 
1846
2023
  const expected = this.registeredArguments.length;
1847
- const s = (expected === 1) ? '' : 's';
2024
+ const s = expected === 1 ? '' : 's';
1848
2025
  const forSubcommand = this.parent ? ` for '${this.name()}'` : '';
1849
2026
  const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
1850
2027
  this.error(message, { code: 'commander.excessArguments' });
@@ -1862,11 +2039,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1862
2039
 
1863
2040
  if (this._showSuggestionAfterError) {
1864
2041
  const candidateNames = [];
1865
- this.createHelp().visibleCommands(this).forEach((command) => {
1866
- candidateNames.push(command.name());
1867
- // just visible alias
1868
- if (command.alias()) candidateNames.push(command.alias());
1869
- });
2042
+ this.createHelp()
2043
+ .visibleCommands(this)
2044
+ .forEach((command) => {
2045
+ candidateNames.push(command.name());
2046
+ // just visible alias
2047
+ if (command.alias()) candidateNames.push(command.alias());
2048
+ });
1870
2049
  suggestion = suggestSimilar(unknownName, candidateNames);
1871
2050
  }
1872
2051
 
@@ -1907,11 +2086,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
1907
2086
  * Set the description.
1908
2087
  *
1909
2088
  * @param {string} [str]
1910
- * @param {Object} [argsDescription]
2089
+ * @param {object} [argsDescription]
1911
2090
  * @return {(string|Command)}
1912
2091
  */
1913
2092
  description(str, argsDescription) {
1914
- if (str === undefined && argsDescription === undefined) return this._description;
2093
+ if (str === undefined && argsDescription === undefined)
2094
+ return this._description;
1915
2095
  this._description = str;
1916
2096
  if (argsDescription) {
1917
2097
  this._argsDescription = argsDescription;
@@ -1944,18 +2124,27 @@ Expecting one of '${allowedValues.join("', '")}'`);
1944
2124
  if (alias === undefined) return this._aliases[0]; // just return first, for backwards compatibility
1945
2125
 
1946
2126
  /** @type {Command} */
2127
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1947
2128
  let command = this;
1948
- if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
2129
+ if (
2130
+ this.commands.length !== 0 &&
2131
+ this.commands[this.commands.length - 1]._executableHandler
2132
+ ) {
1949
2133
  // assume adding alias for last added executable subcommand, rather than this
1950
2134
  command = this.commands[this.commands.length - 1];
1951
2135
  }
1952
2136
 
1953
- if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');
2137
+ if (alias === command._name)
2138
+ throw new Error("Command alias can't be the same as its name");
1954
2139
  const matchingCommand = this.parent?._findCommand(alias);
1955
2140
  if (matchingCommand) {
1956
2141
  // c.f. _registerCommand
1957
- const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join('|');
1958
- throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
2142
+ const existingCmd = [matchingCommand.name()]
2143
+ .concat(matchingCommand.aliases())
2144
+ .join('|');
2145
+ throw new Error(
2146
+ `cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`,
2147
+ );
1959
2148
  }
1960
2149
 
1961
2150
  command._aliases.push(alias);
@@ -1993,11 +2182,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1993
2182
  const args = this.registeredArguments.map((arg) => {
1994
2183
  return humanReadableArgName(arg);
1995
2184
  });
1996
- return [].concat(
1997
- (this.options.length || (this._helpOption !== null) ? '[options]' : []),
1998
- (this.commands.length ? '[command]' : []),
1999
- (this.registeredArguments.length ? args : [])
2000
- ).join(' ');
2185
+ return []
2186
+ .concat(
2187
+ this.options.length || this._helpOption !== null ? '[options]' : [],
2188
+ this.commands.length ? '[command]' : [],
2189
+ this.registeredArguments.length ? args : [],
2190
+ )
2191
+ .join(' ');
2001
2192
  }
2002
2193
 
2003
2194
  this._usage = str;
@@ -2064,7 +2255,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2064
2255
  helpInformation(contextOptions) {
2065
2256
  const helper = this.createHelp();
2066
2257
  if (helper.helpWidth === undefined) {
2067
- helper.helpWidth = (contextOptions && contextOptions.error) ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
2258
+ helper.helpWidth =
2259
+ contextOptions && contextOptions.error
2260
+ ? this._outputConfiguration.getErrHelpWidth()
2261
+ : this._outputConfiguration.getOutHelpWidth();
2068
2262
  }
2069
2263
  return helper.formatHelp(this, helper);
2070
2264
  }
@@ -2103,13 +2297,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
2103
2297
  }
2104
2298
  const context = this._getHelpContext(contextOptions);
2105
2299
 
2106
- this._getCommandAndAncestors().reverse().forEach(command => command.emit('beforeAllHelp', context));
2300
+ this._getCommandAndAncestors()
2301
+ .reverse()
2302
+ .forEach((command) => command.emit('beforeAllHelp', context));
2107
2303
  this.emit('beforeHelp', context);
2108
2304
 
2109
2305
  let helpInformation = this.helpInformation(context);
2110
2306
  if (deprecatedCallback) {
2111
2307
  helpInformation = deprecatedCallback(helpInformation);
2112
- if (typeof helpInformation !== 'string' && !Buffer.isBuffer(helpInformation)) {
2308
+ if (
2309
+ typeof helpInformation !== 'string' &&
2310
+ !Buffer.isBuffer(helpInformation)
2311
+ ) {
2113
2312
  throw new Error('outputHelp callback must return a string or a Buffer');
2114
2313
  }
2115
2314
  }
@@ -2119,7 +2318,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2119
2318
  this.emit(this._getHelpOption().long); // deprecated
2120
2319
  }
2121
2320
  this.emit('afterHelp', context);
2122
- this._getCommandAndAncestors().forEach(command => command.emit('afterAllHelp', context));
2321
+ this._getCommandAndAncestors().forEach((command) =>
2322
+ command.emit('afterAllHelp', context),
2323
+ );
2123
2324
  }
2124
2325
 
2125
2326
  /**
@@ -2159,7 +2360,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2159
2360
  * Returns null if has been disabled with .helpOption(false).
2160
2361
  *
2161
2362
  * @returns {(Option | null)} the help option
2162
- * @package internal use only
2363
+ * @package
2163
2364
  */
2164
2365
  _getHelpOption() {
2165
2366
  // Lazy create help option on demand.
@@ -2192,7 +2393,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
2192
2393
  help(contextOptions) {
2193
2394
  this.outputHelp(contextOptions);
2194
2395
  let exitCode = process.exitCode || 0;
2195
- if (exitCode === 0 && contextOptions && typeof contextOptions !== 'function' && contextOptions.error) {
2396
+ if (
2397
+ exitCode === 0 &&
2398
+ contextOptions &&
2399
+ typeof contextOptions !== 'function' &&
2400
+ contextOptions.error
2401
+ ) {
2196
2402
  exitCode = 1;
2197
2403
  }
2198
2404
  // message: do not have all displayed text available so only passing placeholder.
@@ -2240,7 +2446,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2240
2446
 
2241
2447
  _outputHelpIfRequested(args) {
2242
2448
  const helpOption = this._getHelpOption();
2243
- const helpRequested = helpOption && args.find(arg => helpOption.is(arg));
2449
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
2244
2450
  if (helpRequested) {
2245
2451
  this.outputHelp();
2246
2452
  // (Do not have all displayed text available so only passing placeholder.)
@@ -2273,7 +2479,9 @@ function incrementNodeInspectorPort(args) {
2273
2479
  if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
2274
2480
  // e.g. --inspect
2275
2481
  debugOption = match[1];
2276
- } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
2482
+ } else if (
2483
+ (match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null
2484
+ ) {
2277
2485
  debugOption = match[1];
2278
2486
  if (/^\d+$/.test(match[3])) {
2279
2487
  // e.g. --inspect=1234
@@ -2282,7 +2490,9 @@ function incrementNodeInspectorPort(args) {
2282
2490
  // e.g. --inspect=localhost
2283
2491
  debugHost = match[3];
2284
2492
  }
2285
- } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
2493
+ } else if (
2494
+ (match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null
2495
+ ) {
2286
2496
  // e.g. --inspect=localhost:1234
2287
2497
  debugOption = match[1];
2288
2498
  debugHost = match[3];