commander 13.0.0 → 13.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/Readme.md CHANGED
@@ -175,7 +175,15 @@ const program = new Command();
175
175
 
176
176
  ## Options
177
177
 
178
- Options are defined with the `.option()` method, also serving as documentation for the options. Each option can have a short flag (single character) and a long name, separated by a comma or space or vertical bar ('|').
178
+ Options are defined with the `.option()` method, also serving as documentation for the options. Each option can have a short flag (single character) and a long name, separated by a comma or space or vertical bar ('|'). To allow a wider range of short-ish flags than just
179
+ single characters, you may also have two long options. Examples:
180
+
181
+ ```js
182
+ program
183
+ .option('-p, --port <number>', 'server port number')
184
+ .option('--trace', 'add extra debugging output')
185
+ .option('--ws, --workspace <name>', 'use a custom workspace')
186
+ ```
179
187
 
180
188
  The parsed options can be accessed by calling `.opts()` on a `Command` object, and are passed to the action handler.
181
189
 
package/lib/command.js CHANGED
@@ -756,7 +756,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
756
756
  * @example
757
757
  * program
758
758
  * .option('-p, --pepper', 'add pepper')
759
- * .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
759
+ * .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument
760
760
  * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
761
761
  * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
762
762
  *
package/lib/option.js CHANGED
@@ -18,7 +18,7 @@ class Option {
18
18
  this.variadic = /\w\.\.\.[>\]]$/.test(flags); // The option can take multiple values.
19
19
  this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.
20
20
  const optionFlags = splitOptionFlags(flags);
21
- this.short = optionFlags.shortFlag;
21
+ this.short = optionFlags.shortFlag; // May be a short flag, undefined, or even a long flag (if option has two long flags).
22
22
  this.long = optionFlags.longFlag;
23
23
  this.negate = false;
24
24
  if (this.long) {
@@ -321,25 +321,44 @@ function splitOptionFlags(flags) {
321
321
  const longFlagExp = /^--[^-]/;
322
322
 
323
323
  const flagParts = flags.split(/[ |,]+/).concat('guard');
324
+ // Normal is short and/or long.
324
325
  if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
325
326
  if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();
327
+ // Long then short. Rarely used but fine.
328
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
329
+ shortFlag = flagParts.shift();
330
+ // Allow two long flags, like '--ws, --workspace'
331
+ // This is the supported way to have a shortish option flag.
332
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
333
+ shortFlag = longFlag;
334
+ longFlag = flagParts.shift();
335
+ }
326
336
 
327
- // Check for some unsupported flags that people try.
328
- if (/^-[^-][^-]/.test(flagParts[0]))
329
- throw new Error(
330
- `invalid Option flags, short option is dash and single character: '${flags}'`,
331
- );
332
- if (shortFlag && shortFlagExp.test(flagParts[0]))
333
- throw new Error(
334
- `invalid Option flags, more than one short flag: '${flags}'`,
335
- );
336
- if (longFlag && longFlagExp.test(flagParts[0]))
337
+ // Check for unprocessed flag. Fail noisily rather than silently ignore.
338
+ if (flagParts[0].startsWith('-')) {
339
+ const unsupportedFlag = flagParts[0];
340
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
341
+ if (/^-[^-][^-]/.test(unsupportedFlag))
342
+ throw new Error(
343
+ `${baseError}
344
+ - a short flag is a single dash and a single character
345
+ - either use a single dash and a single character (for a short flag)
346
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`,
347
+ );
348
+ if (shortFlagExp.test(unsupportedFlag))
349
+ throw new Error(`${baseError}
350
+ - too many short flags`);
351
+ if (longFlagExp.test(unsupportedFlag))
352
+ throw new Error(`${baseError}
353
+ - too many long flags`);
354
+
355
+ throw new Error(`${baseError}
356
+ - unrecognised flag format`);
357
+ }
358
+ if (shortFlag === undefined && longFlag === undefined)
337
359
  throw new Error(
338
- `invalid Option flags, more than one long flag: '${flags}'`,
360
+ `option creation failed due to no flags found in '${flags}'.`,
339
361
  );
340
- // Generic error if failed to find a flag or an unexpected flag left over.
341
- if (!(shortFlag || longFlag) || flagParts[0].startsWith('-'))
342
- throw new Error(`invalid Option flags: '${flags}'`);
343
362
 
344
363
  return { shortFlag, longFlag };
345
364
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commander",
3
- "version": "13.0.0",
3
+ "version": "13.1.0",
4
4
  "description": "the complete solution for node.js command-line programs",
5
5
  "keywords": [
6
6
  "commander",
@@ -617,7 +617,7 @@ export class Command {
617
617
  * ```js
618
618
  * program
619
619
  * .option('-p, --pepper', 'add pepper')
620
- * .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
620
+ * .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument
621
621
  * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
622
622
  * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
623
623
  * ```