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/yargs.js CHANGED
@@ -4,1300 +4,11 @@
4
4
  async function requiresNode8OrGreater () {}
5
5
  requiresNode8OrGreater()
6
6
 
7
- const { argsert } = require('./build/lib/argsert')
8
- const fs = require('fs')
9
- const Command = require('./lib/command')
10
- const { completion: Completion } = require('./build/lib/completion')
7
+ const { Yargs, rebase } = require('./build/lib/yargs')
11
8
  const Parser = require('yargs-parser')
12
- const path = require('path')
13
- const { usage: Usage } = require('./build/lib/usage')
14
- const { validation: Validation } = require('./build/lib/validation')
15
- const Y18n = require('y18n')
16
- const { objFilter } = require('./build/lib/obj-filter')
17
- const setBlocking = require('set-blocking')
18
- const { applyExtends } = require('./build/lib/apply-extends')
19
- const { globalMiddlewareFactory } = require('./lib/middleware')
20
- const { YError } = require('./build/lib/yerror')
21
- const processArgv = require('./build/lib/process-argv')
22
9
 
23
10
  exports = module.exports = Yargs
24
- function Yargs (processArgs, cwd, parentRequire) {
25
- processArgs = processArgs || [] // handle calling yargs().
26
-
27
- const self = {}
28
- let command = null
29
- let completion = null
30
- let groups = {}
31
- const globalMiddleware = []
32
- let output = ''
33
- const preservedGroups = {}
34
- let usage = null
35
- let validation = null
36
- let handlerFinishCommand = null
37
-
38
- const y18n = Y18n({
39
- directory: path.resolve(__dirname, './locales'),
40
- updateFiles: false
41
- })
42
-
43
- self.middleware = globalMiddlewareFactory(globalMiddleware, self)
44
-
45
- if (!cwd) cwd = process.cwd()
46
-
47
- self.scriptName = function (scriptName) {
48
- self.customScriptName = true
49
- self.$0 = scriptName
50
- return self
51
- }
52
-
53
- // ignore the node bin, specify this in your
54
- // bin file with #!/usr/bin/env node
55
- if (/\b(node|iojs|electron)(\.exe)?$/.test(process.argv[0])) {
56
- self.$0 = process.argv.slice(1, 2)
57
- } else {
58
- self.$0 = process.argv.slice(0, 1)
59
- }
60
-
61
- self.$0 = self.$0
62
- .map((x, i) => {
63
- const b = rebase(cwd, x)
64
- return x.match(/^(\/|([a-zA-Z]:)?\\)/) && b.length < x.length ? b : x
65
- })
66
- .join(' ').trim()
67
-
68
- if (process.env._ !== undefined && processArgv.getProcessArgvBin() === process.env._) {
69
- self.$0 = process.env._.replace(
70
- `${path.dirname(process.execPath)}/`, ''
71
- )
72
- }
73
-
74
- // use context object to keep track of resets, subcommand execution, etc
75
- // submodules should modify and check the state of context as necessary
76
- const context = { resets: -1, commands: [], fullCommands: [], files: [] }
77
- self.getContext = () => context
78
-
79
- // puts yargs back into an initial state. any keys
80
- // that have been set to "global" will not be reset
81
- // by this action.
82
- let options
83
- self.resetOptions = self.reset = function resetOptions (aliases) {
84
- context.resets++
85
- aliases = aliases || {}
86
- options = options || {}
87
- // put yargs back into an initial state, this
88
- // logic is used to build a nested command
89
- // hierarchy.
90
- const tmpOptions = {}
91
- tmpOptions.local = options.local ? options.local : []
92
- tmpOptions.configObjects = options.configObjects ? options.configObjects : []
93
-
94
- // if a key has been explicitly set as local,
95
- // we should reset it before passing options to command.
96
- const localLookup = {}
97
- tmpOptions.local.forEach((l) => {
98
- localLookup[l] = true
99
- ;(aliases[l] || []).forEach((a) => {
100
- localLookup[a] = true
101
- })
102
- })
103
-
104
- // add all groups not set to local to preserved groups
105
- Object.assign(
106
- preservedGroups,
107
- Object.keys(groups).reduce((acc, groupName) => {
108
- const keys = groups[groupName].filter(key => !(key in localLookup))
109
- if (keys.length > 0) {
110
- acc[groupName] = keys
111
- }
112
- return acc
113
- }, {})
114
- )
115
- // groups can now be reset
116
- groups = {}
117
-
118
- const arrayOptions = [
119
- 'array', 'boolean', 'string', 'skipValidation',
120
- 'count', 'normalize', 'number',
121
- 'hiddenOptions'
122
- ]
123
-
124
- const objectOptions = [
125
- 'narg', 'key', 'alias', 'default', 'defaultDescription',
126
- 'config', 'choices', 'demandedOptions', 'demandedCommands', 'coerce',
127
- 'deprecatedOptions'
128
- ]
129
-
130
- arrayOptions.forEach((k) => {
131
- tmpOptions[k] = (options[k] || []).filter(k => !localLookup[k])
132
- })
133
-
134
- objectOptions.forEach((k) => {
135
- tmpOptions[k] = objFilter(options[k], (k, v) => !localLookup[k])
136
- })
137
-
138
- tmpOptions.envPrefix = options.envPrefix
139
- options = tmpOptions
140
-
141
- // if this is the first time being executed, create
142
- // instances of all our helpers -- otherwise just reset.
143
- usage = usage ? usage.reset(localLookup) : Usage(self, y18n)
144
- validation = validation ? validation.reset(localLookup) : Validation(self, usage, y18n)
145
- command = command ? command.reset() : Command(self, usage, validation, globalMiddleware)
146
- if (!completion) completion = Completion(self, usage, command)
147
-
148
- completionCommand = null
149
- output = ''
150
- exitError = null
151
- hasOutput = false
152
- self.parsed = false
153
-
154
- return self
155
- }
156
- self.resetOptions()
157
-
158
- // temporary hack: allow "freezing" of reset-able state for parse(msg, cb)
159
- const frozens = []
160
- function freeze () {
161
- const frozen = {}
162
- frozens.push(frozen)
163
- frozen.options = options
164
- frozen.configObjects = options.configObjects.slice(0)
165
- frozen.exitProcess = exitProcess
166
- frozen.groups = groups
167
- usage.freeze()
168
- validation.freeze()
169
- command.freeze()
170
- frozen.strict = strict
171
- frozen.strictCommands = strictCommands
172
- frozen.completionCommand = completionCommand
173
- frozen.output = output
174
- frozen.exitError = exitError
175
- frozen.hasOutput = hasOutput
176
- frozen.parsed = self.parsed
177
- frozen.parseFn = parseFn
178
- frozen.parseContext = parseContext
179
- frozen.handlerFinishCommand = handlerFinishCommand
180
- }
181
- function unfreeze () {
182
- const frozen = frozens.pop()
183
- options = frozen.options
184
- options.configObjects = frozen.configObjects
185
- exitProcess = frozen.exitProcess
186
- groups = frozen.groups
187
- output = frozen.output
188
- exitError = frozen.exitError
189
- hasOutput = frozen.hasOutput
190
- self.parsed = frozen.parsed
191
- usage.unfreeze()
192
- validation.unfreeze()
193
- command.unfreeze()
194
- strict = frozen.strict
195
- strictCommands = frozen.strictCommands
196
- completionCommand = frozen.completionCommand
197
- parseFn = frozen.parseFn
198
- parseContext = frozen.parseContext
199
- handlerFinishCommand = frozen.handlerFinishCommand
200
- }
201
-
202
- self.boolean = function (keys) {
203
- argsert('<array|string>', [keys], arguments.length)
204
- populateParserHintArray('boolean', keys)
205
- return self
206
- }
207
-
208
- self.array = function (keys) {
209
- argsert('<array|string>', [keys], arguments.length)
210
- populateParserHintArray('array', keys)
211
- return self
212
- }
213
-
214
- self.number = function (keys) {
215
- argsert('<array|string>', [keys], arguments.length)
216
- populateParserHintArray('number', keys)
217
- return self
218
- }
219
-
220
- self.normalize = function (keys) {
221
- argsert('<array|string>', [keys], arguments.length)
222
- populateParserHintArray('normalize', keys)
223
- return self
224
- }
225
-
226
- self.count = function (keys) {
227
- argsert('<array|string>', [keys], arguments.length)
228
- populateParserHintArray('count', keys)
229
- return self
230
- }
231
-
232
- self.string = function (keys) {
233
- argsert('<array|string>', [keys], arguments.length)
234
- populateParserHintArray('string', keys)
235
- return self
236
- }
237
-
238
- self.requiresArg = function (keys, value) {
239
- argsert('<array|string|object> [number]', [keys], arguments.length)
240
- // If someone configures nargs at the same time as requiresArg,
241
- // nargs should take precedent,
242
- // see: https://github.com/yargs/yargs/pull/1572
243
- // TODO: make this work with aliases, using a check similar to
244
- // checkAllAliases() in yargs-parser.
245
- if (typeof keys === 'string' && options.narg[keys]) {
246
- return self
247
- } else {
248
- populateParserHintObject(self.requiresArg, false, 'narg', keys, NaN)
249
- }
250
- return self
251
- }
252
-
253
- self.skipValidation = function (keys) {
254
- argsert('<array|string>', [keys], arguments.length)
255
- populateParserHintArray('skipValidation', keys)
256
- return self
257
- }
258
-
259
- function populateParserHintArray (type, keys, value) {
260
- keys = [].concat(keys)
261
- keys.forEach((key) => {
262
- key = sanitizeKey(key)
263
- options[type].push(key)
264
- })
265
- }
266
-
267
- self.nargs = function (key, value) {
268
- argsert('<string|object|array> [number]', [key, value], arguments.length)
269
- populateParserHintObject(self.nargs, false, 'narg', key, value)
270
- return self
271
- }
272
-
273
- self.choices = function (key, value) {
274
- argsert('<object|string|array> [string|array]', [key, value], arguments.length)
275
- populateParserHintObject(self.choices, true, 'choices', key, value)
276
- return self
277
- }
278
-
279
- self.alias = function (key, value) {
280
- argsert('<object|string|array> [string|array]', [key, value], arguments.length)
281
- populateParserHintObject(self.alias, true, 'alias', key, value)
282
- return self
283
- }
284
-
285
- // TODO: actually deprecate self.defaults.
286
- self.default = self.defaults = function (key, value, defaultDescription) {
287
- argsert('<object|string|array> [*] [string]', [key, value, defaultDescription], arguments.length)
288
- if (defaultDescription) options.defaultDescription[key] = defaultDescription
289
- if (typeof value === 'function') {
290
- if (!options.defaultDescription[key]) options.defaultDescription[key] = usage.functionDescription(value)
291
- value = value.call()
292
- }
293
- populateParserHintObject(self.default, false, 'default', key, value)
294
- return self
295
- }
296
-
297
- self.describe = function (key, desc) {
298
- argsert('<object|string|array> [string]', [key, desc], arguments.length)
299
- populateParserHintObject(self.describe, false, 'key', key, true)
300
- usage.describe(key, desc)
301
- return self
302
- }
303
-
304
- self.demandOption = function (keys, msg) {
305
- argsert('<object|string|array> [string]', [keys, msg], arguments.length)
306
- populateParserHintObject(self.demandOption, false, 'demandedOptions', keys, msg)
307
- return self
308
- }
309
-
310
- self.coerce = function (keys, value) {
311
- argsert('<object|string|array> [function]', [keys, value], arguments.length)
312
- populateParserHintObject(self.coerce, false, 'coerce', keys, value)
313
- return self
314
- }
315
-
316
- function populateParserHintObject (builder, isArray, type, key, value) {
317
- if (Array.isArray(key)) {
318
- const temp = Object.create(null)
319
- // an array of keys with one value ['x', 'y', 'z'], function parse () {}
320
- key.forEach((k) => {
321
- temp[k] = value
322
- })
323
- builder(temp)
324
- } else if (typeof key === 'object') {
325
- // an object of key value pairs: {'x': parse () {}, 'y': parse() {}}
326
- Object.keys(key).forEach((k) => {
327
- builder(k, key[k])
328
- })
329
- } else {
330
- key = sanitizeKey(key)
331
- // a single key value pair 'x', parse() {}
332
- if (isArray) {
333
- options[type][key] = (options[type][key] || []).concat(value)
334
- } else {
335
- options[type][key] = value
336
- }
337
- }
338
- }
339
-
340
- // TODO(bcoe): in future major versions move more objects towards
341
- // Object.create(null):
342
- function sanitizeKey (key) {
343
- if (key === '__proto__') return '___proto___'
344
- return key
345
- }
346
-
347
- function deleteFromParserHintObject (optionKey) {
348
- // delete from all parsing hints:
349
- // boolean, array, key, alias, etc.
350
- Object.keys(options).forEach((hintKey) => {
351
- const hint = options[hintKey]
352
- if (Array.isArray(hint)) {
353
- if (~hint.indexOf(optionKey)) hint.splice(hint.indexOf(optionKey), 1)
354
- } else if (typeof hint === 'object') {
355
- delete hint[optionKey]
356
- }
357
- })
358
- // now delete the description from usage.js.
359
- delete usage.getDescriptions()[optionKey]
360
- }
361
-
362
- self.config = function config (key, msg, parseFn) {
363
- argsert('[object|string] [string|function] [function]', [key, msg, parseFn], arguments.length)
364
- // allow a config object to be provided directly.
365
- if (typeof key === 'object') {
366
- key = applyExtends(key, cwd, self.getParserConfiguration()['deep-merge-config'])
367
- options.configObjects = (options.configObjects || []).concat(key)
368
- return self
369
- }
370
-
371
- // allow for a custom parsing function.
372
- if (typeof msg === 'function') {
373
- parseFn = msg
374
- msg = null
375
- }
376
-
377
- key = key || 'config'
378
- self.describe(key, msg || usage.deferY18nLookup('Path to JSON config file'))
379
- ;(Array.isArray(key) ? key : [key]).forEach((k) => {
380
- options.config[k] = parseFn || true
381
- })
382
-
383
- return self
384
- }
385
-
386
- self.example = function (cmd, description) {
387
- argsert('<string> [string]', [cmd, description], arguments.length)
388
- usage.example(cmd, description)
389
- return self
390
- }
391
-
392
- self.command = function (cmd, description, builder, handler, middlewares) {
393
- argsert('<string|array|object> [string|boolean] [function|object] [function] [array]', [cmd, description, builder, handler, middlewares], arguments.length)
394
- command.addHandler(cmd, description, builder, handler, middlewares)
395
- return self
396
- }
397
-
398
- self.commandDir = function (dir, opts) {
399
- argsert('<string> [object]', [dir, opts], arguments.length)
400
- const req = parentRequire || require
401
- command.addDirectory(dir, self.getContext(), req, require('get-caller-file')(), opts)
402
- return self
403
- }
404
-
405
- // TODO: deprecate self.demand in favor of
406
- // .demandCommand() .demandOption().
407
- self.demand = self.required = self.require = function demand (keys, max, msg) {
408
- // you can optionally provide a 'max' key,
409
- // which will raise an exception if too many '_'
410
- // options are provided.
411
- if (Array.isArray(max)) {
412
- max.forEach((key) => {
413
- self.demandOption(key, msg)
414
- })
415
- max = Infinity
416
- } else if (typeof max !== 'number') {
417
- msg = max
418
- max = Infinity
419
- }
420
-
421
- if (typeof keys === 'number') {
422
- self.demandCommand(keys, max, msg, msg)
423
- } else if (Array.isArray(keys)) {
424
- keys.forEach((key) => {
425
- self.demandOption(key, msg)
426
- })
427
- } else {
428
- if (typeof msg === 'string') {
429
- self.demandOption(keys, msg)
430
- } else if (msg === true || typeof msg === 'undefined') {
431
- self.demandOption(keys)
432
- }
433
- }
434
-
435
- return self
436
- }
437
-
438
- self.demandCommand = function demandCommand (min, max, minMsg, maxMsg) {
439
- argsert('[number] [number|string] [string|null|undefined] [string|null|undefined]', [min, max, minMsg, maxMsg], arguments.length)
440
-
441
- if (typeof min === 'undefined') min = 1
442
-
443
- if (typeof max !== 'number') {
444
- minMsg = max
445
- max = Infinity
446
- }
447
-
448
- self.global('_', false)
449
-
450
- options.demandedCommands._ = {
451
- min,
452
- max,
453
- minMsg,
454
- maxMsg
455
- }
456
-
457
- return self
458
- }
459
-
460
- self.getDemandedOptions = () => {
461
- argsert([], 0)
462
- return options.demandedOptions
463
- }
464
-
465
- self.getDemandedCommands = () => {
466
- argsert([], 0)
467
- return options.demandedCommands
468
- }
469
-
470
- self.deprecateOption = function deprecateOption (option, message) {
471
- argsert('<string> [string|boolean]', [option, message], arguments.length)
472
- options.deprecatedOptions[option] = message
473
- return self
474
- }
475
-
476
- self.getDeprecatedOptions = () => {
477
- argsert([], 0)
478
- return options.deprecatedOptions
479
- }
480
-
481
- self.implies = function (key, value) {
482
- argsert('<string|object> [number|string|array]', [key, value], arguments.length)
483
- validation.implies(key, value)
484
- return self
485
- }
486
-
487
- self.conflicts = function (key1, key2) {
488
- argsert('<string|object> [string|array]', [key1, key2], arguments.length)
489
- validation.conflicts(key1, key2)
490
- return self
491
- }
492
-
493
- self.usage = function (msg, description, builder, handler) {
494
- argsert('<string|null|undefined> [string|boolean] [function|object] [function]', [msg, description, builder, handler], arguments.length)
495
-
496
- if (description !== undefined) {
497
- // .usage() can be used as an alias for defining
498
- // a default command.
499
- if ((msg || '').match(/^\$0( |$)/)) {
500
- return self.command(msg, description, builder, handler)
501
- } else {
502
- throw new YError('.usage() description must start with $0 if being used as alias for .command()')
503
- }
504
- } else {
505
- usage.usage(msg)
506
- return self
507
- }
508
- }
509
-
510
- self.epilogue = self.epilog = function (msg) {
511
- argsert('<string>', [msg], arguments.length)
512
- usage.epilog(msg)
513
- return self
514
- }
515
-
516
- self.fail = function (f) {
517
- argsert('<function>', [f], arguments.length)
518
- usage.failFn(f)
519
- return self
520
- }
521
-
522
- self.onFinishCommand = function (f) {
523
- argsert('<function>', [f], arguments.length)
524
- handlerFinishCommand = f
525
- return self
526
- }
527
-
528
- self.getHandlerFinishCommand = () => handlerFinishCommand
529
-
530
- self.check = function (f, _global) {
531
- argsert('<function> [boolean]', [f, _global], arguments.length)
532
- validation.check(f, _global !== false)
533
- return self
534
- }
535
-
536
- self.global = function global (globals, global) {
537
- argsert('<string|array> [boolean]', [globals, global], arguments.length)
538
- globals = [].concat(globals)
539
- if (global !== false) {
540
- options.local = options.local.filter(l => globals.indexOf(l) === -1)
541
- } else {
542
- globals.forEach((g) => {
543
- if (options.local.indexOf(g) === -1) options.local.push(g)
544
- })
545
- }
546
- return self
547
- }
548
-
549
- self.pkgConf = function pkgConf (key, rootPath) {
550
- argsert('<string> [string]', [key, rootPath], arguments.length)
551
- let conf = null
552
- // prefer cwd to require-main-filename in this method
553
- // since we're looking for e.g. "nyc" config in nyc consumer
554
- // rather than "yargs" config in nyc (where nyc is the main filename)
555
- const obj = pkgUp(rootPath || cwd)
556
-
557
- // If an object exists in the key, add it to options.configObjects
558
- if (obj[key] && typeof obj[key] === 'object') {
559
- conf = applyExtends(obj[key], rootPath || cwd, self.getParserConfiguration()['deep-merge-config'])
560
- options.configObjects = (options.configObjects || []).concat(conf)
561
- }
562
-
563
- return self
564
- }
565
-
566
- const pkgs = {}
567
- function pkgUp (rootPath) {
568
- const npath = rootPath || '*'
569
- if (pkgs[npath]) return pkgs[npath]
570
- const findUp = require('find-up')
571
-
572
- let obj = {}
573
- try {
574
- let startDir = rootPath || require('require-main-filename')(parentRequire || require)
575
-
576
- // When called in an environment that lacks require.main.filename, such as a jest test runner,
577
- // startDir is already process.cwd(), and should not be shortened.
578
- // Whether or not it is _actually_ a directory (e.g., extensionless bin) is irrelevant, find-up handles it.
579
- if (!rootPath && path.extname(startDir)) {
580
- startDir = path.dirname(startDir)
581
- }
582
-
583
- const pkgJsonPath = findUp.sync('package.json', {
584
- cwd: startDir
585
- })
586
- obj = JSON.parse(fs.readFileSync(pkgJsonPath))
587
- } catch (noop) {}
588
-
589
- pkgs[npath] = obj || {}
590
- return pkgs[npath]
591
- }
592
-
593
- let parseFn = null
594
- let parseContext = null
595
- self.parse = function parse (args, shortCircuit, _parseFn) {
596
- argsert('[string|array] [function|boolean|object] [function]', [args, shortCircuit, _parseFn], arguments.length)
597
- freeze()
598
- if (typeof args === 'undefined') {
599
- const argv = self._parseArgs(processArgs)
600
- const tmpParsed = self.parsed
601
- unfreeze()
602
- // TODO: remove this compatibility hack when we release yargs@15.x:
603
- self.parsed = tmpParsed
604
- return argv
605
- }
606
-
607
- // a context object can optionally be provided, this allows
608
- // additional information to be passed to a command handler.
609
- if (typeof shortCircuit === 'object') {
610
- parseContext = shortCircuit
611
- shortCircuit = _parseFn
612
- }
613
-
614
- // by providing a function as a second argument to
615
- // parse you can capture output that would otherwise
616
- // default to printing to stdout/stderr.
617
- if (typeof shortCircuit === 'function') {
618
- parseFn = shortCircuit
619
- shortCircuit = null
620
- }
621
- // completion short-circuits the parsing process,
622
- // skipping validation, etc.
623
- if (!shortCircuit) processArgs = args
624
-
625
- if (parseFn) exitProcess = false
626
-
627
- const parsed = self._parseArgs(args, shortCircuit)
628
- completion.setParsed(self.parsed)
629
- if (parseFn) parseFn(exitError, parsed, output)
630
- unfreeze()
631
-
632
- return parsed
633
- }
634
-
635
- self._getParseContext = () => parseContext || {}
636
-
637
- self._hasParseCallback = () => !!parseFn
638
-
639
- self.option = self.options = function option (key, opt) {
640
- argsert('<string|object> [object]', [key, opt], arguments.length)
641
- if (typeof key === 'object') {
642
- Object.keys(key).forEach((k) => {
643
- self.options(k, key[k])
644
- })
645
- } else {
646
- if (typeof opt !== 'object') {
647
- opt = {}
648
- }
649
-
650
- options.key[key] = true // track manually set keys.
651
-
652
- if (opt.alias) self.alias(key, opt.alias)
653
-
654
- const deprecate = opt.deprecate || opt.deprecated
655
-
656
- if (deprecate) {
657
- self.deprecateOption(key, deprecate)
658
- }
659
-
660
- const demand = opt.demand || opt.required || opt.require
661
-
662
- // A required option can be specified via "demand: true".
663
- if (demand) {
664
- self.demand(key, demand)
665
- }
666
-
667
- if (opt.demandOption) {
668
- self.demandOption(key, typeof opt.demandOption === 'string' ? opt.demandOption : undefined)
669
- }
670
-
671
- if ('conflicts' in opt) {
672
- self.conflicts(key, opt.conflicts)
673
- }
674
-
675
- if ('default' in opt) {
676
- self.default(key, opt.default)
677
- }
678
-
679
- if ('implies' in opt) {
680
- self.implies(key, opt.implies)
681
- }
682
-
683
- if ('nargs' in opt) {
684
- self.nargs(key, opt.nargs)
685
- }
686
-
687
- if (opt.config) {
688
- self.config(key, opt.configParser)
689
- }
690
-
691
- if (opt.normalize) {
692
- self.normalize(key)
693
- }
694
-
695
- if ('choices' in opt) {
696
- self.choices(key, opt.choices)
697
- }
698
-
699
- if ('coerce' in opt) {
700
- self.coerce(key, opt.coerce)
701
- }
702
-
703
- if ('group' in opt) {
704
- self.group(key, opt.group)
705
- }
706
-
707
- if (opt.boolean || opt.type === 'boolean') {
708
- self.boolean(key)
709
- if (opt.alias) self.boolean(opt.alias)
710
- }
711
-
712
- if (opt.array || opt.type === 'array') {
713
- self.array(key)
714
- if (opt.alias) self.array(opt.alias)
715
- }
716
-
717
- if (opt.number || opt.type === 'number') {
718
- self.number(key)
719
- if (opt.alias) self.number(opt.alias)
720
- }
721
-
722
- if (opt.string || opt.type === 'string') {
723
- self.string(key)
724
- if (opt.alias) self.string(opt.alias)
725
- }
726
-
727
- if (opt.count || opt.type === 'count') {
728
- self.count(key)
729
- }
730
-
731
- if (typeof opt.global === 'boolean') {
732
- self.global(key, opt.global)
733
- }
734
-
735
- if (opt.defaultDescription) {
736
- options.defaultDescription[key] = opt.defaultDescription
737
- }
738
-
739
- if (opt.skipValidation) {
740
- self.skipValidation(key)
741
- }
742
-
743
- const desc = opt.describe || opt.description || opt.desc
744
- self.describe(key, desc)
745
- if (opt.hidden) {
746
- self.hide(key)
747
- }
748
-
749
- if (opt.requiresArg) {
750
- self.requiresArg(key)
751
- }
752
- }
753
-
754
- return self
755
- }
756
- self.getOptions = () => options
757
-
758
- self.positional = function (key, opts) {
759
- argsert('<string> <object>', [key, opts], arguments.length)
760
- if (context.resets === 0) {
761
- throw new YError(".positional() can only be called in a command's builder function")
762
- }
763
-
764
- // .positional() only supports a subset of the configuration
765
- // options available to .option().
766
- const supportedOpts = ['default', 'defaultDescription', 'implies', 'normalize',
767
- 'choices', 'conflicts', 'coerce', 'type', 'describe',
768
- 'desc', 'description', 'alias']
769
- opts = objFilter(opts, (k, v) => {
770
- let accept = supportedOpts.indexOf(k) !== -1
771
- // type can be one of string|number|boolean.
772
- if (k === 'type' && ['string', 'number', 'boolean'].indexOf(v) === -1) accept = false
773
- return accept
774
- })
775
-
776
- // copy over any settings that can be inferred from the command string.
777
- const fullCommand = context.fullCommands[context.fullCommands.length - 1]
778
- const parseOptions = fullCommand ? command.cmdToParseOptions(fullCommand) : {
779
- array: [],
780
- alias: {},
781
- default: {},
782
- demand: {}
783
- }
784
- Object.keys(parseOptions).forEach((pk) => {
785
- if (Array.isArray(parseOptions[pk])) {
786
- if (parseOptions[pk].indexOf(key) !== -1) opts[pk] = true
787
- } else {
788
- if (parseOptions[pk][key] && !(pk in opts)) opts[pk] = parseOptions[pk][key]
789
- }
790
- })
791
- self.group(key, usage.getPositionalGroupName())
792
- return self.option(key, opts)
793
- }
794
-
795
- self.group = function group (opts, groupName) {
796
- argsert('<string|array> <string>', [opts, groupName], arguments.length)
797
- const existing = preservedGroups[groupName] || groups[groupName]
798
- if (preservedGroups[groupName]) {
799
- // we now only need to track this group name in groups.
800
- delete preservedGroups[groupName]
801
- }
802
-
803
- const seen = {}
804
- groups[groupName] = (existing || []).concat(opts).filter((key) => {
805
- if (seen[key]) return false
806
- return (seen[key] = true)
807
- })
808
- return self
809
- }
810
- // combine explicit and preserved groups. explicit groups should be first
811
- self.getGroups = () => Object.assign({}, groups, preservedGroups)
812
-
813
- // as long as options.envPrefix is not undefined,
814
- // parser will apply env vars matching prefix to argv
815
- self.env = function (prefix) {
816
- argsert('[string|boolean]', [prefix], arguments.length)
817
- if (prefix === false) options.envPrefix = undefined
818
- else options.envPrefix = prefix || ''
819
- return self
820
- }
821
-
822
- self.wrap = function (cols) {
823
- argsert('<number|null|undefined>', [cols], arguments.length)
824
- usage.wrap(cols)
825
- return self
826
- }
827
-
828
- let strict = false
829
- self.strict = function (enabled) {
830
- argsert('[boolean]', [enabled], arguments.length)
831
- strict = enabled !== false
832
- return self
833
- }
834
- self.getStrict = () => strict
835
-
836
- let strictCommands = false
837
- self.strictCommands = function (enabled) {
838
- argsert('[boolean]', [enabled], arguments.length)
839
- strictCommands = enabled !== false
840
- return self
841
- }
842
- self.getStrictCommands = () => strictCommands
843
-
844
- let parserConfig = {}
845
- self.parserConfiguration = function parserConfiguration (config) {
846
- argsert('<object>', [config], arguments.length)
847
- parserConfig = config
848
- return self
849
- }
850
- self.getParserConfiguration = () => parserConfig
851
-
852
- self.showHelp = function (level) {
853
- argsert('[string|function]', [level], arguments.length)
854
- if (!self.parsed) self._parseArgs(processArgs) // run parser, if it has not already been executed.
855
- if (command.hasDefaultCommand()) {
856
- context.resets++ // override the restriction on top-level positoinals.
857
- command.runDefaultBuilderOn(self, true)
858
- }
859
- usage.showHelp(level)
860
- return self
861
- }
862
-
863
- let versionOpt = null
864
- self.version = function version (opt, msg, ver) {
865
- const defaultVersionOpt = 'version'
866
- argsert('[boolean|string] [string] [string]', [opt, msg, ver], arguments.length)
867
-
868
- // nuke the key previously configured
869
- // to return version #.
870
- if (versionOpt) {
871
- deleteFromParserHintObject(versionOpt)
872
- usage.version(undefined)
873
- versionOpt = null
874
- }
875
-
876
- if (arguments.length === 0) {
877
- ver = guessVersion()
878
- opt = defaultVersionOpt
879
- } else if (arguments.length === 1) {
880
- if (opt === false) { // disable default 'version' key.
881
- return self
882
- }
883
- ver = opt
884
- opt = defaultVersionOpt
885
- } else if (arguments.length === 2) {
886
- ver = msg
887
- msg = null
888
- }
889
-
890
- versionOpt = typeof opt === 'string' ? opt : defaultVersionOpt
891
- msg = msg || usage.deferY18nLookup('Show version number')
892
-
893
- usage.version(ver || undefined)
894
- self.boolean(versionOpt)
895
- self.describe(versionOpt, msg)
896
- return self
897
- }
898
-
899
- function guessVersion () {
900
- const obj = pkgUp()
901
-
902
- return obj.version || 'unknown'
903
- }
904
-
905
- let helpOpt = null
906
- self.addHelpOpt = self.help = function addHelpOpt (opt, msg) {
907
- const defaultHelpOpt = 'help'
908
- argsert('[string|boolean] [string]', [opt, msg], arguments.length)
909
-
910
- // nuke the key previously configured
911
- // to return help.
912
- if (helpOpt) {
913
- deleteFromParserHintObject(helpOpt)
914
- helpOpt = null
915
- }
916
-
917
- if (arguments.length === 1) {
918
- if (opt === false) return self
919
- }
920
-
921
- // use arguments, fallback to defaults for opt and msg
922
- helpOpt = typeof opt === 'string' ? opt : defaultHelpOpt
923
- self.boolean(helpOpt)
924
- self.describe(helpOpt, msg || usage.deferY18nLookup('Show help'))
925
- return self
926
- }
927
-
928
- const defaultShowHiddenOpt = 'show-hidden'
929
- options.showHiddenOpt = defaultShowHiddenOpt
930
- self.addShowHiddenOpt = self.showHidden = function addShowHiddenOpt (opt, msg) {
931
- argsert('[string|boolean] [string]', [opt, msg], arguments.length)
932
-
933
- if (arguments.length === 1) {
934
- if (opt === false) return self
935
- }
936
-
937
- const showHiddenOpt = typeof opt === 'string' ? opt : defaultShowHiddenOpt
938
- self.boolean(showHiddenOpt)
939
- self.describe(showHiddenOpt, msg || usage.deferY18nLookup('Show hidden options'))
940
- options.showHiddenOpt = showHiddenOpt
941
- return self
942
- }
943
-
944
- self.hide = function hide (key) {
945
- argsert('<string|object>', [key], arguments.length)
946
- options.hiddenOptions.push(key)
947
- return self
948
- }
949
-
950
- self.showHelpOnFail = function showHelpOnFail (enabled, message) {
951
- argsert('[boolean|string] [string]', [enabled, message], arguments.length)
952
- usage.showHelpOnFail(enabled, message)
953
- return self
954
- }
955
-
956
- var exitProcess = true
957
- self.exitProcess = function (enabled) {
958
- argsert('[boolean]', [enabled], arguments.length)
959
- if (typeof enabled !== 'boolean') {
960
- enabled = true
961
- }
962
- exitProcess = enabled
963
- return self
964
- }
965
- self.getExitProcess = () => exitProcess
966
-
967
- var completionCommand = null
968
- self.completion = function (cmd, desc, fn) {
969
- argsert('[string] [string|boolean|function] [function]', [cmd, desc, fn], arguments.length)
970
-
971
- // a function to execute when generating
972
- // completions can be provided as the second
973
- // or third argument to completion.
974
- if (typeof desc === 'function') {
975
- fn = desc
976
- desc = null
977
- }
978
-
979
- // register the completion command.
980
- completionCommand = cmd || completionCommand || 'completion'
981
- if (!desc && desc !== false) {
982
- desc = 'generate completion script'
983
- }
984
- self.command(completionCommand, desc)
985
-
986
- // a function can be provided
987
- if (fn) completion.registerFunction(fn)
988
-
989
- return self
990
- }
991
-
992
- self.showCompletionScript = function ($0, cmd) {
993
- argsert('[string] [string]', [$0, cmd], arguments.length)
994
- $0 = $0 || self.$0
995
- _logger.log(completion.generateCompletionScript($0, cmd || completionCommand || 'completion'))
996
- return self
997
- }
998
-
999
- self.getCompletion = function (args, done) {
1000
- argsert('<array> <function>', [args, done], arguments.length)
1001
- completion.getCompletion(args, done)
1002
- }
1003
-
1004
- self.locale = function (locale) {
1005
- argsert('[string]', [locale], arguments.length)
1006
- if (arguments.length === 0) {
1007
- guessLocale()
1008
- return y18n.getLocale()
1009
- }
1010
- detectLocale = false
1011
- y18n.setLocale(locale)
1012
- return self
1013
- }
1014
-
1015
- self.updateStrings = self.updateLocale = function (obj) {
1016
- argsert('<object>', [obj], arguments.length)
1017
- detectLocale = false
1018
- y18n.updateLocale(obj)
1019
- return self
1020
- }
1021
-
1022
- let detectLocale = true
1023
- self.detectLocale = function (detect) {
1024
- argsert('<boolean>', [detect], arguments.length)
1025
- detectLocale = detect
1026
- return self
1027
- }
1028
- self.getDetectLocale = () => detectLocale
1029
-
1030
- var hasOutput = false
1031
- var exitError = null
1032
- // maybe exit, always capture
1033
- // context about why we wanted to exit.
1034
- self.exit = (code, err) => {
1035
- hasOutput = true
1036
- exitError = err
1037
- if (exitProcess) process.exit(code)
1038
- }
1039
-
1040
- // we use a custom logger that buffers output,
1041
- // so that we can print to non-CLIs, e.g., chat-bots.
1042
- const _logger = {
1043
- log () {
1044
- const args = []
1045
- for (let i = 0; i < arguments.length; i++) args.push(arguments[i])
1046
- if (!self._hasParseCallback()) console.log.apply(console, args)
1047
- hasOutput = true
1048
- if (output.length) output += '\n'
1049
- output += args.join(' ')
1050
- },
1051
- error () {
1052
- const args = []
1053
- for (let i = 0; i < arguments.length; i++) args.push(arguments[i])
1054
- if (!self._hasParseCallback()) console.error.apply(console, args)
1055
- hasOutput = true
1056
- if (output.length) output += '\n'
1057
- output += args.join(' ')
1058
- }
1059
- }
1060
- self._getLoggerInstance = () => _logger
1061
- // has yargs output an error our help
1062
- // message in the current execution context.
1063
- self._hasOutput = () => hasOutput
1064
-
1065
- self._setHasOutput = () => {
1066
- hasOutput = true
1067
- }
1068
-
1069
- let recommendCommands
1070
- self.recommendCommands = function (recommend) {
1071
- argsert('[boolean]', [recommend], arguments.length)
1072
- recommendCommands = typeof recommend === 'boolean' ? recommend : true
1073
- return self
1074
- }
1075
-
1076
- self.getUsageInstance = () => usage
1077
-
1078
- self.getValidationInstance = () => validation
1079
-
1080
- self.getCommandInstance = () => command
1081
-
1082
- self.terminalWidth = () => {
1083
- argsert([], 0)
1084
- return typeof process.stdout.columns !== 'undefined' ? process.stdout.columns : null
1085
- }
1086
-
1087
- Object.defineProperty(self, 'argv', {
1088
- get: () => self._parseArgs(processArgs),
1089
- enumerable: true
1090
- })
1091
-
1092
- self._parseArgs = function parseArgs (args, shortCircuit, _calledFromCommand, commandIndex) {
1093
- let skipValidation = !!_calledFromCommand
1094
- args = args || processArgs
1095
-
1096
- options.__ = y18n.__
1097
- options.configuration = self.getParserConfiguration()
1098
-
1099
- const populateDoubleDash = !!options.configuration['populate--']
1100
- const config = Object.assign({}, options.configuration, {
1101
- 'populate--': true
1102
- })
1103
- const parsed = Parser.detailed(args, Object.assign({}, options, {
1104
- configuration: config
1105
- }))
1106
-
1107
- let argv = parsed.argv
1108
- if (parseContext) argv = Object.assign({}, argv, parseContext)
1109
- const aliases = parsed.aliases
1110
-
1111
- argv.$0 = self.$0
1112
- self.parsed = parsed
1113
-
1114
- try {
1115
- guessLocale() // guess locale lazily, so that it can be turned off in chain.
1116
-
1117
- // while building up the argv object, there
1118
- // are two passes through the parser. If completion
1119
- // is being performed short-circuit on the first pass.
1120
- if (shortCircuit) {
1121
- return (populateDoubleDash || _calledFromCommand) ? argv : self._copyDoubleDash(argv)
1122
- }
1123
-
1124
- // if there's a handler associated with a
1125
- // command defer processing to it.
1126
- if (helpOpt) {
1127
- // consider any multi-char helpOpt alias as a valid help command
1128
- // unless all helpOpt aliases are single-char
1129
- // note that parsed.aliases is a normalized bidirectional map :)
1130
- const helpCmds = [helpOpt]
1131
- .concat(aliases[helpOpt] || [])
1132
- .filter(k => k.length > 1)
1133
- // check if help should trigger and strip it from _.
1134
- if (~helpCmds.indexOf(argv._[argv._.length - 1])) {
1135
- argv._.pop()
1136
- argv[helpOpt] = true
1137
- }
1138
- }
1139
-
1140
- const handlerKeys = command.getCommands()
1141
- const requestCompletions = completion.completionKey in argv
1142
- const skipRecommendation = argv[helpOpt] || requestCompletions
1143
- const skipDefaultCommand = skipRecommendation && (handlerKeys.length > 1 || handlerKeys[0] !== '$0')
1144
-
1145
- if (argv._.length) {
1146
- if (handlerKeys.length) {
1147
- let firstUnknownCommand
1148
- for (let i = (commandIndex || 0), cmd; argv._[i] !== undefined; i++) {
1149
- cmd = String(argv._[i])
1150
- if (~handlerKeys.indexOf(cmd) && cmd !== completionCommand) {
1151
- // commands are executed using a recursive algorithm that executes
1152
- // the deepest command first; we keep track of the position in the
1153
- // argv._ array that is currently being executed.
1154
- const innerArgv = command.runCommand(cmd, self, parsed, i + 1)
1155
- return populateDoubleDash ? innerArgv : self._copyDoubleDash(innerArgv)
1156
- } else if (!firstUnknownCommand && cmd !== completionCommand) {
1157
- firstUnknownCommand = cmd
1158
- break
1159
- }
1160
- }
1161
-
1162
- // run the default command, if defined
1163
- if (command.hasDefaultCommand() && !skipDefaultCommand) {
1164
- const innerArgv = command.runCommand(null, self, parsed)
1165
- return populateDoubleDash ? innerArgv : self._copyDoubleDash(innerArgv)
1166
- }
1167
-
1168
- // recommend a command if recommendCommands() has
1169
- // been enabled, and no commands were found to execute
1170
- if (recommendCommands && firstUnknownCommand && !skipRecommendation) {
1171
- validation.recommendCommands(firstUnknownCommand, handlerKeys)
1172
- }
1173
- }
1174
-
1175
- // generate a completion script for adding to ~/.bashrc.
1176
- if (completionCommand && ~argv._.indexOf(completionCommand) && !requestCompletions) {
1177
- if (exitProcess) setBlocking(true)
1178
- self.showCompletionScript()
1179
- self.exit(0)
1180
- }
1181
- } else if (command.hasDefaultCommand() && !skipDefaultCommand) {
1182
- const innerArgv = command.runCommand(null, self, parsed)
1183
- return populateDoubleDash ? innerArgv : self._copyDoubleDash(innerArgv)
1184
- }
1185
-
1186
- // we must run completions first, a user might
1187
- // want to complete the --help or --version option.
1188
- if (requestCompletions) {
1189
- if (exitProcess) setBlocking(true)
1190
-
1191
- // we allow for asynchronous completions,
1192
- // e.g., loading in a list of commands from an API.
1193
- const completionArgs = args.slice(args.indexOf(`--${completion.completionKey}`) + 1)
1194
- completion.getCompletion(completionArgs, (completions) => {
1195
- ;(completions || []).forEach((completion) => {
1196
- _logger.log(completion)
1197
- })
1198
-
1199
- self.exit(0)
1200
- })
1201
- return (populateDoubleDash || _calledFromCommand) ? argv : self._copyDoubleDash(argv)
1202
- }
1203
-
1204
- // Handle 'help' and 'version' options
1205
- // if we haven't already output help!
1206
- if (!hasOutput) {
1207
- Object.keys(argv).forEach((key) => {
1208
- if (key === helpOpt && argv[key]) {
1209
- if (exitProcess) setBlocking(true)
1210
-
1211
- skipValidation = true
1212
- self.showHelp('log')
1213
- self.exit(0)
1214
- } else if (key === versionOpt && argv[key]) {
1215
- if (exitProcess) setBlocking(true)
1216
-
1217
- skipValidation = true
1218
- usage.showVersion()
1219
- self.exit(0)
1220
- }
1221
- })
1222
- }
1223
-
1224
- // Check if any of the options to skip validation were provided
1225
- if (!skipValidation && options.skipValidation.length > 0) {
1226
- skipValidation = Object.keys(argv).some(key => options.skipValidation.indexOf(key) >= 0 && argv[key] === true)
1227
- }
1228
-
1229
- // If the help or version options where used and exitProcess is false,
1230
- // or if explicitly skipped, we won't run validations.
1231
- if (!skipValidation) {
1232
- if (parsed.error) throw new YError(parsed.error.message)
1233
-
1234
- // if we're executed via bash completion, don't
1235
- // bother with validation.
1236
- if (!requestCompletions) {
1237
- self._runValidation(argv, aliases, {}, parsed.error)
1238
- }
1239
- }
1240
- } catch (err) {
1241
- if (err instanceof YError) usage.fail(err.message, err)
1242
- else throw err
1243
- }
1244
-
1245
- return (populateDoubleDash || _calledFromCommand) ? argv : self._copyDoubleDash(argv)
1246
- }
1247
-
1248
- // to simplify the parsing of positionals in commands,
1249
- // we temporarily populate '--' rather than _, with arguments
1250
- // after the '--' directive. After the parse, we copy these back.
1251
- self._copyDoubleDash = function (argv) {
1252
- if (!argv._ || !argv['--']) return argv
1253
- argv._.push.apply(argv._, argv['--'])
1254
-
1255
- // TODO(bcoe): refactor command parsing such that this delete is not
1256
- // necessary: https://github.com/yargs/yargs/issues/1482
1257
- try {
1258
- delete argv['--']
1259
- } catch (_err) {}
1260
-
1261
- return argv
1262
- }
1263
-
1264
- self._runValidation = function runValidation (argv, aliases, positionalMap, parseErrors) {
1265
- if (parseErrors) throw new YError(parseErrors.message)
1266
- validation.nonOptionCount(argv)
1267
- validation.requiredArguments(argv)
1268
- let failedStrictCommands = false
1269
- if (strictCommands) {
1270
- failedStrictCommands = validation.unknownCommands(argv)
1271
- }
1272
- if (strict && !failedStrictCommands) {
1273
- validation.unknownArguments(argv, aliases, positionalMap)
1274
- }
1275
- validation.customChecks(argv, aliases)
1276
- validation.limitedChoices(argv)
1277
- validation.implications(argv)
1278
- validation.conflicting(argv)
1279
- }
1280
-
1281
- function guessLocale () {
1282
- if (!detectLocale) return
1283
- const locale = process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG || process.env.LANGUAGE || 'en_US'
1284
- self.locale(locale.replace(/[.:].*/, ''))
1285
- }
1286
-
1287
- // an app should almost always have --version and --help,
1288
- // if you *really* want to disable this use .help(false)/.version(false).
1289
- self.help()
1290
- self.version()
1291
-
1292
- return self
1293
- }
11
+ exports.rebase = rebase
1294
12
 
1295
13
  // allow consumers to directly use the version of yargs-parser used by yargs
1296
14
  exports.Parser = Parser
1297
-
1298
- // rebase an absolute path to a relative one with respect to a base directory
1299
- // exported for tests
1300
- exports.rebase = rebase
1301
- function rebase (base, dir) {
1302
- return path.relative(base, dir)
1303
- }