diff --git a/lib/yargs-factory.ts b/lib/yargs-factory.ts index 7c39e2883..b8a78d6f7 100644 --- a/lib/yargs-factory.ts +++ b/lib/yargs-factory.ts @@ -124,6 +124,7 @@ const kRunYargsParserAndExecuteCommands = Symbol( ); const kRunValidation = Symbol('runValidation'); const kSetHasOutput = Symbol('setHasOutput'); +const kTrackManuallySetKeys = Symbol('kTrackManuallySetKeys'); export interface YargsInternalMethods { getCommandInstance(): CommandInstance; getContext(): Context; @@ -283,11 +284,13 @@ export class YargsInstance { array(keys: string | string[]): YargsInstance { argsert('', [keys], arguments.length); this[kPopulateParserHintArray]('array', keys); + this[kTrackManuallySetKeys](keys); return this; } boolean(keys: string | string[]): YargsInstance { argsert('', [keys], arguments.length); this[kPopulateParserHintArray]('boolean', keys); + this[kTrackManuallySetKeys](keys); return this; } check(f: (argv: Arguments) => any, global?: boolean): YargsInstance { @@ -530,6 +533,7 @@ export class YargsInstance { count(keys: string | string[]): YargsInstance { argsert('', [keys], arguments.length); this[kPopulateParserHintArray]('count', keys); + this[kTrackManuallySetKeys](keys); return this; } default( @@ -890,6 +894,7 @@ export class YargsInstance { number(keys: string | string[]): YargsInstance { argsert('', [keys], arguments.length); this[kPopulateParserHintArray]('number', keys); + this[kTrackManuallySetKeys](keys); return this; } option( @@ -906,6 +911,8 @@ export class YargsInstance { opt = {}; } + this[kTrackManuallySetKeys](key); + // Warn about version name collision // Addresses: https://github.com/yargs/yargs/issues/1979 if (this.#versionOpt && (key === 'version' || opt?.alias === 'version')) { @@ -1327,9 +1334,10 @@ export class YargsInstance { this.#strictOptions = enabled !== false; return this; } - string(key: string | string[]): YargsInstance { - argsert('', [key], arguments.length); - this[kPopulateParserHintArray]('string', key); + string(keys: string | string[]): YargsInstance { + argsert('', [keys], arguments.length); + this[kPopulateParserHintArray]('string', keys); + this[kTrackManuallySetKeys](keys); return this; } terminalWidth(): number | null { @@ -2206,6 +2214,15 @@ export class YargsInstance { [kSetHasOutput]() { this.#hasOutput = true; } + [kTrackManuallySetKeys](keys: string | string[]) { + if (typeof keys === 'string') { + this.#options.key[keys] = true; + } else { + for (const k of keys) { + this.#options.key[k] = true; + } + } + } } export function isYargsInstance(y: YargsInstance | void): y is YargsInstance { diff --git a/test/validation.cjs b/test/validation.cjs index 8a116fdab..458fbc155 100644 --- a/test/validation.cjs +++ b/test/validation.cjs @@ -1021,6 +1021,46 @@ describe('validation tests', () => { args.matey.should.equal('ben'); args._.should.deep.equal(['ahoy', '--arrr']); }); + + it('does not fail when options are defined using array/boolean/count/number/string', () => { + yargs + .command({ + command: 'cmd', + desc: 'cmd desc', + builder: yargs => + yargs + .option('opt1', { + desc: 'opt1 desc', + type: 'boolean', + }) + .option('opt2', { + desc: 'opt2 desc', + boolean: true, + }) + .array('opt3') + .boolean('opt4') + .count('opt5') + .number('opt6') + .string('opt7') + .fail(() => { + expect.fail(); + }), + handler: argv => { + argv.opt1.should.equal(true); + argv.opt2.should.equal(true); + argv.opt3.should.deep.equal(['foo', 'bar', 'baz']); + argv.opt4.should.equal(true); + argv.opt5.should.equal(1); + argv.opt6.should.equal(3); + argv.opt7.should.equal('cat'); + }, + }) + .help() + .strict() + .parse( + 'cmd --opt1 --opt2 --opt3 foo bar baz --opt4 --opt5 --opt6 3 --opt7 cat' + ); + }); }); describe('demandOption', () => {