File tree 3 files changed +67
-12
lines changed
fixtures/one-file-builder-object-literal
3 files changed +67
-12
lines changed Original file line number Diff line number Diff line change @@ -1029,19 +1029,22 @@ export async function discoverCommands(
1029
1029
: { [ args [ 0 ] as string ] : args [ 1 ] || /* istanbul ignore next */ { } }
1030
1030
) as Record < string , Options > ;
1031
1031
1032
- Object . entries ( options ) . forEach ( ( [ option , optionConfiguration ] ) => {
1033
- if ( 'demandOption' in optionConfiguration ) {
1034
- debug_ (
1035
- `discarded attempted mutation of disabled yargs option configuration key "demandOption" (for the %O option) on %O program` ,
1036
- option ,
1037
- descriptor
1038
- ) ;
1039
-
1040
- delete optionConfiguration . demandOption ;
1041
- }
1042
- } ) ;
1032
+ const optionsShallowClone = Object . fromEntries (
1033
+ Object . entries ( options ) . map ( ( [ option , optionConfiguration ] ) => {
1034
+ if ( 'demandOption' in optionConfiguration ) {
1035
+ debug_ (
1036
+ `discarded attempted mutation of disabled yargs option configuration key "demandOption" (for the %O option) on %O program` ,
1037
+ option ,
1038
+ descriptor
1039
+ ) ;
1040
+ }
1041
+
1042
+ const { demandOption : _ , ...rest } = optionConfiguration ;
1043
+ return [ option , rest ] ;
1044
+ } )
1045
+ ) ;
1043
1046
1044
- target . options ( options ) ;
1047
+ target . options ( optionsShallowClone ) ;
1045
1048
return proxy ;
1046
1049
} ;
1047
1050
}
Original file line number Diff line number Diff line change
1
+ // @ts -check
2
+ /// <reference path="../index.d.ts"/>
3
+
4
+ const { dirname, basename } = require ( 'node:path' ) ;
5
+ const name = basename ( dirname ( __filename ) ) ;
6
+
7
+ /**
8
+ * @type {Type.RootConfig }
9
+ */
10
+ module . exports = {
11
+ usage : `usage text for root program ${ name } ` ,
12
+ builder : {
13
+ option : { demandOption : true , string : true , choices : [ 'a' , 'b' ] }
14
+ } ,
15
+ handler : ( argv ) => {
16
+ argv . handled_by = __filename ;
17
+ }
18
+ } ;
Original file line number Diff line number Diff line change @@ -3590,6 +3590,40 @@ describe('<command module auto-discovery>', () => {
3590
3590
} ) ;
3591
3591
} ) ;
3592
3592
3593
+ it ( 'does not pass undefined through argv when using "builder"' , async ( ) => {
3594
+ expect . hasAssertions ( ) ;
3595
+
3596
+ const run = bf_util . makeRunner ( {
3597
+ commandModulePath : getFixturePath ( 'one-file-builder-object-literal' )
3598
+ } ) ;
3599
+
3600
+ await withMocks ( async ( { errorSpy, getExitCode } ) => {
3601
+ await expect ( run ( [ '--option' , 'a' ] ) ) . resolves . toContainEntries ( [
3602
+ [ 'option' , 'a' ] ,
3603
+ [ 'handled_by' , expect . any ( String ) ]
3604
+ ] ) ;
3605
+
3606
+ expect ( getExitCode ( ) ) . toBe ( bf . FrameworkExitCode . Ok ) ;
3607
+
3608
+ await expect ( run ( [ '--option' , 'b' ] ) ) . resolves . toContainEntries ( [
3609
+ [ 'option' , 'b' ] ,
3610
+ [ 'handled_by' , expect . any ( String ) ]
3611
+ ] ) ;
3612
+
3613
+ expect ( getExitCode ( ) ) . toBe ( bf . FrameworkExitCode . Ok ) ;
3614
+
3615
+ await expect ( run ( ) ) . resolves . toBeUndefined ( ) ;
3616
+
3617
+ expect ( getExitCode ( ) ) . toBe ( bf . FrameworkExitCode . DefaultError ) ;
3618
+
3619
+ expect ( errorSpy . mock . calls ) . toStrictEqual ( [
3620
+ [ expect . any ( String ) ] ,
3621
+ [ ] ,
3622
+ [ expect . stringContaining ( 'Missing required argument: option' ) ]
3623
+ ] ) ;
3624
+ } ) ;
3625
+ } ) ;
3626
+
3593
3627
it ( 'ensures PreExecutionContext::rootPrograms is PreExecutionContext.commands[0].programs and also referenced by the root command full name' , async ( ) => {
3594
3628
expect . hasAssertions ( ) ;
3595
3629
You can’t perform that action at this time.
0 commit comments