UNPKG

node-desleri-by105

Version:

du bir deneme sürümüdür. 22222

1,357 lines (1,334 loc) 108 kB
'use strict'; var assert = require('assert'); class YError extends Error { constructor(msg) { super(msg || 'yargs error'); this.name = 'YError'; Error.captureStackTrace(this, YError); } } let previouslyVisitedConfigs = []; let shim; function applyExtends(config, cwd, mergeExtends, _shim) { shim = _shim; let defaultConfig = {}; if (Object.prototype.hasOwnProperty.call(config, 'extends')) { if (typeof config.extends !== 'string') return defaultConfig; const isPath = /\.json|\..*rc$/.test(config.extends); let pathToDefault = null; if (!isPath) { try { pathToDefault = require.resolve(config.extends); } catch (_err) { return config; } } else { pathToDefault = getPathToDefaultConfig(cwd, config.extends); } checkForCircularExtends(pathToDefault); previouslyVisitedConfigs.push(pathToDefault); defaultConfig = isPath ? JSON.parse(shim.readFileSync(pathToDefault, 'utf8')) : require(config.extends); delete config.extends; defaultConfig = applyExtends(defaultConfig, shim.path.dirname(pathToDefault), mergeExtends, shim); } previouslyVisitedConfigs = []; return mergeExtends ? mergeDeep(defaultConfig, config) : Object.assign({}, defaultConfig, config); } function checkForCircularExtends(cfgPath) { if (previouslyVisitedConfigs.indexOf(cfgPath) > -1) { throw new YError(`Circular extended configurations: '${cfgPath}'.`); } } function getPathToDefaultConfig(cwd, pathToExtend) { return shim.path.resolve(cwd, pathToExtend); } function mergeDeep(config1, config2) { const target = {}; function isObject(obj) { return obj && typeof obj === 'object' && !Array.isArray(obj); } Object.assign(target, config1); for (const key of Object.keys(config2)) { if (isObject(config2[key]) && isObject(target[key])) { target[key] = mergeDeep(config1[key], config2[key]); } else { target[key] = config2[key]; } } return target; } function parseCommand(cmd) { const extraSpacesStrippedCommand = cmd.replace(/\s{2,}/g, ' '); const splitCommand = extraSpacesStrippedCommand.split(/\s+(?![^[]*]|[^<]*>)/); const bregex = /\.*[\][<>]/g; const firstCommand = splitCommand.shift(); if (!firstCommand) throw new Error(`No command found in: ${cmd}`); const parsedCommand = { cmd: firstCommand.replace(bregex, ''), demanded: [], optional: [], }; splitCommand.forEach((cmd, i) => { let variadic = false; cmd = cmd.replace(/\s/g, ''); if (/\.+[\]>]/.test(cmd) && i === splitCommand.length - 1) variadic = true; if (/^\[/.test(cmd)) { parsedCommand.optional.push({ cmd: cmd.replace(bregex, '').split('|'), variadic, }); } else { parsedCommand.demanded.push({ cmd: cmd.replace(bregex, '').split('|'), variadic, }); } }); return parsedCommand; } const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']; function argsert(arg1, arg2, arg3) { function parseArgs() { return typeof arg1 === 'object' ? [{ demanded: [], optional: [] }, arg1, arg2] : [ parseCommand(`cmd ${arg1}`), arg2, arg3, ]; } try { let position = 0; const [parsed, callerArguments, _length] = parseArgs(); const args = [].slice.call(callerArguments); while (args.length && args[args.length - 1] === undefined) args.pop(); const length = _length || args.length; if (length < parsed.demanded.length) { throw new YError(`Not enough arguments provided. Expected ${parsed.demanded.length} but received ${args.length}.`); } const totalCommands = parsed.demanded.length + parsed.optional.length; if (length > totalCommands) { throw new YError(`Too many arguments provided. Expected max ${totalCommands} but received ${length}.`); } parsed.demanded.forEach(demanded => { const arg = args.shift(); const observedType = guessType(arg); const matchingTypes = demanded.cmd.filter(type => type === observedType || type === '*'); if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position); position += 1; }); parsed.optional.forEach(optional => { if (args.length === 0) return; const arg = args.shift(); const observedType = guessType(arg); const matchingTypes = optional.cmd.filter(type => type === observedType || type === '*'); if (matchingTypes.length === 0) argumentTypeError(observedType, optional.cmd, position); position += 1; }); } catch (err) { console.warn(err.stack); } } function guessType(arg) { if (Array.isArray(arg)) { return 'array'; } else if (arg === null) { return 'null'; } return typeof arg; } function argumentTypeError(observedType, allowedTypes, position) { throw new YError(`Invalid ${positionName[position] || 'manyith'} argument. Expected ${allowedTypes.join(' or ')} but received ${observedType}.`); } function isPromise(maybePromise) { return (!!maybePromise && !!maybePromise.then && typeof maybePromise.then === 'function'); } function assertNotStrictEqual(actual, expected, shim, message) { shim.assert.notStrictEqual(actual, expected, message); } function assertSingleKey(actual, shim) { shim.assert.strictEqual(typeof actual, 'string'); } function objectKeys(object) { return Object.keys(object); } function objFilter(original = {}, filter = () => true) { const obj = {}; objectKeys(original).forEach(key => { if (filter(key, original[key])) { obj[key] = original[key]; } }); return obj; } function globalMiddlewareFactory(globalMiddleware, context) { return function (callback, applyBeforeValidation = false) { argsert('<array|function> [boolean]', [callback, applyBeforeValidation], arguments.length); if (Array.isArray(callback)) { for (let i = 0; i < callback.length; i++) { if (typeof callback[i] !== 'function') { throw Error('middleware must be a function'); } callback[i].applyBeforeValidation = applyBeforeValidation; } Array.prototype.push.apply(globalMiddleware, callback); } else if (typeof callback === 'function') { callback.applyBeforeValidation = applyBeforeValidation; globalMiddleware.push(callback); } return context; }; } function commandMiddlewareFactory(commandMiddleware) { if (!commandMiddleware) return []; return commandMiddleware.map(middleware => { middleware.applyBeforeValidation = false; return middleware; }); } function applyMiddleware(argv, yargs, middlewares, beforeValidation) { const beforeValidationError = new Error('middleware cannot return a promise when applyBeforeValidation is true'); return middlewares.reduce((acc, middleware) => { if (middleware.applyBeforeValidation !== beforeValidation) { return acc; } if (isPromise(acc)) { return acc .then(initialObj => Promise.all([ initialObj, middleware(initialObj, yargs), ])) .then(([initialObj, middlewareObj]) => Object.assign(initialObj, middlewareObj)); } else { const result = middleware(acc, yargs); if (beforeValidation && isPromise(result)) throw beforeValidationError; return isPromise(result) ? result.then(middlewareObj => Object.assign(acc, middlewareObj)) : Object.assign(acc, result); } }, argv); } function getProcessArgvBinIndex() { if (isBundledElectronApp()) return 0; return 1; } function isBundledElectronApp() { return isElectronApp() && !process.defaultApp; } function isElectronApp() { return !!process.versions.electron; } function hideBin(argv) { return argv.slice(getProcessArgvBinIndex() + 1); } function getProcessArgvBin() { return process.argv[getProcessArgvBinIndex()]; } var processArgv = /*#__PURE__*/Object.freeze({ __proto__: null, hideBin: hideBin, getProcessArgvBin: getProcessArgvBin }); function whichModule(exported) { if (typeof require === 'undefined') return null; for (let i = 0, files = Object.keys(require.cache), mod; i < files.length; i++) { mod = require.cache[files[i]]; if (mod.exports === exported) return mod; } return null; } const DEFAULT_MARKER = /(^\*)|(^\$0)/; function command(yargs, usage, validation, globalMiddleware = [], shim) { const self = {}; let handlers = {}; let aliasMap = {}; let defaultCommand; self.addHandler = function addHandler(cmd, description, builder, handler, commandMiddleware, deprecated) { let aliases = []; const middlewares = commandMiddlewareFactory(commandMiddleware); handler = handler || (() => { }); if (Array.isArray(cmd)) { if (isCommandAndAliases(cmd)) { [cmd, ...aliases] = cmd; } else { for (const command of cmd) { self.addHandler(command); } } } else if (isCommandHandlerDefinition(cmd)) { let command = Array.isArray(cmd.command) || typeof cmd.command === 'string' ? cmd.command : moduleName(cmd); if (cmd.aliases) command = [].concat(command).concat(cmd.aliases); self.addHandler(command, extractDesc(cmd), cmd.builder, cmd.handler, cmd.middlewares, cmd.deprecated); return; } else if (isCommandBuilderDefinition(builder)) { self.addHandler([cmd].concat(aliases), description, builder.builder, builder.handler, builder.middlewares, builder.deprecated); return; } if (typeof cmd === 'string') { const parsedCommand = parseCommand(cmd); aliases = aliases.map(alias => parseCommand(alias).cmd); let isDefault = false; const parsedAliases = [parsedCommand.cmd].concat(aliases).filter(c => { if (DEFAULT_MARKER.test(c)) { isDefault = true; return false; } return true; }); if (parsedAliases.length === 0 && isDefault) parsedAliases.push('$0'); if (isDefault) { parsedCommand.cmd = parsedAliases[0]; aliases = parsedAliases.slice(1); cmd = cmd.replace(DEFAULT_MARKER, parsedCommand.cmd); } aliases.forEach(alias => { aliasMap[alias] = parsedCommand.cmd; }); if (description !== false) { usage.command(cmd, description, isDefault, aliases, deprecated); } handlers[parsedCommand.cmd] = { original: cmd, description, handler, builder: builder || {}, middlewares, deprecated, demanded: parsedCommand.demanded, optional: parsedCommand.optional, }; if (isDefault) defaultCommand = handlers[parsedCommand.cmd]; } }; self.addDirectory = function addDirectory(dir, context, req, callerFile, opts) { opts = opts || {}; if (typeof opts.recurse !== 'boolean') opts.recurse = false; if (!Array.isArray(opts.extensions)) opts.extensions = ['js']; const parentVisit = typeof opts.visit === 'function' ? opts.visit : (o) => o; opts.visit = function visit(obj, joined, filename) { const visited = parentVisit(obj, joined, filename); if (visited) { if (~context.files.indexOf(joined)) return visited; context.files.push(joined); self.addHandler(visited); } return visited; }; shim.requireDirectory({ require: req, filename: callerFile }, dir, opts); }; function moduleName(obj) { const mod = whichModule(obj); if (!mod) throw new Error(`No command name given for module: ${shim.inspect(obj)}`); return commandFromFilename(mod.filename); } function commandFromFilename(filename) { return shim.path.basename(filename, shim.path.extname(filename)); } function extractDesc({ describe, description, desc, }) { for (const test of [describe, description, desc]) { if (typeof test === 'string' || test === false) return test; assertNotStrictEqual(test, true, shim); } return false; } self.getCommands = () => Object.keys(handlers).concat(Object.keys(aliasMap)); self.getCommandHandlers = () => handlers; self.hasDefaultCommand = () => !!defaultCommand; self.runCommand = function runCommand(command, yargs, parsed, commandIndex) { let aliases = parsed.aliases; const commandHandler = handlers[command] || handlers[aliasMap[command]] || defaultCommand; const currentContext = yargs.getContext(); let numFiles = currentContext.files.length; const parentCommands = currentContext.commands.slice(); let innerArgv = parsed.argv; let positionalMap = {}; if (command) { currentContext.commands.push(command); currentContext.fullCommands.push(commandHandler.original); } const builder = commandHandler.builder; if (isCommandBuilderCallback(builder)) { const builderOutput = builder(yargs.reset(parsed.aliases)); const innerYargs = isYargsInstance(builderOutput) ? builderOutput : yargs; if (shouldUpdateUsage(innerYargs)) { innerYargs .getUsageInstance() .usage(usageFromParentCommandsCommandHandler(parentCommands, commandHandler), commandHandler.description); } innerArgv = innerYargs._parseArgs(null, null, true, commandIndex); aliases = innerYargs.parsed.aliases; } else if (isCommandBuilderOptionDefinitions(builder)) { const innerYargs = yargs.reset(parsed.aliases); if (shouldUpdateUsage(innerYargs)) { innerYargs .getUsageInstance() .usage(usageFromParentCommandsCommandHandler(parentCommands, commandHandler), commandHandler.description); } Object.keys(commandHandler.builder).forEach(key => { innerYargs.option(key, builder[key]); }); innerArgv = innerYargs._parseArgs(null, null, true, commandIndex); aliases = innerYargs.parsed.aliases; } if (!yargs._hasOutput()) { positionalMap = populatePositionals(commandHandler, innerArgv, currentContext); } const middlewares = globalMiddleware .slice(0) .concat(commandHandler.middlewares); applyMiddleware(innerArgv, yargs, middlewares, true); if (!yargs._hasOutput()) { yargs._runValidation(innerArgv, aliases, positionalMap, yargs.parsed.error, !command); } if (commandHandler.handler && !yargs._hasOutput()) { yargs._setHasOutput(); const populateDoubleDash = !!yargs.getOptions().configuration['populate--']; yargs._postProcess(innerArgv, populateDoubleDash); innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false); let handlerResult; if (isPromise(innerArgv)) { handlerResult = innerArgv.then(argv => commandHandler.handler(argv)); } else { handlerResult = commandHandler.handler(innerArgv); } const handlerFinishCommand = yargs.getHandlerFinishCommand(); if (isPromise(handlerResult)) { yargs.getUsageInstance().cacheHelpMessage(); handlerResult .then(value => { if (handlerFinishCommand) { handlerFinishCommand(value); } }) .catch(error => { try { yargs.getUsageInstance().fail(null, error); } catch (err) { } }) .then(() => { yargs.getUsageInstance().clearCachedHelpMessage(); }); } else { if (handlerFinishCommand) { handlerFinishCommand(handlerResult); } } } if (command) { currentContext.commands.pop(); currentContext.fullCommands.pop(); } numFiles = currentContext.files.length - numFiles; if (numFiles > 0) currentContext.files.splice(numFiles * -1, numFiles); return innerArgv; }; function shouldUpdateUsage(yargs) { return (!yargs.getUsageInstance().getUsageDisabled() && yargs.getUsageInstance().getUsage().length === 0); } function usageFromParentCommandsCommandHandler(parentCommands, commandHandler) { const c = DEFAULT_MARKER.test(commandHandler.original) ? commandHandler.original.replace(DEFAULT_MARKER, '').trim() : commandHandler.original; const pc = parentCommands.filter(c => { return !DEFAULT_MARKER.test(c); }); pc.push(c); return `$0 ${pc.join(' ')}`; } self.runDefaultBuilderOn = function (yargs) { assertNotStrictEqual(defaultCommand, undefined, shim); if (shouldUpdateUsage(yargs)) { const commandString = DEFAULT_MARKER.test(defaultCommand.original) ? defaultCommand.original : defaultCommand.original.replace(/^[^[\]<>]*/, '$0 '); yargs.getUsageInstance().usage(commandString, defaultCommand.description); } const builder = defaultCommand.builder; if (isCommandBuilderCallback(builder)) { builder(yargs); } else if (!isCommandBuilderDefinition(builder)) { Object.keys(builder).forEach(key => { yargs.option(key, builder[key]); }); } }; function populatePositionals(commandHandler, argv, context) { argv._ = argv._.slice(context.commands.length); const demanded = commandHandler.demanded.slice(0); const optional = commandHandler.optional.slice(0); const positionalMap = {}; validation.positionalCount(demanded.length, argv._.length); while (demanded.length) { const demand = demanded.shift(); populatePositional(demand, argv, positionalMap); } while (optional.length) { const maybe = optional.shift(); populatePositional(maybe, argv, positionalMap); } argv._ = context.commands.concat(argv._.map(a => '' + a)); postProcessPositionals(argv, positionalMap, self.cmdToParseOptions(commandHandler.original)); return positionalMap; } function populatePositional(positional, argv, positionalMap) { const cmd = positional.cmd[0]; if (positional.variadic) { positionalMap[cmd] = argv._.splice(0).map(String); } else { if (argv._.length) positionalMap[cmd] = [String(argv._.shift())]; } } function postProcessPositionals(argv, positionalMap, parseOptions) { const options = Object.assign({}, yargs.getOptions()); options.default = Object.assign(parseOptions.default, options.default); for (const key of Object.keys(parseOptions.alias)) { options.alias[key] = (options.alias[key] || []).concat(parseOptions.alias[key]); } options.array = options.array.concat(parseOptions.array); options.config = {}; const unparsed = []; Object.keys(positionalMap).forEach(key => { positionalMap[key].map(value => { if (options.configuration['unknown-options-as-args']) options.key[key] = true; unparsed.push(`--${key}`); unparsed.push(value); }); }); if (!unparsed.length) return; const config = Object.assign({}, options.configuration, { 'populate--': true, }); const parsed = shim.Parser.detailed(unparsed, Object.assign({}, options, { configuration: config, })); if (parsed.error) { yargs.getUsageInstance().fail(parsed.error.message, parsed.error); } else { const positionalKeys = Object.keys(positionalMap); Object.keys(positionalMap).forEach(key => { positionalKeys.push(...parsed.aliases[key]); }); Object.keys(parsed.argv).forEach(key => { if (positionalKeys.indexOf(key) !== -1) { if (!positionalMap[key]) positionalMap[key] = parsed.argv[key]; argv[key] = parsed.argv[key]; } }); } } self.cmdToParseOptions = function (cmdString) { const parseOptions = { array: [], default: {}, alias: {}, demand: {}, }; const parsed = parseCommand(cmdString); parsed.demanded.forEach(d => { const [cmd, ...aliases] = d.cmd; if (d.variadic) { parseOptions.array.push(cmd); parseOptions.default[cmd] = []; } parseOptions.alias[cmd] = aliases; parseOptions.demand[cmd] = true; }); parsed.optional.forEach(o => { const [cmd, ...aliases] = o.cmd; if (o.variadic) { parseOptions.array.push(cmd); parseOptions.default[cmd] = []; } parseOptions.alias[cmd] = aliases; }); return parseOptions; }; self.reset = () => { handlers = {}; aliasMap = {}; defaultCommand = undefined; return self; }; const frozens = []; self.freeze = () => { frozens.push({ handlers, aliasMap, defaultCommand, }); }; self.unfreeze = () => { const frozen = frozens.pop(); assertNotStrictEqual(frozen, undefined, shim); ({ handlers, aliasMap, defaultCommand } = frozen); }; return self; } function isCommandBuilderDefinition(builder) { return (typeof builder === 'object' && !!builder.builder && typeof builder.handler === 'function'); } function isCommandAndAliases(cmd) { if (cmd.every(c => typeof c === 'string')) { return true; } else { return false; } } function isCommandBuilderCallback(builder) { return typeof builder === 'function'; } function isCommandBuilderOptionDefinitions(builder) { return typeof builder === 'object'; } function isCommandHandlerDefinition(cmd) { return typeof cmd === 'object' && !Array.isArray(cmd); } function setBlocking(blocking) { if (typeof process === 'undefined') return; [process.stdout, process.stderr].forEach(_stream => { const stream = _stream; if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === 'function') { stream._handle.setBlocking(blocking); } }); } function usage(yargs, y18n, shim) { const __ = y18n.__; const self = {}; const fails = []; self.failFn = function failFn(f) { fails.push(f); }; let failMessage = null; let showHelpOnFail = true; self.showHelpOnFail = function showHelpOnFailFn(arg1 = true, arg2) { function parseFunctionArgs() { return typeof arg1 === 'string' ? [true, arg1] : [arg1, arg2]; } const [enabled, message] = parseFunctionArgs(); failMessage = message; showHelpOnFail = enabled; return self; }; let failureOutput = false; self.fail = function fail(msg, err) { const logger = yargs._getLoggerInstance(); if (fails.length) { for (let i = fails.length - 1; i >= 0; --i) { fails[i](msg, err, self); } } else { if (yargs.getExitProcess()) setBlocking(true); if (!failureOutput) { failureOutput = true; if (showHelpOnFail) { yargs.showHelp('error'); logger.error(); } if (msg || err) logger.error(msg || err); if (failMessage) { if (msg || err) logger.error(''); logger.error(failMessage); } } err = err || new YError(msg); if (yargs.getExitProcess()) { return yargs.exit(1); } else if (yargs._hasParseCallback()) { return yargs.exit(1, err); } else { throw err; } } }; let usages = []; let usageDisabled = false; self.usage = (msg, description) => { if (msg === null) { usageDisabled = true; usages = []; return self; } usageDisabled = false; usages.push([msg, description || '']); return self; }; self.getUsage = () => { return usages; }; self.getUsageDisabled = () => { return usageDisabled; }; self.getPositionalGroupName = () => { return __('Positionals:'); }; let examples = []; self.example = (cmd, description) => { examples.push([cmd, description || '']); }; let commands = []; self.command = function command(cmd, description, isDefault, aliases, deprecated = false) { if (isDefault) { commands = commands.map(cmdArray => { cmdArray[2] = false; return cmdArray; }); } commands.push([cmd, description || '', isDefault, aliases, deprecated]); }; self.getCommands = () => commands; let descriptions = {}; self.describe = function describe(keyOrKeys, desc) { if (Array.isArray(keyOrKeys)) { keyOrKeys.forEach(k => { self.describe(k, desc); }); } else if (typeof keyOrKeys === 'object') { Object.keys(keyOrKeys).forEach(k => { self.describe(k, keyOrKeys[k]); }); } else { descriptions[keyOrKeys] = desc; } }; self.getDescriptions = () => descriptions; let epilogs = []; self.epilog = msg => { epilogs.push(msg); }; let wrapSet = false; let wrap; self.wrap = cols => { wrapSet = true; wrap = cols; }; function getWrap() { if (!wrapSet) { wrap = windowWidth(); wrapSet = true; } return wrap; } const deferY18nLookupPrefix = '__yargsString__:'; self.deferY18nLookup = str => deferY18nLookupPrefix + str; self.help = function help() { if (cachedHelpMessage) return cachedHelpMessage; normalizeAliases(); const base$0 = yargs.customScriptName ? yargs.$0 : shim.path.basename(yargs.$0); const demandedOptions = yargs.getDemandedOptions(); const demandedCommands = yargs.getDemandedCommands(); const deprecatedOptions = yargs.getDeprecatedOptions(); const groups = yargs.getGroups(); const options = yargs.getOptions(); let keys = []; keys = keys.concat(Object.keys(descriptions)); keys = keys.concat(Object.keys(demandedOptions)); keys = keys.concat(Object.keys(demandedCommands)); keys = keys.concat(Object.keys(options.default)); keys = keys.filter(filterHiddenOptions); keys = Object.keys(keys.reduce((acc, key) => { if (key !== '_') acc[key] = true; return acc; }, {})); const theWrap = getWrap(); const ui = shim.cliui({ width: theWrap, wrap: !!theWrap, }); if (!usageDisabled) { if (usages.length) { usages.forEach(usage => { ui.div(`${usage[0].replace(/\$0/g, base$0)}`); if (usage[1]) { ui.div({ text: `${usage[1]}`, padding: [1, 0, 0, 0] }); } }); ui.div(); } else if (commands.length) { let u = null; if (demandedCommands._) { u = `${base$0} <${__('command')}>\n`; } else { u = `${base$0} [${__('command')}]\n`; } ui.div(`${u}`); } } if (commands.length) { ui.div(__('Commands:')); const context = yargs.getContext(); const parentCommands = context.commands.length ? `${context.commands.join(' ')} ` : ''; if (yargs.getParserConfiguration()['sort-commands'] === true) { commands = commands.sort((a, b) => a[0].localeCompare(b[0])); } commands.forEach(command => { const commandString = `${base$0} ${parentCommands}${command[0].replace(/^\$0 ?/, '')}`; ui.span({ text: commandString, padding: [0, 2, 0, 2], width: maxWidth(commands, theWrap, `${base$0}${parentCommands}`) + 4, }, { text: command[1] }); const hints = []; if (command[2]) hints.push(`[${__('default')}]`); if (command[3] && command[3].length) { hints.push(`[${__('aliases:')} ${command[3].join(', ')}]`); } if (command[4]) { if (typeof command[4] === 'string') { hints.push(`[${__('deprecated: %s', command[4])}]`); } else { hints.push(`[${__('deprecated')}]`); } } if (hints.length) { ui.div({ text: hints.join(' '), padding: [0, 0, 0, 2], align: 'right', }); } else { ui.div(); } }); ui.div(); } const aliasKeys = (Object.keys(options.alias) || []).concat(Object.keys(yargs.parsed.newAliases) || []); keys = keys.filter(key => !yargs.parsed.newAliases[key] && aliasKeys.every(alias => (options.alias[alias] || []).indexOf(key) === -1)); const defaultGroup = __('Options:'); if (!groups[defaultGroup]) groups[defaultGroup] = []; addUngroupedKeys(keys, options.alias, groups, defaultGroup); const isLongSwitch = (sw) => /^--/.test(getText(sw)); const displayedGroups = Object.keys(groups) .filter(groupName => groups[groupName].length > 0) .map(groupName => { const normalizedKeys = groups[groupName] .filter(filterHiddenOptions) .map(key => { if (~aliasKeys.indexOf(key)) return key; for (let i = 0, aliasKey; (aliasKey = aliasKeys[i]) !== undefined; i++) { if (~(options.alias[aliasKey] || []).indexOf(key)) return aliasKey; } return key; }); return { groupName, normalizedKeys }; }) .filter(({ normalizedKeys }) => normalizedKeys.length > 0) .map(({ groupName, normalizedKeys }) => { const switches = normalizedKeys.reduce((acc, key) => { acc[key] = [key] .concat(options.alias[key] || []) .map(sw => { if (groupName === self.getPositionalGroupName()) return sw; else { return ((/^[0-9]$/.test(sw) ? ~options.boolean.indexOf(key) ? '-' : '--' : sw.length > 1 ? '--' : '-') + sw); } }) .sort((sw1, sw2) => isLongSwitch(sw1) === isLongSwitch(sw2) ? 0 : isLongSwitch(sw1) ? 1 : -1) .join(', '); return acc; }, {}); return { groupName, normalizedKeys, switches }; }); const shortSwitchesUsed = displayedGroups .filter(({ groupName }) => groupName !== self.getPositionalGroupName()) .some(({ normalizedKeys, switches }) => !normalizedKeys.every(key => isLongSwitch(switches[key]))); if (shortSwitchesUsed) { displayedGroups .filter(({ groupName }) => groupName !== self.getPositionalGroupName()) .forEach(({ normalizedKeys, switches }) => { normalizedKeys.forEach(key => { if (isLongSwitch(switches[key])) { switches[key] = addIndentation(switches[key], '-x, '.length); } }); }); } displayedGroups.forEach(({ groupName, normalizedKeys, switches }) => { ui.div(groupName); normalizedKeys.forEach(key => { const kswitch = switches[key]; let desc = descriptions[key] || ''; let type = null; if (~desc.lastIndexOf(deferY18nLookupPrefix)) desc = __(desc.substring(deferY18nLookupPrefix.length)); if (~options.boolean.indexOf(key)) type = `[${__('boolean')}]`; if (~options.count.indexOf(key)) type = `[${__('count')}]`; if (~options.string.indexOf(key)) type = `[${__('string')}]`; if (~options.normalize.indexOf(key)) type = `[${__('string')}]`; if (~options.array.indexOf(key)) type = `[${__('array')}]`; if (~options.number.indexOf(key)) type = `[${__('number')}]`; const deprecatedExtra = (deprecated) => typeof deprecated === 'string' ? `[${__('deprecated: %s', deprecated)}]` : `[${__('deprecated')}]`; const extra = [ key in deprecatedOptions ? deprecatedExtra(deprecatedOptions[key]) : null, type, key in demandedOptions ? `[${__('required')}]` : null, options.choices && options.choices[key] ? `[${__('choices:')} ${self.stringifiedValues(options.choices[key])}]` : null, defaultString(options.default[key], options.defaultDescription[key]), ] .filter(Boolean) .join(' '); ui.span({ text: getText(kswitch), padding: [0, 2, 0, 2 + getIndentation(kswitch)], width: maxWidth(switches, theWrap) + 4, }, desc); if (extra) ui.div({ text: extra, padding: [0, 0, 0, 2], align: 'right' }); else ui.div(); }); ui.div(); }); if (examples.length) { ui.div(__('Examples:')); examples.forEach(example => { example[0] = example[0].replace(/\$0/g, base$0); }); examples.forEach(example => { if (example[1] === '') { ui.div({ text: example[0], padding: [0, 2, 0, 2], }); } else { ui.div({ text: example[0], padding: [0, 2, 0, 2], width: maxWidth(examples, theWrap) + 4, }, { text: example[1], }); } }); ui.div(); } if (epilogs.length > 0) { const e = epilogs .map(epilog => epilog.replace(/\$0/g, base$0)) .join('\n'); ui.div(`${e}\n`); } return ui.toString().replace(/\s*$/, ''); }; function maxWidth(table, theWrap, modifier) { let width = 0; if (!Array.isArray(table)) { table = Object.values(table).map(v => [v]); } table.forEach(v => { width = Math.max(shim.stringWidth(modifier ? `${modifier} ${getText(v[0])}` : getText(v[0])) + getIndentation(v[0]), width); }); if (theWrap) width = Math.min(width, parseInt((theWrap * 0.5).toString(), 10)); return width; } function normalizeAliases() { const demandedOptions = yargs.getDemandedOptions(); const options = yargs.getOptions(); (Object.keys(options.alias) || []).forEach(key => { options.alias[key].forEach(alias => { if (descriptions[alias]) self.describe(key, descriptions[alias]); if (alias in demandedOptions) yargs.demandOption(key, demandedOptions[alias]); if (~options.boolean.indexOf(alias)) yargs.boolean(key); if (~options.count.indexOf(alias)) yargs.count(key); if (~options.string.indexOf(alias)) yargs.string(key); if (~options.normalize.indexOf(alias)) yargs.normalize(key); if (~options.array.indexOf(alias)) yargs.array(key); if (~options.number.indexOf(alias)) yargs.number(key); }); }); } let cachedHelpMessage; self.cacheHelpMessage = function () { cachedHelpMessage = this.help(); }; self.clearCachedHelpMessage = function () { cachedHelpMessage = undefined; }; function addUngroupedKeys(keys, aliases, groups, defaultGroup) { let groupedKeys = []; let toCheck = null; Object.keys(groups).forEach(group => { groupedKeys = groupedKeys.concat(groups[group]); }); keys.forEach(key => { toCheck = [key].concat(aliases[key]); if (!toCheck.some(k => groupedKeys.indexOf(k) !== -1)) { groups[defaultGroup].push(key); } }); return groupedKeys; } function filterHiddenOptions(key) { return (yargs.getOptions().hiddenOptions.indexOf(key) < 0 || yargs.parsed.argv[yargs.getOptions().showHiddenOpt]); } self.showHelp = (level) => { const logger = yargs._getLoggerInstance(); if (!level) level = 'error'; const emit = typeof level === 'function' ? level : logger[level]; emit(self.help()); }; self.functionDescription = fn => { const description = fn.name ? shim.Parser.decamelize(fn.name, '-') : __('generated-value'); return ['(', description, ')'].join(''); }; self.stringifiedValues = function stringifiedValues(values, separator) { let string = ''; const sep = separator || ', '; const array = [].concat(values); if (!values || !array.length) return string; array.forEach(value => { if (string.length) string += sep; string += JSON.stringify(value); }); return string; }; function defaultString(value, defaultDescription) { let string = `[${__('default:')} `; if (value === undefined && !defaultDescription) return null; if (defaultDescription) { string += defaultDescription; } else { switch (typeof value) { case 'string': string += `"${value}"`; break; case 'object': string += JSON.stringify(value); break; default: string += value; } } return `${string}]`; } function windowWidth() { const maxWidth = 80; if (shim.process.stdColumns) { return Math.min(maxWidth, shim.process.stdColumns); } else { return maxWidth; } } let version = null; self.version = ver => { version = ver; }; self.showVersion = () => { const logger = yargs._getLoggerInstance(); logger.log(version); }; self.reset = function reset(localLookup) { failMessage = null; failureOutput = false; usages = []; usageDisabled = false; epilogs = []; examples = []; commands = []; descriptions = objFilter(descriptions, k => !localLookup[k]); return self; }; const frozens = []; self.freeze = function freeze() { frozens.push({ failMessage, failureOutput, usages, usageDisabled, epilogs, examples, commands, descriptions, }); }; self.unfreeze = function unfreeze() { const frozen = frozens.pop(); assertNotStrictEqual(frozen, undefined, shim); ({ failMessage, failureOutput, usages, usageDisabled, epilogs, examples, commands, descriptions, } = frozen); }; return self; } function isIndentedText(text) { return typeof text === 'object'; } function addIndentation(text, indent) { return isIndentedText(text) ? { text: text.text, indentation: text.indentation + indent } : { text, indentation: indent }; } function getIndentation(text) { return isIndentedText(text) ? text.indentation : 0; } function getText(text) { return isIndentedText(text) ? text.text : text; } const completionShTemplate = `###-begin-{{app_name}}-completions-### # # yargs command completion script # # Installation: {{app_path}} {{completion_command}} >> ~/.bashrc # or {{app_path}} {{completion_command}} >> ~/.bash_profile on OSX. # _yargs_completions() { local cur_word args type_list cur_word="\${COMP_WORDS[COMP_CWORD]}" args=("\${COMP_WORDS[@]}") # ask yargs to generate completions. type_list=$({{app_path}} --get-yargs-completions "\${args[@]}") COMPREPLY=( $(compgen -W "\${type_list}" -- \${cur_word}) ) # if no match was found, fall back to filename completion if [ \${#COMPREPLY[@]} -eq 0 ]; then COMPREPLY=() fi return 0 } complete -o default -F _yargs_completions {{app_name}} ###-end-{{app_name}}-completions-### `; const completionZshTemplate = `###-begin-{{app_name}}-completions-### # # yargs command completion script # # Installation: {{app_path}} {{completion_command}} >> ~/.zshrc # or {{app_path}} {{completion_command}} >> ~/.zsh_profile on OSX. # _{{app_name}}_yargs_completions() { local reply local si=$IFS IFS=$'\n' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" {{app_path}} --get-yargs-completions "\${words[@]}")) IFS=$si _describe 'values' reply } compdef _{{app_name}}_yargs_completions {{app_name}} ###-end-{{app_name}}-completions-### `; function completion(yargs, usage, command, shim) { const self = { completionKey: 'get-yargs-completions', }; let aliases; self.setParsed = function setParsed(parsed) { aliases = parsed.aliases; }; const zshShell = (shim.getEnv('SHELL') && shim.getEnv('SHELL').indexOf('zsh') !== -1) || (shim.getEnv('ZSH_NAME') && shim.getEnv('ZSH_NAME').indexOf('zsh') !== -1); self.getCompletion = function getCompletion(args, done) { const completions = []; const current = args.length ? args[args.length - 1] : ''; const argv = yargs.parse(args, true); const parentCommands = yargs.getContext().commands; function runCompletionFunction(argv) { assertNotStrictEqual(completionFunction, null, shim); if (isSyncCompletionFunction(completionFunction)) { const result = completionFunction(current, argv); if (isPromise(result)) { return result .then(list => { shim.process.nextTick(() => { done(list); }); }) .catch(err => { shim.process.nextTick(() => { throw err; }); }); } return done(result); } else { return completionFunction(current, argv, completions => { done(completions); }); } } if (completionFunction) { return isPromise(argv) ? argv.then(runCompletionFunction) : runCompletionFunction(argv); } const handlers = command.getCommandHandlers(); for (let i = 0, ii = args.length; i < ii; ++i) { if (handlers[args[i]] && handlers[args[i]].builder) { const builder = handlers[args[i]].builder; if (isCommandBuilderCallback(builder)) { const y = yargs.reset(); builder(y); return y.argv; } } } if (!current.match(/^-/) && parentCommands[parentCommands.length - 1] !== current) { usage.getCommands().forEach(usageCommand => { const commandName = parseCommand(usageCommand[0]).cmd; if (args.indexOf(commandName) === -1) { if (!zshShell) { completions.push(commandName); } else { const desc = usageCommand[1] || ''; completions.push(commandName.replace(/:/g, '\\:') + ':' + desc); } } }); } if (current.match(/^-/) || (current === '' && completions.length === 0)) { const descs = usage.getDescriptions(); const options = yargs.getOptions(); Object.keys(options.key).forEach(key => { const negable = !!options.configuration['boolean-negation'] && options.boolean.includes(key); let keyAndAliases = [key].concat(aliases[key] || []); if (negable) keyAndAliases = keyAndAliases.concat(keyAndAliases.map(key => `no-${key}`)); function completeOptionKey(key) { const notInArgs = keyAndAliases.every(val => args.indexOf(`--${val}`) === -1); if (notInArgs) { const startsByTwoDashes = (s) => /^--/.test(s); const isShortOption = (s) => /^[^0-9]$/.test(s); const dashes = !startsByTwoDashes(current) && isShortOption(key) ? '-' : '--'; if (!zshShell) { completions.push(dashes + key); } else { const desc = descs[key] || ''; completions.push(dashes + `${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`); } }