@@ -25,7 +25,9 @@ function nopt (args, {
2525 types,
2626 shorthands,
2727 typeDefs,
28- invalidHandler,
28+ invalidHandler, // opt is configured but its value does not validate against given type
29+ unknownHandler, // opt is not configured
30+ abbrevHandler, // opt is being expanded via abbrev
2931 typeDefault,
3032 dynamicTypes,
3133} = { } ) {
@@ -38,7 +40,9 @@ function nopt (args, {
3840 original : args . slice ( 0 ) ,
3941 }
4042
41- parse ( args , data , argv . remain , { typeDefs, types, dynamicTypes, shorthands } )
43+ parse ( args , data , argv . remain , {
44+ typeDefs, types, dynamicTypes, shorthands, unknownHandler, abbrevHandler,
45+ } )
4246
4347 // now data is full
4448 clean ( data , { types, dynamicTypes, typeDefs, invalidHandler, typeDefault } )
@@ -247,6 +251,8 @@ function parse (args, data, remain, {
247251 typeDefs = { } ,
248252 shorthands = { } ,
249253 dynamicTypes,
254+ unknownHandler,
255+ abbrevHandler,
250256} = { } ) {
251257 const StringType = typeDefs . String ?. type
252258 const NumberType = typeDefs . Number ?. type
@@ -282,7 +288,7 @@ function parse (args, data, remain, {
282288
283289 // see if it's a shorthand
284290 // if so, splice and back up to re-parse it.
285- const shRes = resolveShort ( arg , shortAbbr , abbrevs , { shorthands } )
291+ const shRes = resolveShort ( arg , shortAbbr , abbrevs , { shorthands, abbrevHandler } )
286292 debug ( 'arg=%j shRes=%j' , arg , shRes )
287293 if ( shRes ) {
288294 args . splice . apply ( args , [ i , 1 ] . concat ( shRes ) )
@@ -298,7 +304,13 @@ function parse (args, data, remain, {
298304 arg = arg . slice ( 3 )
299305 }
300306
301- if ( abbrevs [ arg ] ) {
307+ // abbrev includes the original full string in its abbrev list
308+ if ( abbrevs [ arg ] && abbrevs [ arg ] !== arg ) {
309+ if ( abbrevHandler ) {
310+ abbrevHandler ( arg , abbrevs [ arg ] )
311+ } else if ( abbrevHandler !== false ) {
312+ debug ( `abbrev: ${ arg } -> ${ abbrevs [ arg ] } ` )
313+ }
302314 arg = abbrevs [ arg ]
303315 }
304316
@@ -331,6 +343,23 @@ function parse (args, data, remain, {
331343 ( argType === null ||
332344 isTypeArray && ~ argType . indexOf ( null ) ) )
333345
346+ if ( typeof argType === 'undefined' ) {
347+ // la is going to unexpectedly be parsed outside the context of this arg
348+ const hangingLa = ! hadEq && la && ! la ?. startsWith ( '-' ) && ! [ 'true' , 'false' ] . includes ( la )
349+ if ( unknownHandler ) {
350+ if ( hangingLa ) {
351+ unknownHandler ( arg , la )
352+ } else {
353+ unknownHandler ( arg )
354+ }
355+ } else if ( unknownHandler !== false ) {
356+ debug ( `unknown: ${ arg } ` )
357+ if ( hangingLa ) {
358+ debug ( `unknown: ${ la } parsed as normal opt` )
359+ }
360+ }
361+ }
362+
334363 if ( isBool ) {
335364 // just set and move along
336365 val = ! no
@@ -420,7 +449,7 @@ const singleCharacters = (arg, shorthands) => {
420449}
421450
422451function resolveShort ( arg , ...rest ) {
423- const { types = { } , shorthands = { } } = rest . length ? rest . pop ( ) : { }
452+ const { abbrevHandler , types = { } , shorthands = { } } = rest . length ? rest . pop ( ) : { }
424453 const shortAbbr = rest [ 0 ] ?? abbrev ( Object . keys ( shorthands ) )
425454 const abbrevs = rest [ 1 ] ?? abbrev ( Object . keys ( types ) )
426455
@@ -457,7 +486,13 @@ function resolveShort (arg, ...rest) {
457486 }
458487
459488 // if it's an abbr for a shorthand, then use that
489+ // exact match has already happened so we don't need to account for that here
460490 if ( shortAbbr [ arg ] ) {
491+ if ( abbrevHandler ) {
492+ abbrevHandler ( arg , shortAbbr [ arg ] )
493+ } else if ( abbrevHandler !== false ) {
494+ debug ( `abbrev: ${ arg } -> ${ shortAbbr [ arg ] } ` )
495+ }
461496 arg = shortAbbr [ arg ]
462497 }
463498
0 commit comments