diff --git a/lib/yargs-factory.ts b/lib/yargs-factory.ts index b8a78d6f7..2dff7e395 100644 --- a/lib/yargs-factory.ts +++ b/lib/yargs-factory.ts @@ -293,7 +293,10 @@ export class YargsInstance { this[kTrackManuallySetKeys](keys); return this; } - check(f: (argv: Arguments) => any, global?: boolean): YargsInstance { + check( + f: (argv: Arguments, options: Options) => any, + global?: boolean + ): YargsInstance { argsert(' [boolean]', [f, global], arguments.length); this.middleware( ( @@ -304,7 +307,7 @@ export class YargsInstance { Partial | Promise> | any >( () => { - return f(argv); + return f(argv, _yargs.getOptions()); }, (result: any): Partial | Promise> => { if (!result) { diff --git a/test/validation.cjs b/test/validation.cjs index 458fbc155..f2e677c23 100644 --- a/test/validation.cjs +++ b/test/validation.cjs @@ -14,6 +14,96 @@ describe('validation tests', () => { yargs.getInternalMethods().reset(); }); + describe('check', () => { + it('fails if error is thrown in check callback', done => { + yargs + .command( + '$0', + 'default command desc', + yargs => + yargs + .option('name', { + describe: 'name desc', + type: 'string', + alias: 'n', + }) + .check(argv => { + const {name} = argv; + if (typeof name !== 'string' || !name.length) { + throw new Error('Option "name" must be a non-empty string'); + } + return true; + }), + () => { + expect.fail(); + } + ) + .fail(() => { + return done(); + }) + .parse('--name'); + }); + + it('does not fail if error is not thrown in check callback, and true is returned', () => { + yargs + .command( + '$0', + 'default command desc', + yargs => + yargs + .option('name', { + describe: 'version desc', + type: 'string', + alias: 'n', + }) + .check(argv => { + const {name} = argv; + if (typeof name !== 'string' || !name.length) { + throw new Error('Option "name" must be a non-empty string'); + } + return true; + }), + argv => argv + ) + .fail(() => { + expect.fail(); + }) + .parse('--name Itachi'); + }); + + it('callback has access to options', () => { + yargs + .command( + '$0', + 'default command desc', + yargs => + yargs + .option('name', { + describe: 'name desc', + type: 'string', + alias: 'n', + }) + .check((_, options) => { + if ( + typeof options !== 'object' || + !Object.prototype.hasOwnProperty.call(options, 'string') || + !options.string.includes('name') + ) { + throw new Error( + 'Check callback should have access to options' + ); + } + return true; + }), + argv => argv + ) + .fail(() => { + expect.fail(); + }) + .parse('--name Itachi'); + }); + }); + describe('implies', () => { const implicationsFailedPattern = new RegExp( english['Implications failed:']