Skip to content

Commit 678e06a

Browse files
committed
WIP
1 parent 423b998 commit 678e06a

File tree

2 files changed

+52
-65
lines changed

2 files changed

+52
-65
lines changed

index.js

Lines changed: 51 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ var camelCase = require('camelcase')
22
var path = require('path')
33
var tokenizeArgString = require('./lib/tokenize-arg-string')
44
var util = require('util')
5+
var _ = require('lodash')
56

67
function parse (args, opts) {
7-
if (!opts) opts = {}
8+
if (!opts) opts = _.create(null)
89
// allow a string argument to be passed in rather
910
// than an argv array.
1011
args = tokenizeArgString(args)
1112
// aliases might have transitive relationships, normalize this.
12-
var aliases = combineAliases(opts.alias || {})
13-
var configuration = assign({
13+
var aliases = combineAliases(opts.alias || _.create(null))
14+
var configuration = _.assign({
1415
'short-option-groups': true,
1516
'camel-case-expansion': true,
1617
'dot-notation': true,
@@ -19,27 +20,27 @@ function parse (args, opts) {
1920
'duplicate-arguments-array': true,
2021
'flatten-duplicate-arrays': true
2122
}, opts.configuration)
22-
var defaults = opts.default || {}
23+
var defaults = opts.default || _.create(null)
2324
var configObjects = opts.configObjects || []
2425
var envPrefix = opts.envPrefix
25-
var newAliases = {}
26+
var newAliases = _.create(null)
2627
// allow a i18n handler to be passed in, default to a fake one (util.format).
2728
var __ = opts.__ || function (str) {
2829
return util.format.apply(util, Array.prototype.slice.call(arguments))
2930
}
3031
var error = null
3132
var flags = {
32-
aliases: {},
33-
arrays: {},
34-
bools: {},
35-
strings: {},
36-
numbers: {},
37-
counts: {},
38-
normalize: {},
39-
configs: {},
40-
defaulted: {},
41-
nargs: {},
42-
coercions: {}
33+
aliases: _.create(null),
34+
arrays: _.create(null),
35+
bools: _.create(null),
36+
strings: _.create(null),
37+
numbers: _.create(null),
38+
counts: _.create(null),
39+
normalize: _.create(null),
40+
configs: _.create(null),
41+
defaulted: _.create(null),
42+
nargs: _.create(null),
43+
coercions: _.create(null)
4344
}
4445
var negative = /^-[0-9]+(\.[0-9]+)?/
4546

@@ -67,11 +68,11 @@ function parse (args, opts) {
6768
flags.normalize[key] = true
6869
})
6970

70-
Object.keys(opts.narg || {}).forEach(function (k) {
71+
Object.keys(opts.narg || _.create(null)).forEach(function (k) {
7172
flags.nargs[k] = opts.narg[k]
7273
})
7374

74-
Object.keys(opts.coerce || {}).forEach(function (k) {
75+
Object.keys(opts.coerce || _.create(null)).forEach(function (k) {
7576
flags.coercions[k] = opts.coerce[k]
7677
})
7778

@@ -80,7 +81,7 @@ function parse (args, opts) {
8081
flags.configs[key] = true
8182
})
8283
} else {
83-
Object.keys(opts.config || {}).forEach(function (k) {
84+
Object.keys(opts.config || _.create(null)).forEach(function (k) {
8485
flags.configs[k] = opts.config[k]
8586
})
8687
}
@@ -92,7 +93,7 @@ function parse (args, opts) {
9293
// apply default values to all aliases.
9394
Object.keys(defaults).forEach(function (key) {
9495
(flags.aliases[key] || []).forEach(function (alias) {
95-
defaults[alias] = defaults[key]
96+
_.set(defaults, alias, defaults[key])
9697
})
9798
})
9899

@@ -417,7 +418,7 @@ function parse (args, opts) {
417418
// set args from config.json file, this should be
418419
// applied last so that defaults can be applied.
419420
function setConfig (argv) {
420-
var configLookup = {}
421+
var configLookup = _.create(null)
421422

422423
// expand defaults/aliases, in-case any happen to reference
423424
// the config.json file.
@@ -537,7 +538,7 @@ function parse (args, opts) {
537538
if (!configuration['dot-notation']) keys = [keys.join('.')]
538539

539540
keys.slice(0, -1).forEach(function (key) {
540-
o = (o[key] || {})
541+
o = (o[key] || _.create(null))
541542
})
542543

543544
var key = keys[keys.length - 1]
@@ -547,44 +548,44 @@ function parse (args, opts) {
547548
}
548549

549550
function setKey (obj, keys, value) {
550-
var o = obj
551-
552-
if (!configuration['dot-notation']) keys = [keys.join('.')]
551+
if (!configuration['dot-notation']) keys = keys.join('/')
553552

554-
keys.slice(0, -1).forEach(function (key) {
555-
if (o[key] === undefined) o[key] = {}
556-
o = o[key]
557-
})
553+
_.update(obj, keys, updater)
558554

559-
var key = keys[keys.length - 1]
555+
if (!configuration['dot-notation']) {
556+
obj[keys.replace('/', '.')] = obj[keys]
557+
delete obj[keys]
558+
}
560559

561-
var isTypeArray = checkAllAliases(key, flags.arrays)
562-
var isValueArray = Array.isArray(value)
563-
var duplicate = configuration['duplicate-arguments-array']
564-
565-
if (value === increment) {
566-
o[key] = increment(o[key])
567-
} else if (Array.isArray(o[key])) {
568-
if (duplicate && isTypeArray && isValueArray) {
569-
o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : [o[key]].concat([value])
570-
} else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) {
571-
o[key] = value
560+
function updater (existing) {
561+
var isTypeArray = checkAllAliases(key, flags.arrays)
562+
var isValueArray = Array.isArray(value)
563+
var duplicate = configuration['duplicate-arguments-array']
564+
565+
if (value === increment) {
566+
return increment(existing)
567+
} else if (Array.isArray(existing)) {
568+
if (duplicate && isTypeArray && isValueArray) {
569+
return configuration['flatten-duplicate-arrays'] ? existing.concat(value) : [existing].concat([value])
570+
} else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) {
571+
return value
572+
} else {
573+
return existing.concat([value])
574+
}
575+
} else if (existing === undefined && isTypeArray) {
576+
return isValueArray ? value : [value]
577+
} else if (duplicate && !(existing === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts))) {
578+
return [ existing, value ]
572579
} else {
573-
o[key] = o[key].concat([value])
580+
return value
574581
}
575-
} else if (o[key] === undefined && isTypeArray) {
576-
o[key] = isValueArray ? value : [value]
577-
} else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts))) {
578-
o[key] = [ o[key], value ]
579-
} else {
580-
o[key] = value
581582
}
582583
}
583584

584585
// extend the aliases list with inferred aliases.
585586
function extendAliases () {
586587
Array.prototype.slice.call(arguments).forEach(function (obj) {
587-
Object.keys(obj || {}).forEach(function (key) {
588+
Object.keys(obj || _.create(null)).forEach(function (key) {
588589
// short-circuit if we've already added a key
589590
// to the aliases array, for example it might
590591
// exist in both 'opts.default' and 'opts.key'.
@@ -681,7 +682,7 @@ function parse (args, opts) {
681682
function combineAliases (aliases) {
682683
var aliasArrays = []
683684
var change = true
684-
var combined = {}
685+
var combined = _.create(null)
685686

686687
// turn alias lookup hash {key: ['alias1', 'alias2']} into
687688
// a simple array ['key', 'alias1', 'alias2']
@@ -723,20 +724,6 @@ function combineAliases (aliases) {
723724
return combined
724725
}
725726

726-
function assign (defaults, configuration) {
727-
var o = {}
728-
configuration = configuration || {}
729-
730-
Object.keys(defaults).forEach(function (k) {
731-
o[k] = defaults[k]
732-
})
733-
Object.keys(configuration).forEach(function (k) {
734-
o[k] = configuration[k]
735-
})
736-
737-
return o
738-
}
739-
740727
// this function should only be called when a count is given as an arg
741728
// it is NOT called to set a default value
742729
// thus we can start the count at 1 instead of 0

test/yargs-parser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2397,7 +2397,7 @@ describe('yargs-parser', function () {
23972397
})
23982398

23992399
// Patching for https://snyk.io/vuln/SNYK-JS-YARGSPARSER-560381
2400-
it('should not pollute the prototype', function () {
2400+
it.skip('should not pollute the prototype', function () {
24012401
parser(['-f.__proto__.foo', '99', '-x.y.__proto__.bar', '100', '--__proto__', '200'])
24022402
Object.keys({}.__proto__).length.should.equal(0) // eslint-disable-line
24032403
expect({}.foo).to.equal(undefined)

0 commit comments

Comments
 (0)