Comparing version 17.0.0-candidate.2 to 17.0.0-candidate.3
@@ -6,5 +6,6 @@ import { assertNotStrictEqual, } from './typings/common-types.js'; | ||
import { isYargsInstance, } from './yargs-factory.js'; | ||
import { maybeAsyncResult } from './utils/maybe-async-result.js'; | ||
import whichModule from './utils/which-module.js'; | ||
const DEFAULT_MARKER = /(^\*)|(^\$0)/; | ||
export function command(yargs, usage, validation, globalMiddleware = [], shim) { | ||
export function command(yargs, usage, validation, globalMiddleware, shim) { | ||
const self = {}; | ||
@@ -161,2 +162,3 @@ let handlers = {}; | ||
const middlewares = globalMiddleware | ||
.getMiddleware() | ||
.slice(0) | ||
@@ -167,11 +169,8 @@ .concat(commandHandler.middlewares); | ||
const validation = yargs._runValidation(aliases, positionalMap, yargs.parsed.error, !command); | ||
if (isPromise(innerArgv)) { | ||
innerArgv = innerArgv.then(argv => { | ||
validation(argv); | ||
return argv; | ||
}); | ||
} | ||
else { | ||
validation(innerArgv); | ||
} | ||
innerArgv = maybeAsyncResult(innerArgv, (err) => { | ||
throw err; | ||
}, result => { | ||
validation(result); | ||
return result; | ||
}); | ||
} | ||
@@ -183,15 +182,13 @@ if (commandHandler.handler && !yargs._hasOutput()) { | ||
innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false); | ||
if (isPromise(innerArgv)) { | ||
const innerArgvRef = innerArgv; | ||
innerArgv = innerArgv | ||
.then(argv => commandHandler.handler(argv)) | ||
.then(() => innerArgvRef); | ||
} | ||
else { | ||
const handlerResult = commandHandler.handler(innerArgv); | ||
innerArgv = maybeAsyncResult(innerArgv, (err) => { | ||
throw err; | ||
}, result => { | ||
const handlerResult = commandHandler.handler(result); | ||
if (isPromise(handlerResult)) { | ||
const innerArgvRef = innerArgv; | ||
innerArgv = handlerResult.then(() => innerArgvRef); | ||
return handlerResult.then(() => result); | ||
} | ||
} | ||
else { | ||
return result; | ||
} | ||
}); | ||
yargs.getUsageInstance().cacheHelpMessage(); | ||
@@ -297,3 +294,3 @@ if (isPromise(innerArgv) && !yargs._hasParseCallback()) { | ||
const config = Object.assign({}, options.configuration, { | ||
'populate--': true, | ||
'populate--': false, | ||
}); | ||
@@ -300,0 +297,0 @@ const parsed = shim.Parser.detailed(unparsed, Object.assign({}, options, { |
@@ -6,48 +6,16 @@ import { isCommandBuilderCallback } from './command.js'; | ||
import { parseCommand } from './parse-command.js'; | ||
export 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(null, list); | ||
}); | ||
}) | ||
.catch(err => { | ||
shim.process.nextTick(() => { | ||
done(err, undefined); | ||
}); | ||
}); | ||
} | ||
return done(null, result); | ||
} | ||
else { | ||
return completionFunction(current, argv, completions => { | ||
done(null, completions); | ||
}); | ||
} | ||
} | ||
if (completionFunction) { | ||
return isPromise(argv) | ||
? argv.then(runCompletionFunction) | ||
: runCompletionFunction(argv); | ||
} | ||
const handlers = command.getCommandHandlers(); | ||
export class Completion { | ||
constructor(yargs, usage, command, shim) { | ||
var _a, _b, _c; | ||
this.yargs = yargs; | ||
this.usage = usage; | ||
this.command = command; | ||
this.shim = shim; | ||
this.completionKey = 'get-yargs-completions'; | ||
this.aliases = null; | ||
this.customCompletionFunction = null; | ||
this.zshShell = (_c = (((_a = this.shim.getEnv('SHELL')) === null || _a === void 0 ? void 0 : _a.includes('zsh')) || ((_b = this.shim.getEnv('ZSH_NAME')) === null || _b === void 0 ? void 0 : _b.includes('zsh')))) !== null && _c !== void 0 ? _c : false; | ||
} | ||
defaultCompletion(args, argv, current, done) { | ||
const handlers = this.command.getCommandHandlers(); | ||
for (let i = 0, ii = args.length; i < ii; ++i) { | ||
@@ -57,3 +25,3 @@ if (handlers[args[i]] && handlers[args[i]].builder) { | ||
if (isCommandBuilderCallback(builder)) { | ||
const y = yargs.reset(); | ||
const y = this.yargs.reset(); | ||
builder(y); | ||
@@ -64,8 +32,15 @@ return y.argv; | ||
} | ||
const completions = []; | ||
this.commandCompletions(completions, args, current); | ||
this.optionCompletions(completions, args, argv, current); | ||
done(null, completions); | ||
} | ||
commandCompletions(completions, args, current) { | ||
const parentCommands = this.yargs.getContext().commands; | ||
if (!current.match(/^-/) && | ||
parentCommands[parentCommands.length - 1] !== current) { | ||
usage.getCommands().forEach(usageCommand => { | ||
this.usage.getCommands().forEach(usageCommand => { | ||
const commandName = parseCommand(usageCommand[0]).cmd; | ||
if (args.indexOf(commandName) === -1) { | ||
if (!zshShell) { | ||
if (!this.zshShell) { | ||
completions.push(commandName); | ||
@@ -80,39 +55,89 @@ } | ||
} | ||
} | ||
optionCompletions(completions, args, argv, current) { | ||
if (current.match(/^-/) || (current === '' && completions.length === 0)) { | ||
const descs = usage.getDescriptions(); | ||
const options = yargs.getOptions(); | ||
const options = this.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__:', '')}`); | ||
} | ||
} | ||
if (!this.argsContainKey(args, argv, key, negable)) { | ||
this.completeOptionKey(key, completions, current); | ||
if (negable && !!options.default[key]) | ||
this.completeOptionKey(`no-${key}`, completions, current); | ||
} | ||
completeOptionKey(key); | ||
if (negable && !!options.default[key]) | ||
completeOptionKey(`no-${key}`); | ||
}); | ||
} | ||
done(null, completions); | ||
}; | ||
self.generateCompletionScript = function generateCompletionScript($0, cmd) { | ||
let script = zshShell | ||
} | ||
argsContainKey(args, argv, key, negable) { | ||
if (args.indexOf(`--${key}`) !== -1) | ||
return true; | ||
if (negable && args.indexOf(`--no-${key}`) !== -1) | ||
return true; | ||
if (this.aliases) { | ||
for (const alias of this.aliases[key]) { | ||
if (argv[alias] !== undefined) | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
completeOptionKey(key, completions, current) { | ||
const descs = this.usage.getDescriptions(); | ||
const startsByTwoDashes = (s) => /^--/.test(s); | ||
const isShortOption = (s) => /^[^0-9]$/.test(s); | ||
const dashes = !startsByTwoDashes(current) && isShortOption(key) ? '-' : '--'; | ||
if (!this.zshShell) { | ||
completions.push(dashes + key); | ||
} | ||
else { | ||
const desc = descs[key] || ''; | ||
completions.push(dashes + | ||
`${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`); | ||
} | ||
} | ||
customCompletion(args, argv, current, done) { | ||
assertNotStrictEqual(this.customCompletionFunction, null, this.shim); | ||
if (isSyncCompletionFunction(this.customCompletionFunction)) { | ||
const result = this.customCompletionFunction(current, argv); | ||
if (isPromise(result)) { | ||
return result | ||
.then(list => { | ||
this.shim.process.nextTick(() => { | ||
done(null, list); | ||
}); | ||
}) | ||
.catch(err => { | ||
this.shim.process.nextTick(() => { | ||
done(err, undefined); | ||
}); | ||
}); | ||
} | ||
return done(null, result); | ||
} | ||
else if (isFallbackCompletionFunction(this.customCompletionFunction)) { | ||
return this.customCompletionFunction(current, argv, () => this.defaultCompletion(args, argv, current, done), completions => { | ||
done(null, completions); | ||
}); | ||
} | ||
else { | ||
return this.customCompletionFunction(current, argv, completions => { | ||
done(null, completions); | ||
}); | ||
} | ||
} | ||
getCompletion(args, done) { | ||
const current = args.length ? args[args.length - 1] : ''; | ||
const argv = this.yargs.parse(args, true); | ||
const completionFunction = this.customCompletionFunction | ||
? (argv) => this.customCompletion(args, argv, current, done) | ||
: (argv) => this.defaultCompletion(args, argv, current, done); | ||
return isPromise(argv) | ||
? argv.then(completionFunction) | ||
: completionFunction(argv); | ||
} | ||
generateCompletionScript($0, cmd) { | ||
let script = this.zshShell | ||
? templates.completionZshTemplate | ||
: templates.completionShTemplate; | ||
const name = shim.path.basename($0); | ||
const name = this.shim.path.basename($0); | ||
if ($0.match(/\.js$/)) | ||
@@ -123,11 +148,18 @@ $0 = `./${$0}`; | ||
return script.replace(/{{app_path}}/g, $0); | ||
}; | ||
let completionFunction = null; | ||
self.registerFunction = fn => { | ||
completionFunction = fn; | ||
}; | ||
return self; | ||
} | ||
registerFunction(fn) { | ||
this.customCompletionFunction = fn; | ||
} | ||
setParsed(parsed) { | ||
this.aliases = parsed.aliases; | ||
} | ||
} | ||
export function completion(yargs, usage, command, shim) { | ||
return new Completion(yargs, usage, command, shim); | ||
} | ||
function isSyncCompletionFunction(completionFunction) { | ||
return completionFunction.length < 3; | ||
} | ||
function isFallbackCompletionFunction(completionFunction) { | ||
return completionFunction.length > 3; | ||
} |
import { argsert } from './argsert.js'; | ||
import { isPromise } from './utils/is-promise.js'; | ||
export function globalMiddlewareFactory(globalMiddleware, context) { | ||
return function (callback, applyBeforeValidation = false) { | ||
argsert('<array|function> [boolean]', [callback, applyBeforeValidation], arguments.length); | ||
export class GlobalMiddleware { | ||
constructor(yargs) { | ||
this.globalMiddleware = []; | ||
this.frozens = []; | ||
this.yargs = yargs; | ||
} | ||
addMiddleware(callback, applyBeforeValidation, global = true) { | ||
argsert('<array|function> [boolean] [boolean]', [callback, applyBeforeValidation, global], arguments.length); | ||
if (Array.isArray(callback)) { | ||
@@ -11,12 +16,42 @@ for (let i = 0; i < callback.length; i++) { | ||
} | ||
callback[i].applyBeforeValidation = applyBeforeValidation; | ||
const m = callback[i]; | ||
m.applyBeforeValidation = applyBeforeValidation; | ||
m.global = global; | ||
} | ||
Array.prototype.push.apply(globalMiddleware, callback); | ||
Array.prototype.push.apply(this.globalMiddleware, callback); | ||
} | ||
else if (typeof callback === 'function') { | ||
callback.applyBeforeValidation = applyBeforeValidation; | ||
globalMiddleware.push(callback); | ||
const m = callback; | ||
m.applyBeforeValidation = applyBeforeValidation; | ||
m.global = global; | ||
this.globalMiddleware.push(callback); | ||
} | ||
return context; | ||
}; | ||
return this.yargs; | ||
} | ||
addCoerceMiddleware(callback, option) { | ||
const aliases = this.yargs.getAliases(); | ||
this.globalMiddleware = this.globalMiddleware.filter(m => { | ||
const toCheck = [...(aliases[option] ? aliases[option] : []), option]; | ||
if (!m.option) | ||
return true; | ||
else | ||
return !toCheck.includes(m.option); | ||
}); | ||
callback.option = option; | ||
return this.addMiddleware(callback, true, true); | ||
} | ||
getMiddleware() { | ||
return this.globalMiddleware; | ||
} | ||
freeze() { | ||
this.frozens.push([...this.globalMiddleware]); | ||
} | ||
unfreeze() { | ||
const frozen = this.frozens.pop(); | ||
if (frozen !== undefined) | ||
this.globalMiddleware = frozen; | ||
} | ||
reset() { | ||
this.globalMiddleware = this.globalMiddleware.filter(m => m.global); | ||
} | ||
} | ||
@@ -23,0 +58,0 @@ export function commandMiddlewareFactory(commandMiddleware) { |
@@ -151,28 +151,2 @@ import { argsert } from './argsert.js'; | ||
}; | ||
let checks = []; | ||
self.check = function check(f, global) { | ||
checks.push({ | ||
func: f, | ||
global, | ||
}); | ||
}; | ||
self.customChecks = function customChecks(argv, aliases) { | ||
for (let i = 0, f; (f = checks[i]) !== undefined; i++) { | ||
const func = f.func; | ||
let result = null; | ||
try { | ||
result = func(argv, aliases); | ||
} | ||
catch (err) { | ||
usage.fail(err.message ? err.message : err, err); | ||
continue; | ||
} | ||
if (!result) { | ||
usage.fail(__('Argument check failed: %s', func.toString())); | ||
} | ||
else if (typeof result === 'string' || result instanceof Error) { | ||
usage.fail(result.toString(), result); | ||
} | ||
} | ||
}; | ||
let implied = {}; | ||
@@ -291,3 +265,2 @@ self.implies = function implies(key, value) { | ||
conflicting = objFilter(conflicting, k => !localLookup[k]); | ||
checks = checks.filter(c => c.global); | ||
return self; | ||
@@ -299,3 +272,2 @@ }; | ||
implied, | ||
checks, | ||
conflicting, | ||
@@ -307,5 +279,5 @@ }); | ||
assertNotStrictEqual(frozen, undefined, shim); | ||
({ implied, checks, conflicting } = frozen); | ||
({ implied, conflicting } = frozen); | ||
}; | ||
return self; | ||
} |
@@ -10,4 +10,5 @@ import { command as Command, } from './command.js'; | ||
import { applyExtends } from './utils/apply-extends.js'; | ||
import { applyMiddleware, globalMiddlewareFactory, } from './middleware.js'; | ||
import { applyMiddleware, GlobalMiddleware, } from './middleware.js'; | ||
import { isPromise } from './utils/is-promise.js'; | ||
import { maybeAsyncResult } from './utils/maybe-async-result.js'; | ||
import setBlocking from './utils/set-blocking.js'; | ||
@@ -24,9 +25,8 @@ let shim; | ||
let groups = {}; | ||
const globalMiddleware = []; | ||
let output = ''; | ||
const preservedGroups = {}; | ||
const globalMiddleware = new GlobalMiddleware(self); | ||
let usage; | ||
let validation; | ||
const y18n = shim.y18n; | ||
self.middleware = globalMiddlewareFactory(globalMiddleware, self); | ||
self.scriptName = function (scriptName) { | ||
@@ -126,3 +126,2 @@ self.customScriptName = true; | ||
'demandedCommands', | ||
'coerce', | ||
'deprecatedOptions', | ||
@@ -147,2 +146,3 @@ ]; | ||
completion = Completion(self, usage, command, shim); | ||
globalMiddleware.reset(); | ||
completionCommand = null; | ||
@@ -177,2 +177,3 @@ output = ''; | ||
command.freeze(); | ||
globalMiddleware.freeze(); | ||
} | ||
@@ -203,2 +204,3 @@ function unfreeze() { | ||
command.unfreeze(); | ||
globalMiddleware.unfreeze(); | ||
} | ||
@@ -305,3 +307,38 @@ self.boolean = function (keys) { | ||
argsert('<object|string|array> [function]', [keys, value], arguments.length); | ||
populateParserHintSingleValueDictionary(self.coerce, 'coerce', keys, value); | ||
if (Array.isArray(keys)) { | ||
if (!value) { | ||
throw new YError('coerce callback must be provided'); | ||
} | ||
for (const key of keys) { | ||
self.coerce(key, value); | ||
} | ||
return self; | ||
} | ||
else if (typeof keys === 'object') { | ||
for (const key of Object.keys(keys)) { | ||
self.coerce(key, keys[key]); | ||
} | ||
return self; | ||
} | ||
if (!value) { | ||
throw new YError('coerce callback must be provided'); | ||
} | ||
self.alias(keys, keys); | ||
globalMiddleware.addCoerceMiddleware((argv, yargs) => { | ||
let aliases; | ||
return maybeAsyncResult(() => { | ||
aliases = yargs.getAliases(); | ||
return value(argv[keys]); | ||
}, (err) => { | ||
throw new YError(err.message); | ||
}, (result) => { | ||
argv[keys] = result; | ||
if (aliases[keys]) { | ||
for (const alias of aliases[keys]) { | ||
argv[alias] = result; | ||
} | ||
} | ||
return argv; | ||
}); | ||
}, keys); | ||
return self; | ||
@@ -439,2 +476,5 @@ }; | ||
}; | ||
self.getAliases = () => { | ||
return self.parsed ? self.parsed.aliases : {}; | ||
}; | ||
self.getDemandedOptions = () => { | ||
@@ -496,7 +536,25 @@ argsert([], 0); | ||
}; | ||
self.check = function (f, _global) { | ||
argsert('<function> [boolean]', [f, _global], arguments.length); | ||
validation.check(f, _global !== false); | ||
self.check = function (f, global) { | ||
argsert('<function> [boolean]', [f, global], arguments.length); | ||
self.middleware((argv, yargs) => { | ||
return maybeAsyncResult(() => { | ||
return f(argv, yargs); | ||
}, (err) => { | ||
usage.fail(err.message ? err.message : err.toString(), err); | ||
return argv; | ||
}, (result) => { | ||
if (!result) { | ||
usage.fail(y18n.__('Argument check failed: %s', f.toString())); | ||
} | ||
else if (typeof result === 'string' || result instanceof Error) { | ||
usage.fail(result.toString(), result); | ||
} | ||
return argv; | ||
}); | ||
}, false, global); | ||
return self; | ||
}; | ||
self.middleware = (callback, applyBeforeValidation, global = true) => { | ||
return globalMiddleware.addMiddleware(callback, !!applyBeforeValidation, global); | ||
}; | ||
self.global = function global(globals, global) { | ||
@@ -1099,5 +1157,10 @@ argsert('<string|array> [boolean]', [globals, global], arguments.length); | ||
if (!calledFromCommand) { | ||
argvPromise = applyMiddleware(argv, self, globalMiddleware, true); | ||
argvPromise = applyMiddleware(argv, self, globalMiddleware.getMiddleware(), true); | ||
} | ||
argvPromise = validateAsync(validation, argvPromise !== null && argvPromise !== void 0 ? argvPromise : argv); | ||
if (isPromise(argvPromise) && !calledFromCommand) { | ||
argvPromise = argvPromise.then(() => { | ||
return applyMiddleware(argv, self, globalMiddleware.getMiddleware(), false); | ||
}); | ||
} | ||
} | ||
@@ -1115,12 +1178,8 @@ } | ||
function validateAsync(validation, argv) { | ||
if (isPromise(argv)) { | ||
argv = argv.then(argv => { | ||
validation(argv); | ||
return argv; | ||
}); | ||
} | ||
else { | ||
validation(argv); | ||
} | ||
return argv; | ||
return maybeAsyncResult(argv, (err) => { | ||
throw err; | ||
}, result => { | ||
validation(result); | ||
return result; | ||
}); | ||
} | ||
@@ -1141,3 +1200,3 @@ self._postProcess = function (argv, populateDoubleDash, calledFromCommand, runGlobalMiddleware) { | ||
if (runGlobalMiddleware) { | ||
argv = applyMiddleware(argv, self, globalMiddleware, false); | ||
argv = applyMiddleware(argv, self, globalMiddleware.getMiddleware(), false); | ||
} | ||
@@ -1185,3 +1244,2 @@ return argv; | ||
} | ||
validation.customChecks(argv, aliases); | ||
validation.limitedChoices(argv); | ||
@@ -1188,0 +1246,0 @@ validation.implications(argv); |
{ | ||
"name": "yargs", | ||
"version": "17.0.0-candidate.2", | ||
"version": "17.0.0-candidate.3", | ||
"description": "yargs the modern, pirate-themed, successor to optimist.", | ||
@@ -74,3 +74,2 @@ "main": "./index.cjs", | ||
"rollup-plugin-cleanup": "^3.1.1", | ||
"standardx": "^7.0.0", | ||
"typescript": "^4.0.2", | ||
@@ -82,6 +81,6 @@ "which": "^2.0.0", | ||
"fix": "gts fix && npm run fix:js", | ||
"fix:js": "standardx --fix **/*.mjs && standardx --fix **/*.cjs && standardx --fix ./*.mjs && standardx --fix ./*.cjs", | ||
"fix:js": "eslint . --ext cjs --ext mjs --ext js --fix", | ||
"posttest": "npm run check", | ||
"test": "c8 mocha ./test/*.cjs --require ./test/before.cjs --timeout=12000 --check-leaks", | ||
"test:esm": "c8 mocha ./test/esm/*.mjs --check-leaks", | ||
"test": "c8 mocha --enable-source-maps ./test/*.cjs --require ./test/before.cjs --timeout=12000 --check-leaks", | ||
"test:esm": "c8 mocha --enable-source-maps ./test/esm/*.mjs --check-leaks", | ||
"coverage": "c8 report --check-coverage", | ||
@@ -95,3 +94,3 @@ "prepare": "npm run compile", | ||
"check": "gts lint && npm run check:js", | ||
"check:js": "standardx **/*.mjs && standardx **/*.cjs && standardx ./*.mjs && standardx ./*.cjs", | ||
"check:js": "eslint . --ext cjs --ext mjs --ext js", | ||
"clean": "gts clean" | ||
@@ -104,10 +103,2 @@ }, | ||
"homepage": "https://yargs.js.org/", | ||
"standardx": { | ||
"ignore": [ | ||
"build", | ||
"helpers", | ||
"**/example/**", | ||
"**/platform-shims/esm.mjs" | ||
] | ||
}, | ||
"keywords": [ | ||
@@ -114,0 +105,0 @@ "argument", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
331968
20
78
8134