@@ -141,48 +141,76 @@ function help(config, options) {
141
141
142
142
exports . help = help ;
143
143
144
+ /** Sanitizes an option value to be a valid value of the option's type. */
145
+ function sanitizeValue ( value , type ) {
146
+ if ( value != null ) {
147
+ switch ( type ) {
148
+ case undefined :
149
+ case "b" : return Boolean ( value ) ;
150
+ case "i" : return + ( + value ) . toFixed ( 0 ) || 0 ;
151
+ case "f" : return + value || 0 ;
152
+ case "s" : return String ( value ) ;
153
+ case "I" : {
154
+ if ( ! Array . isArray ( value ) ) value = [ value ] ;
155
+ return value . map ( v => + ( + v ) . toFixed ( 0 ) || 0 ) ;
156
+ }
157
+ case "F" : {
158
+ if ( ! Array . isArray ( value ) ) value = [ value ] ;
159
+ return value . map ( v => + v || 0 ) ;
160
+ }
161
+ case "S" : {
162
+ if ( ! Array . isArray ( value ) ) value = [ value ] ;
163
+ return value . map ( v => String ( v ) ) ;
164
+ }
165
+ }
166
+ }
167
+ return undefined ;
168
+ }
169
+
144
170
/** Merges two sets of options into one, preferring the current over the parent set. */
145
171
function merge ( config , currentOptions , parentOptions ) {
146
172
const mergedOptions = { } ;
147
- for ( const [ key , { mutuallyExclusive } ] of Object . entries ( config ) ) {
148
- if ( currentOptions [ key ] == null ) {
149
- if ( parentOptions [ key ] != null ) {
173
+ for ( const [ key , { type, mutuallyExclusive } ] of Object . entries ( config ) ) {
174
+ let currentValue = sanitizeValue ( currentOptions [ key ] , type ) ;
175
+ let parentValue = sanitizeValue ( parentOptions [ key ] , type ) ;
176
+ if ( currentValue == null ) {
177
+ if ( parentValue != null ) {
150
178
// only parent value present
151
- if ( Array . isArray ( parentOptions [ key ] ) ) {
179
+ if ( Array . isArray ( parentValue ) ) {
152
180
let exclude ;
153
181
if ( mutuallyExclusive != null && ( exclude = currentOptions [ mutuallyExclusive ] ) ) {
154
- mergedOptions [ key ] = parentOptions [ key ] . filter ( value => ! exclude . includes ( value ) ) ;
182
+ mergedOptions [ key ] = parentValue . filter ( value => ! exclude . includes ( value ) ) ;
155
183
} else {
156
- mergedOptions [ key ] = parentOptions [ key ] . slice ( ) ;
184
+ mergedOptions [ key ] = parentValue . slice ( ) ;
157
185
}
158
186
} else {
159
- mergedOptions [ key ] = parentOptions [ key ] ;
187
+ mergedOptions [ key ] = parentValue ;
160
188
}
161
189
}
162
- } else if ( parentOptions [ key ] == null ) {
190
+ } else if ( parentValue == null ) {
163
191
// only current value present
164
- if ( Array . isArray ( currentOptions [ key ] ) ) {
165
- mergedOptions [ key ] = currentOptions [ key ] . slice ( ) ;
192
+ if ( Array . isArray ( currentValue ) ) {
193
+ mergedOptions [ key ] = currentValue . slice ( ) ;
166
194
} else {
167
- mergedOptions [ key ] = currentOptions [ key ] ;
195
+ mergedOptions [ key ] = currentValue ;
168
196
}
169
197
} else {
170
198
// both current and parent values present
171
- if ( Array . isArray ( currentOptions [ key ] ) ) {
199
+ if ( Array . isArray ( currentValue ) ) {
172
200
let exclude ;
173
201
if ( mutuallyExclusive != null && ( exclude = currentOptions [ mutuallyExclusive ] ) ) {
174
202
mergedOptions [ key ] = [
175
- ...currentOptions [ key ] ,
176
- ...parentOptions [ key ] . filter ( value => ! currentOptions [ key ] . includes ( value ) && ! exclude . includes ( value ) )
203
+ ...currentValue ,
204
+ ...parentValue . filter ( value => ! currentValue . includes ( value ) && ! exclude . includes ( value ) )
177
205
] ;
178
206
} else {
179
207
mergedOptions [ key ] = [
180
- ...currentOptions [ key ] ,
181
- ...parentOptions [ key ] . filter ( value => ! currentOptions [ key ] . includes ( value ) ) // dedup
208
+ ...currentValue ,
209
+ ...parentValue . filter ( value => ! currentValue . includes ( value ) ) // dedup
182
210
] ;
183
211
}
184
212
} else {
185
- mergedOptions [ key ] = currentOptions [ key ] ;
213
+ mergedOptions [ key ] = currentValue ;
186
214
}
187
215
}
188
216
}
0 commit comments