Repository: yargs/yargs-parser
Pull request #136 (2018-09-28 17:46:52)

fix: make requiresArg work with arrays
When `requiresArg` was used together with `array`, only the first
argument of the array would end up being parsed. With this change
things work as expected.

The `requireArg` option sets the `nargs` options to `1`, so only
one additional argument will be parsed. The problem was that that
parsing step was checked before the array parsing one. The solution
is as simple as flipping those if conditions and check if its an
array first, hence ignoring the `nargs` option.

Fixes https://github.com/yargs/yargs/issues/1170.


Patch:
diff --git a/.travis.yml b/.travis.yml
index a0fa326..e1e7f5e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,9 +6,3 @@ node_js:
   - "6"
   - "node"
 after_script: npm run coverage
-deploy:
-  provider: npm
-  email: ben@npmjs.com
-  api_key: $NPM_TOKEN
-  on:
-    tags: true
diff --git a/README.md b/README.md
index 9c43338..138f73c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # yargs-parser
 
-[![Build Status](https://travis-ci.org/yargs/yargs-parser.png)](https://travis-ci.org/yargs/yargs-parser)
+[![Build Status](https://travis-ci.org/yargs/yargs-parser.svg)](https://travis-ci.org/yargs/yargs-parser)
 [![Coverage Status](https://coveralls.io/repos/yargs/yargs-parser/badge.svg?branch=)](https://coveralls.io/r/yargs/yargs-parser?branch=master)
 [![NPM version](https://img.shields.io/npm/v/yargs-parser.svg)](https://www.npmjs.com/package/yargs-parser)
 [![Windows Tests](https://img.shields.io/appveyor/ci/bcoe/yargs-parser/master.svg?label=Windows%20Tests)](https://ci.appveyor.com/project/bcoe/yargs-parser)
diff --git a/index.js b/index.js
index a3849bc..e0054fd 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,5 @@
 var camelCase = require('camelcase')
+var decamelize = require('decamelize')
 var path = require('path')
 var tokenizeArgString = require('./lib/tokenize-arg-string')
 var util = require('util')
@@ -136,7 +137,7 @@ function parse (args, opts) {
     var next
     var value
 
-    // -- seperated by =
+    // -- separated by =
     if (arg.match(/^--.+=/) || (
       !configuration['short-option-groups'] && arg.match(/^-.+=/)
     )) {
@@ -166,12 +167,12 @@ function parse (args, opts) {
     )) {
       key = arg.match(/^--?(.+)/)[1]
 
-      // nargs format = '--foo a b c'
-      if (checkAllAliases(key, flags.nargs)) {
-        i = eatNargs(i, key, args)
       // array format = '--foo a b c'
-      } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) {
+      if (checkAllAliases(key, flags.arrays) && args.length > i + 1) {
         i = eatArray(i, key, args)
+      // nargs format = '--foo a b c'
+      } else if (checkAllAliases(key, flags.nargs)) {
+        i = eatNargs(i, key, args)
       } else {
         next = args[i + 1]
 
@@ -371,7 +372,10 @@ function parse (args, opts) {
     unsetDefaulted(key)
 
     if (/-/.test(key) && configuration['camel-case-expansion']) {
-      addNewAlias(key, camelCase(key))
+      var alias = key.split('.').map(function (prop) {
+        return camelCase(prop)
+      }).join('.')
+      addNewAlias(key, alias)
     }
 
     var value = processValue(key, val)
@@ -639,7 +643,7 @@ function parse (args, opts) {
       o[key] = increment(o[key])
     } else if (Array.isArray(o[key])) {
       if (duplicate && isTypeArray && isValueArray) {
-        o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : [o[key]].concat([value])
+        o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : (Array.isArray(o[key][0]) ? o[key] : [o[key]]).concat([value])
       } else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) {
         o[key] = value
       } else {
@@ -674,6 +678,16 @@ function parse (args, opts) {
             }
           }
         })
+        // For "--optionName", also set argv['option-name']
+        flags.aliases[key].concat(key).forEach(function (x) {
+          if (/[A-Z]/.test(x) && configuration['camel-case-expansion']) {
+            var c = decamelize(x, '-')
+            if (c !== key && flags.aliases[key].indexOf(c) === -1) {
+              flags.aliases[key].push(c)
+              newAliases[c] = true
+            }
+          }
+        })
         flags.aliases[key].forEach(function (x) {
           flags.aliases[x] = [key].concat(flags.aliases[key].filter(function (y) {
             return x !== y
diff --git a/package.json b/package.json
index 74b2efe..933ca21 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,8 @@
     "standard-version": "^4.3.0"
   },
   "dependencies": {
-    "camelcase": "^4.1.0"
+    "camelcase": "^4.1.0",
+    "decamelize": "^2.0.0"
   },
   "files": [
     "lib",


Test patch:
diff --git a/test/yargs-parser.js b/test/yargs-parser.js
index 2910424..e483536 100644
--- a/test/yargs-parser.js
+++ b/test/yargs-parser.js
@@ -1115,6 +1115,15 @@ describe('yargs-parser', function () {
 
         argv.fooBar.should.equal(99)
       })
+
+      // Fixes: https://github.com/yargs/yargs-parser/issues/77
+      it('should combine dot-notation and camel-case expansion', function () {
+        var argv = parser(['--dot-notation.foo.bar'])
+
+        argv.should.satisfy(function (args) {
+          return args.dotNotation.foo.bar
+        })
+      })
     })
 
     it('should define option as boolean and set default to true', function () {
@@ -1529,6 +1538,35 @@ describe('yargs-parser', function () {
       var result = parser(['-x', 'val1', '-x', 'val1'])
       result.should.have.property('x').that.is.an('array').and.to.deep.equal(['val1', 'val1'])
     })
+
+    it('should eat camelCase switch with camelCase array option', function () {
+      var result = parser(['--someOption', '1', '2'], {
+        array: ['someOption']
+      })
+      Array.isArray(result.someOption).should.equal(true)
+      result.someOption.should.deep.equal([1, 2])
+    })
+    it('should eat hyphenated switch with hyphenated array option', function () {
+      var result = parser(['--some-option', '1', '2'], {
+        array: ['some-option']
+      })
+      Array.isArray(result['some-option']).should.equal(true)
+      result['some-option'].should.deep.equal([1, 2])
+    })
+    it('should eat camelCase switch with hyphenated array option', function () {
+      var result = parser(['--someOption', '1', '2'], {
+        array: ['some-option']
+      })
+      Array.isArray(result['some-option']).should.equal(true)
+      result['some-option'].should.deep.equal([1, 2])
+    })
+    it('should eat hyphenated switch with camelCase array option', function () {
+      var result = parser(['--some-option', '1', '2'], {
+        array: ['someOption']
+      })
+      Array.isArray(result['someOption']).should.equal(true)
+      result['someOption'].should.deep.equal([1, 2])
+    })
   })
 
   describe('nargs', function () {
@@ -1664,6 +1702,17 @@ describe('yargs-parser', function () {
 
       result.foo.should.eql('a')
     })
+
+    it('should be ignored if input is an array', function () {
+      var result = parser(['--foo', 'a', 'b'], {
+        array: 'foo',
+        narg: {
+          foo: 1
+        }
+      })
+
+      result.foo.should.eql(['a', 'b'])
+    })
   })
 
   describe('env vars', function () {
@@ -2088,6 +2137,16 @@ describe('yargs-parser', function () {
 
         parsed['x'].should.deep.equal([['a', 'b'], ['c', 'd']])
       })
+      it('nests duplicate array types of more than 2', function () {
+        var parsed = parser('-x a b -x c d -x e f -x g h', {
+          array: ['x'],
+          configuration: {
+            'flatten-duplicate-arrays': false
+          }
+        })
+
+        parsed['x'].should.deep.equal([['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']])
+      })
       it('doesn\'t nests single arrays', function () {
         var parsed = parser('-x a b', {
           array: ['x'],