@@ -142,6 +142,11 @@ const paramParsersAndChecks = {
142
142
'bbox' : {
143
143
parser : bboxParser ,
144
144
check : poly => poly
145
+ } ,
146
+ 'Integer' : {
147
+ parser : Number . parseFloat ,
148
+ check : Number . isSafeInteger ,
149
+ failOnCheckResultEquals : false
145
150
}
146
151
} ;
147
152
@@ -208,25 +213,53 @@ const extractParam = function extractParam ({ req: { params, rawBody, body, _bod
208
213
return { value, nameUsed } ;
209
214
} ;
210
215
216
+ const validateMinMaxParam = function validateMinMaxParam ( valueArr , min , max ) {
217
+ if ( ! Array . isArray ( valueArr ) ) {
218
+ return valueArr ;
219
+ }
220
+
221
+ for ( const value of valueArr ) {
222
+ const tooLow = ( min && value < min ) ,
223
+ tooHigh = ( max && value > max ) ;
224
+
225
+ const errStr = `Supplied value ${ value } is outside of allowed range` ;
226
+ if ( tooLow === true && tooHigh === true ) {
227
+ return new Error ( `${ errStr } (${ min } , ${ max } )` ) ;
228
+ }
229
+
230
+ if ( tooLow === true ) {
231
+ return new Error ( `${ errStr } (< ${ min } )` ) ;
232
+ }
233
+
234
+ if ( tooHigh === true ) {
235
+ return new Error ( `${ errStr } (> ${ max } )` ) ;
236
+ }
237
+ }
238
+
239
+ return valueArr ;
240
+ } ;
241
+
211
242
const ARRAY_NOT_ALLOWED = 1 ,
212
243
CAST_FAILED = 2 ,
213
244
ILLEGAL_VALUE = 3 ,
214
245
ERROR_CUSTOM_MESSAGE = 4 ;
215
246
216
- const validateAndCastParam = function validateAndCastParam ( { value, dataType, allowedValues, mapping, dataTypeIsArray } ) {
247
+ const validateAndCastParam = function validateAndCastParam ( { value, dataType, allowedValues, mapping, dataTypeIsArray, min , max } ) {
217
248
// wrap dataType in array for calling of casting function
218
249
dataType = ( dataTypeIsArray ? dataType [ 0 ] : dataType ) ;
219
250
if ( ! dataTypeIsArray && Array . isArray ( value ) ) {
220
251
return { error : ARRAY_NOT_ALLOWED } ;
221
252
}
222
253
223
254
// test and cast value against dataType
224
- const castedValue = castParam ( value , dataType , dataTypeIsArray ) ;
255
+ let castedValue = castParam ( value , dataType , dataTypeIsArray ) ;
225
256
226
257
if ( typeof castedValue === 'undefined' ) {
227
258
return { error : CAST_FAILED } ;
228
259
}
229
260
261
+ castedValue = validateMinMaxParam ( castedValue , min , max ) ;
262
+
230
263
if ( castedValue instanceof Error ) {
231
264
return { error : ERROR_CUSTOM_MESSAGE , message : castedValue . message } ;
232
265
}
@@ -325,7 +358,7 @@ const retrieveParametersPredefs = {
325
358
}
326
359
} ;
327
360
328
- const handleAndSetParameterRequest = function handleAndSetParameterRequest ( req , next , { name, aliases, dataType = 'String' , allowedValues, mapping, required = false , defaultValue, paramValidatorAndParser = validateAndCastParam } ) {
361
+ const handleAndSetParameterRequest = function handleAndSetParameterRequest ( req , next , { name, aliases, dataType = 'String' , allowedValues, mapping, required = false , defaultValue, min , max , paramValidatorAndParser = validateAndCastParam } ) {
329
362
// extract param from request
330
363
const { value, nameUsed } = extractParam ( { req, name, aliases } ) ;
331
364
// there was no user supplied value but a default value
@@ -344,7 +377,7 @@ const handleAndSetParameterRequest = function handleAndSetParameterRequest (req,
344
377
const dataTypeIsArray = Array . isArray ( dataType ) ;
345
378
// at this point we can assume the parameter was set
346
379
// validate
347
- const { castedValue, error, message } = paramValidatorAndParser ( { value, dataType, allowedValues, mapping, dataTypeIsArray } ) ;
380
+ const { castedValue, error, message } = paramValidatorAndParser ( { value, dataType, allowedValues, mapping, dataTypeIsArray, min , max } ) ;
348
381
switch ( error ) {
349
382
case ARRAY_NOT_ALLOWED :
350
383
return next ( new BadRequestError ( `Parameter ${ nameUsed } must only be specified once` ) ) ;
@@ -365,12 +398,14 @@ const handleAndSetParameterRequest = function handleAndSetParameterRequest (req,
365
398
// A single parameter has the following properties:
366
399
// name: String
367
400
// aliases: String[]
368
- // dataType: ['String', ['String'], 'StringWithEmpty', ['StringWithEmpty'], 'Number', ['Number'] 'object', ['object'], 'ISO8601', ['ISO8601'], 'as-is'] // default: String 'as-is' disables casting and lets restify cast the value
401
+ // dataType: ['String', ['String'], 'StringWithEmpty', ['StringWithEmpty'], 'Number', ['Number'] 'object', ['object'], 'ISO8601', ['ISO8601'], 'as-is', 'Integer', ['Integer'] ] // default: String 'as-is' disables casting and lets restify cast the value
369
402
// allowedValues: String[]
370
403
// mapping: Object
371
404
// required: Boolean // default: false
372
405
// defaultValue: Anything
373
406
// predef: load definition from elsewhere
407
+ // min: minimal value for Numbers and Integers. Compared with >=
408
+ // max: maximal value for Numbers and Integers. Compared with <
374
409
const retrieveParameters = function retrieveParameters ( parameters = [ ] ) {
375
410
return function ( req , res , next ) {
376
411
//for (let { name, aliases, dataType, allowedValues, mapping, required, defaultValue, predef } of parameters) {
0 commit comments