diff --git a/src/CAC.ts b/src/CAC.ts index 7a3df11a..85ce6194 100644 --- a/src/CAC.ts +++ b/src/CAC.ts @@ -328,6 +328,8 @@ class CAC extends EventEmitter { command.checkRequiredArgs() + command.checkPreviousArgument() + const actionArgs: any[] = [] command.args.forEach((arg, index) => { if (arg.variadic) { diff --git a/src/Command.ts b/src/Command.ts index 93027972..65cbec91 100644 --- a/src/Command.ts +++ b/src/Command.ts @@ -253,6 +253,18 @@ class Command { } } + checkPreviousArgument() { + const length = this.args.length + + for (let i = 0; i < length; i++) { + const { variadic, value } = this.args[i] + + if (variadic && i !== length - 1) { + throw new CACError(`only the last argument can be variadic '${value}'`) + } + } + } + /** * Check if the parsed options contain any unknown options * diff --git a/src/utils.ts b/src/utils.ts index a564e16c..0ebfdd64 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,14 +3,14 @@ import Option from './Option' export const removeBrackets = (v: string) => v.replace(/[<[].+/, '').trim() export const findAllBrackets = (v: string) => { - const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g - const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g + const BRACKET_RE_GLOBAL = /<([^>]+)>|\[([^\]]+)\]/g const res = [] const parse = (match: string[]) => { let variadic = false - let value = match[1] + let value = match[1] ?? match[2] + if (value.startsWith('...')) { value = value.slice(3) variadic = true @@ -22,14 +22,9 @@ export const findAllBrackets = (v: string) => { } } - let angledMatch - while ((angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v))) { - res.push(parse(angledMatch)) - } - - let squareMatch - while ((squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v))) { - res.push(parse(squareMatch)) + let match + while ((match = BRACKET_RE_GLOBAL.exec(v))) { + res.push(parse(match)) } return res