Skip to content

Commit 387b6fc

Browse files
cravlershadowspawn
andauthored
Factory routine to create a new unattached argument (#1497)
* Factory routine to create a new unattached argument * ESM export improvements * createArgument ESM test * Add typings for createArgument * Add tests for createArgument Co-authored-by: John Gee <[email protected]>
1 parent 0504945 commit 387b6fc

File tree

6 files changed

+83
-3
lines changed

6 files changed

+83
-3
lines changed

esm.mjs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
import commander from './index.js';
22

33
// wrapper to provide named exports for ESM.
4-
export const { program, Option, Command, Argument, CommanderError, InvalidOptionArgumentError, Help, createCommand, createOption } = commander;
4+
export const {
5+
program,
6+
createCommand,
7+
createArgument,
8+
createOption,
9+
CommanderError,
10+
InvalidOptionArgumentError,
11+
Command,
12+
Argument,
13+
Option,
14+
Help
15+
} = commander;

index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,21 @@ class Command extends EventEmitter {
836836
return this;
837837
};
838838

839+
/**
840+
* Factory routine to create a new unattached argument.
841+
*
842+
* See .argument() for creating an attached argument, which uses this routine to
843+
* create the argument. You can override createArgument to return a custom argument.
844+
*
845+
* @param {string} name
846+
* @param {string} [description]
847+
* @return {Argument} new argument
848+
*/
849+
850+
createArgument(name, description) {
851+
return new Argument(name, description);
852+
};
853+
839854
/**
840855
* Define argument syntax for command.
841856
*
@@ -852,7 +867,7 @@ class Command extends EventEmitter {
852867
* @return {Command} `this` command for chaining
853868
*/
854869
argument(name, description) {
855-
const argument = new Argument(name, description);
870+
const argument = this.createArgument(name, description);
856871
this.addArgument(argument);
857872
return this;
858873
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const commander = require('../');
2+
3+
class MyArgument extends commander.Argument {
4+
constructor(name, description) {
5+
super(name, description);
6+
this.myProperty = 'MyArgument';
7+
};
8+
}
9+
10+
class MyCommand extends commander.Command {
11+
createArgument(name, description) {
12+
return new MyArgument(name, description);
13+
};
14+
15+
// createCommand for testing .command('sub <file>')
16+
createCommand(name) {
17+
return new MyCommand(name);
18+
}
19+
}
20+
21+
test('when override createArgument then used for argument()', () => {
22+
const program = new MyCommand();
23+
program.argument('<file>');
24+
expect(program._args.length).toEqual(1);
25+
expect(program._args[0].myProperty).toEqual('MyArgument');
26+
});
27+
28+
test('when override createArgument then used for arguments()', () => {
29+
const program = new MyCommand();
30+
program.arguments('<file>');
31+
expect(program._args.length).toEqual(1);
32+
expect(program._args[0].myProperty).toEqual('MyArgument');
33+
});
34+
35+
test('when override createArgument and createCommand then used for argument of command()', () => {
36+
const program = new MyCommand();
37+
const sub = program.command('sub <file>');
38+
expect(sub._args.length).toEqual(1);
39+
expect(sub._args[0].myProperty).toEqual('MyArgument');
40+
});

tests/esm-imports-test.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { program, Command, Option, Argument, CommanderError, InvalidOptionArgumentError, Help, createCommand, createOption } from '../esm.mjs';
1+
import { program, Command, Option, Argument, CommanderError, InvalidOptionArgumentError, Help, createCommand, createArgument, createOption } from '../esm.mjs';
22

33
// Do some simple checks that expected imports are available at runtime.
44
// Run using `npm run test-esm`.
@@ -30,6 +30,8 @@ checkClass(new Argument('<file>'), 'Argument');
3030

3131
console.log('Checking createCommand');
3232
check(typeof createCommand === 'function', 'createCommand is function');
33+
console.log('Checking createArgument');
34+
check(typeof createArgument === 'function', 'createArgument is function');
3335
console.log('Checking createOption');
3436
check(typeof createOption === 'function', 'createOption is function');
3537

typings/index.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,14 @@ declare namespace commander {
249249
*/
250250
addCommand(cmd: Command, opts?: CommandOptions): this;
251251

252+
/**
253+
* Factory routine to create a new unattached argument.
254+
*
255+
* See .argument() for creating an attached argument, which uses this routine to
256+
* create the argument. You can override createArgument to return a custom argument.
257+
*/
258+
createArgument(name: string, description?: string): Argument;
259+
252260
/**
253261
* Define argument syntax for command.
254262
*

typings/index.test-d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,3 +345,7 @@ expectType<boolean>(baseArgument.variadic);
345345
// Argument methods
346346
// name
347347
expectType<string>(baseArgument.name());
348+
349+
// createArgument
350+
expectType<commander.Argument>(program.createArgument('<name>'));
351+
expectType<commander.Argument>(program.createArgument('<name>', 'description'));

0 commit comments

Comments
 (0)