| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | 
							- const { InvalidArgumentError } = require('./error.js');
 
- // @ts-check
 
- class Argument {
 
-   /**
 
-    * Initialize a new command argument with the given name and description.
 
-    * The default is that the argument is required, and you can explicitly
 
-    * indicate this with <> around the name. Put [] around the name for an optional argument.
 
-    *
 
-    * @param {string} name
 
-    * @param {string} [description]
 
-    */
 
-   constructor(name, description) {
 
-     this.description = description || '';
 
-     this.variadic = false;
 
-     this.parseArg = undefined;
 
-     this.defaultValue = undefined;
 
-     this.defaultValueDescription = undefined;
 
-     this.argChoices = undefined;
 
-     switch (name[0]) {
 
-       case '<': // e.g. <required>
 
-         this.required = true;
 
-         this._name = name.slice(1, -1);
 
-         break;
 
-       case '[': // e.g. [optional]
 
-         this.required = false;
 
-         this._name = name.slice(1, -1);
 
-         break;
 
-       default:
 
-         this.required = true;
 
-         this._name = name;
 
-         break;
 
-     }
 
-     if (this._name.length > 3 && this._name.slice(-3) === '...') {
 
-       this.variadic = true;
 
-       this._name = this._name.slice(0, -3);
 
-     }
 
-   }
 
-   /**
 
-    * Return argument name.
 
-    *
 
-    * @return {string}
 
-    */
 
-   name() {
 
-     return this._name;
 
-   }
 
-   /**
 
-    * @api private
 
-    */
 
-   _concatValue(value, previous) {
 
-     if (previous === this.defaultValue || !Array.isArray(previous)) {
 
-       return [value];
 
-     }
 
-     return previous.concat(value);
 
-   }
 
-   /**
 
-    * Set the default value, and optionally supply the description to be displayed in the help.
 
-    *
 
-    * @param {any} value
 
-    * @param {string} [description]
 
-    * @return {Argument}
 
-    */
 
-   default(value, description) {
 
-     this.defaultValue = value;
 
-     this.defaultValueDescription = description;
 
-     return this;
 
-   }
 
-   /**
 
-    * Set the custom handler for processing CLI command arguments into argument values.
 
-    *
 
-    * @param {Function} [fn]
 
-    * @return {Argument}
 
-    */
 
-   argParser(fn) {
 
-     this.parseArg = fn;
 
-     return this;
 
-   }
 
-   /**
 
-    * Only allow argument value to be one of choices.
 
-    *
 
-    * @param {string[]} values
 
-    * @return {Argument}
 
-    */
 
-   choices(values) {
 
-     this.argChoices = values.slice();
 
-     this.parseArg = (arg, previous) => {
 
-       if (!this.argChoices.includes(arg)) {
 
-         throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(', ')}.`);
 
-       }
 
-       if (this.variadic) {
 
-         return this._concatValue(arg, previous);
 
-       }
 
-       return arg;
 
-     };
 
-     return this;
 
-   }
 
-   /**
 
-    * Make argument required.
 
-    */
 
-   argRequired() {
 
-     this.required = true;
 
-     return this;
 
-   }
 
-   /**
 
-    * Make argument optional.
 
-    */
 
-   argOptional() {
 
-     this.required = false;
 
-     return this;
 
-   }
 
- }
 
- /**
 
-  * Takes an argument and returns its human readable equivalent for help usage.
 
-  *
 
-  * @param {Argument} arg
 
-  * @return {string}
 
-  * @api private
 
-  */
 
- function humanReadableArgName(arg) {
 
-   const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');
 
-   return arg.required
 
-     ? '<' + nameOutput + '>'
 
-     : '[' + nameOutput + ']';
 
- }
 
- exports.Argument = Argument;
 
- exports.humanReadableArgName = humanReadableArgName;
 
 
  |