argumental
Version:
Framework for building CLI apps with Node.js
439 lines • 44.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
const lodash_1 = __importDefault(require("lodash"));
const minimist_1 = __importDefault(require("minimist"));
class Parser {
/**
* Casts all parsed values to string (except for booleans).
* @param parsed Minimist parsed arguments.
*/
_stringifyMinimist(parsed) {
for (const key in parsed) {
// If boolean
if (typeof parsed[key] === 'boolean')
continue;
if (typeof parsed[key] === 'string')
continue;
if (typeof parsed[key] === 'number')
parsed[key] = parsed[key] + '';
if (this._isArray(parsed[key])) {
for (let i = 0; i < parsed[key].length; i++) {
if (typeof parsed[key][i] === 'boolean')
continue;
if (typeof parsed[key][i] === 'string')
continue;
if (typeof parsed[key][i] === 'number')
parsed[key][i] = parsed[key][i] + '';
}
}
}
return parsed;
}
/**
* Determines if value is an array.
* @param value The value to check.
*/
_isArray(value) {
return value && typeof value === 'object' && value.constructor === Array;
}
/**
* Determines whether a value can overwrite the other version (short name and long name for options).
* @param value The provided value.
*/
_canOverwriteOpt(value) {
return typeof value === 'string' || value === null || this._isArray(value);
}
/**
* Sorts an array of values based on their order of occurrence in the process arguments.
* @param args The process arguments.
* @param values The named values array (e.g. ['-a 0', '--abort 1', '-a']).
*/
_sortBasedOnPriority(args, values) {
return values.sort((a, b) => args.join(' ').indexOf(' ' + a) - args.join(' ').indexOf(' ' + b));
}
/**
* Returns Argumental parsed option equivalent of Minimist parsed.
* @param minimistParsed The Minimist parsed object.
* @param minimistName The Minimist parsed object key.
*/
_getArgumentalValue(minimistParsed, minimistName) {
// If not provided at all
if (!minimistParsed.hasOwnProperty(minimistName))
return undefined;
// If provided without argument
else if (minimistParsed[minimistName] === '')
return null;
// If provided with argument
else {
// If array, transform each value
if (this._isArray(minimistParsed[minimistName])) {
const transformed = [];
for (const value of minimistParsed[minimistName]) {
// If provided without argument
if (value === '')
transformed.push(null);
else
transformed.push(value);
}
return transformed;
}
else {
return minimistParsed[minimistName];
}
}
}
/**
* Adds a Minimist parsed string option to Argumental parsed object with proper translation.
* @param minimistParsed The Minimist parsed object.
* @param argumentalParsed The Argumental parsed object.
* @param minimistName The Minimist parsed object key.
* @param argumentalName The Argumental parsed object key.
*/
_addStringOption(minimistParsed, argumentalParsed, minimistName, argumentalName) {
// If argumental parsed exists and is not an array
if (argumentalParsed.opts.hasOwnProperty(argumentalName) && !this._isArray(argumentalParsed.opts[argumentalName])) {
// Turn into array
argumentalParsed.opts[argumentalName] = [argumentalParsed.opts[argumentalName]];
argumentalParsed.opts[argumentalName] = argumentalParsed.opts[argumentalName].concat(this._getArgumentalValue(minimistParsed, minimistName));
}
else {
argumentalParsed.opts[argumentalName] = this._getArgumentalValue(minimistParsed, minimistName);
}
}
/**
* Parses an argument based on the given syntax.
* @param syntax The argument syntax.
* @param command Whether this argument belongs to a command or an option.
* @param validators A single or an array of validators.
* @param defaultValue Argument's default value.
*/
parseArgument(syntax, command, validators, defaultValue) {
// Check if argument has wrong syntax or contains invalid characters
if (!command && !syntax.trim().match(/^(<[a-z0-9-_]+>)|(\[[a-z0-9-_]+\])$/i))
throw new Error(`ARGUMENTAL_ERROR: Argument ${syntax.trim()} has invalid syntax or contains invalid characters!`);
if (command && !syntax.trim().match(/^(<(\.\.\.)?[a-z0-9-_]+>)|(\[(\.\.\.)?[a-z0-9-_]+\])$/i))
throw new Error(`ARGUMENTAL_ERROR: Argument ${syntax.trim()} has invalid syntax or contains invalid characters!`);
// Set rest flag
let rest = false;
if (command && syntax.trim().match(/^[<\[]\.\.\./i)) {
rest = true;
syntax = syntax.trim().replace('...', '');
}
// Check if argument name has consecutive - or _s, or it starts or ends with - or _
const name = syntax.trim().match(/^[<\[]([a-z0-9-_]+)[>\]]$/i)[1].toLowerCase();
if (name.includes('__') || name.includes('--') || (name.includes('-') && name.includes('_')) || ['-', '_'].includes(name[0]) || ['-', '_'].includes(name[name.length - 1]))
throw new Error(`ARGUMENTAL_ERROR: Argument ${name} has invalid name!`);
const argument = {
name,
apiName: lodash_1.default.camelCase(name),
required: syntax.trim()[0] === '<',
validators: [],
default: defaultValue
};
if (command)
argument.rest = rest;
// Sanitize validators array
if (validators && (typeof validators !== 'object' || validators.constructor !== Array))
validators = [validators];
else if (!validators)
validators = [];
// Validate validators type
for (const validator of validators) {
// Check if validator is invalid
if (typeof validator !== 'function' && (!validator || typeof validator !== 'object' || validator.constructor !== RegExp))
throw new Error(`ARGUMENTAL_ERROR: Invalid validator for argument ${argument.name}! Validator must be either a validator function or a regular expression.`);
// Append validator
if (validator instanceof RegExp)
argument.validators.push(validator);
else
argument.validators.push({ destructuringParams: false, callback: validator });
}
return argument;
}
/**
* Parses an option based on the given syntax.
* @param syntax The option syntax.
* @param description The option description to display in help.
* @param required A boolean indicating if option is required.
* @param validators A single or an array of validators.
* @param multi A boolean indicating if option can be repeated more than once.
* @param defaultValue The option's argument's default value.
* @param immediate Whether to stop parsing other components and run the action handlers when this option is provided.
*/
parseOption(syntax, description, required, validators, multi, defaultValue, immediate) {
const option = {
shortName: null,
longName: null,
apiName: null,
description: description || null,
argument: null,
required: !!required,
multi: !!multi,
immediate: !!immediate
};
// Parse short name
const shortNameMatch = syntax.trim().match(/^-([a-z])( |$)|^--[a-z0-9-]{2,} -([a-z])( |$)/i);
if (shortNameMatch)
option.shortName = shortNameMatch[1] || shortNameMatch[3];
// Parse long name
const longNameMatch = syntax.trim().match(/^--([a-z0-9-]{2,})|^-[a-z] --([a-z0-9-]{2,})/i);
if (longNameMatch) {
option.longName = longNameMatch[1] || longNameMatch[2];
option.apiName = lodash_1.default.camelCase(option.longName);
}
// Parse argument
const argumentMatch = syntax.trim().match(/(<[a-z0-9-_]+>)|(\[[a-z0-9-_]+\])$/i);
if (argumentMatch)
option.argument = this.parseArgument(argumentMatch[1] || argumentMatch[2], false, validators, defaultValue);
// Check if option has wrong syntax or contains invalid characters
const invalidLongName = option.longName && (option.longName.includes('--') || option.longName[0] === '-' || option.longName[option.longName.length - 1] === '-');
const syntaxWithoutArgument = syntax.trim().replace(/<[a-z0-9-_]+>|\[[a-z0-9-_]+\]$/i, '').trim();
if ((!syntaxWithoutArgument.match(/^-[a-z]( --[a-z0-9-]{2,})?$/i) && !syntaxWithoutArgument.match(/^--[a-z0-9-]{2,}( -[a-z])?$/i)) || invalidLongName || (!option.shortName && !option.longName))
throw new Error(`ARGUMENTAL_ERROR: Option ${syntax} has invalid syntax or contains invalid characters!`);
return option;
}
/**
* Parses command-line arguments with options tailored for the given commands.
* @param args The passed in arguments array (should be <code>process.argv.slice(2)</code>).
* @param commands The final commands object.
*/
parseCliArguments(args, commands) {
// Detect command
let detectedCommand = '';
let remainingArgs = null;
const commandMappings = {};
// Create command mappings including aliases
for (const command in commands) {
// Add the command itself
commandMappings[command] = command;
// Add all aliases
for (const alias of commands[command].aliases) {
commandMappings[alias] = command;
}
}
// Detect all commands and aliases in the passed-in arguments (using the mappings)
for (const command in commandMappings) {
const segments = command.split(' ');
if (lodash_1.default.isEqual(segments, args.slice(0, segments.length))) {
detectedCommand = commandMappings[command];
remainingArgs = args.slice(segments.length);
break;
}
}
// Configure Minimist
const minimistConfig = { boolean: [], string: [] };
for (const option of commands[detectedCommand].options) {
const pointer = option.argument ? minimistConfig.string : minimistConfig.boolean;
if (option.shortName)
pointer.push(option.shortName);
if (option.longName)
pointer.push(option.longName);
}
// Parse arguments using Minimist
const parsed = this._stringifyMinimist(minimist_1.default(remainingArgs || args, minimistConfig));
const parsedArgs = { cmd: detectedCommand, args: {}, opts: {} };
// Add arguments
for (const argument of commands[detectedCommand].arguments) {
// Rest argument
if (argument.rest) {
if (!parsed._.length) {
parsedArgs.args[argument.apiName] = null;
}
else {
parsedArgs.args[argument.apiName] = parsed._;
parsed._ = [];
}
}
else {
parsedArgs.args[argument.apiName] = parsed._.shift() || null;
}
}
// If top-level has no arguments and detected is top-level while arguments are provided, count as unknown command
if (detectedCommand === '' && !commands[detectedCommand].arguments.length && parsed._.length)
return new Error(`Unknown command!`);
// Add options
for (const option of commands[detectedCommand].options) {
// If boolean option
if (!option.argument) {
if (option.longName)
parsedArgs.opts[option.apiName] = !!parsed[option.longName];
if (option.shortName)
parsedArgs.opts[option.shortName] = !!parsed[option.shortName];
}
// If string option (with argument)
else {
// Set long name
if (option.longName)
this._addStringOption(parsed, parsedArgs, option.longName, option.apiName);
// Set short name
if (option.shortName)
this._addStringOption(parsed, parsedArgs, option.shortName, option.shortName);
}
}
// Sanitize options
for (const option of commands[detectedCommand].options) {
// Option with argument
if (option.argument) {
if (option.longName && option.shortName) {
// If option has both names and both their values are either a string or an array of strings, merge them
if (this._canOverwriteOpt(parsedArgs.opts[option.apiName]) && this._canOverwriteOpt(parsedArgs.opts[option.shortName])) {
let merged = [];
// Merge and transform longNames
if (this._isArray(parsedArgs.opts[option.apiName])) {
merged = merged.concat(parsedArgs.opts[option.apiName].map(value => {
// If value is null, transform it to empty name (e.g. --abort)
if (value === null)
return `--${option.longName}`;
// Otherwise, transform it fully (e.g. --abort 0)
else
return `--${option.longName} ${value}`;
}));
}
else {
// If value is null, transform it to empty name (e.g. --abort)
if (parsedArgs.opts[option.apiName] === null)
merged.push(`--${option.longName}`);
// Otherwise, transform it fully (e.g. --abort 0)
else
merged.push(`--${option.longName} ${parsedArgs.opts[option.apiName]}`);
}
// Merge and transform shortNames
if (this._isArray(parsedArgs.opts[option.shortName])) {
merged = merged.concat(parsedArgs.opts[option.shortName].map(value => {
// If value is null, transform it to empty name (e.g. -a)
if (value === null)
return `-${option.shortName}`;
// Otherwise, transform it fully (e.g. -a 0)
else
return `-${option.shortName} ${value}`;
}));
}
else {
// If value is null, transform it to empty name (e.g. -a)
if (parsedArgs.opts[option.shortName] === null)
merged.push(`-${option.shortName}`);
// Otherwise, transform it fully (e.g. -a 0)
else
merged.push(`-${option.shortName} ${parsedArgs.opts[option.shortName]}`);
}
// Sort the merged named values based on their order of occurrence in args
merged = this._sortBasedOnPriority(args, merged);
// Transform named values to original form
merged = merged.map(value => {
// If name only
if (value.match(/^-(-)?[^ ]+$/i))
return null;
// If name and value
return value.match(/^-(-)?[^ ]+ (.+)$/i)[2];
});
parsedArgs.opts[option.shortName] = merged;
parsedArgs.opts[option.apiName] = merged;
}
// If has short name and it is string or array of string and long name is either null or undefined, align
if (!this._canOverwriteOpt(parsedArgs.opts[option.apiName]) && this._canOverwriteOpt(parsedArgs.opts[option.shortName]))
parsedArgs.opts[option.apiName] = parsedArgs.opts[option.shortName];
// If has long name and it is string or array of string and short name is either null or undefined, align
if (!this._canOverwriteOpt(parsedArgs.opts[option.shortName]) && this._canOverwriteOpt(parsedArgs.opts[option.apiName]))
parsedArgs.opts[option.shortName] = parsedArgs.opts[option.apiName];
}
}
// Binary option
else {
// If boolean option has both names and their value differs, align them
if (option.shortName && option.longName) {
if (parsedArgs.opts[option.shortName] === true && parsedArgs.opts[option.apiName] === false)
parsedArgs.opts[option.apiName] = true;
if (parsedArgs.opts[option.shortName] === false && parsedArgs.opts[option.apiName] === true)
parsedArgs.opts[option.shortName] = true;
}
}
// Multi options
if (option.multi && option.argument) {
// If single value, wrap it with an array
if (option.shortName && parsedArgs.opts[option.shortName] !== undefined && !this._isArray(parsedArgs.opts[option.shortName]))
parsedArgs.opts[option.shortName] = [parsedArgs.opts[option.shortName]];
if (option.longName && parsedArgs.opts[option.apiName] !== undefined && !this._isArray(parsedArgs.opts[option.apiName]))
parsedArgs.opts[option.apiName] = [parsedArgs.opts[option.apiName]];
}
}
// Remove wrapping "" and '' for string values (options)
for (const name in parsedArgs.opts) {
// If value is array
if (this._isArray(parsedArgs.opts[name])) {
parsedArgs.opts[name] = parsedArgs.opts[name].map(value => {
// If value is not string
if (typeof value !== 'string')
return value;
if (value.match(/^".*"$/))
return value.replace(/^"/, '').replace(/"$/, '');
if (value.match(/^'.*'$/))
return value.replace(/^'/, '').replace(/'$/, '');
return value;
});
}
else {
// If value is not string or was not wrapped
if (typeof parsedArgs.opts[name] !== 'string')
continue;
if (parsedArgs.opts[name].match(/^".*"$/i))
parsedArgs.opts[name] = parsedArgs.opts[name].replace(/^"/, '').replace(/"$/, '');
if (parsedArgs.opts[name].match(/^'.*'$/i))
parsedArgs.opts[name] = parsedArgs.opts[name].replace(/^'/, '').replace(/'$/, '');
}
}
// Remove wrapping "" and '' for string values (arguments)
for (const name in parsedArgs.args) {
// If value is array
if (this._isArray(parsedArgs.args[name])) {
parsedArgs.args[name] = parsedArgs.args[name].map(value => {
// If value is not string
if (typeof value !== 'string')
return value;
if (value.match(/^".*"$/))
return value.replace(/^"/, '').replace(/"$/, '');
if (value.match(/^'.*'$/))
return value.replace(/^'/, '').replace(/'$/, '');
return value;
});
}
else {
// If value is not string or was not wrapped
if (typeof parsedArgs.args[name] !== 'string')
continue;
if (parsedArgs.args[name].match(/^".*"$/i))
parsedArgs.args[name] = parsedArgs.args[name].replace(/^"/, '').replace(/"$/, '');
if (parsedArgs.args[name].match(/^'.*'$/i))
parsedArgs.args[name] = parsedArgs.args[name].replace(/^'/, '').replace(/'$/, '');
}
}
let immediateOption = null;
// Check for immediate options
for (const option of commands[detectedCommand].options) {
// If immediate option provided
if (option.immediate && ((option.argument && parsedArgs.opts[option.apiName || option.shortName] !== undefined) || (!option.argument && parsedArgs.opts[option.apiName || option.shortName] === true))) {
immediateOption = option;
break;
}
}
// If more arguments were provided (any arguments left over) and no immediate option provided
if (parsed._.length && !immediateOption)
return new Error(`Expected ${commands[detectedCommand].arguments.length} argument${commands[detectedCommand].arguments.length !== 1 ? 's' : ''} but got ${commands[detectedCommand].arguments.length + parsed._.length}!`);
// If unknown options were provided and no immediate option was
if (!immediateOption) {
for (const key in parsed) {
if (key === '_')
continue;
// If key was not defined in current command's options
if (!commands[detectedCommand].options.filter(opt => opt.shortName === key || opt.longName === key).length)
return new Error(`Unknown option ${key}!`);
}
}
return parsedArgs;
}
}
exports.Parser = Parser;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6InNyYy8iLCJzb3VyY2VzIjpbImxpYi9wYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsb0RBQXVCO0FBQ3ZCLHdEQUFnQztBQUdoQyxNQUFhLE1BQU07SUFFakI7OztNQUdFO0lBQ00sa0JBQWtCLENBQUMsTUFBMkI7UUFFcEQsS0FBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUc7WUFFMUIsYUFBYTtZQUNiLElBQUssT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssU0FBUztnQkFBRyxTQUFTO1lBQ2pELElBQUssT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssUUFBUTtnQkFBRyxTQUFTO1lBQ2hELElBQUssT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssUUFBUTtnQkFBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN0RSxJQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUc7Z0JBRWhDLEtBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFHO29CQUU3QyxJQUFLLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVM7d0JBQUcsU0FBUztvQkFDcEQsSUFBSyxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRO3dCQUFHLFNBQVM7b0JBQ25ELElBQUssT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUTt3QkFBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMs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