Spaces:
Sleeping
Sleeping
| const { InvalidArgumentError } = require('./error.js'); | |
| 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; | |
| } | |
| /** | |
| * @package | |
| */ | |
| _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 {*} 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. | |
| * | |
| * @returns {Argument} | |
| */ | |
| argRequired() { | |
| this.required = true; | |
| return this; | |
| } | |
| /** | |
| * Make argument optional. | |
| * | |
| * @returns {Argument} | |
| */ | |
| argOptional() { | |
| this.required = false; | |
| return this; | |
| } | |
| } | |
| /** | |
| * Takes an argument and returns its human readable equivalent for help usage. | |
| * | |
| * @param {Argument} arg | |
| * @return {string} | |
| * @private | |
| */ | |
| function humanReadableArgName(arg) { | |
| const nameOutput = arg.name() + (arg.variadic === true ? '...' : ''); | |
| return arg.required ? '<' + nameOutput + '>' : '[' + nameOutput + ']'; | |
| } | |
| exports.Argument = Argument; | |
| exports.humanReadableArgName = humanReadableArgName; | |