You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
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 option value to be one of choices. * * @param {string[]} values * @return {Argument} */
choices(values) { this.argChoices = values; this.parseArg = (arg, previous) => { if (!values.includes(arg)) { throw new InvalidArgumentError(`Allowed choices are ${values.join(', ')}.`); } if (this.variadic) { return this._concatValue(arg, previous); } return arg; }; return this; };
/** * Make option-argument required. */ argRequired() { this.required = true; return this; }
/** * Make option-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;
|