yargs 15.3.2-beta.0 → 15.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +2 -3
  3. package/README.md +4 -4
  4. package/build/lib/apply-extends.d.ts +2 -2
  5. package/build/lib/apply-extends.js +2 -1
  6. package/build/lib/argsert.js +1 -0
  7. package/build/lib/command.d.ts +64 -0
  8. package/build/lib/command.js +416 -0
  9. package/build/lib/common-types.d.ts +36 -0
  10. package/build/lib/common-types.js +25 -0
  11. package/build/lib/completion-templates.js +1 -0
  12. package/build/lib/completion.d.ts +20 -1
  13. package/build/lib/completion.js +14 -5
  14. package/build/lib/is-promise.js +1 -0
  15. package/build/lib/levenshtein.js +1 -0
  16. package/build/lib/middleware.d.ts +10 -0
  17. package/build/lib/middleware.js +57 -0
  18. package/build/lib/obj-filter.d.ts +1 -2
  19. package/build/lib/obj-filter.js +4 -2
  20. package/build/lib/parse-command.d.ts +10 -1
  21. package/build/lib/parse-command.js +1 -0
  22. package/build/lib/process-argv.js +1 -0
  23. package/build/lib/usage.d.ts +48 -2
  24. package/build/lib/usage.js +19 -5
  25. package/build/lib/validation.d.ts +33 -2
  26. package/build/lib/validation.js +6 -4
  27. package/build/lib/yargs.d.ts +274 -0
  28. package/build/lib/yargs.js +1190 -0
  29. package/build/lib/yerror.js +1 -0
  30. package/package.json +5 -8
  31. package/yargs.js +2 -1291
  32. package/build/lib/type-helpers/command-builder.d.ts +0 -2
  33. package/build/lib/type-helpers/command-builder.js +0 -6
  34. package/build/lib/type-helpers/completion-function.d.ts +0 -2
  35. package/build/lib/type-helpers/completion-function.js +0 -6
  36. package/build/lib/type-helpers/index.d.ts +0 -2
  37. package/build/lib/type-helpers/index.js +0 -7
  38. package/build/lib/types/command-builder.d.ts +0 -5
  39. package/build/lib/types/command-builder.js +0 -2
  40. package/build/lib/types/command-handler.d.ts +0 -4
  41. package/build/lib/types/command-handler.js +0 -2
  42. package/build/lib/types/command-instance.d.ts +0 -7
  43. package/build/lib/types/command-instance.js +0 -2
  44. package/build/lib/types/completion-function.d.ts +0 -8
  45. package/build/lib/types/completion-function.js +0 -2
  46. package/build/lib/types/completion-instance.d.ts +0 -10
  47. package/build/lib/types/completion-instance.js +0 -2
  48. package/build/lib/types/context.d.ts +0 -4
  49. package/build/lib/types/context.js +0 -2
  50. package/build/lib/types/custom-check.d.ts +0 -5
  51. package/build/lib/types/custom-check.js +0 -2
  52. package/build/lib/types/dictionary.d.ts +0 -3
  53. package/build/lib/types/dictionary.js +0 -2
  54. package/build/lib/types/electron-process.d.ts +0 -7
  55. package/build/lib/types/electron-process.js +0 -2
  56. package/build/lib/types/failure-function.d.ts +0 -5
  57. package/build/lib/types/failure-function.js +0 -2
  58. package/build/lib/types/frozen-usage-instance.d.ts +0 -11
  59. package/build/lib/types/frozen-usage-instance.js +0 -2
  60. package/build/lib/types/frozen-validation-instance.d.ts +0 -8
  61. package/build/lib/types/frozen-validation-instance.js +0 -2
  62. package/build/lib/types/index.d.ts +0 -20
  63. package/build/lib/types/index.js +0 -2
  64. package/build/lib/types/key-or-pos.d.ts +0 -1
  65. package/build/lib/types/key-or-pos.js +0 -2
  66. package/build/lib/types/logger-instance.d.ts +0 -2
  67. package/build/lib/types/logger-instance.js +0 -2
  68. package/build/lib/types/options.d.ts +0 -19
  69. package/build/lib/types/options.js +0 -2
  70. package/build/lib/types/parsed-command.d.ts +0 -6
  71. package/build/lib/types/parsed-command.js +0 -2
  72. package/build/lib/types/parser-configuration.d.ts +0 -5
  73. package/build/lib/types/parser-configuration.js +0 -2
  74. package/build/lib/types/positional.d.ts +0 -4
  75. package/build/lib/types/positional.js +0 -2
  76. package/build/lib/types/usage-instance.d.ts +0 -37
  77. package/build/lib/types/usage-instance.js +0 -2
  78. package/build/lib/types/validation-instance.d.ts +0 -28
  79. package/build/lib/types/validation-instance.js +0 -2
  80. package/build/lib/types/yargs-instance.d.ts +0 -44
  81. package/build/lib/types/yargs-instance.js +0 -2
  82. package/lib/command.js +0 -435
  83. package/lib/middleware.js +0 -64
