11const abbrev = require ( 'abbrev' )
2+ const debug = require ( './debug' )
23const defaultTypeDefs = require ( './type-defs' )
34
45const hasOwn = ( o , k ) => Object . prototype . hasOwnProperty . call ( o , k )
@@ -30,6 +31,8 @@ function nopt (args, {
3031 typeDefault,
3132 dynamicTypes,
3233} = { } ) {
34+ debug ( types , shorthands , args , typeDefs )
35+
3336 const data = { }
3437 const argv = {
3538 remain : [ ] ,
@@ -86,6 +89,7 @@ function clean (data, {
8689 return
8790 }
8891 let val = data [ k ]
92+ debug ( 'val=%j' , val )
8993 const isArray = Array . isArray ( val )
9094 let [ hasType , rawType ] = getType ( k , { types, dynamicTypes } )
9195 let type = rawType
@@ -102,19 +106,25 @@ function clean (data, {
102106 type = [ type ]
103107 }
104108
109+ debug ( 'val=%j' , val )
110+ debug ( 'types=' , type )
105111 val = val . map ( ( v ) => {
106112 // if it's an unknown value, then parse false/true/null/numbers/dates
107113 if ( typeof v === 'string' ) {
114+ debug ( 'string %j' , v )
108115 v = v . trim ( )
109116 if ( ( v === 'null' && ~ type . indexOf ( null ) )
110117 || ( v === 'true' &&
111118 ( ~ type . indexOf ( true ) || hasTypeDef ( type , BooleanType ) ) )
112119 || ( v === 'false' &&
113120 ( ~ type . indexOf ( false ) || hasTypeDef ( type , BooleanType ) ) ) ) {
114121 v = JSON . parse ( v )
122+ debug ( 'jsonable %j' , v )
115123 } else if ( hasTypeDef ( type , NumberType ) && ! isNaN ( v ) ) {
124+ debug ( 'convert to number' , v )
116125 v = + v
117126 } else if ( hasTypeDef ( type , DateType ) && ! isNaN ( Date . parse ( v ) ) ) {
127+ debug ( 'convert to date' , v )
118128 v = new Date ( v )
119129 }
120130 }
@@ -138,24 +148,32 @@ function clean (data, {
138148
139149 const d = { }
140150 d [ k ] = v
151+ debug ( 'prevalidated val' , d , v , rawType )
141152 if ( ! validate ( d , k , v , rawType , { typeDefs } ) ) {
142153 if ( invalidHandler ) {
143154 invalidHandler ( k , v , rawType , data )
155+ } else if ( invalidHandler !== false ) {
156+ debug ( 'invalid: ' + k + '=' + v , rawType )
144157 }
145158 return remove
146159 }
160+ debug ( 'validated v' , d , v , rawType )
147161 return d [ k ]
148162 } ) . filter ( ( v ) => v !== remove )
149163
150164 // if we allow Array specifically, then an empty array is how we
151165 // express 'no value here', not null. Allow it.
152166 if ( ! val . length && doesNotHaveTypeDef ( type , ArrayType ) ) {
167+ debug ( 'VAL HAS NO LENGTH, DELETE IT' , val , k , type . indexOf ( ArrayType ) )
153168 delete data [ k ]
154169 } else if ( isArray ) {
170+ debug ( isArray , data [ k ] , val )
155171 data [ k ] = val
156172 } else {
157173 data [ k ] = val [ 0 ]
158174 }
175+
176+ debug ( 'k=%s val=%j' , k , val , data [ k ] )
159177 } )
160178}
161179
@@ -181,21 +199,21 @@ function validate (data, k, val, type, { typeDefs } = {}) {
181199 }
182200
183201 // Original comment:
184- // NaN is poisonous, it means that something is not allowed.
185-
186- // New comment:
187- // Changing this to an isNaN check breaks a lot of tests.
188- // Something is being assumed here that is not actually what happens in practice.
189- // Fixing it is outside the scope of getting linting to pass in this repo.
190- // Leaving as-is for now.
202+ // NaN is poisonous. Means that something is not allowed.
203+ // New comment: Changing this to an isNaN check breaks a lot of tests.
204+ // Something is being assumed here that is not actually what happens in
205+ // practice. Fixing it is outside the scope of getting linting to pass in
206+ // this repo. Leaving as-is for now.
191207 /* eslint-disable-next-line no-self-compare */
192208 if ( type !== type ) {
209+ debug ( 'Poison NaN' , k , val , type )
193210 delete data [ k ]
194211 return false
195212 }
196213
197214 // explicit list of values
198215 if ( val === type ) {
216+ debug ( 'Explicitly allowed %j' , val )
199217 data [ k ] = val
200218 return true
201219 }
@@ -204,6 +222,7 @@ function validate (data, k, val, type, { typeDefs } = {}) {
204222 let ok = false
205223 const types = Object . keys ( typeDefs )
206224 for ( let i = 0 , l = types . length ; i < l ; i ++ ) {
225+ debug ( 'test type %j %j %j' , k , val , types [ i ] )
207226 const t = typeDefs [ types [ i ] ]
208227 if ( t && (
209228 ( type && type . name && t . type && t . type . name ) ?
@@ -219,6 +238,7 @@ function validate (data, k, val, type, { typeDefs } = {}) {
219238 }
220239 }
221240 }
241+ debug ( 'OK? %j (%j %j %j)' , ok , k , val , types [ types . length - 1 ] )
222242
223243 if ( ! ok ) {
224244 delete data [ k ]
@@ -238,11 +258,16 @@ function parse (args, data, remain, {
238258 const NumberType = typeDefs . Number ?. type
239259 const ArrayType = typeDefs . Array ?. type
240260 const BooleanType = typeDefs . Boolean ?. type
261+
262+ debug ( 'parse' , args , data , remain )
263+
241264 const abbrevs = abbrev ( Object . keys ( types ) )
265+ debug ( 'abbrevs=%j' , abbrevs )
242266 const shortAbbr = abbrev ( Object . keys ( shorthands ) )
243267
244268 for ( let i = 0 ; i < args . length ; i ++ ) {
245269 let arg = args [ i ]
270+ debug ( 'arg' , arg )
246271
247272 if ( arg . match ( / ^ - { 2 , } $ / ) ) {
248273 // done with keys.
@@ -264,6 +289,7 @@ function parse (args, data, remain, {
264289 // see if it's a shorthand
265290 // if so, splice and back up to re-parse it.
266291 const shRes = resolveShort ( arg , shortAbbr , abbrevs , { shorthands, abbrevHandler } )
292+ debug ( 'arg=%j shRes=%j' , arg , shRes )
267293 if ( shRes ) {
268294 args . splice . apply ( args , [ i , 1 ] . concat ( shRes ) )
269295 if ( arg !== shRes [ 0 ] ) {
@@ -282,6 +308,8 @@ function parse (args, data, remain, {
282308 if ( abbrevs [ arg ] && abbrevs [ arg ] !== arg ) {
283309 if ( abbrevHandler ) {
284310 abbrevHandler ( arg , abbrevs [ arg ] )
311+ } else if ( abbrevHandler !== false ) {
312+ debug ( `abbrev: ${ arg } -> ${ abbrevs [ arg ] } ` )
285313 }
286314 arg = abbrevs [ arg ]
287315 }
@@ -324,6 +352,11 @@ function parse (args, data, remain, {
324352 } else {
325353 unknownHandler ( arg )
326354 }
355+ } else if ( unknownHandler !== false ) {
356+ debug ( `unknown: ${ arg } ` )
357+ if ( hangingLa ) {
358+ debug ( `unknown: ${ la } parsed as normal opt` )
359+ }
327360 }
328361 }
329362
@@ -409,6 +442,7 @@ const singleCharacters = (arg, shorthands) => {
409442 return l
410443 } , { } )
411444 shorthands [ SINGLES ] = singles
445+ debug ( 'shorthand singles' , singles )
412446 }
413447 const chrs = arg . split ( '' ) . filter ( ( c ) => singles [ c ] )
414448 return chrs . join ( '' ) === arg ? chrs : null
@@ -456,6 +490,8 @@ function resolveShort (arg, ...rest) {
456490 if ( shortAbbr [ arg ] ) {
457491 if ( abbrevHandler ) {
458492 abbrevHandler ( arg , shortAbbr [ arg ] )
493+ } else if ( abbrevHandler !== false ) {
494+ debug ( `abbrev: ${ arg } -> ${ shortAbbr [ arg ] } ` )
459495 }
460496 arg = shortAbbr [ arg ]
461497 }
0 commit comments