UNPKG

argumental

Version:

Framework for building CLI apps with Node.js

439 lines 44.1 kB
"use strict"; 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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