From 2f2643602f6310078c6ec141bd395435818f90ef Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Sun, 23 Jun 2019 00:35:03 +0200 Subject: [PATCH 01/11] fix!: maybeCoerceNumber now takes precedence over coerce return value (#182) --- index.js | 4 ++-- test/yargs-parser.js | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index a6c95ba3..315d1aab 100644 --- a/index.js +++ b/index.js @@ -497,7 +497,7 @@ function parse (args, opts) { } function maybeCoerceNumber (key, value) { - if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.coercions)) { + if (!checkAllAliases(key, flags.strings)) { const shouldCoerceNumber = isNumber(value) && configuration['parse-numbers'] && ( Number.isSafeInteger(Math.floor(value)) ) @@ -604,7 +604,7 @@ function parse (args, opts) { coerce = checkAllAliases(key, flags.coercions) if (typeof coerce === 'function') { try { - var value = coerce(argv[key]) + var value = maybeCoerceNumber(key, coerce(argv[key])) ;([].concat(flags.aliases[key] || [], key)).forEach(ali => { applied[ali] = argv[ali] = value }) diff --git a/test/yargs-parser.js b/test/yargs-parser.js index a8628261..c908187b 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -2147,14 +2147,18 @@ describe('yargs-parser', function () { }) it('parses number if option explicitly set to number type', function () { - var parsed = parser(['--foo', '5', '--bar', '6'], { - number: 'bar', + var parsed = parser(['--foo', '5', '--bar', '6', '--baz', '7'], { + number: ['bar', 'baz'], + coerce: { + 'baz': val => val + }, configuration: { 'parse-numbers': false } }) expect(parsed['foo']).to.equal('5') expect(parsed['bar']).to.equal(6) + expect(parsed['baz']).to.equal(7) }) }) From 17ca3bdaada25605ab06fe72946d2da4b52087fa Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Mon, 24 Jun 2019 23:43:25 +0200 Subject: [PATCH 02/11] fix!: boolean now behaves the same as other array types (#184) BREAKING CHANGE: we have dropped the broken "defaulted" functionality; we would like to revisit adding this in the future. --- index.js | 29 +++--------------------- test/yargs-parser.js | 54 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/index.js b/index.js index 315d1aab..4fd05531 100644 --- a/index.js +++ b/index.js @@ -46,7 +46,6 @@ function parse (args, opts) { counts: {}, normalize: {}, configs: {}, - defaulted: {}, nargs: {}, coercions: {}, keys: [] @@ -132,14 +131,6 @@ function parse (args, opts) { }) var argv = { _: [] } - - Object.keys(flags.bools).forEach(function (key) { - if (Object.prototype.hasOwnProperty.call(defaults, key)) { - setArg(key, defaults[key]) - setDefaulted(key) - } - }) - var notFlags = [] for (var i = 0; i < args.length; i++) { @@ -406,8 +397,6 @@ function parse (args, opts) { } function setArg (key, val) { - unsetDefaulted(key) - if (/-/.test(key) && configuration['camel-case-expansion']) { var alias = key.split('.').map(function (prop) { return camelCase(prop) @@ -560,7 +549,7 @@ function parse (args, opts) { } else { // setting arguments via CLI takes precedence over // values within the config file. - if (!hasKey(argv, fullKey.split('.')) || (flags.defaulted[fullKey]) || (flags.arrays[fullKey] && configuration['combine-arrays'])) { + if (!hasKey(argv, fullKey.split('.')) || (flags.arrays[fullKey] && configuration['combine-arrays'])) { setArg(fullKey, value) } } @@ -589,7 +578,7 @@ function parse (args, opts) { return camelCase(key) }) - if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && (!hasKey(argv, keys) || flags.defaulted[keys.join('.')])) { + if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && !hasKey(argv, keys)) { setArg(keys.join('.'), process.env[envVar]) } } @@ -704,7 +693,7 @@ function parse (args, opts) { } } else if (o[key] === undefined && isTypeArray) { o[key] = isValueArray ? value : [value] - } else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts))) { + } else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.counts))) { o[key] = [ o[key], value ] } else { o[key] = value @@ -762,18 +751,6 @@ function parse (args, opts) { return isSet } - function setDefaulted (key) { - [].concat(flags.aliases[key] || [], key).forEach(function (k) { - flags.defaulted[k] = true - }) - } - - function unsetDefaulted (key) { - [].concat(flags.aliases[key] || [], key).forEach(function (k) { - delete flags.defaulted[k] - }) - } - // make a best effor to pick a default value // for an option based on name and type. function defaultValue (key) { diff --git a/test/yargs-parser.js b/test/yargs-parser.js index c908187b..abcfaafd 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -1108,7 +1108,7 @@ describe('yargs-parser', function () { }) }) - describe('with implied false default', function () { + describe('without any default value', function () { var opts = null beforeEach(function () { @@ -1125,8 +1125,8 @@ describe('yargs-parser', function () { parser(['--no-flag'], opts).flag.should.be.false // eslint-disable-line }) - it('should set false if no flag in arg', function () { - expect(parser([], opts).flag).to.be.undefined // eslint-disable-line + it('should not add property if no flag in arg', function () { + parser([''], opts).should.not.have.property('flag') }) }) @@ -2334,6 +2334,18 @@ describe('yargs-parser', function () { parsed['x'].should.deep.equal(3) }) }) + describe('type=boolean', function () { + it('[-x true -x true -x false] => false', function () { + var parsed = parser('-x true -x true -x false', { + boolean: ['x'], + configuration: { + 'duplicate-arguments-array': false, + 'flatten-duplicate-arrays': false + } + }) + parsed['x'].should.deep.equal(false) + }) + }) }) describe('duplicate=false, flatten=true,', function () { describe('type=array', function () { @@ -2370,6 +2382,18 @@ describe('yargs-parser', function () { parsed['x'].should.deep.equal(3) }) }) + describe('type=boolean', function () { + it('[-x true -x true -x false] => false', function () { + var parsed = parser('-x true -x true -x false', { + boolean: ['x'], + configuration: { + 'duplicate-arguments-array': false, + 'flatten-duplicate-arrays': true + } + }) + parsed['x'].should.deep.equal(false) + }) + }) }) describe('duplicate=true, flatten=true,', function () { describe('type=array', function () { @@ -2406,6 +2430,18 @@ describe('yargs-parser', function () { parsed['x'].should.deep.equal([1, 2, 3]) }) }) + describe('type=boolean', function () { + it('[-x true -x true -x false] => [true, true, false]', function () { + var parsed = parser('-x true -x true -x false', { + boolean: ['x'], + configuration: { + 'duplicate-arguments-array': true, + 'flatten-duplicate-arrays': true + } + }) + parsed['x'].should.deep.equal([true, true, false]) + }) + }) }) describe('duplicate=true, flatten=false,', function () { describe('type=array', function () { @@ -2442,6 +2478,18 @@ describe('yargs-parser', function () { parsed['x'].should.deep.equal([1, 2, 3]) }) }) + describe('type=boolean', function () { + it('[-x true -x true -x false] => [true, true, false]', function () { + var parsed = parser('-x true -x true -x false', { + boolean: ['x'], + configuration: { + 'duplicate-arguments-array': true, + 'flatten-duplicate-arrays': false + } + }) + parsed['x'].should.deep.equal([true, true, false]) + }) + }) }) }) From 31c204b35eb35e9a3c382f8068e7cb80674a2f22 Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Sun, 14 Jul 2019 01:54:37 +0200 Subject: [PATCH 03/11] feat!: maybeCoerceNumber() now takes into account arrays (#187) BREAKING CHANGE: unless "parse-numbers" is set to "false", arrays of numeric strings are now parsed as numbers, rather than strings. --- index.js | 6 ++++-- test/yargs-parser.js | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 4fd05531..11eac1e5 100644 --- a/index.js +++ b/index.js @@ -470,7 +470,9 @@ function parse (args, opts) { if (typeof val === 'string') val = val === 'true' } - var value = maybeCoerceNumber(key, val) + var value = Array.isArray(val) + ? val.map(function (v) { return maybeCoerceNumber(key, v) }) + : maybeCoerceNumber(key, val) // increment a count given as arg (either no value or value parsed as boolean) if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) { @@ -486,7 +488,7 @@ function parse (args, opts) { } function maybeCoerceNumber (key, value) { - if (!checkAllAliases(key, flags.strings)) { + if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) { const shouldCoerceNumber = isNumber(value) && configuration['parse-numbers'] && ( Number.isSafeInteger(Math.floor(value)) ) diff --git a/test/yargs-parser.js b/test/yargs-parser.js index abcfaafd..773cfe32 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -2160,6 +2160,19 @@ describe('yargs-parser', function () { expect(parsed['bar']).to.equal(6) expect(parsed['baz']).to.equal(7) }) + + it('should coerce elements of number typed arrays to numbers', function () { + var parsed = parser(['--foo', '4', '--foo', '5', '2'], { + array: ['foo'], + configObjects: [{ foo: ['1', '2', '3'] }], + configuration: { + 'combine-arrays': true, + 'flatten-duplicate-arrays': false + } + }) + + expect(parsed['foo']).to.deep.equal([[4], [5, 2], [1, 2, 3]]) + }) }) describe('boolean negation', function () { @@ -2445,7 +2458,7 @@ describe('yargs-parser', function () { }) describe('duplicate=true, flatten=false,', function () { describe('type=array', function () { - it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () { + it('[-x 1 -x 2 -x 3] => [[1], [2], [3]]', function () { var parsed = parser('-x 1 -x 2 -x 3', { array: ['x'], configuration: { @@ -2453,7 +2466,7 @@ describe('yargs-parser', function () { 'flatten-duplicate-arrays': false } }) - parsed['x'].should.deep.equal([1, 2, 3]) + parsed['x'].should.deep.equal([[1], [2], [3]]) }) it('[-x 1 2 3 -x 2 3 4] => [[1, 2, 3], [ 2, 3, 4]]', function () { var parsed = parser('-x 1 2 3 -x 2 3 4', { From c5a1db06eabc4dd249adf2a471156bd133b693bf Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Tue, 23 Jul 2019 20:42:54 +0200 Subject: [PATCH 04/11] fix: eatNargs() for 'opt.narg === 0' and boolean typed options (#188) --- index.js | 15 +++++++++++---- test/yargs-parser.js | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 11eac1e5..1b821031 100644 --- a/index.js +++ b/index.js @@ -173,13 +173,14 @@ function parse (args, opts) { key = arg.match(/^--?(.+)/)[1] // nargs format = '--foo a b c' - if (checkAllAliases(key, flags.nargs)) { + // should be truthy even if: flags.nargs[key] === 0 + if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args) // array format = '--foo a b c' } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { i = eatArray(i, key, args) } else { - next = flags.nargs[key] === 0 ? undefined : args[i + 1] + next = args[i + 1] if (next !== undefined && (!next.match(/^-/) || next.match(negative)) && @@ -266,7 +267,8 @@ function parse (args, opts) { if (!broken && key !== '-') { // nargs format = '-f a b c' - if (checkAllAliases(key, flags.nargs)) { + // should be truthy even if: flags.nargs[key] === 0 + if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args) // array format = '-f a b c' } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { @@ -347,6 +349,11 @@ function parse (args, opts) { var ii const toEat = checkAllAliases(key, flags.nargs) + if (toEat === 0) { + setArg(key, defaultValue(key)) + return i + } + // nargs will not consume flag arguments, e.g., -abc, --foo, // and terminates when one is observed. var available = 0 @@ -747,7 +754,7 @@ function parse (args, opts) { var toCheck = [].concat(flags.aliases[key] || [], key) toCheck.forEach(function (key) { - if (flag[key]) isSet = flag[key] + if (flag.hasOwnProperty(key)) isSet = flag[key] }) return isSet diff --git a/test/yargs-parser.js b/test/yargs-parser.js index 773cfe32..d5532ace 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -194,15 +194,17 @@ describe('yargs-parser', function () { parse.should.have.property('_').and.deep.equal(['aaatrueaaa', 'moo', 'aaafalseaaa']) }) - it('should not use next value for boolean configured with zero narg', function () { - var parse = parser(['--all', 'false'], { - boolean: ['all'], - narg: { - all: 0 - } - }) - parse.should.have.property('all', true).and.be.a('boolean') - parse.should.have.property('_').and.deep.equal(['false']) + it('should not use next value for boolean/number/string configured with zero narg', function () { + var parse = parser(['--bool', 'false', '--nr', '7', '--str', 'foo'], { + boolean: ['bool'], + number: ['nr'], + string: ['str'], + narg: { bool: 0, nr: 0, str: 0 } + }) + parse.should.have.property('bool', true).and.be.a('boolean') + parse.should.have.property('nr', undefined).and.be.a('undefined') + parse.should.have.property('str', '').and.be.a('string') + parse.should.have.property('_').and.deep.equal(['false', 7, 'foo']) }) it('should allow defining options as boolean in groups', function () { From 7d42572acf7e81f1d78f357b3229d415abe3d6c5 Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Tue, 30 Jul 2019 22:01:30 +0200 Subject: [PATCH 05/11] fix: boolean arrays with default values (#185) --- index.js | 48 +++++++++++++++++++++----------------------- test/yargs-parser.js | 24 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/index.js b/index.js index 1b821031..79d433c4 100644 --- a/index.js +++ b/index.js @@ -156,7 +156,7 @@ function parse (args, opts) { args.splice(i + 1, 0, m[2]) i = eatNargs(i, m[1], args) // arrays format = '--f=a b c' - } else if (checkAllAliases(m[1], flags.arrays) && args.length > i + 1) { + } else if (checkAllAliases(m[1], flags.arrays)) { args.splice(i + 1, 0, m[2]) i = eatArray(i, m[1], args) } else { @@ -164,7 +164,7 @@ function parse (args, opts) { } } else if (arg.match(negatedBoolean) && configuration['boolean-negation']) { key = arg.match(negatedBoolean)[1] - setArg(key, false) + setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false) // -- seperated by space. } else if (arg.match(/^--.+/) || ( @@ -177,7 +177,7 @@ function parse (args, opts) { if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args) // array format = '--foo a b c' - } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { + } else if (checkAllAliases(key, flags.arrays)) { i = eatArray(i, key, args) } else { next = args[i + 1] @@ -230,7 +230,7 @@ function parse (args, opts) { args.splice(i + 1, 0, value) i = eatNargs(i, key, args) // array format = '-f=a b c' - } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { + } else if (checkAllAliases(key, flags.arrays)) { args.splice(i + 1, 0, value) i = eatArray(i, key, args) } else { @@ -271,7 +271,7 @@ function parse (args, opts) { if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args) // array format = '-f a b c' - } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { + } else if (checkAllAliases(key, flags.arrays)) { i = eatArray(i, key, args) } else { next = args[i + 1] @@ -376,30 +376,27 @@ function parse (args, opts) { // following it... YUM! // e.g., --foo apple banana cat becomes ["apple", "banana", "cat"] function eatArray (i, key, args) { - var start = i + 1 - var argsToSet = [] - var multipleArrayFlag = i > 0 - for (var ii = i + 1; ii < args.length; ii++) { - if (/^-/.test(args[ii]) && !negative.test(args[ii])) { - if (ii === start) { - setArg(key, defaultForType('array')) - } - multipleArrayFlag = true - break + let argsToSet = [] + let next = args[i + 1] + + if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) { + argsToSet.push(true) + } else if (isUndefined(next) || (/^-/.test(next) && !negative.test(next))) { + // for keys without value ==> argsToSet remains an empty [] + // set user default value, if available + if (defaults.hasOwnProperty(key)) { + argsToSet.push(defaults[key]) } - i = ii - argsToSet.push(args[ii]) - } - if (multipleArrayFlag) { - setArg(key, argsToSet.map(function (arg) { - return processValue(key, arg) - })) } else { - argsToSet.forEach(function (arg) { - setArg(key, arg) - }) + for (var ii = i + 1; ii < args.length; ii++) { + next = args[ii] + if (/^-/.test(next) && !negative.test(next)) break + i = ii + argsToSet.push(processValue(key, next)) + } } + setArg(key, argsToSet) return i } @@ -791,6 +788,7 @@ function parse (args, opts) { if (checkAllAliases(key, flags.strings)) type = 'string' else if (checkAllAliases(key, flags.numbers)) type = 'number' + else if (checkAllAliases(key, flags.bools)) type = 'boolean' else if (checkAllAliases(key, flags.arrays)) type = 'array' return type diff --git a/test/yargs-parser.js b/test/yargs-parser.js index d5532ace..65d90e40 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -1492,6 +1492,14 @@ describe('yargs-parser', function () { result.should.have.property('b').and.deep.equal([]) }) + it('should place default of argument in array, when default provided', function () { + var result = parser(['-b'], { + array: 'b', + default: { 'b': 33 } + }) + result.should.have.property('b').and.deep.equal([33]) + }) + it('should place value of argument in array, when one argument provided', function () { var result = parser(['-b', '33'], { array: ['b'] @@ -1618,6 +1626,22 @@ describe('yargs-parser', function () { result.should.have.property('x').that.is.an('array').and.to.deep.equal([true, false]) }) + it('should respect type `boolean` without value for arrays', function () { + var result = parser(['-x', '-x'], { + array: [{ key: 'x', boolean: true }], + configuration: { 'flatten-duplicate-arrays': false } + }) + result.x.should.deep.equal([[true], [true]]) + }) + + it('should respect `boolean negation` for arrays', function () { + var result = parser(['--no-bool', '--no-bool'], { + array: [{ key: 'bool', boolean: true }], + configuration: { 'flatten-duplicate-arrays': false } + }) + result.bool.should.deep.equal([[false], [false]]) + }) + it('should respect the type `number` option for arrays', function () { var result = parser(['-x=5', '2'], { array: [{ key: 'x', number: true }] From f8a2d3f26a84cc57e210deb1aa27b580e4b06388 Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Tue, 20 Aug 2019 03:07:29 +0200 Subject: [PATCH 06/11] fix: take into account aliases when appending arrays from config object (#199) --- index.js | 2 +- test/yargs-parser.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 79d433c4..7f00f363 100644 --- a/index.js +++ b/index.js @@ -555,7 +555,7 @@ function parse (args, opts) { } else { // setting arguments via CLI takes precedence over // values within the config file. - if (!hasKey(argv, fullKey.split('.')) || (flags.arrays[fullKey] && configuration['combine-arrays'])) { + if (!hasKey(argv, fullKey.split('.')) || (checkAllAliases(fullKey, flags.arrays) && configuration['combine-arrays'])) { setArg(fullKey, value) } } diff --git a/test/yargs-parser.js b/test/yargs-parser.js index 65d90e40..e51bb3dc 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -774,6 +774,21 @@ describe('yargs-parser', function () { argv.should.have.property('foo', 'bar') argv.should.have.property('bar', 'baz') }) + + it('should combine array typed options with alias and camel-case', function () { + var argv = parser(['--camEl', 'foo', '--camEl', 'bar', '-a', 'red'], { + array: ['cam-el', 'apple'], + alias: { apple: 'a' }, + configObjects: [{ camEl: 'baz' }, { a: 'sweet' }], + configuration: { + 'combine-arrays': true, + 'camel-case-expansion': true + } + }) + + argv['cam-el'].should.deep.equal(['foo', 'bar', 'baz']) + argv.apple.should.deep.equal(['red', 'sweet']) + }) }) describe('dot notation', function () { From 89d5a158900d923e8de21c9b6994d2b5736dfbe7 Mon Sep 17 00:00:00 2001 From: 0xflotus <0xflotus@gmail.com> Date: Tue, 20 Aug 2019 03:09:52 +0200 Subject: [PATCH 07/11] docs: fix typoe (#195) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dde9f84d..95d70b9e 100644 --- a/README.md +++ b/README.md @@ -370,7 +370,7 @@ node example.js --test-field 1 * key: `strip-dashed` Should dashed keys be removed before returning results? This option has no effect if -`camel-case-exansion` is disabled. +`camel-case-expansion` is disabled. _If disabled:_ From d3d9027f9c9235be8e7a650d0e33d4d55287e0e2 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 20 Aug 2019 04:10:24 +0300 Subject: [PATCH 08/11] docs: fix typos (#194) --- index.js | 6 +++--- test/tokenize-arg-string.js | 2 +- test/yargs-parser.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 7f00f363..cf7872c5 100644 --- a/index.js +++ b/index.js @@ -166,7 +166,7 @@ function parse (args, opts) { key = arg.match(negatedBoolean)[1] setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false) - // -- seperated by space. + // -- separated by space. } else if (arg.match(/^--.+/) || ( !configuration['short-option-groups'] && arg.match(/^-[^-]+/) )) { @@ -196,12 +196,12 @@ function parse (args, opts) { } } - // dot-notation flag seperated by '='. + // dot-notation flag separated by '='. } else if (arg.match(/^-.\..+=/)) { m = arg.match(/^-([^=]+)=([\s\S]*)$/) setArg(m[1], m[2]) - // dot-notation flag seperated by space. + // dot-notation flag separated by space. } else if (arg.match(/^-.\..+/)) { next = args[i + 1] key = arg.match(/^-(.\..+)/)[1] diff --git a/test/tokenize-arg-string.js b/test/tokenize-arg-string.js index 6795e1d2..8575de65 100644 --- a/test/tokenize-arg-string.js +++ b/test/tokenize-arg-string.js @@ -52,7 +52,7 @@ describe('TokenizeArgString', function () { args[2].should.equal('--bar=""') }) - it('handles quoted string with embeded quotes', function () { + it('handles quoted string with embedded quotes', function () { var args = tokenizeArgString('--foo "hello \'world\'" --bar=\'foo "bar"\'') args[0].should.equal('--foo') args[1].should.equal('"hello \'world\'"') diff --git a/test/yargs-parser.js b/test/yargs-parser.js index e51bb3dc..cb1342cf 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -83,7 +83,7 @@ describe('yargs-parser', function () { parse.should.have.property('_').with.length(0) }) - it('should explicitly set a boolean option to false if preceeded by "--no-"', function () { + it('should explicitly set a boolean option to false if preceded by "--no-"', function () { var parse = parser(['--no-moo']) parse.should.have.property('moo', false) parse.should.have.property('_').with.length(0) @@ -894,12 +894,12 @@ describe('yargs-parser', function () { argv.foo.bar.cool.should.eql(11) }) - it("should allow flags to use dot notation, when seperated by '='", function () { + it("should allow flags to use dot notation, when separated by '='", function () { var argv = parser(['-f.foo=99']) argv.f.foo.should.eql(99) }) - it("should allow flags to use dot notation, when seperated by ' '", function () { + it("should allow flags to use dot notation, when separated by ' '", function () { var argv = parser(['-f.foo', '99']) argv.f.foo.should.eql(99) }) From 7909cc4679c76770d4d7950ecd527da823b08f91 Mon Sep 17 00:00:00 2001 From: Eric Henderson Date: Fri, 6 Sep 2019 15:26:33 -0400 Subject: [PATCH 09/11] feat: add configuration option to "collect-unknown-options" (#181) --- README.md | 22 ++++ index.js | 75 +++++++++++- test/yargs-parser.js | 272 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 314 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 95d70b9e..f754df09 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,28 @@ node example.js --test-field 1 { _: [], testField: 1 } ``` +### collect unknown options + +* default: `false` +* key: `collect-unknown-options` + +Should unknown options be collected into `_`? An unknown option is one that is not +configured in `opts`. + +_If disabled_ + +```sh +node example.js --unknown-option --known-option 2 +{ _: [], unknownOption: true, knownOption: 2 } +``` + +_If enabled_ + +```sh +node example.js --unknown-option --known-option 2 +{ _: ['--unknown-option'], knownOption: 2 } +``` + ## Special Thanks The yargs project evolves from optimist and minimist. It owes its diff --git a/index.js b/index.js index cf7872c5..08f9852c 100644 --- a/index.js +++ b/index.js @@ -26,7 +26,8 @@ function parse (args, opts) { 'set-placeholder-key': false, 'halt-at-non-option': false, 'strip-aliased': false, - 'strip-dashed': false + 'strip-dashed': false, + 'collect-unknown-options': false }, opts.configuration) var defaults = opts.default || {} var configObjects = opts.configObjects || [] @@ -142,8 +143,10 @@ function parse (args, opts) { var next var value + if (configuration['collect-unknown-options'] && isUnknownOption(arg)) { + argv._.push(arg) // -- separated by = - if (arg.match(/^--.+=/) || ( + } else if (arg.match(/^--.+=/) || ( !configuration['short-option-groups'] && arg.match(/^-.+=/) )) { // Using [\s\S] instead of . because js doesn't support the @@ -757,6 +760,74 @@ function parse (args, opts) { return isSet } + function hasAnyFlag (key) { + var isSet = false + // XXX Switch to [].concat(...Object.values(flags)) once node.js 6 is dropped + var toCheck = [].concat(...Object.keys(flags).map(k => flags[k])) + + toCheck.forEach(function (flag) { + if (flag[key]) isSet = flag[key] + }) + + return isSet + } + + function hasFlagsMatching (arg, ...patterns) { + var hasFlag = false + var toCheck = [].concat(...patterns) + toCheck.forEach(function (pattern) { + var match = arg.match(pattern) + if (match && hasAnyFlag(match[1])) { + hasFlag = true + } + }) + return hasFlag + } + + // based on a simplified version of the short flag group parsing logic + function hasAllShortFlags (arg) { + // if this is a negative number, or doesn't start with a single hyphen, it's not a short flag group + if (arg.match(negative) || !arg.match(/^-[^-]+/)) { return false } + var hasAllFlags = true + var letters = arg.slice(1).split('') + var next + for (var j = 0; j < letters.length; j++) { + next = arg.slice(j + 2) + + if (!hasAnyFlag(letters[j])) { + hasAllFlags = false + break + } + + if ((letters[j + 1] && letters[j + 1] === '=') || + next === '-' || + (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) || + (letters[j + 1] && letters[j + 1].match(/\W/))) { + break + } + } + return hasAllFlags + } + + function isUnknownOption (arg) { + // ignore negative numbers + if (arg.match(negative)) { return false } + // if this is a short option group and all of them are configured, it isn't unknown + if (hasAllShortFlags(arg)) { return false } + // e.g. '--count=2' + const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/ + // e.g. '-a' or '--arg' + const normalFlag = /^-+([^=]+?)$/ + // e.g. '-a-' + const flagEndingInHyphen = /^-+([^=]+?)-$/ + // e.g. '-abc123' + const flagEndingInDigits = /^-+([^=]+?)\d+$/ + // e.g. '-a/usr/local' + const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/ + // check the different types of flag styles, including negatedBoolean, a pattern defined near the start of the parse method + return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters) + } + // make a best effor to pick a default value // for an option based on name and type. function defaultValue (key) { diff --git a/test/yargs-parser.js b/test/yargs-parser.js index cb1342cf..27f80740 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -9,7 +9,7 @@ var path = require('path') describe('yargs-parser', function () { it('should parse a "short boolean"', function () { - var parse = parser([ '-b' ]) + var parse = parser(['-b']) parse.should.not.have.property('--') parse.should.have.property('b').to.be.ok.and.be.a('boolean') parse.should.have.property('_').with.length(0) @@ -166,7 +166,7 @@ describe('yargs-parser', function () { }) it('should not set the next value as the value of a short option if that option is explicitly defined as a boolean', function () { - var parse = parser([ '-t', 'moo' ], { + var parse = parser(['-t', 'moo'], { boolean: 't' }) parse.should.have.property('t', true).and.be.a('boolean') @@ -208,7 +208,7 @@ describe('yargs-parser', function () { }) it('should allow defining options as boolean in groups', function () { - var parse = parser([ '-x', '-z', 'one', 'two', 'three' ], { + var parse = parser(['-x', '-z', 'one', 'two', 'three'], { boolean: ['x', 'y', 'z'] }) parse.should.have.property('x', true).and.be.a('boolean') @@ -243,25 +243,25 @@ describe('yargs-parser', function () { }) it('should not convert numbers to type number if explicitly defined as strings', function () { - var s = parser([ '-s', '0001234' ], { + var s = parser(['-s', '0001234'], { string: 's' }).s s.should.be.a('string').and.equal('0001234') - var x = parser([ '-x', '56' ], { + var x = parser(['-x', '56'], { string: ['x'] }).x x.should.be.a('string').and.equal('56') }) it('should default numbers to undefined', function () { - var n = parser([ '-n' ], { + var n = parser(['-n'], { number: ['n'] }).n expect(n).to.equal(undefined) }) it('should default number to NaN if value is not a valid number', function () { - var n = parser([ '-n', 'string' ], { + var n = parser(['-n', 'string'], { number: ['n'] }).n expect(n).to.deep.equal(NaN) @@ -269,24 +269,24 @@ describe('yargs-parser', function () { // Fixes: https://github.com/bcoe/yargs/issues/68 it('should parse flag arguments with no right-hand value as strings, if defined as strings', function () { - var s = parser([ '-s' ], { + var s = parser(['-s'], { string: ['s'] }).s s.should.be.a('string').and.equal('') - s = parser([ '-sf' ], { + s = parser(['-sf'], { string: ['s'] }).s s.should.be.a('string').and.equal('') - s = parser([ '--string' ], { + s = parser(['--string'], { string: ['string'] }).string s.should.be.a('string').and.equal('') }) it('should leave all non-hyphenated values as strings if _ is defined as a string', function () { - var s = parser([ ' ', ' ' ], { + var s = parser([' ', ' '], { string: ['_'] })._ s.should.have.length(2) @@ -296,7 +296,7 @@ describe('yargs-parser', function () { describe('normalize', function () { it('should normalize redundant paths', function () { - var a = parser([ '-s', ['', 'tmp', '..', ''].join(path.sep) ], { + var a = parser(['-s', ['', 'tmp', '..', ''].join(path.sep)], { alias: { s: ['save'] }, @@ -316,7 +316,7 @@ describe('yargs-parser', function () { }) it('should normalize when key is also an array', function () { - var a = parser([ '-s', ['', 'tmp', '..', ''].join(path.sep), ['', 'path', 'to', 'new', 'dir', '..', '..', ''].join(path.sep) ], { + var a = parser(['-s', ['', 'tmp', '..', ''].join(path.sep), ['', 'path', 'to', 'new', 'dir', '..', '..', ''].join(path.sep)], { alias: { s: ['save'] }, @@ -331,7 +331,7 @@ describe('yargs-parser', function () { describe('alias', function () { it('should set alias value to the same value as the full option', function () { - var argv = parser([ '-f', '11', '--zoom', '55' ], { + var argv = parser(['-f', '11', '--zoom', '55'], { alias: { z: ['zoom'] } @@ -342,7 +342,7 @@ describe('yargs-parser', function () { }) it('should allow multiple aliases to be specified', function () { - var argv = parser([ '-f', '11', '--zoom', '55' ], { + var argv = parser(['-f', '11', '--zoom', '55'], { alias: { z: ['zm', 'zoom'] } @@ -385,7 +385,7 @@ describe('yargs-parser', function () { }) it('should allow transitive aliases to be specified', function () { - var argv = parser([ '-f', '11', '--zoom', '55' ], { + var argv = parser(['-f', '11', '--zoom', '55'], { alias: { z: 'zm', zm: 'zoom' @@ -431,7 +431,7 @@ describe('yargs-parser', function () { // See: https://github.com/chevex/yargs/issues/12 it('should load options and values from default config if specified', function () { - var argv = parser([ '--foo', 'bar' ], { + var argv = parser(['--foo', 'bar'], { alias: { z: 'zoom' }, @@ -520,7 +520,7 @@ describe('yargs-parser', function () { }) it("should allow config to be set as flag in 'option'", function () { - var argv = parser([ '--settings', jsonPath, '--foo', 'bar' ], { + var argv = parser(['--settings', jsonPath, '--foo', 'bar'], { alias: { z: 'zoom' }, @@ -534,7 +534,7 @@ describe('yargs-parser', function () { it('should load options and values from a JS file when config has .js extention', function () { var jsPath = path.resolve(__dirname, './fixtures/settings.js') - var argv = parser([ '--settings', jsPath, '--foo', 'bar' ], { + var argv = parser(['--settings', jsPath, '--foo', 'bar'], { config: ['settings'] }) @@ -599,7 +599,7 @@ describe('yargs-parser', function () { it('allows a custom parsing function to be provided', function () { var jsPath = path.resolve(__dirname, './fixtures/config.txt') - var argv = parser([ '--settings', jsPath, '--foo', 'bar' ], { + var argv = parser(['--settings', jsPath, '--foo', 'bar'], { config: { settings: function (configPath) { // as an example, parse an environment @@ -624,7 +624,7 @@ describe('yargs-parser', function () { it('allows a custom parsing function to be provided as an alias', function () { var jsPath = path.resolve(__dirname, './fixtures/config.json') - var argv = parser([ '--settings', jsPath, '--foo', 'bar' ], { + var argv = parser(['--settings', jsPath, '--foo', 'bar'], { config: { s: function (configPath) { return JSON.parse(fs.readFileSync(configPath, 'utf-8')) @@ -666,7 +666,7 @@ describe('yargs-parser', function () { describe('config objects', function () { it('should load options from config object', function () { - var argv = parser([ '--foo', 'bar' ], { + var argv = parser(['--foo', 'bar'], { configObjects: [{ apple: 'apple', banana: 42, @@ -855,7 +855,7 @@ describe('yargs-parser', function () { } }) - ;('foo.bar' in argv).should.equal(false) + ; ('foo.bar' in argv).should.equal(false) }) it('should respect .string() for dot notation arguments', function () { @@ -912,7 +912,7 @@ describe('yargs-parser', function () { }) it('should set boolean and alias using explicit true', function () { - var aliased = [ '-h', 'true' ] + var aliased = ['-h', 'true'] var aliasedArgv = parser(aliased, { boolean: ['h'], alias: { @@ -978,12 +978,12 @@ describe('yargs-parser', function () { }) it('should set n to the numeric value 123', function () { - var argv = parser([ '-n123' ]) + var argv = parser(['-n123']) argv.should.have.property('n', 123) }) it('should set n to the numeric value 123, with n at the end of a group', function () { - var argv = parser([ '-ab5n123' ]) + var argv = parser(['-ab5n123']) argv.should.have.property('a', true) argv.should.have.property('b', true) argv.should.have.property('5', true) @@ -992,12 +992,12 @@ describe('yargs-parser', function () { }) it('should set n to the numeric value 123, with = as separator', function () { - var argv = parser([ '-n=123' ]) + var argv = parser(['-n=123']) argv.should.have.property('n', 123) }) it('should set n to the numeric value 123, with n at the end of a group and = as separator', function () { - var argv = parser([ '-ab5n=123' ]) + var argv = parser(['-ab5n=123']) argv.should.have.property('a', true) argv.should.have.property('b', true) argv.should.have.property('5', true) @@ -1008,7 +1008,7 @@ describe('yargs-parser', function () { describe('whitespace', function () { it('should be whitespace', function () { - var argv = parser([ '-x', '\t' ]) + var argv = parser(['-x', '\t']) argv.should.have.property('x', '\t') }) }) @@ -1049,7 +1049,7 @@ describe('yargs-parser', function () { function checkStringArg (opts, hasAlias) { it('should set defaults even if arg looks like a string', function () { - var result = parser([ '--flag', 'extra' ], opts) + var result = parser(['--flag', 'extra'], opts) result.should.have.property('flag', true) result.should.have.property('_').and.deep.equal(['extra']) if (hasAlias) { @@ -1215,7 +1215,7 @@ describe('yargs-parser', function () { } it('should provide count options with dashes as camelCase properties', function () { - var result = parser([ '--some-option', '--some-option', '--some-option' ], { + var result = parser(['--some-option', '--some-option', '--some-option'], { count: ['some-option'] }) @@ -1352,7 +1352,7 @@ describe('yargs-parser', function () { }) it('should set - as the value of s when s is set as a string', function () { - var argv = parser([ '-s', '-' ], { + var argv = parser(['-s', '-'], { string: ['s'] }) @@ -1406,13 +1406,13 @@ describe('yargs-parser', function () { }) it('should not consume the next argument', function () { - var parsed = parser([ '-v', 'moo' ], { + var parsed = parser(['-v', 'moo'], { count: 'v' }) parsed.v.should.equal(1) parsed.should.have.property('_').and.deep.equal(['moo']) - parsed = parser([ '--verbose', 'moomoo', '--verbose' ], { + parsed = parser(['--verbose', 'moomoo', '--verbose'], { count: 'verbose' }) parsed.verbose.should.equal(2) @@ -1709,7 +1709,7 @@ describe('yargs-parser', function () { describe('nargs', function () { it('should allow the number of arguments following a key to be specified', function () { - var result = parser([ '--foo', 'apple', 'bar' ], { + var result = parser(['--foo', 'apple', 'bar'], { narg: { foo: 2 } @@ -1744,7 +1744,7 @@ describe('yargs-parser', function () { }) it('should apply nargs to flag arguments', function () { - var result = parser([ '-f', 'apple', 'bar', 'blerg' ], { + var result = parser(['-f', 'apple', 'bar', 'blerg'], { narg: { f: 2 } @@ -1793,7 +1793,7 @@ describe('yargs-parser', function () { }) it('allows multiple nargs to be set at the same time', function () { - var result = parser([ '--foo', 'apple', 'bar', '--bar', 'banana', '-f' ], { + var result = parser(['--foo', 'apple', 'bar', '--bar', 'banana', '-f'], { narg: { foo: 2, bar: 1 @@ -2689,6 +2689,172 @@ describe('yargs-parser', function () { }) }) }) + + describe('collect-unknown-options = true', function () { + it('should ignore unknown options in long format separated by =', function () { + const argv = parser('--known-arg=1 --unknown-arg=2', { + number: ['known-arg'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['--unknown-arg=2'], + 'known-arg': 1, + 'knownArg': 1 + }) + }) + it('should ignore unknown options in boolean negations', function () { + const argv = parser('--no-known-arg --no-unknown-arg', { + boolean: ['known-arg'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['--no-unknown-arg'], + 'known-arg': false, + 'knownArg': false + }) + }) + it('should ignore unknown options in long format separated by space', function () { + const argv = parser('--known-arg a --unknown-arg b', { + string: ['known-arg'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['--unknown-arg', 'b'], + 'known-arg': 'a', + 'knownArg': 'a' + }) + }) + it('should ignore unknown options in short dot format separated by equals', function () { + const argv = parser('-k.arg=a -u.arg=b', { + string: ['k.arg'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u.arg=b'], + 'k': { + 'arg': 'a' + } + }) + }) + it('should ignore unknown options in short dot format separated by space', function () { + const argv = parser('-k.arg 1 -u.arg 2', { + number: ['k.arg'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u.arg', '2'], + 'k': { + 'arg': 1 + } + }) + }) + it('should ignore unknown options in short format separated by equals', function () { + const argv = parser('-k=a -u=b', { + string: ['k'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u=b'], + 'k': 'a' + }) + }) + it('should ignore unknown options in short format followed by hyphen', function () { + const argv = parser('-k- -u-', { + string: ['k'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u-'], + 'k': '-' + }) + }) + it('should ignore unknown options in short format separated by space', function () { + const argv = parser('-k 1 -u 2', { + number: ['k'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u', '2'], + 'k': 1 + }) + }) + it('should ignore unknown options in short format followed by a number', function () { + const argv = parser('-k1 -u2', { + number: ['k'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u2'], + 'k': 1 + }) + }) + it('should ignore unknown options in short format followed by a non-word character', function () { + const argv = parser('-k/1/ -u/2/', { + string: ['k'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-u/2/'], + 'k': '/1/' + }) + }) + it('should ignore unknown options in short format with multiple flags in one argument where an unknown flag is before the end', function () { + const argv = parser('-kuv', { + boolean: ['k', 'v'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: ['-kuv'] + }) + }) + it('should parse known options in short format with multiple flags in one argument where no unknown flag is in the argument', function () { + const argv = parser('-kv', { + boolean: ['k', 'v'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: [], + k: true, + v: true + }) + }) + it('should parse negative numbers', function () { + const argv = parser('-k -33', { + boolean: ['k'], + configuration: { + 'collect-unknown-options': true + } + }) + argv.should.deep.equal({ + _: [-33], + k: true + }) + }) + }) }) // addresses: https://github.com/yargs/yargs-parser/issues/41 @@ -2832,9 +2998,9 @@ describe('yargs-parser', function () { bar: fancyNumberParser } }) - ;(typeof parsed.foo).should.equal('string') + ; (typeof parsed.foo).should.equal('string') parsed.foo.should.equal('88888889999990000998989898989898') - ;(typeof parsed.bar).should.equal('number') + ; (typeof parsed.bar).should.equal('number') parsed.bar.should.equal(998) }) @@ -2868,7 +3034,7 @@ describe('yargs-parser', function () { runcount++ return undefined } - parser([ '--foo', 'bar' ], { + parser(['--foo', 'bar'], { alias: { foo: ['f', 'foo-bar', 'bar'], b: ['bar'] @@ -2883,7 +3049,7 @@ describe('yargs-parser', function () { // see: https://github.com/yargs/yargs-parser/issues/37 it('normalizes all paths in array when provided via config object', function () { - var argv = parser([ '--foo', 'bar' ], { + var argv = parser(['--foo', 'bar'], { array: ['a'], normalize: ['a'], configObjects: [{ 'a': ['bin/../a.txt', 'bin/../b.txt'] }] @@ -2893,17 +3059,17 @@ describe('yargs-parser', function () { // see: https://github.com/yargs/yargs/issues/963 it('does not magically convert numeric strings larger than Number.MAX_SAFE_INTEGER', () => { - const argv = parser([ '--foo', '93940495950949399948393' ]) + const argv = parser(['--foo', '93940495950949399948393']) argv.foo.should.equal('93940495950949399948393') }) it('does not magically convert scientific notation larger than Number.MAX_SAFE_INTEGER', () => { - const argv = parser([ '--foo', '33e99999' ]) + const argv = parser(['--foo', '33e99999']) argv.foo.should.equal('33e99999') }) it('converts numeric options larger than Number.MAX_SAFE_INTEGER to number', () => { - const argv = parser([ '--foo', '93940495950949399948393' ], { + const argv = parser(['--foo', '93940495950949399948393'], { number: ['foo'] }) argv.foo.should.equal(9.39404959509494e+22) @@ -2930,21 +3096,21 @@ describe('yargs-parser', function () { // see: https://github.com/yargs/yargs-parser/issues/101 describe('dot-notation array arguments combined with string arguments', function () { it('parses correctly when dot-notation argument is first', function () { - var argv = parser([ '--foo.bar', 'baz', '--foo', 'bux' ]) + var argv = parser(['--foo.bar', 'baz', '--foo', 'bux']) Array.isArray(argv.foo).should.equal(true) argv.foo[0].bar.should.equal('baz') argv.foo[1].should.equal('bux') }) it('parses correctly when dot-notation argument is last', function () { - var argv = parser([ '--foo', 'bux', '--foo.bar', 'baz' ]) + var argv = parser(['--foo', 'bux', '--foo.bar', 'baz']) Array.isArray(argv.foo).should.equal(true) argv.foo[0].should.equal('bux') argv.foo[1].bar.should.equal('baz') }) it('parses correctly when there are multiple dot-notation arguments', function () { - var argv = parser([ '--foo.first', 'firstvalue', '--foo', 'bux', '--foo.bar', 'baz', '--foo.bla', 'banana' ]) + var argv = parser(['--foo.first', 'firstvalue', '--foo', 'bux', '--foo.bar', 'baz', '--foo.bla', 'banana']) Array.isArray(argv.foo).should.equal(true) argv.foo.length.should.equal(4) argv.foo[0].first.should.equal('firstvalue') @@ -2983,7 +3149,7 @@ describe('yargs-parser', function () { // see: https://github.com/yargs/yargs-parser/issues/144 it('number/string types should use default when no right-hand value', () => { - let argv = parser([ '--foo' ], { + let argv = parser(['--foo'], { number: ['foo'], default: { foo: 99 @@ -2991,7 +3157,7 @@ describe('yargs-parser', function () { }) argv.foo.should.equal(99) - argv = parser([ '-b' ], { + argv = parser(['-b'], { alias: { bar: 'b' }, @@ -3005,7 +3171,7 @@ describe('yargs-parser', function () { describe('stripping', function () { it('strip-dashed removes expected fields from argv', function () { - const argv = parser([ '--test-value', '1' ], { + const argv = parser(['--test-value', '1'], { number: ['test-value'], alias: { 'test-value': ['alt-test'] @@ -3022,7 +3188,7 @@ describe('yargs-parser', function () { }) it('strip-aliased removes expected fields from argv', function () { - const argv = parser([ '--test-value', '1' ], { + const argv = parser(['--test-value', '1'], { number: ['test-value'], alias: { 'test-value': ['alt-test'] @@ -3039,7 +3205,7 @@ describe('yargs-parser', function () { }) it('strip-aliased and strip-dashed combined removes expected fields from argv', function () { - const argv = parser([ '--test-value', '1' ], { + const argv = parser(['--test-value', '1'], { number: ['test-value'], alias: { 'test-value': ['alt-test'] @@ -3056,7 +3222,7 @@ describe('yargs-parser', function () { }) it('ignores strip-dashed if camel-case-expansion is disabled', function () { - const argv = parser([ '--test-value', '1' ], { + const argv = parser(['--test-value', '1'], { number: ['test-value'], configuration: { 'camel-case-expansion': false, From 051601951c458e1294270c6baca79b4aff32f8b6 Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Fri, 6 Sep 2019 21:26:52 +0200 Subject: [PATCH 10/11] docs: fix typo require (#200) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f754df09..1110bbca 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ node example.js --foo=33 --bar hello _or parse a string!_ ```js -var argv = require('./')('--foo=99 --bar=33') +var argv = require('yargs-parser')('--foo=99 --bar=33') console.log(argv) ``` From ac11361ab90204698499ca06e292fac47088971a Mon Sep 17 00:00:00 2001 From: bcoe Date: Fri, 6 Sep 2019 12:33:00 -0700 Subject: [PATCH 11/11] chore(release): 14.0.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df11c002..a8d22d3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [14.0.0](https://github.com/yargs/yargs-parser/compare/v13.1.1...v14.0.0) (2019-09-06) + + +### Bug Fixes + +* boolean arrays with default values ([#185](https://github.com/yargs/yargs-parser/issues/185)) ([7d42572](https://github.com/yargs/yargs-parser/commit/7d42572)) +* boolean now behaves the same as other array types ([#184](https://github.com/yargs/yargs-parser/issues/184)) ([17ca3bd](https://github.com/yargs/yargs-parser/commit/17ca3bd)) +* eatNargs() for 'opt.narg === 0' and boolean typed options ([#188](https://github.com/yargs/yargs-parser/issues/188)) ([c5a1db0](https://github.com/yargs/yargs-parser/commit/c5a1db0)) +* maybeCoerceNumber now takes precedence over coerce return value ([#182](https://github.com/yargs/yargs-parser/issues/182)) ([2f26436](https://github.com/yargs/yargs-parser/commit/2f26436)) +* take into account aliases when appending arrays from config object ([#199](https://github.com/yargs/yargs-parser/issues/199)) ([f8a2d3f](https://github.com/yargs/yargs-parser/commit/f8a2d3f)) + + +### Features + +* add configuration option to "collect-unknown-options" ([#181](https://github.com/yargs/yargs-parser/issues/181)) ([7909cc4](https://github.com/yargs/yargs-parser/commit/7909cc4)) +* maybeCoerceNumber() now takes into account arrays ([#187](https://github.com/yargs/yargs-parser/issues/187)) ([31c204b](https://github.com/yargs/yargs-parser/commit/31c204b)) + + +### BREAKING CHANGES + +* unless "parse-numbers" is set to "false", arrays of numeric strings are now parsed as numbers, rather than strings. +* we have dropped the broken "defaulted" functionality; we would like to revisit adding this in the future. +* maybeCoerceNumber now takes precedence over coerce return value (#182) + + + ### [13.1.1](https://www.github.com/yargs/yargs-parser/compare/v13.1.0...v13.1.1) (2019-06-10) diff --git a/package.json b/package.json index 35a3885d..806485e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yargs-parser", - "version": "13.1.1", + "version": "14.0.0", "description": "the mighty option parser used by yargs", "main": "index.js", "scripts": {