From 02cd01885b8aaa59f2db8308f2d4479e64340068 Mon Sep 17 00:00:00 2001 From: John Gee Date: Mon, 11 Apr 2022 02:23:57 +1200 Subject: [PATCH] feat!: Require type to be specified for each supplied option (#95) --- README.md | 3 ++- index.js | 4 +--- test/index.js | 16 +++++++++++++--- test/short-option-combined-with-value.js | 2 +- test/short-option-groups.js | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 088297f..c5ff5da 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ process.mainArgs = process.argv.slice(process._exec ? 1 : 2) * `args` {string[]} (Optional) Array of argument strings; defaults to [`process.mainArgs`](process_argv) * `options` {Object} (Optional) An object describing the known options to look for in `args`; `options` keys are the long names of the known options, and the values are objects with the following properties: - * `type` {'string'|'boolean'} (Optional) Type of known option; defaults to `'boolean'`; + * `type` {'string'|'boolean'} (Required) Type of known option * `multiple` {boolean} (Optional) If true, when appearing one or more times in `args`, results are collected in an `Array` * `short` {string} (Optional) A single character alias for an option; When appearing one or more times in `args`; Respects the `multiple` configuration * `strict` {Boolean} (Optional) A `Boolean` on wheather or not to throw an error when unknown args are encountered @@ -147,6 +147,7 @@ const args = ['-f', 'b']; const options = { foo: { short: 'f', + type: 'boolean' }, }; const { flags, values, positionals } = parseArgs({ args, options }); diff --git a/index.js b/index.js index 48bc422..6fb591e 100644 --- a/index.js +++ b/index.js @@ -111,9 +111,7 @@ const parseArgs = ({ ({ 0: longOption, 1: optionConfig }) => { validateObject(optionConfig, `options.${longOption}`); - if (ObjectHasOwn(optionConfig, 'type')) { - validateUnion(optionConfig.type, `options.${longOption}.type`, ['string', 'boolean']); - } + validateUnion(optionConfig.type, `options.${longOption}.type`, ['string', 'boolean']); if (ObjectHasOwn(optionConfig, 'short')) { const shortOption = optionConfig.short; diff --git a/test/index.js b/test/index.js index 57be514..93fe85c 100644 --- a/test/index.js +++ b/test/index.js @@ -39,7 +39,7 @@ test('when short option `type: "string"` used with value then stored as value', test('when short option listed in short used as flag then long option stored as flag', (t) => { const passedArgs = ['-f']; - const passedOptions = { foo: { short: 'f' } }; + const passedOptions = { foo: { short: 'f', type: 'boolean' } }; const expected = { flags: { foo: true }, values: { foo: undefined }, positionals: [] }; const args = parseArgs({ args: passedArgs, options: passedOptions }); @@ -114,7 +114,7 @@ test('handles short-option groups in conjunction with long-options', (t) => { test('handles short-option groups with "short" alias configured', (t) => { const passedArgs = ['-rf']; - const passedOptions = { remove: { short: 'r' } }; + const passedOptions = { remove: { short: 'r', type: 'boolean' } }; const expected = { flags: { remove: true, f: true }, values: { remove: undefined, f: undefined }, positionals: [] }; const args = parseArgs({ args: passedArgs, options: passedOptions }); t.deepEqual(args, expected); @@ -375,6 +375,16 @@ test('invalid argument passed for options', (t) => { t.end(); }); +test('then type property missing for option then throw', function(t) { + const knownOptions = { foo: { } }; + + t.throws(function() { parseArgs({ options: knownOptions }); }, { + code: 'ERR_INVALID_ARG_TYPE' + }); + + t.end(); +}); + test('boolean passed to "type" option', (t) => { const passedArgs = ['--so=wat']; const passedOptions = { foo: { type: true } }; @@ -399,7 +409,7 @@ test('invalid union value passed to "type" option', (t) => { test('invalid short option length', (t) => { const passedArgs = []; - const passedOptions = { foo: { short: 'fo' } }; + const passedOptions = { foo: { short: 'fo', type: 'boolean' } }; t.throws(function() { parseArgs({ args: passedArgs, options: passedOptions }); }, { code: 'ERR_INVALID_SHORT_OPTION' diff --git a/test/short-option-combined-with-value.js b/test/short-option-combined-with-value.js index 66fb5d2..fd5dfc6 100644 --- a/test/short-option-combined-with-value.js +++ b/test/short-option-combined-with-value.js @@ -62,7 +62,7 @@ test('when combine string short with value like negative number then parsed as v test('when combine string short with value which matches configured flag then parsed as value', (t) => { const passedArgs = ['-af']; - const passedOptions = { alpha: { short: 'a', type: 'string' }, file: { short: 'f' } }; + const passedOptions = { alpha: { short: 'a', type: 'string' }, file: { short: 'f', type: 'boolean' } }; const expected = { flags: { alpha: true }, values: { alpha: 'f' }, positionals: [] }; const result = parseArgs({ args: passedArgs, options: passedOptions }); diff --git a/test/short-option-groups.js b/test/short-option-groups.js index f849b50..bff6609 100644 --- a/test/short-option-groups.js +++ b/test/short-option-groups.js @@ -17,7 +17,7 @@ test('when pass zero-config group of booleans then parsed as booleans', (t) => { test('when pass low-config group of booleans then parsed as booleans', (t) => { const passedArgs = ['-rf', 'p']; - const passedOptions = { r: {}, f: {} }; + const passedOptions = { r: { type: 'boolean' }, f: { type: 'boolean' } }; const expected = { flags: { r: true, f: true }, values: { r: undefined, f: undefined }, positionals: ['p'] }; const result = parseArgs({ args: passedArgs, options: passedOptions });