serverless/lib/cli/resolve-input.js

86 lines
2.6 KiB
JavaScript

/**
* CLI params parser, to be used before we have deducted
* what commands and options are supported in given context.
*/
'use strict';
const ensureMap = require('type/map/ensure');
const memoizee = require('memoizee');
const parseArgs = require('./parse-args');
const isParamName = RegExp.prototype.test.bind(require('./param-reg-exp'));
/**
* This JavaScript function takes a schema of command
* line options and organizes them into categories
* (boolean, string, multiple, alias) based on their
* types and shortcuts, returning an object with these
* categorized options.
* @param {*} commandOptionsSchema
* @returns
*/
const resolveArgsSchema = (commandOptionsSchema) => {
const options = { boolean: new Set(), string: new Set(), alias: new Map(), multiple: new Set() };
for (const [name, optionSchema] of Object.entries(commandOptionsSchema)) {
switch (optionSchema.type) {
case 'boolean':
options.boolean.add(name);
break;
case 'multiple':
options.multiple.add(name);
break;
case 'string':
options.string.add(name);
break;
default:
}
if (optionSchema.shortcut) options.alias.set(optionSchema.shortcut, name);
}
return options;
};
/**
* Parses command line arguments, identifies the command and
* its options, and returns an object containing these
* details. It also determines if the command is a
* container command or if a help request has been made,
* and sets corresponding flags in the returned object.
*/
module.exports = memoizee((commandsSchema = require('./commands-schema')) => {
commandsSchema = ensureMap(commandsSchema);
const args = process.argv.slice(2);
const firstParamIndex = args.findIndex(isParamName);
const commands = args.slice(0, firstParamIndex === -1 ? Infinity : firstParamIndex);
const command = commands.join(' ');
const commandSchema = commandsSchema.get(command);
const options = parseArgs(
args.slice(firstParamIndex === -1 ? Infinity : firstParamIndex),
resolveArgsSchema(commandSchema ? commandSchema.options : commandsSchema.commonOptions)
);
delete options._;
const result = { commands, options, command, commandSchema, commandsSchema };
if (!commandSchema) {
result.isContainerCommand = Array.from(commandsSchema.keys()).some((commandName) =>
commandName.startsWith(`${command} `)
);
if (result.isContainerCommand) {
result.isHelpRequest = true;
return result;
}
}
if (
(!command && options['help-interactive']) ||
options.help ||
options.version ||
command === 'help'
) {
result.isHelpRequest = true;
}
return result;
});