diff --git a/lib/command.ts b/lib/command.ts index 866eb5324..99f0724bb 100644 --- a/lib/command.ts +++ b/lib/command.ts @@ -598,7 +598,18 @@ export class CommandInstance { // any new aliases need to be placed in positionalMap, which // is used for validation. if (!positionalMap[key]) positionalMap[key] = parsed.argv[key]; - argv[key] = parsed.argv[key]; + // Addresses: https://github.com/yargs/yargs/issues/1637 + // If both positionals/options provided, + // and if at least one is an array: don't overwrite, combine. + if ( + Object.prototype.hasOwnProperty.call(argv, key) && + Object.prototype.hasOwnProperty.call(parsed.argv, key) && + (Array.isArray(argv[key]) || Array.isArray(parsed.argv[key])) + ) { + argv[key] = ([] as string[]).concat(argv[key], parsed.argv[key]); + } else { + argv[key] = parsed.argv[key]; + } } }); } diff --git a/lib/yargs-factory.ts b/lib/yargs-factory.ts index 4f602d7e8..23d6e0f27 100644 --- a/lib/yargs-factory.ts +++ b/lib/yargs-factory.ts @@ -809,7 +809,7 @@ export class YargsInstance { ); } else { globals.forEach(g => { - if (this.#options.local.indexOf(g) === -1) this.#options.local.push(g); + if (!this.#options.local.includes(g)) this.#options.local.push(g); }); } return this; diff --git a/test/command.cjs b/test/command.cjs index fd0eefef8..984481cf4 100644 --- a/test/command.cjs +++ b/test/command.cjs @@ -209,6 +209,58 @@ describe('Command', () => { argv['--'].should.eql(['apple', 'banana']); called.should.equal(true); }); + + // Addresses: https://github.com/yargs/yargs/issues/1637 + it('does not overwrite options in argv if variadic', () => { + yargs + .command({ + command: 'cmd [foods..]', + desc: 'cmd desc', + builder: yargs => + yargs.positional('foods', { + desc: 'foods desc', + type: 'string', + }), + handler: argv => { + argv.foods.should.deep.equal(['apples', 'cherries', 'grapes']); + }, + }) + .parse('cmd --foods apples cherries grapes'); + }); + + it('does not overwrite options in argv if variadic and when using default command', () => { + yargs + .command({ + command: '$0 [foods..]', + desc: 'default desc', + builder: yargs => + yargs.positional('foods', { + desc: 'foods desc', + type: 'string', + }), + handler: argv => { + argv.foods.should.deep.equal(['apples', 'cherries', 'grapes']); + }, + }) + .parse('--foods apples cherries grapes'); + }); + + it('does not overwrite options in argv if variadic and preserves falsey values', () => { + yargs + .command({ + command: '$0 [numbers..]', + desc: 'default desc', + builder: yargs => + yargs.positional('numbers', { + desc: 'numbers desc', + type: 'number', + }), + handler: argv => { + argv.numbers.should.deep.equal([0, 1, 2]); + }, + }) + .parse('--numbers 0 1 2'); + }); }); describe('variadic', () => {