diff --git a/package.json b/package.json index 04821f3..f0fd8b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@navy.gif/commandparser", - "version": "1.7.0", + "version": "1.7.1", "description": "Parser meant to parse commands and their options for discord bots", "author": "Navy.gif", "license": "MIT", diff --git a/src/Parser.ts b/src/Parser.ts index 03332c8..85f311a 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -391,7 +391,7 @@ class Parser extends EventEmitter { const flags = options.filter((opt) => opt.flag); let currentFlag = null; - const parsed = []; + const parsed: T[] = []; this.debug(`${params.length} params to go through: "${params.join('", "')}"`); for (let index = 0; index < params.length;) { @@ -441,6 +441,17 @@ class Parser extends EventEmitter } this.debug(`Matched flag: ${flag.name} with ${_flag}`); + if (flag.instances) + { + const count = parsed.reduce((prev, curr) => + { + if (curr.name === flag.name) + prev++; + return prev; + }, 0); + if (count === flag.instances) + throw new ParserError(`Cannot have more than ${flag.instances} instances of option "${flag.name}"`); + } // params.splice(index, 1, ''); // Replace with empty string as to not alter the length of the params array params.splice(index, 1); if (aliased) @@ -448,7 +459,7 @@ class Parser extends EventEmitter this.debug('Aliased'); const clone = flag.clone([ _flag ], this.resolver); clone.aliased = true; - parsed.push(clone); + parsed.push(clone as T); currentFlag = null; } else @@ -456,7 +467,7 @@ class Parser extends EventEmitter this.debug('Not aliased'); // eslint-disable-next-line no-undefined currentFlag = flag.clone(undefined, this.resolver); - parsed.push(currentFlag); + parsed.push(currentFlag as T); } // index++; } diff --git a/src/classes/CommandOption.ts b/src/classes/CommandOption.ts index 2617912..0c79626 100644 --- a/src/classes/CommandOption.ts +++ b/src/classes/CommandOption.ts @@ -82,6 +82,7 @@ class CommandOption implements ICommandOption this.minimum = def.minimum; this.maximum = def.maximum; // Default to 1 to retain original behaviour + // Really only applies to flag type options, given that non-flags aren't parsed by their name, rather by their type and order this.instances = def.instances ?? 1; this.required = def.required || false; diff --git a/tests/playground.js b/tests/playground.js index fa31353..3adf400 100644 --- a/tests/playground.js +++ b/tests/playground.js @@ -27,7 +27,8 @@ const commands = [ type: OptionType.INTEGER, defaultValue: 1, valueOptional: true, - required: true + required: true, + instances: 2 }] }] }), @@ -79,7 +80,7 @@ const parser = new Parser({ allowIncompleteReturn: true }); parser.on('debug', console.log); -console.log((await parser.parseMessage('create code -a 1'))); +console.log((await parser.parseMessage('create code -a 1 -a 6 -a 7'))); console.log((await parser.parseMessage('create code --help'))); console.log(await parser.parseMessage('create --help')); console.log((await parser.parseMessage('test sub --help')));