Initial commit
This commit is contained in:
132
node_modules/cliss/lib/cli-help.js
generated
vendored
Normal file
132
node_modules/cliss/lib/cli-help.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
|
||||
const commandLineUsage = require('command-line-usage');
|
||||
const stripAnsiFn = require('strip-ansi');
|
||||
|
||||
function getCommandFromPath(commandPath, subcommandsDelimiter) {
|
||||
commandPath = commandPath.filter(command => !!command);
|
||||
if (subcommandsDelimiter) {
|
||||
return commandPath && commandPath.length && `${commandPath.shift()} ${commandPath.join(subcommandsDelimiter)}`;
|
||||
}
|
||||
|
||||
return commandPath && commandPath.length && commandPath.join(' ');
|
||||
}
|
||||
|
||||
function prepareDescriptionSection(description) {
|
||||
return description && { header: 'Description:', content: description };
|
||||
}
|
||||
|
||||
function prepareValueSection(value) {
|
||||
return value !== undefined && { header: 'Value:', content: value };
|
||||
}
|
||||
|
||||
function prepareCommandsSection(commands) {
|
||||
return commands.length && {
|
||||
header: 'Commands:',
|
||||
content: commands.map(command => ({
|
||||
name: command.name,
|
||||
summary: command.description
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
function prepareOptions(options) {
|
||||
options = options.slice(0);
|
||||
|
||||
const variadicArguments = options.find(option => option.variadic);
|
||||
if (variadicArguments) {
|
||||
// options = options.filter(option => option !== variadicArguments);
|
||||
}
|
||||
|
||||
const optionsSection = {
|
||||
header: 'Options:',
|
||||
optionList: options.map(option => {
|
||||
let description = option.required && `[red]{Required}`;
|
||||
if(option.description) {
|
||||
description = description ? `${description} - ${option.description}` : option.description;
|
||||
}
|
||||
|
||||
return {
|
||||
name: option.name,
|
||||
description,
|
||||
alias: option.alias,
|
||||
typeLabel: option.type && `[underline]{${option.type}}`
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
return { options, variadicArguments, optionsSection };
|
||||
}
|
||||
|
||||
function prepareUsageSection(command, options = [], variadicArguments, hasSubcommand, subcommandRequired, subcommandsDelimiter) {
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
|
||||
let usage = [];
|
||||
|
||||
let usageText = `$ ${command}`;
|
||||
|
||||
let usageOptions = options.length ? options.some(option => option.required) ? '<options>' : '[options]' : '';
|
||||
if (usageOptions) {
|
||||
usageText = `${usageText} ${usageOptions}`
|
||||
}
|
||||
|
||||
if (variadicArguments) {
|
||||
let variadicArgumentsUsage = `${variadicArguments.name}...`;
|
||||
variadicArgumentsUsage = variadicArguments.required ? `<${variadicArgumentsUsage}>` : `[${variadicArgumentsUsage}]`;
|
||||
usageText = `${usageText} ${variadicArgumentsUsage}`
|
||||
}
|
||||
|
||||
if(!subcommandRequired){
|
||||
usage.push(usageText);
|
||||
}
|
||||
|
||||
if (hasSubcommand) {
|
||||
let usageCommand = subcommandRequired ? '<command>' : '[command]';
|
||||
usage.push(`$ ${command} ${usageCommand}`);
|
||||
}
|
||||
|
||||
return { header: 'Usage:', content: usage };
|
||||
}
|
||||
|
||||
function getHelp({ name, description, action, value, commandPath, options = [], commands = [] } = {}, { stripAnsi = false, subcommandsDelimiter } = {}) {
|
||||
const command = getCommandFromPath(commandPath, subcommandsDelimiter);
|
||||
const descriptionSection = prepareDescriptionSection(description);
|
||||
const valueSection = prepareValueSection(value);
|
||||
const commandsSection = prepareCommandsSection(commands);
|
||||
const preparedOptions = prepareOptions(options);
|
||||
const optionsSection = preparedOptions.optionsSection;
|
||||
const usageSection = prepareUsageSection(command, preparedOptions.options, preparedOptions.variadicArguments, commands.length, value === undefined && !action);
|
||||
|
||||
const cmdLineUsageData = [];
|
||||
|
||||
if(descriptionSection){
|
||||
cmdLineUsageData.push(descriptionSection);
|
||||
}
|
||||
|
||||
if(usageSection){
|
||||
cmdLineUsageData.push(usageSection);
|
||||
}
|
||||
|
||||
if(valueSection){
|
||||
cmdLineUsageData.push(valueSection);
|
||||
}
|
||||
|
||||
if(preparedOptions.options.length){
|
||||
cmdLineUsageData.push(optionsSection);
|
||||
}
|
||||
|
||||
if(commandsSection){
|
||||
cmdLineUsageData.push(commandsSection);
|
||||
}
|
||||
|
||||
let helpContent = commandLineUsage(cmdLineUsageData);
|
||||
if (stripAnsi) {
|
||||
helpContent = stripAnsiFn(helpContent);
|
||||
}
|
||||
|
||||
return helpContent;
|
||||
}
|
||||
|
||||
module.exports = getHelp;
|
||||
249
node_modules/cliss/lib/cliss.js
generated
vendored
Normal file
249
node_modules/cliss/lib/cliss.js
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
'use strict';
|
||||
|
||||
const os = require('os');
|
||||
const yargsParser = require('yargs-parser');
|
||||
const { prepareArgs, prepareArgsAndCall } = require('object-to-arguments');
|
||||
const { inspectParameters, getParametersNames } = require('inspect-parameters-declaration');
|
||||
const pipeFn = require('pipe-functions');
|
||||
const getStdin = require('get-stdin');
|
||||
const getHelp = require('./cli-help');
|
||||
const deepMerge = require('deepmerge')
|
||||
|
||||
const defaultOptions = {
|
||||
command: {
|
||||
subcommandsDelimiter: undefined
|
||||
},
|
||||
options: {
|
||||
validateRequiredParameters: false
|
||||
},
|
||||
version: {
|
||||
option: 'version'
|
||||
},
|
||||
help: {
|
||||
option: 'help',
|
||||
stripAnsi: false
|
||||
}
|
||||
};
|
||||
|
||||
function callCommand(command, parsedArgs, optionsPipe) {
|
||||
if (command && (command.value || command.action)) {
|
||||
if (command.value) {
|
||||
return execCommandPipeline(() => command.value, parsedArgs, command.pipe, optionsPipe);
|
||||
}
|
||||
|
||||
return execCommandPipeline(command.action, parsedArgs, command.pipe, optionsPipe);
|
||||
}
|
||||
}
|
||||
|
||||
function removeEOL(str) {
|
||||
return str.replace(RegExp(`${os.EOL}$`), '');
|
||||
}
|
||||
|
||||
function checkStdin(stdinFn, stdinValue, parsedArgs, positionalArgs, argsAfterEndOfOptions) {
|
||||
if (stdinValue === '') {
|
||||
return parsedArgs;
|
||||
}
|
||||
|
||||
stdinValue = removeEOL(stdinValue);
|
||||
return stdinFn(stdinValue, parsedArgs, positionalArgs, argsAfterEndOfOptions);
|
||||
}
|
||||
|
||||
function execCommandPipeline(command, parsedArgs, commandPipe = {}, optionsPipe = {}) {
|
||||
const positionalArgs = parsedArgs._;
|
||||
const argsAfterEndOfOptions = parsedArgs['--'];
|
||||
delete parsedArgs._;
|
||||
delete parsedArgs['--'];
|
||||
|
||||
let pipelineArray = [];
|
||||
|
||||
// Wait for stdin or start passing in parsedArgs
|
||||
let pipeStdin = commandPipe.stdin || optionsPipe.stdin;
|
||||
if (pipeStdin) {
|
||||
pipelineArray.push(getStdin);
|
||||
pipelineArray.push(stdinValue => checkStdin(pipeStdin, stdinValue, parsedArgs, positionalArgs, argsAfterEndOfOptions));
|
||||
} else {
|
||||
pipelineArray.push(parsedArgs);
|
||||
}
|
||||
|
||||
// Options Before
|
||||
if (optionsPipe.before) {
|
||||
pipelineArray.push(args => optionsPipe.before(args, positionalArgs, argsAfterEndOfOptions));
|
||||
}
|
||||
|
||||
// Command Before
|
||||
if (commandPipe.before) {
|
||||
pipelineArray.push(args => commandPipe.before(args, positionalArgs, argsAfterEndOfOptions));
|
||||
}
|
||||
|
||||
// Main Command
|
||||
pipelineArray.push(args => prepareArgsAndCall(command, args, ...positionalArgs));
|
||||
|
||||
// Command After
|
||||
if (commandPipe.after) {
|
||||
pipelineArray.push(result => commandPipe.after(result, parsedArgs, positionalArgs, argsAfterEndOfOptions));
|
||||
}
|
||||
|
||||
// Options After
|
||||
if (optionsPipe.after) {
|
||||
pipelineArray.push(result => optionsPipe.after(result, parsedArgs, positionalArgs, argsAfterEndOfOptions));
|
||||
}
|
||||
|
||||
// Exec pipeline
|
||||
const pipeResult = pipeFn(...pipelineArray);
|
||||
|
||||
// Output Promises
|
||||
if (pipeResult && pipeResult.then) {
|
||||
return pipeResult
|
||||
.then(result => result !== undefined && console.log(result))
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
// console.log('pipeResult', command\);
|
||||
|
||||
// Output
|
||||
if (pipeResult !== undefined) {
|
||||
console.log(pipeResult);
|
||||
}
|
||||
}
|
||||
|
||||
function matchCommandFromArgs(args, command, commandPath = []) {
|
||||
commandPath.push(command.name);
|
||||
|
||||
if (command.commands) {
|
||||
for (let subcommand of command.commands) {
|
||||
if (subcommand.name === args[0]) {
|
||||
return matchCommandFromArgs(args.slice(1), subcommand, commandPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
command.commandPath = commandPath;
|
||||
return { command, args };
|
||||
}
|
||||
|
||||
function matchDelimitedSubcommand(subcommandArg = [], command, subcommandDelimiter, commandPath = []) {
|
||||
subcommandArg = subcommandArg.constructor === Array ? subcommandArg : subcommandArg.split(subcommandDelimiter);
|
||||
|
||||
for (let subcommand of command.commands) {
|
||||
if (subcommand.name === subcommandArg[0]) {
|
||||
const nextSubcommand = subcommandArg.slice(1);
|
||||
if (nextSubcommand.length) {
|
||||
return matchDelimitedSubcommand(nextSubcommand, subcommand, subcommandDelimiter, commandPath);
|
||||
} else {
|
||||
return subcommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function matchCommand(args, command, subcommandsDelimiter) {
|
||||
|
||||
if (subcommandsDelimiter && command.commands) {
|
||||
const matchedSubcommand = matchDelimitedSubcommand(args[0], command, subcommandsDelimiter);
|
||||
if (matchedSubcommand) {
|
||||
const commandPath = [command.name].concat(args[0].split(subcommandsDelimiter));
|
||||
command = matchedSubcommand;
|
||||
args = args.slice(1);
|
||||
|
||||
command.commandPath = commandPath;
|
||||
return { command, args };
|
||||
}
|
||||
}
|
||||
|
||||
return matchCommandFromArgs(args.slice(0), command);
|
||||
}
|
||||
|
||||
function buildOptionsFromParametersAndSpec(action, optionsSpec) {
|
||||
// Build options from functions parameters and merge with options spec
|
||||
return getParametersNames(action).map(parameter => {
|
||||
const option = { name: parameter };
|
||||
|
||||
const [, variadic] = parameter.match(/^\.{3}(.*)/) || [];
|
||||
if (variadic) {
|
||||
option.name = variadic;
|
||||
option.variadic = true;
|
||||
}
|
||||
|
||||
const optionSpec = (optionsSpec && optionsSpec.find(optionSpec => optionSpec.name === option.name)) || {};
|
||||
return Object.assign(option, optionSpec);
|
||||
});
|
||||
}
|
||||
|
||||
function buildYargsParserOptions(options) {
|
||||
return options.reduce((result, option) => {
|
||||
// yargsParser option type
|
||||
if (option.type) {
|
||||
const optionType = option.type.toString().toLowerCase();
|
||||
result[optionType] = result[optionType] || [];
|
||||
result[optionType].push(option.name);
|
||||
}
|
||||
|
||||
// yargsParser option alias
|
||||
if (option.alias) {
|
||||
result.alias = result.alias || {};
|
||||
result.alias[option.name] = option.alias
|
||||
}
|
||||
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function parseArgs(args, parserOptions) {
|
||||
return yargsParser(args, Object.assign({
|
||||
configuration: {
|
||||
'boolean-negation': false,
|
||||
'populate--': true
|
||||
}
|
||||
}, parserOptions));
|
||||
}
|
||||
|
||||
function cliss(cliSpec, clissOptions = {}, argv) {
|
||||
if (cliSpec.constructor === Function) {
|
||||
cliSpec = {
|
||||
action: cliSpec
|
||||
};
|
||||
}
|
||||
|
||||
clissOptions = deepMerge(defaultOptions, clissOptions);
|
||||
|
||||
const argsArray = argv || process.argv.slice(2);
|
||||
|
||||
const { command, args } = matchCommand(argsArray.slice(0), cliSpec, clissOptions.command.subcommandsDelimiter);
|
||||
|
||||
command.options = buildOptionsFromParametersAndSpec(command.action, command.options);
|
||||
|
||||
const yargsParserOptions = buildYargsParserOptions(command.options);
|
||||
const parsedArgs = parseArgs(args, yargsParserOptions);
|
||||
|
||||
// Show version if --version is passed in (disabled if { versionOption: falsey })
|
||||
if ((clissOptions.version.option && parsedArgs[clissOptions.version.option]) && (command.version || cliSpec.version)) {
|
||||
return console.log(command.version || cliSpec.version);
|
||||
}
|
||||
|
||||
const helpOptions = Object.assign({}, clissOptions.help, { subcommandsDelimiter: clissOptions.command.subcommandsDelimiter });
|
||||
|
||||
// Show help if the command doesn't have an action or value
|
||||
if (!command.action && !command.value) {
|
||||
return console.log(getHelp(command, helpOptions));
|
||||
}
|
||||
|
||||
// Show help if the option says to validateRequiredParameters and some of then are not being passed in
|
||||
if (clissOptions.options.validateRequiredParameters) {
|
||||
const everyRequiredOptionsAreSet = command.options.filter(option => option.required).every(requiredOption => {
|
||||
return parsedArgs[requiredOption.name] !== undefined;
|
||||
});
|
||||
|
||||
if (!everyRequiredOptionsAreSet) {
|
||||
return console.log(getHelp(command, helpOptions));
|
||||
}
|
||||
}
|
||||
|
||||
// Show help if --help is passed in
|
||||
if (clissOptions.help.option && parsedArgs[clissOptions.help.option]) {
|
||||
return console.log(getHelp(command, helpOptions));
|
||||
}
|
||||
|
||||
callCommand(command, parsedArgs, clissOptions.pipe);
|
||||
}
|
||||
|
||||
module.exports = cliss;
|
||||
Reference in New Issue
Block a user