Repository: yargs/yargs-parser
Pull request #172 (2019-04-04 18:37:46)

feat: Add `strip-aliased` and `strip-dashed` configuration options.
Enabling these options cause redundant keys to be removed from the
results.  This can be useful when printing the results for debugging as
it reduces the amount of information to look at.


Patch:
diff --git a/README.md b/README.md
index e1f8abe..94bbe46 100644
--- a/README.md
+++ b/README.md
@@ -340,6 +340,49 @@ node example.js -a run b -x y
 { _: [ 'run', 'b', '-x', 'y' ], a: true }
 ```
 
+### strip aliased
+
+* default: `false`
+* key: `strip-aliased`
+
+Should aliases be removed before returning results?
+
+_If disabled:_
+
+```sh
+node example.js --test-field 1
+{ _: [], 'test-field': 1, testField: 1, 'test-alias': 1, testAlias: 1 }
+```
+
+_If enabled:_
+
+```sh
+node example.js --test-field 1
+{ _: [], 'test-field': 1, testField: 1 }
+```
+
+### strip dashed
+
+* default: `false`
+* key: `strip-dashed`
+
+Should dashed keys be removed before returning results?  This option has no effect if
+`camel-case-exansion` is disabled.
+
+_If disabled:_
+
+```sh
+node example.js --test-field 1
+{ _: [], 'test-field': 1, testField: 1 }
+```
+
+_If enabled:_
+
+```sh
+node example.js --test-field 1
+{ _: [], testField: 1 }
+```
+
 ## Special Thanks
 
 The yargs project evolves from optimist and minimist. It owes its
diff --git a/index.js b/index.js
index 20d472d..ed54b8d 100644
--- a/index.js
+++ b/index.js
@@ -12,7 +12,7 @@ function parse (args, opts) {
 
   // aliases might have transitive relationships, normalize this.
   var aliases = combineAliases(opts.alias || {})
-  var configuration = assign({
+  var configuration = Object.assign({
     'short-option-groups': true,
     'camel-case-expansion': true,
     'dot-notation': true,
@@ -24,7 +24,9 @@ function parse (args, opts) {
     'populate--': false,
     'combine-arrays': false,
     'set-placeholder-key': false,
-    'halt-at-non-option': false
+    'halt-at-non-option': false,
+    'strip-aliased': false,
+    'strip-dashed': false
   }, opts.configuration)
   var defaults = opts.default || {}
   var configObjects = opts.configObjects || []
@@ -33,9 +35,7 @@ function parse (args, opts) {
   var notFlagsArgv = notFlagsOption ? '--' : '_'
   var newAliases = {}
   // allow a i18n handler to be passed in, default to a fake one (util.format).
-  var __ = opts.__ || function (str) {
-    return util.format.apply(util, Array.prototype.slice.call(arguments))
-  }
+  var __ = opts.__ || util.format
   var error = null
   var flags = {
     aliases: {},
@@ -188,7 +188,7 @@ function parse (args, opts) {
       } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) {
         i = eatArray(i, key, args)
       } else {
-        next = args[i + 1]
+        next = flags.nargs[key] === 0 ? undefined : args[i + 1]
 
         if (next !== undefined && (!next.match(/^-/) ||
           next.match(negative)) &&
@@ -333,6 +333,23 @@ function parse (args, opts) {
     argv[notFlagsArgv].push(key)
   })
 
+  if (configuration['camel-case-expansion'] && configuration['strip-dashed']) {
+    Object.keys(argv).filter(key => key !== '--' && key.includes('-')).forEach(key => {
+      delete argv[key]
+    })
+  }
+
+  if (configuration['strip-aliased']) {
+    // XXX Switch to [].concat(...Object.values(aliases)) once node.js 6 is dropped
+    ;[].concat(...Object.keys(aliases).map(k => aliases[k])).forEach(alias => {
+      if (configuration['camel-case-expansion']) {
+        delete argv[alias.split('.').map(prop => camelCase(prop)).join('.')]
+      }
+
+      delete argv[alias]
+    })
+  }
+
   // how many arguments should we consume, based
   // on the nargs option?
   function eatNargs (i, key, args) {
@@ -687,8 +704,8 @@ function parse (args, opts) {
   }
 
   // extend the aliases list with inferred aliases.
-  function extendAliases () {
-    Array.prototype.slice.call(arguments).forEach(function (obj) {
+  function extendAliases (...args) {
+    args.forEach(function (obj) {
       Object.keys(obj || {}).forEach(function (key) {
         // short-circuit if we've already added a key
         // to the aliases array, for example it might
@@ -856,20 +873,6 @@ function combineAliases (aliases) {
   return combined
 }
 
-function assign (defaults, configuration) {
-  var o = {}
-  configuration = configuration || {}
-
-  Object.keys(defaults).forEach(function (k) {
-    o[k] = defaults[k]
-  })
-  Object.keys(configuration).forEach(function (k) {
-    o[k] = configuration[k]
-  })
-
-  return o
-}
-
 // this function should only be called when a count is given as an arg
 // it is NOT called to set a default value
 // thus we can start the count at 1 instead of 0


Test patch:
diff --git a/test/yargs-parser.js b/test/yargs-parser.js
index ee76e41..fcff562 100644
--- a/test/yargs-parser.js
+++ b/test/yargs-parser.js
@@ -194,6 +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 allow defining options as boolean in groups', function () {
     var parse = parser([ '-x', '-z', 'one', 'two', 'three' ], {
       boolean: ['x', 'y', 'z']
@@ -2863,4 +2874,71 @@ describe('yargs-parser', function () {
     })
     argv.bar.should.equal('hello')
   })
+
+  describe('stripping', function () {
+    it('strip-dashed removes expected fields from argv', function () {
+      const argv = parser([ '--test-value', '1' ], {
+        number: ['test-value'],
+        alias: {
+          'test-value': ['alt-test']
+        },
+        configuration: {
+          'strip-dashed': true
+        }
+      })
+      argv.should.deep.equal({
+        _: [],
+        'testValue': 1,
+        'altTest': 1
+      })
+    })
+
+    it('strip-aliased removes expected fields from argv', function () {
+      const argv = parser([ '--test-value', '1' ], {
+        number: ['test-value'],
+        alias: {
+          'test-value': ['alt-test']
+        },
+        configuration: {
+          'strip-aliased': true
+        }
+      })
+      argv.should.deep.equal({
+        _: [],
+        'test-value': 1,
+        'testValue': 1
+      })
+    })
+
+    it('strip-aliased and strip-dashed combined removes expected fields from argv', function () {
+      const argv = parser([ '--test-value', '1' ], {
+        number: ['test-value'],
+        alias: {
+          'test-value': ['alt-test']
+        },
+        configuration: {
+          'strip-aliased': true,
+          'strip-dashed': true
+        }
+      })
+      argv.should.deep.equal({
+        _: [],
+        'testValue': 1
+      })
+    })
+
+    it('ignores strip-dashed if camel-case-expansion is disabled', function () {
+      const argv = parser([ '--test-value', '1' ], {
+        number: ['test-value'],
+        configuration: {
+          'camel-case-expansion': false,
+          'strip-dashed': true
+        }
+      })
+      argv.should.deep.equal({
+        _: [],
+        'test-value': 1
+      })
+    })
+  })
 })