diff --git a/lib/command-line-args.js b/lib/command-line-args.js index 7581abf..33a397c 100644 --- a/lib/command-line-args.js +++ b/lib/command-line-args.js @@ -34,8 +34,9 @@ module.exports = commandLineArgs * ]) * ``` */ -function commandLineArgs (definitions, argv) { - definitions = new Definitions(definitions) +function commandLineArgs (optionDefinitions, argv) { + const definitions = new Definitions() + definitions.load(optionDefinitions) argv = new Argv(argv) argv.expandOptionEqualsNotation() argv.expandGetoptNotation() diff --git a/lib/definitions.js b/lib/definitions.js index 26b4b51..11a2f8a 100644 --- a/lib/definitions.js +++ b/lib/definitions.js @@ -12,10 +12,9 @@ const t = require('typical') /** * @alias module:definitions */ -class Definitions { - constructor (definitions) { - this.list = [] - arrayify(definitions).forEach(def => this.list.push(new Definition(def))) +class Definitions extends Array { + load (definitions) { + arrayify(definitions).forEach(def => this.push(new Definition(def))) this.validate() } @@ -24,7 +23,7 @@ class Definitions { * @returns {string} */ validate (argv) { - const someHaveNoName = this.list.some(def => !def.name) + const someHaveNoName = this.some(def => !def.name) if (someHaveNoName) { halt( 'NAME_MISSING', @@ -32,7 +31,7 @@ class Definitions { ) } - const someDontHaveFunctionType = this.list.some(def => def.type && typeof def.type !== 'function') + const someDontHaveFunctionType = this.some(def => def.type && typeof def.type !== 'function') if (someDontHaveFunctionType) { halt( 'INVALID_TYPE', @@ -42,7 +41,7 @@ class Definitions { let invalidOption - const numericAlias = this.list.some(def => { + const numericAlias = this.some(def => { invalidOption = def return t.isDefined(def.alias) && t.isNumber(def.alias) }) @@ -53,7 +52,7 @@ class Definitions { ) } - const multiCharacterAlias = this.list.some(def => { + const multiCharacterAlias = this.some(def => { invalidOption = def return t.isDefined(def.alias) && def.alias.length !== 1 }) @@ -64,7 +63,7 @@ class Definitions { ) } - const hypenAlias = this.list.some(def => { + const hypenAlias = this.some(def => { invalidOption = def return def.alias === '-' }) @@ -75,7 +74,7 @@ class Definitions { ) } - const duplicateName = hasDuplicates(this.list.map(def => def.name)) + const duplicateName = hasDuplicates(this.map(def => def.name)) if (duplicateName) { halt( 'DUPLICATE_NAME', @@ -83,7 +82,7 @@ class Definitions { ) } - const duplicateAlias = hasDuplicates(this.list.map(def => def.alias)) + const duplicateAlias = hasDuplicates(this.map(def => def.alias)) if (duplicateAlias) { halt( 'DUPLICATE_ALIAS', @@ -91,7 +90,7 @@ class Definitions { ) } - const duplicateDefaultOption = hasDuplicates(this.list.map(def => def.defaultOption)) + const duplicateDefaultOption = hasDuplicates(this.map(def => def.defaultOption)) if (duplicateDefaultOption) { halt( 'DUPLICATE_DEFAULT_OPTION', @@ -106,8 +105,10 @@ class Definitions { */ createOutput () { const output = {} - this.list.forEach(def => { - if (t.isDefined(def.defaultValue)) output[def.name] = def.defaultValue + this.forEach(def => { + if (t.isDefined(def.defaultValue)) { + output[def.name] = def.multiple ? arrayify(def.defaultValue) : def.defaultValue + } if (Array.isArray(output[def.name])) { output[def.name]._initial = true } @@ -121,23 +122,23 @@ class Definitions { */ get (arg) { return option.short.test(arg) - ? this.list.find(def => def.alias === option.short.name(arg)) - : this.list.find(def => def.name === option.long.name(arg)) + ? this.find(def => def.alias === option.short.name(arg)) + : this.find(def => def.name === option.long.name(arg)) } getDefault () { - return this.list.find(def => def.defaultOption === true) + return this.find(def => def.defaultOption === true) } isGrouped () { - return this.list.some(def => def.group) + return this.some(def => def.group) } whereGrouped () { - return this.list.filter(containsValidGroup) + return this.filter(containsValidGroup) } whereNotGrouped () { - return this.list.filter(def => !containsValidGroup(def)) + return this.filter(def => !containsValidGroup(def)) } } diff --git a/test/class-argv.js b/test/class-argv.js index 432c200..06614d2 100644 --- a/test/class-argv.js +++ b/test/class-argv.js @@ -31,7 +31,8 @@ runner.test('.expandGetoptNotation() with values', function () { }) runner.test('.validate()', function () { - const definitions = new Definitions([ + const definitions = new Definitions() + definitions.load([ { name: 'one', type: Number } ]) diff --git a/test/class-definitions.js b/test/class-definitions.js index 785bd64..1a43994 100644 --- a/test/class-definitions.js +++ b/test/class-definitions.js @@ -6,17 +6,20 @@ const Definitions = require('../lib/definitions') const runner = new TestRunner() runner.test('.createOutput()', function () { - const definitions = new Definitions([ { name: 'one', defaultValue: 'eins' } ]) + const definitions = new Definitions() + definitions.load([ { name: 'one', defaultValue: 'eins' } ]) a.deepStrictEqual(definitions.createOutput(), { one: 'eins' }) }) runner.test('.get()', function () { - const definitions = new Definitions([ { name: 'one', defaultValue: 'eins' } ]) + const definitions = new Definitions() + definitions.load([ { name: 'one', defaultValue: 'eins' } ]) a.strictEqual(definitions.get('--one').name, 'one') }) runner.test('.validate()', function () { a.throws(function () { - const definitions = new Definitions([ { name: 'one' }, { name: 'one' } ]) // eslint-disable-line no-unused-vars + const definitions = new Definitions() + definitions.load([ { name: 'one' }, { name: 'one' } ]) }) }) diff --git a/test/default-value.js b/test/default-value.js index 3c1a1ef..ac49000 100644 --- a/test/default-value.js +++ b/test/default-value.js @@ -48,3 +48,18 @@ runner.test('default value: falsy default values', function () { two: false }) }) + +runner.test('default value: is arrayifed if multiple set', function () { + const defs = [ + { name: 'one', defaultValue: 0, multiple: true } + ] + + let argv = [] + a.deepStrictEqual(cliArgs(defs, argv), { + one: [ 0 ] + }) + argv = [ '--one', '2' ] + a.deepStrictEqual(cliArgs(defs, argv), { + one: [ '2' ] + }) +})