diff --git a/index.js b/index.js index f2ca6a3..128088d 100644 --- a/index.js +++ b/index.js @@ -78,7 +78,5 @@ function commandLineArgs (optionDefinitions, options) { } } - const result = output.toObject({ skipUnknown: !options.partial }) - const optionUtil = require('./lib/option-util') - return options.camelCase ? optionUtil.camelCaseObject(result) : result + return output.toObject({ skipUnknown: !options.partial, camelCase: options.camelCase }) } diff --git a/lib/option-util.js b/lib/option-util.js deleted file mode 100644 index 65f17bf..0000000 --- a/lib/option-util.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict' - -function camelCaseObject (object) { - const camelCase = require('lodash.camelcase') - for (const prop of Object.keys(object)) { - const converted = camelCase(prop) - if (converted !== prop) { - object[converted] = object[prop] - delete object[prop] - } - } - return object -} - -exports.camelCaseObject = camelCaseObject diff --git a/lib/output-grouped.js b/lib/output-grouped.js index ace2061..9ca1c77 100644 --- a/lib/output-grouped.js +++ b/lib/output-grouped.js @@ -5,6 +5,8 @@ class GroupedOutput extends Output { toObject (options) { const arrayify = require('array-back') const t = require('typical') + const camelCase = require('lodash.camelcase') + const superOutputNoCamel = super.toObject({ skipUnknown: options.skipUnknown }) const superOutput = super.toObject(options) const unknown = superOutput._unknown delete superOutput._unknown @@ -14,20 +16,22 @@ class GroupedOutput extends Output { if (unknown && unknown.length) grouped._unknown = unknown this.definitions.whereGrouped().forEach(def => { - const outputValue = superOutput[def.name] + const name = options.camelCase ? camelCase(def.name) : def.name + const outputValue = superOutputNoCamel[def.name] for (const groupName of arrayify(def.group)) { grouped[groupName] = grouped[groupName] || {} if (t.isDefined(outputValue)) { - grouped[groupName][def.name] = outputValue + grouped[groupName][name] = outputValue } } }) this.definitions.whereNotGrouped().forEach(def => { - const outputValue = superOutput[def.name] + const name = options.camelCase ? camelCase(def.name) : def.name + const outputValue = superOutputNoCamel[def.name] if (t.isDefined(outputValue)) { if (!grouped._none) grouped._none = {} - grouped._none[def.name] = outputValue + grouped._none[name] = outputValue } }) return grouped diff --git a/lib/output.js b/lib/output.js index 53eef14..65bad23 100644 --- a/lib/output.js +++ b/lib/output.js @@ -21,10 +21,11 @@ class Output extends Map { } toObject (options) { + const camelCase = require('lodash.camelcase') options = options || {} const output = {} for (const item of this) { - const name = item[0] + const name = options.camelCase && item[0] !== '_unknown' ? camelCase(item[0]) : item[0] const option = item[1] if (name === '_unknown' && !option.get().length) continue output[name] = option.get() diff --git a/package-lock.json b/package-lock.json index 539b6f6..9d0410a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,15 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-escape-sequences": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", + "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", + "dev": true, + "requires": { + "array-back": "2.0.0" + } + }, "argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", @@ -117,6 +126,12 @@ "tweetnacl": "0.14.5" } }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, "boom": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", @@ -227,9 +242,9 @@ } }, "command-line-args": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.0.tgz", - "integrity": "sha512-jp5PY9xA7pff6TaLS5y10zRqD5Xwsk/kODoIZy+FIKyHwcKFBsMAL3OMwL88VfrpAN706WFWZaPEjDaY5u2/xA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.1.tgz", + "integrity": "sha512-gRJDcIjFSzMcmG/GrJlgL0wWoAxr11mVzCq32bjka0endupm9meLwvoJUKc4HDeFiEIB2X3GvNrhF5cKO4Bd4A==", "dev": true, "requires": { "argv-tools": "0.1.1", @@ -239,6 +254,19 @@ "typical": "2.6.1" } }, + "command-line-tool": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", + "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", + "dev": true, + "requires": { + "ansi-escape-sequences": "4.0.0", + "array-back": "2.0.0", + "command-line-args": "5.0.1", + "command-line-usage": "4.1.0", + "typical": "2.6.1" + } + }, "command-line-usage": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", @@ -249,17 +277,6 @@ "array-back": "2.0.0", "table-layout": "0.4.2", "typical": "2.6.1" - }, - "dependencies": { - "ansi-escape-sequences": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", - "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", - "dev": true, - "requires": { - "array-back": "2.0.0" - } - } } }, "common-sequence": { @@ -358,6 +375,26 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "dmd": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/dmd/-/dmd-3.0.10.tgz", + "integrity": "sha512-+tRZIFV9fII538XFZSoRP1abtIy55RYa4waGvtKB36LD97NRorWsYT3V3HEURmnXpA4eGIFQph1E2f+51hWrTg==", + "dev": true, + "requires": { + "array-back": "2.0.0", + "cache-point": "0.4.1", + "common-sequence": "1.0.2", + "file-set": "1.1.1", + "handlebars": "4.0.11", + "marked": "0.3.12", + "object-get": "2.1.0", + "reduce-flatten": "1.0.1", + "reduce-unique": "1.0.0", + "reduce-without": "1.0.1", + "test-value": "3.0.0", + "walk-back": "3.0.0" + } + }, "ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", @@ -593,6 +630,15 @@ "esprima": "4.0.0" } }, + "js2xmlparser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz", + "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=", + "dev": true, + "requires": { + "xmlcreate": "1.0.2" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -618,32 +664,23 @@ "strip-json-comments": "2.0.1", "taffydb": "2.6.2", "underscore": "1.8.3" - }, - "dependencies": { - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "js2xmlparser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz", - "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=", - "dev": true, - "requires": { - "xmlcreate": "1.0.2" - } - }, - "klaw": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz", - "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - } + } + }, + "jsdoc-api": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-4.0.1.tgz", + "integrity": "sha512-qCzHGQxfd9toMRjQft9E44Y40zWDPgf13pt3n+xExk8+wmVd7aueW6cTSQOHyjQG1v07INunQD8AcCAPxhZVmw==", + "dev": true, + "requires": { + "array-back": "2.0.0", + "cache-point": "0.4.1", + "collect-all": "1.0.3", + "file-set": "1.1.1", + "fs-then-native": "2.0.0", + "jsdoc": "3.5.5", + "object-to-spawn-args": "1.1.1", + "temp-path": "1.0.0", + "walk-back": "3.0.0" } }, "jsdoc-parse": { @@ -673,67 +710,6 @@ "jsdoc-api": "4.0.1", "jsdoc-parse": "3.0.1", "walk-back": "3.0.0" - }, - "dependencies": { - "ansi-escape-sequences": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", - "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", - "dev": true, - "requires": { - "array-back": "2.0.0" - } - }, - "command-line-tool": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", - "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", - "dev": true, - "requires": { - "ansi-escape-sequences": "4.0.0", - "array-back": "2.0.0", - "command-line-args": "5.0.0", - "command-line-usage": "4.1.0", - "typical": "2.6.1" - } - }, - "dmd": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/dmd/-/dmd-3.0.10.tgz", - "integrity": "sha512-+tRZIFV9fII538XFZSoRP1abtIy55RYa4waGvtKB36LD97NRorWsYT3V3HEURmnXpA4eGIFQph1E2f+51hWrTg==", - "dev": true, - "requires": { - "array-back": "2.0.0", - "cache-point": "0.4.1", - "common-sequence": "1.0.2", - "file-set": "1.1.1", - "handlebars": "4.0.11", - "marked": "0.3.12", - "object-get": "2.1.0", - "reduce-flatten": "1.0.1", - "reduce-unique": "1.0.0", - "reduce-without": "1.0.1", - "test-value": "3.0.0", - "walk-back": "3.0.0" - } - }, - "jsdoc-api": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-4.0.1.tgz", - "integrity": "sha512-qCzHGQxfd9toMRjQft9E44Y40zWDPgf13pt3n+xExk8+wmVd7aueW6cTSQOHyjQG1v07INunQD8AcCAPxhZVmw==", - "dev": true, - "requires": { - "array-back": "2.0.0", - "cache-point": "0.4.1", - "collect-all": "1.0.3", - "file-set": "1.1.1", - "fs-then-native": "2.0.0", - "jsdoc": "3.5.5", - "object-to-spawn-args": "1.1.1", - "temp-path": "1.0.0", - "walk-back": "3.0.0" - } - } } }, "json-schema": { @@ -775,6 +751,15 @@ "is-buffer": "1.1.6" } }, + "klaw": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz", + "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -1225,21 +1210,10 @@ "requires": { "ansi-escape-sequences": "4.0.0", "array-back": "2.0.0", - "command-line-args": "5.0.0", + "command-line-args": "5.0.1", "command-line-usage": "4.1.0", "file-set": "1.1.1", "reduce-flatten": "1.0.1" - }, - "dependencies": { - "ansi-escape-sequences": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz", - "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==", - "dev": true, - "requires": { - "array-back": "2.0.0" - } - } } }, "test-value": { diff --git a/test/camel-case.js b/test/camel-case.js index ce17b94..0a2ed60 100644 --- a/test/camel-case.js +++ b/test/camel-case.js @@ -5,7 +5,7 @@ const a = require('assert') const runner = new TestRunner() -runner.test('camel-case', function () { +runner.test('camel-case: regular', function () { const optionDefinitions = [ { name: 'one-two' }, { name: 'three', type: Boolean } @@ -17,3 +17,62 @@ runner.test('camel-case', function () { three: true }) }) + +runner.test('camel-case: grouped', function () { + const optionDefinitions = [ + { name: 'one-one', group: 'a' }, + { name: 'two-two', group: 'a' }, + { name: 'three-three', group: 'b', type: Boolean }, + { name: 'four-four' } + ] + const argv = [ '--one-one', '1', '--two-two', '2', '--three-three', '--four-four', '4' ] + const result = commandLineArgs(optionDefinitions, { argv, camelCase: true }) + a.deepStrictEqual(result, { + a: { + oneOne: '1', + twoTwo: '2' + }, + b: { + threeThree: true + }, + _all: { + oneOne: '1', + twoTwo: '2', + threeThree: true, + fourFour: '4' + }, + _none: { + fourFour: '4' + } + }) +}) + +runner.test('camel-case: grouped with unknowns', function () { + const optionDefinitions = [ + { name: 'one-one', group: 'a' }, + { name: 'two-two', group: 'a' }, + { name: 'three-three', group: 'b', type: Boolean }, + { name: 'four-four' } + ] + const argv = [ '--one-one', '1', '--two-two', '2', '--three-three', '--four-four', '4', '--five' ] + const result = commandLineArgs(optionDefinitions, { argv, camelCase: true, partial: true }) + a.deepStrictEqual(result, { + a: { + oneOne: '1', + twoTwo: '2' + }, + b: { + threeThree: true + }, + _all: { + oneOne: '1', + twoTwo: '2', + threeThree: true, + fourFour: '4' + }, + _none: { + fourFour: '4' + }, + _unknown: [ '--five' ] + }) +}) diff --git a/test/grouping.js b/test/grouping.js index e415094..39d8384 100644 --- a/test/grouping.js +++ b/test/grouping.js @@ -118,3 +118,57 @@ runner.test('groups: two ungrouped, both set', function () { _none: { three: '3', four: '4' } }) }) + +runner.test('groups: with partial', function () { + const definitions = [ + { name: 'one', group: 'a' }, + { name: 'two', group: 'a' }, + { name: 'three', group: 'b' } + ] + const argv = [ '--one', '1', '--two', '2', '--three', '3', 'ham', '--cheese' ] + a.deepStrictEqual(commandLineArgs(definitions, { argv, partial: true }), { + a: { + one: '1', + two: '2' + }, + b: { + three: '3' + }, + _all: { + one: '1', + two: '2', + three: '3' + }, + _unknown: [ 'ham', '--cheese' ] + }) +}) + +runner.test('partial: with partial, multiple groups and _none', function () { + const definitions = [ + { name: 'one', group: ['a', 'f'] }, + { name: 'two', group: ['a', 'g'] }, + { name: 'three' } + ] + const argv = [ '--cheese', '--one', '1', 'ham', '--two', '2', '--three', '3', '-c' ] + a.deepStrictEqual(commandLineArgs(definitions, { argv, partial: true }), { + a: { + one: '1', + two: '2' + }, + f: { + one: '1' + }, + g: { + two: '2' + }, + _none: { + three: '3' + }, + _all: { + one: '1', + two: '2', + three: '3' + }, + _unknown: [ '--cheese', 'ham', '-c' ] + }) +}) diff --git a/test/partial.js b/test/partial.js index 8da4747..3fa6d0c 100644 --- a/test/partial.js +++ b/test/partial.js @@ -159,60 +159,6 @@ runner.test('unknown options: rejected defaultOption values end up in _unknown', }) }) -runner.test('partial: groups', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three', group: 'b' } - ] - const argv = [ '--one', '1', '--two', '2', '--three', '3', 'ham', '--cheese' ] - a.deepStrictEqual(commandLineArgs(definitions, { argv, partial: true }), { - a: { - one: '1', - two: '2' - }, - b: { - three: '3' - }, - _all: { - one: '1', - two: '2', - three: '3' - }, - _unknown: [ 'ham', '--cheese' ] - }) -}) - -runner.test('partial: multiple groups and _none', function () { - const definitions = [ - { name: 'one', group: ['a', 'f'] }, - { name: 'two', group: ['a', 'g'] }, - { name: 'three' } - ] - const argv = [ '--cheese', '--one', '1', 'ham', '--two', '2', '--three', '3', '-c' ] - a.deepStrictEqual(commandLineArgs(definitions, { argv, partial: true }), { - a: { - one: '1', - two: '2' - }, - f: { - one: '1' - }, - g: { - two: '2' - }, - _none: { - three: '3' - }, - _all: { - one: '1', - two: '2', - three: '3' - }, - _unknown: [ '--cheese', 'ham', '-c' ] - }) -}) - runner.test('partial: defaultOption with --option=value notation', function () { const definitions = [ { name: 'files', type: String, multiple: true, defaultOption: true }