package/lib/command.js DELETED
@@ -1,435 +0,0 @@
1
- 'use strict'
2
-
3
- const inspect = require('util').inspect
4
- const { isPromise } = require('../build/lib/is-promise')
5
- const { applyMiddleware, commandMiddlewareFactory } = require('./middleware')
6
- const { parseCommand } = require('../build/lib/parse-command')
7
- const path = require('path')
8
- const Parser = require('yargs-parser')
9
-
10
- const DEFAULT_MARKER = /(^\*)|(^\$0)/
11
-
12
- // handles parsing positional arguments,
13
- // and populating argv with said positional
14
- // arguments.
15
- module.exports = function command (yargs, usage, validation, globalMiddleware) {
16
- const self = {}
17
- let handlers = {}
18
- let aliasMap = {}
19
- let defaultCommand
20
- globalMiddleware = globalMiddleware || []
21
-
22
- self.addHandler = function addHandler (cmd, description, builder, handler, commandMiddleware) {
23
- let aliases = []
24
- const middlewares = commandMiddlewareFactory(commandMiddleware)
25
- handler = handler || (() => {})
26
-
27
- if (Array.isArray(cmd)) {
28
- aliases = cmd.slice(1)
29
- cmd = cmd[0]
30
- } else if (typeof cmd === 'object') {
31
- let command = (Array.isArray(cmd.command) || typeof cmd.command === 'string') ? cmd.command : moduleName(cmd)
32
- if (cmd.aliases) command = [].concat(command).concat(cmd.aliases)
33
- self.addHandler(command, extractDesc(cmd), cmd.builder, cmd.handler, cmd.middlewares)
34
- return
35
- }
36
-
37
- // allow a module to be provided instead of separate builder and handler
38
- if (typeof builder === 'object' && builder.builder && typeof builder.handler === 'function') {
39
- self.addHandler([cmd].concat(aliases), description, builder.builder, builder.handler, builder.middlewares)
40
- return
41
- }
42
-
43
- // parse positionals out of cmd string
44
- const parsedCommand = parseCommand(cmd)
45
-
46
- // remove positional args from aliases only
47
- aliases = aliases.map(alias => parseCommand(alias).cmd)
48
-
49
- // check for default and filter out '*''
50
- let isDefault = false
51
- const parsedAliases = [parsedCommand.cmd].concat(aliases).filter((c) => {
52
- if (DEFAULT_MARKER.test(c)) {
53
- isDefault = true
54
- return false
55
- }
56
- return true
57
- })
58
-
59
- // standardize on $0 for default command.
60
- if (parsedAliases.length === 0 && isDefault) parsedAliases.push('$0')
61
-
62
- // shift cmd and aliases after filtering out '*'
63
- if (isDefault) {
64
- parsedCommand.cmd = parsedAliases[0]
65
- aliases = parsedAliases.slice(1)
66
- cmd = cmd.replace(DEFAULT_MARKER, parsedCommand.cmd)
67
- }
68
-
69
- // populate aliasMap
70
- aliases.forEach((alias) => {
71
- aliasMap[alias] = parsedCommand.cmd
72
- })
73
-
74
- if (description !== false) {
75
- usage.command(cmd, description, isDefault, aliases)
76
- }
77
-
78
- handlers[parsedCommand.cmd] = {
79
- original: cmd,
80
- description: description,
81
- handler,
82
- builder: builder || {},
83
- middlewares,
84
- demanded: parsedCommand.demanded,
85
- optional: parsedCommand.optional
86
- }
87
-
88
- if (isDefault) defaultCommand = handlers[parsedCommand.cmd]
89
- }
90
-
91
- self.addDirectory = function addDirectory (dir, context, req, callerFile, opts) {
92
- opts = opts || {}
93
- // disable recursion to support nested directories of subcommands
94
- if (typeof opts.recurse !== 'boolean') opts.recurse = false
95
- // exclude 'json', 'coffee' from require-directory defaults
96
- if (!Array.isArray(opts.extensions)) opts.extensions = ['js']
97
- // allow consumer to define their own visitor function
98
- const parentVisit = typeof opts.visit === 'function' ? opts.visit : o => o
99
- // call addHandler via visitor function
100
- opts.visit = function visit (obj, joined, filename) {
101
- const visited = parentVisit(obj, joined, filename)
102
- // allow consumer to skip modules with their own visitor
103
- if (visited) {
104
- // check for cyclic reference
105
- // each command file path should only be seen once per execution
106
- if (~context.files.indexOf(joined)) return visited
107
- // keep track of visited files in context.files
108
- context.files.push(joined)
109
- self.addHandler(visited)
110
- }
111
- return visited
112
- }
113
- require('require-directory')({ require: req, filename: callerFile }, dir, opts)
114
- }
115
-
116
- // lookup module object from require()d command and derive name
117
- // if module was not require()d and no name given, throw error
118
- function moduleName (obj) {
119
- const mod = require('which-module')(obj)
120
- if (!mod) throw new Error(`No command name given for module: ${inspect(obj)}`)
121
- return commandFromFilename(mod.filename)
122
- }
123
-
124
- // derive command name from filename
125
- function commandFromFilename (filename) {
126
- return path.basename(filename, path.extname(filename))
127
- }
128
-
129
- function extractDesc (obj) {
130
- for (let keys = ['describe', 'description', 'desc'], i = 0, l = keys.length, test; i < l; i++) {
131
- test = obj[keys[i]]
132
- if (typeof test === 'string' || typeof test === 'boolean') return test
133
- }
134
- return false
135
- }
136
-
137
- self.getCommands = () => Object.keys(handlers).concat(Object.keys(aliasMap))
138
-
139
- self.getCommandHandlers = () => handlers
140
-
141
- self.hasDefaultCommand = () => !!defaultCommand
142
-
143
- self.runCommand = function runCommand (command, yargs, parsed, commandIndex) {
144
- let aliases = parsed.aliases
145
- const commandHandler = handlers[command] || handlers[aliasMap[command]] || defaultCommand
146
- const currentContext = yargs.getContext()
147
- let numFiles = currentContext.files.length
148
- const parentCommands = currentContext.commands.slice()
149
-
150
- // what does yargs look like after the builder is run?
151
- let innerArgv = parsed.argv
152
- let innerYargs = null
153
- let positionalMap = {}
154
- if (command) {
155
- currentContext.commands.push(command)
156
- currentContext.fullCommands.push(commandHandler.original)
157
- }
158
- if (typeof commandHandler.builder === 'function') {
159
- // a function can be provided, which builds
160
- // up a yargs chain and possibly returns it.
161
- innerYargs = commandHandler.builder(yargs.reset(parsed.aliases))
162
- if (!innerYargs || (typeof innerYargs._parseArgs !== 'function')) {
163
- innerYargs = yargs
164
- }
165
- if (shouldUpdateUsage(innerYargs)) {
166
- innerYargs.getUsageInstance().usage(
167
- usageFromParentCommandsCommandHandler(parentCommands, commandHandler),
168
- commandHandler.description
169
- )
170
- }
171
- innerArgv = innerYargs._parseArgs(null, null, true, commandIndex)
172
- aliases = innerYargs.parsed.aliases
173
- } else if (typeof commandHandler.builder === 'object') {
174
- // as a short hand, an object can instead be provided, specifying
175
- // the options that a command takes.
176
- innerYargs = yargs.reset(parsed.aliases)
177
- if (shouldUpdateUsage(innerYargs)) {
178
- innerYargs.getUsageInstance().usage(
179
- usageFromParentCommandsCommandHandler(parentCommands, commandHandler),
180
- commandHandler.description
181
- )
182
- }
183
- Object.keys(commandHandler.builder).forEach((key) => {
184
- innerYargs.option(key, commandHandler.builder[key])
185
- })
186
- innerArgv = innerYargs._parseArgs(null, null, true, commandIndex)
187
- aliases = innerYargs.parsed.aliases
188
- }
189
-
190
- if (!yargs._hasOutput()) {
191
- positionalMap = populatePositionals(commandHandler, innerArgv, currentContext, yargs)
192
- }
193
-
194
- const middlewares = globalMiddleware.slice(0).concat(commandHandler.middlewares)
195
- applyMiddleware(innerArgv, yargs, middlewares, true)
196
-
197
- // we apply validation post-hoc, so that custom
198
- // checks get passed populated positional arguments.
199
- if (!yargs._hasOutput()) yargs._runValidation(innerArgv, aliases, positionalMap, yargs.parsed.error)
200
-
201
- if (commandHandler.handler && !yargs._hasOutput()) {
202
- yargs._setHasOutput()
203
- // to simplify the parsing of positionals in commands,
204
- // we temporarily populate '--' rather than _, with arguments
205
- const populateDoubleDash = !!yargs.getOptions().configuration['populate--']
206
- if (!populateDoubleDash) yargs._copyDoubleDash(innerArgv)
207
-
208
- innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false)
209
- let handlerResult
210
- if (isPromise(innerArgv)) {
211
- handlerResult = innerArgv.then(argv => commandHandler.handler(argv))
212
- } else {
213
- handlerResult = commandHandler.handler(innerArgv)
214
- }
215
-
216
- const handlerFinishCommand = yargs.getHandlerFinishCommand()
217
- if (isPromise(handlerResult)) {
218
- yargs.getUsageInstance().cacheHelpMessage()
219
- handlerResult
220
- .then(value => {
221
- if (handlerFinishCommand) {
222
- handlerFinishCommand(value)
223
- }
224
- })
225
- .catch(error => {
226
- try {
227
- yargs.getUsageInstance().fail(null, error)
228
- } catch (err) {
229
- // fail's throwing would cause an unhandled rejection.
230
- }
231
- })
232
- .then(() => {
233
- yargs.getUsageInstance().clearCachedHelpMessage()
234
- })
235
- } else {
236
- if (handlerFinishCommand) {
237
- handlerFinishCommand(handlerResult)
238
- }
239
- }
240
- }
241
-
242
- if (command) {
243
- currentContext.commands.pop()
244
- currentContext.fullCommands.pop()
245
- }
246
- numFiles = currentContext.files.length - numFiles
247
- if (numFiles > 0) currentContext.files.splice(numFiles * -1, numFiles)
248
-
249
- return innerArgv
250
- }
251
-
252
- function shouldUpdateUsage (yargs) {
253
- return !yargs.getUsageInstance().getUsageDisabled() &&
254
- yargs.getUsageInstance().getUsage().length === 0
255
- }
256
-
257
- function usageFromParentCommandsCommandHandler (parentCommands, commandHandler) {
258
- const c = DEFAULT_MARKER.test(commandHandler.original) ? commandHandler.original.replace(DEFAULT_MARKER, '').trim() : commandHandler.original
259
- const pc = parentCommands.filter((c) => { return !DEFAULT_MARKER.test(c) })
260
- pc.push(c)
261
- return `$0 ${pc.join(' ')}`
262
- }
263
-
264
- self.runDefaultBuilderOn = function (yargs) {
265
- if (shouldUpdateUsage(yargs)) {
266
- // build the root-level command string from the default string.
267
- const commandString = DEFAULT_MARKER.test(defaultCommand.original)
268
- ? defaultCommand.original : defaultCommand.original.replace(/^[^[\]<>]*/, '$0 ')
269
- yargs.getUsageInstance().usage(
270
- commandString,
271
- defaultCommand.description
272
- )
273
- }
274
- const builder = defaultCommand.builder
275
- if (typeof builder === 'function') {
276
- builder(yargs)
277
- } else {
278
- Object.keys(builder).forEach((key) => {
279
- yargs.option(key, builder[key])
280
- })
281
- }
282
- }
283
-
284
- // transcribe all positional arguments "command <foo> <bar> [apple]"
285
- // onto argv.
286
- function populatePositionals (commandHandler, argv, context, yargs) {
287
- argv._ = argv._.slice(context.commands.length) // nuke the current commands
288
- const demanded = commandHandler.demanded.slice(0)
289
- const optional = commandHandler.optional.slice(0)
290
- const positionalMap = {}
291
-
292
- validation.positionalCount(demanded.length, argv._.length)
293
-
294
- while (demanded.length) {
295
- const demand = demanded.shift()
296
- populatePositional(demand, argv, positionalMap)
297
- }
298
-
299
- while (optional.length) {
300
- const maybe = optional.shift()
301
- populatePositional(maybe, argv, positionalMap)
302
- }
303
-
304
- argv._ = context.commands.concat(argv._)
305
-
306
- postProcessPositionals(argv, positionalMap, self.cmdToParseOptions(commandHandler.original))
307
-
308
- return positionalMap
309
- }
310
-
311
- function populatePositional (positional, argv, positionalMap, parseOptions) {
312
- const cmd = positional.cmd[0]
313
- if (positional.variadic) {
314
- positionalMap[cmd] = argv._.splice(0).map(String)
315
- } else {
316
- if (argv._.length) positionalMap[cmd] = [String(argv._.shift())]
317
- }
318
- }
319
-
320
- // we run yargs-parser against the positional arguments
321
- // applying the same parsing logic used for flags.
322
- function postProcessPositionals (argv, positionalMap, parseOptions) {
323
- // combine the parsing hints we've inferred from the command
324
- // string with explicitly configured parsing hints.
325
- const options = Object.assign({}, yargs.getOptions())
326
- options.default = Object.assign(parseOptions.default, options.default)
327
- options.alias = Object.assign(parseOptions.alias, options.alias)
328
- options.array = options.array.concat(parseOptions.array)
329
- delete options.config // don't load config when processing positionals.
330
-
331
- const unparsed = []
332
- Object.keys(positionalMap).forEach((key) => {
333
- positionalMap[key].map((value) => {
334
- if (options.configuration['unknown-options-as-args']) options.key[key] = true
335
- unparsed.push(`--${key}`)
336
- unparsed.push(value)
337
- })
338
- })
339
-
340
- // short-circuit parse.
341
- if (!unparsed.length) return
342
-
343
- const config = Object.assign({}, options.configuration, {
344
- 'populate--': true
345
- })
346
- const parsed = Parser.detailed(unparsed, Object.assign({}, options, {
347
- configuration: config
348
- }))
349
-
350
- if (parsed.error) {
351
- yargs.getUsageInstance().fail(parsed.error.message, parsed.error)
352
- } else {
353
- // only copy over positional keys (don't overwrite
354
- // flag arguments that were already parsed).
355
- const positionalKeys = Object.keys(positionalMap)
356
- Object.keys(positionalMap).forEach((key) => {
357
- [].push.apply(positionalKeys, parsed.aliases[key])
358
- })
359
-
360
- Object.keys(parsed.argv).forEach((key) => {
361
- if (positionalKeys.indexOf(key) !== -1) {
362
- // any new aliases need to be placed in positionalMap, which
363
- // is used for validation.
364
- if (!positionalMap[key]) positionalMap[key] = parsed.argv[key]
365
- argv[key] = parsed.argv[key]
366
- }
367
- })
368
- }
369
- }
370
-
371
- self.cmdToParseOptions = function (cmdString) {
372
- const parseOptions = {
373
- array: [],
374
- default: {},
375
- alias: {},
376
- demand: {}
377
- }
378
-
379
- const parsed = parseCommand(cmdString)
380
- parsed.demanded.forEach((d) => {
381
- const cmds = d.cmd.slice(0)
382
- const cmd = cmds.shift()
383
- if (d.variadic) {
384
- parseOptions.array.push(cmd)
385
- parseOptions.default[cmd] = []
386
- }
387
- cmds.forEach((c) => {
388
- parseOptions.alias[cmd] = c
389
- })
390
- parseOptions.demand[cmd] = true
391
- })
392
-
393
- parsed.optional.forEach((o) => {
394
- const cmds = o.cmd.slice(0)
395
- const cmd = cmds.shift()
396
- if (o.variadic) {
397
- parseOptions.array.push(cmd)
398
- parseOptions.default[cmd] = []
399
- }
400
- cmds.forEach((c) => {
401
- parseOptions.alias[cmd] = c
402
- })
403
- })
404
-
405
- return parseOptions
406
- }
407
-
408
- self.reset = () => {
409
- handlers = {}
410
- aliasMap = {}
411
- defaultCommand = undefined
412
- return self
413
- }
414
-
415
- // used by yargs.parse() to freeze
416
- // the state of commands such that
417
- // we can apply .parse() multiple times
418
- // with the same yargs instance.
419
- const frozens = []
420
- self.freeze = () => {
421
- const frozen = {}
422
- frozens.push(frozen)
423
- frozen.handlers = handlers
424
- frozen.aliasMap = aliasMap
425
- frozen.defaultCommand = defaultCommand
426
- }
427
- self.unfreeze = () => {
428
- const frozen = frozens.pop()
429
- handlers = frozen.handlers
430
- aliasMap = frozen.aliasMap
431
- defaultCommand = frozen.defaultCommand
432
- }
433
-
434
- return self
435
- }
package/lib/middleware.js DELETED
@@ -1,64 +0,0 @@
1
- 'use strict'
2
-
3
- // hoisted due to circular dependency on command.
4
- module.exports = {
5
- applyMiddleware,
6
- commandMiddlewareFactory,
7
- globalMiddlewareFactory
8
- }
9
- const { isPromise } = require('../build/lib/is-promise')
10
- const { argsert } = require('../build/lib/argsert')
11
-
12
- function globalMiddlewareFactory (globalMiddleware, context) {
13
- return function (callback, applyBeforeValidation = false) {
14
- argsert('<array|function> [boolean]', [callback, applyBeforeValidation], arguments.length)
15
- if (Array.isArray(callback)) {
16
- for (let i = 0; i < callback.length; i++) {
17
- if (typeof callback[i] !== 'function') {
18
- throw Error('middleware must be a function')
19
- }
20
- callback[i].applyBeforeValidation = applyBeforeValidation
21
- }
22
- Array.prototype.push.apply(globalMiddleware, callback)
23
- } else if (typeof callback === 'function') {
24
- callback.applyBeforeValidation = applyBeforeValidation
25
- globalMiddleware.push(callback)
26
- }
27
- return context
28
- }
29
- }
30
-
31
- function commandMiddlewareFactory (commandMiddleware) {
32
- if (!commandMiddleware) return []
33
- return commandMiddleware.map(middleware => {
34
- middleware.applyBeforeValidation = false
35
- return middleware
36
- })
37
- }
38
-
39
- function applyMiddleware (argv, yargs, middlewares, beforeValidation) {
40
- const beforeValidationError = new Error('middleware cannot return a promise when applyBeforeValidation is true')
41
- return middlewares
42
- .reduce((accumulation, middleware) => {
43
- if (middleware.applyBeforeValidation !== beforeValidation) {
44
- return accumulation
45
- }
46
-
47
- if (isPromise(accumulation)) {
48
- return accumulation
49
- .then(initialObj =>
50
- Promise.all([initialObj, middleware(initialObj, yargs)])
51
- )
52
- .then(([initialObj, middlewareObj]) =>
53
- Object.assign(initialObj, middlewareObj)
54
- )
55
- } else {
56
- const result = middleware(argv, yargs)
57
- if (beforeValidation && isPromise(result)) throw beforeValidationError
58
-
59
- return isPromise(result)
60
- ? result.then(middlewareObj => Object.assign(accumulation, middlewareObj))
61
- : Object.assign(accumulation, result)
62
- }
63
- }, argv)
64
- }