yargs 8.0.0 → 9.0.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.
package/lib/validation.js CHANGED
@@ -1,16 +1,18 @@
1
+ 'use strict'
2
+ const argsert = require('./argsert')
1
3
  const objFilter = require('./obj-filter')
2
4
  const specialKeys = ['$0', '--', '_']
3
5
 
4
6
  // validation-type-stuff, missing params,
5
7
  // bad implications, custom checks.
6
- module.exports = function (yargs, usage, y18n) {
8
+ module.exports = function validation (yargs, usage, y18n) {
7
9
  const __ = y18n.__
8
10
  const __n = y18n.__n
9
11
  const self = {}
10
12
 
11
13
  // validate appropriate # of non-option
12
14
  // arguments were provided, i.e., '_'.
13
- self.nonOptionCount = function (argv) {
15
+ self.nonOptionCount = function nonOptionCount (argv) {
14
16
  const demandedCommands = yargs.getDemandedCommands()
15
17
  // don't count currently executing commands
16
18
  const _s = argv._.length - yargs.getContext().commands.length
@@ -44,7 +46,7 @@ module.exports = function (yargs, usage, y18n) {
44
46
 
45
47
  // validate the appropriate # of <required>
46
48
  // positional arguments were provided:
47
- self.positionalCount = function (required, observed) {
49
+ self.positionalCount = function positionalCount (required, observed) {
48
50
  if (observed < required) {
49
51
  usage.fail(
50
52
  __('Not enough non-option arguments: got %s, need at least %s', observed, required)
@@ -54,14 +56,14 @@ module.exports = function (yargs, usage, y18n) {
54
56
 
55
57
  // make sure that any args that require an
56
58
  // value (--foo=bar), have a value.
57
- self.missingArgumentValue = function (argv) {
59
+ self.missingArgumentValue = function missingArgumentValue (argv) {
58
60
  const defaultValues = [true, false, '']
59
61
  const options = yargs.getOptions()
60
62
 
61
63
  if (options.requiresArg.length > 0) {
62
64
  const missingRequiredArgs = []
63
65
 
64
- options.requiresArg.forEach(function (key) {
66
+ options.requiresArg.forEach((key) => {
65
67
  const value = argv[key]
66
68
 
67
69
  // if a value is explicitly requested,
@@ -85,11 +87,11 @@ module.exports = function (yargs, usage, y18n) {
85
87
  }
86
88
 
87
89
  // make sure all the required arguments are present.
88
- self.requiredArguments = function (argv) {
90
+ self.requiredArguments = function requiredArguments (argv) {
89
91
  const demandedOptions = yargs.getDemandedOptions()
90
- var missing = null
92
+ let missing = null
91
93
 
92
- Object.keys(demandedOptions).forEach(function (key) {
94
+ Object.keys(demandedOptions).forEach((key) => {
93
95
  if (!argv.hasOwnProperty(key) || typeof argv[key] === 'undefined') {
94
96
  missing = missing || {}
95
97
  missing[key] = demandedOptions[key]
@@ -98,14 +100,14 @@ module.exports = function (yargs, usage, y18n) {
98
100
 
99
101
  if (missing) {
100
102
  const customMsgs = []
101
- Object.keys(missing).forEach(function (key) {
103
+ Object.keys(missing).forEach((key) => {
102
104
  const msg = missing[key]
103
105
  if (msg && customMsgs.indexOf(msg) < 0) {
104
106
  customMsgs.push(msg)
105
107
  }
106
108
  })
107
109
 
108
- const customMsg = customMsgs.length ? '\n' + customMsgs.join('\n') : ''
110
+ const customMsg = customMsgs.length ? `\n${customMsgs.join('\n')}` : ''
109
111
 
110
112
  usage.fail(__n(
111
113
  'Missing required argument: %s',
@@ -117,33 +119,23 @@ module.exports = function (yargs, usage, y18n) {
117
119
  }
118
120
 
119
121
  // check for unknown arguments (strict-mode).
120
- self.unknownArguments = function (argv, aliases, positionalMap) {
121
- const aliasLookup = {}
122
- const descriptions = usage.getDescriptions()
123
- const demandedOptions = yargs.getDemandedOptions()
122
+ self.unknownArguments = function unknownArguments (argv, aliases, positionalMap) {
124
123
  const commandKeys = yargs.getCommandInstance().getCommands()
125
124
  const unknown = []
126
125
  const currentContext = yargs.getContext()
127
126
 
128
- Object.keys(aliases).forEach(function (key) {
129
- aliases[key].forEach(function (alias) {
130
- aliasLookup[alias] = key
131
- })
132
- })
133
-
134
- Object.keys(argv).forEach(function (key) {
127
+ Object.keys(argv).forEach((key) => {
135
128
  if (specialKeys.indexOf(key) === -1 &&
136
- !descriptions.hasOwnProperty(key) &&
137
- !demandedOptions.hasOwnProperty(key) &&
138
129
  !positionalMap.hasOwnProperty(key) &&
139
130
  !yargs._getParseContext().hasOwnProperty(key) &&
140
- !aliasLookup.hasOwnProperty(key)) {
131
+ !aliases.hasOwnProperty(key)
132
+ ) {
141
133
  unknown.push(key)
142
134
  }
143
135
  })
144
136
 
145
137
  if (commandKeys.length > 0) {
146
- argv._.slice(currentContext.commands.length).forEach(function (key) {
138
+ argv._.slice(currentContext.commands.length).forEach((key) => {
147
139
  if (commandKeys.indexOf(key) === -1) {
148
140
  unknown.push(key)
149
141
  }
@@ -161,18 +153,19 @@ module.exports = function (yargs, usage, y18n) {
161
153
  }
162
154
 
163
155
  // validate arguments limited to enumerated choices
164
- self.limitedChoices = function (argv) {
156
+ self.limitedChoices = function limitedChoices (argv) {
165
157
  const options = yargs.getOptions()
166
158
  const invalid = {}
167
159
 
168
160
  if (!Object.keys(options.choices).length) return
169
161
 
170
- Object.keys(argv).forEach(function (key) {
162
+ Object.keys(argv).forEach((key) => {
171
163
  if (specialKeys.indexOf(key) === -1 &&
172
164
  options.choices.hasOwnProperty(key)) {
173
- [].concat(argv[key]).forEach(function (value) {
165
+ [].concat(argv[key]).forEach((value) => {
174
166
  // TODO case-insensitive configurability
175
- if (options.choices[key].indexOf(value) === -1) {
167
+ if (options.choices[key].indexOf(value) === -1 &&
168
+ value !== undefined) {
176
169
  invalid[key] = (invalid[key] || []).concat(value)
177
170
  }
178
171
  })
@@ -183,31 +176,31 @@ module.exports = function (yargs, usage, y18n) {
183
176
 
184
177
  if (!invalidKeys.length) return
185
178
 
186
- var msg = __('Invalid values:')
187
- invalidKeys.forEach(function (key) {
188
- msg += '\n ' + __(
179
+ let msg = __('Invalid values:')
180
+ invalidKeys.forEach((key) => {
181
+ msg += `\n ${__(
189
182
  'Argument: %s, Given: %s, Choices: %s',
190
183
  key,
191
184
  usage.stringifiedValues(invalid[key]),
192
185
  usage.stringifiedValues(options.choices[key])
193
- )
186
+ )}`
194
187
  })
195
188
  usage.fail(msg)
196
189
  }
197
190
 
198
191
  // custom checks, added using the `check` option on yargs.
199
- var checks = []
200
- self.check = function (f, global) {
192
+ let checks = []
193
+ self.check = function check (f, global) {
201
194
  checks.push({
202
195
  func: f,
203
- global: global
196
+ global
204
197
  })
205
198
  }
206
199
 
207
- self.customChecks = function (argv, aliases) {
208
- for (var i = 0, f; (f = checks[i]) !== undefined; i++) {
209
- var func = f.func
210
- var result = null
200
+ self.customChecks = function customChecks (argv, aliases) {
201
+ for (let i = 0, f; (f = checks[i]) !== undefined; i++) {
202
+ const func = f.func
203
+ let result = null
211
204
  try {
212
205
  result = func(argv, aliases)
213
206
  } catch (err) {
@@ -224,107 +217,129 @@ module.exports = function (yargs, usage, y18n) {
224
217
  }
225
218
 
226
219
  // check implications, argument foo implies => argument bar.
227
- var implied = {}
228
- self.implies = function (key, value) {
220
+ let implied = {}
221
+ self.implies = function implies (key, value) {
222
+ argsert('<string|object> [array|number|string]', [key, value], arguments.length)
223
+
229
224
  if (typeof key === 'object') {
230
- Object.keys(key).forEach(function (k) {
225
+ Object.keys(key).forEach((k) => {
231
226
  self.implies(k, key[k])
232
227
  })
233
228
  } else {
234
229
  yargs.global(key)
235
- implied[key] = value
230
+ if (!implied[key]) {
231
+ implied[key] = []
232
+ }
233
+ if (Array.isArray(value)) {
234
+ value.forEach((i) => self.implies(key, i))
235
+ } else {
236
+ implied[key].push(value)
237
+ }
236
238
  }
237
239
  }
238
- self.getImplied = function () {
240
+ self.getImplied = function getImplied () {
239
241
  return implied
240
242
  }
241
243
 
242
- self.implications = function (argv) {
244
+ self.implications = function implications (argv) {
243
245
  const implyFail = []
244
246
 
245
- Object.keys(implied).forEach(function (key) {
246
- var num
247
+ Object.keys(implied).forEach((key) => {
247
248
  const origKey = key
248
- var value = implied[key]
249
-
250
- // convert string '1' to number 1
251
- num = Number(key)
252
- key = isNaN(num) ? key : num
253
-
254
- if (typeof key === 'number') {
255
- // check length of argv._
256
- key = argv._.length >= key
257
- } else if (key.match(/^--no-.+/)) {
258
- // check if key doesn't exist
259
- key = key.match(/^--no-(.+)/)[1]
260
- key = !argv[key]
261
- } else {
262
- // check if key exists
263
- key = argv[key]
264
- }
265
-
266
- num = Number(value)
267
- value = isNaN(num) ? value : num
249
+ ;(implied[key] || []).forEach((value) => {
250
+ let num
251
+ let key = origKey
252
+ const origValue = value
253
+
254
+ // convert string '1' to number 1
255
+ num = Number(key)
256
+ key = isNaN(num) ? key : num
257
+
258
+ if (typeof key === 'number') {
259
+ // check length of argv._
260
+ key = argv._.length >= key
261
+ } else if (key.match(/^--no-.+/)) {
262
+ // check if key doesn't exist
263
+ key = key.match(/^--no-(.+)/)[1]
264
+ key = !argv[key]
265
+ } else {
266
+ // check if key exists
267
+ key = argv[key]
268
+ }
268
269
 
269
- if (typeof value === 'number') {
270
- value = argv._.length >= value
271
- } else if (value.match(/^--no-.+/)) {
272
- value = value.match(/^--no-(.+)/)[1]
273
- value = !argv[value]
274
- } else {
275
- value = argv[value]
276
- }
270
+ num = Number(value)
271
+ value = isNaN(num) ? value : num
277
272
 
278
- if (key && !value) {
279
- implyFail.push(origKey)
280
- }
273
+ if (typeof value === 'number') {
274
+ value = argv._.length >= value
275
+ } else if (value.match(/^--no-.+/)) {
276
+ value = value.match(/^--no-(.+)/)[1]
277
+ value = !argv[value]
278
+ } else {
279
+ value = argv[value]
280
+ }
281
+ if (key && !value) {
282
+ implyFail.push(` ${origKey} -> ${origValue}`)
283
+ }
284
+ })
281
285
  })
282
286
 
283
287
  if (implyFail.length) {
284
- var msg = __('Implications failed:') + '\n'
288
+ let msg = `${__('Implications failed:')}\n`
285
289
 
286
- implyFail.forEach(function (key) {
287
- msg += (' ' + key + ' -> ' + implied[key])
290
+ implyFail.forEach((value) => {
291
+ msg += (value)
288
292
  })
289
293
 
290
294
  usage.fail(msg)
291
295
  }
292
296
  }
293
297
 
294
- var conflicting = {}
295
- self.conflicts = function (key, value) {
298
+ let conflicting = {}
299
+ self.conflicts = function conflicts (key, value) {
300
+ argsert('<string|object> [array|string]', [key, value], arguments.length)
301
+
296
302
  if (typeof key === 'object') {
297
- Object.keys(key).forEach(function (k) {
303
+ Object.keys(key).forEach((k) => {
298
304
  self.conflicts(k, key[k])
299
305
  })
300
306
  } else {
301
307
  yargs.global(key)
302
- conflicting[key] = value
308
+ if (!conflicting[key]) {
309
+ conflicting[key] = []
310
+ }
311
+ if (Array.isArray(value)) {
312
+ value.forEach((i) => self.conflicts(key, i))
313
+ } else {
314
+ conflicting[key].push(value)
315
+ }
303
316
  }
304
317
  }
305
- self.getConflicting = function () {
306
- return conflicting
307
- }
308
-
309
- self.conflicting = function (argv) {
310
- var args = Object.getOwnPropertyNames(argv)
311
-
312
- args.forEach(function (arg) {
313
- if (conflicting[arg] && args.indexOf(conflicting[arg]) !== -1) {
314
- usage.fail(__('Arguments %s and %s are mutually exclusive', arg, conflicting[arg]))
318
+ self.getConflicting = () => conflicting
319
+
320
+ self.conflicting = function conflictingFn (argv) {
321
+ Object.keys(argv).forEach((key) => {
322
+ if (conflicting[key]) {
323
+ conflicting[key].forEach((value) => {
324
+ // we default keys to 'undefined' that have been configured, we should not
325
+ // apply conflicting check unless they are a value other than 'undefined'.
326
+ if (value && argv[key] !== undefined && argv[value] !== undefined) {
327
+ usage.fail(__(`Arguments ${key} and ${value} are mutually exclusive`))
328
+ }
329
+ })
315
330
  }
316
331
  })
317
332
  }
318
333
 
319
- self.recommendCommands = function (cmd, potentialCommands) {
334
+ self.recommendCommands = function recommendCommands (cmd, potentialCommands) {
320
335
  const distance = require('./levenshtein')
321
336
  const threshold = 3 // if it takes more than three edits, let's move on.
322
- potentialCommands = potentialCommands.sort(function (a, b) { return b.length - a.length })
337
+ potentialCommands = potentialCommands.sort((a, b) => b.length - a.length)
323
338
 
324
- var recommended = null
325
- var bestDistance = Infinity
326
- for (var i = 0, candidate; (candidate = potentialCommands[i]) !== undefined; i++) {
327
- var d = distance(cmd, candidate)
339
+ let recommended = null
340
+ let bestDistance = Infinity
341
+ for (let i = 0, candidate; (candidate = potentialCommands[i]) !== undefined; i++) {
342
+ const d = distance(cmd, candidate)
328
343
  if (d <= threshold && d < bestDistance) {
329
344
  bestDistance = d
330
345
  recommended = candidate
@@ -333,27 +348,21 @@ module.exports = function (yargs, usage, y18n) {
333
348
  if (recommended) usage.fail(__('Did you mean %s?', recommended))
334
349
  }
335
350
 
336
- self.reset = function (localLookup) {
337
- implied = objFilter(implied, function (k, v) {
338
- return !localLookup[k]
339
- })
340
- conflicting = objFilter(conflicting, function (k, v) {
341
- return !localLookup[k]
342
- })
343
- checks = checks.filter(function (c) {
344
- return c.global
345
- })
351
+ self.reset = function reset (localLookup) {
352
+ implied = objFilter(implied, (k, v) => !localLookup[k])
353
+ conflicting = objFilter(conflicting, (k, v) => !localLookup[k])
354
+ checks = checks.filter(c => c.global)
346
355
  return self
347
356
  }
348
357
 
349
- var frozen
350
- self.freeze = function () {
358
+ let frozen
359
+ self.freeze = function freeze () {
351
360
  frozen = {}
352
361
  frozen.implied = implied
353
362
  frozen.checks = checks
354
363
  frozen.conflicting = conflicting
355
364
  }
356
- self.unfreeze = function () {
365
+ self.unfreeze = function unfreeze () {
357
366
  implied = frozen.implied
358
367
  checks = frozen.checks
359
368
  conflicting = frozen.conflicting
package/lib/yerror.js CHANGED
@@ -1,3 +1,4 @@
1
+ 'use strict'
1
2
  function YError (msg) {
2
3
  this.name = 'YError'
3
4
  this.message = msg || 'yargs error'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yargs",
3
- "version": "8.0.0",
3
+ "version": "9.0.1",
4
4
  "description": "yargs the modern, pirate-themed, successor to optimist.",
5
5
  "main": "./index.js",
6
6
  "files": [
@@ -12,19 +12,19 @@
12
12
  "LICENSE"
13
13
  ],
14
14
  "dependencies": {
15
- "camelcase": "^3.0.0",
15
+ "camelcase": "^4.1.0",
16
16
  "cliui": "^3.2.0",
17
17
  "decamelize": "^1.1.1",
18
18
  "get-caller-file": "^1.0.1",
19
- "os-locale": "^1.4.0",
20
- "read-pkg-up": "^1.0.1",
19
+ "os-locale": "^2.0.0",
20
+ "read-pkg-up": "^2.0.0",
21
21
  "require-directory": "^2.1.1",
22
22
  "require-main-filename": "^1.0.1",
23
23
  "set-blocking": "^2.0.0",
24
- "string-width": "^1.0.2",
25
- "which-module": "^1.0.0",
24
+ "string-width": "^2.0.0",
25
+ "which-module": "^2.0.0",
26
26
  "y18n": "^3.2.1",
27
- "yargs-parser": "^6.0.1"
27
+ "yargs-parser": "^7.0.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "chai": "^3.4.1",
@@ -38,7 +38,7 @@
38
38
  "nyc": "^10.3.0",
39
39
  "rimraf": "^2.5.0",
40
40
  "standard": "^8.6.0",
41
- "standard-version": "^3.0.0",
41
+ "standard-version": "^4.2.0",
42
42
  "which": "^1.2.9",
43
43
  "yargs-test-extends": "^1.0.1"
44
44
  },
@@ -69,13 +69,6 @@
69
69
  ],
70
70
  "license": "MIT",
71
71
  "engine": {
72
- "node": ">=0.10"
73
- },
74
- "greenkeeper": {
75
- "ignore": [
76
- "string-width",
77
- "read-pkg-up",
78
- "camelcase"
79
- ]
72
+ "node": ">=4"
80
73
  }
81
74
  }