@@ -3,12 +3,19 @@ import { namedTypes, builders } from 'ast-types';
3
3
import { Compiler , ValidationErrorIdentifier } from './compiler' ;
4
4
import {
5
5
OpenAPIAnyOfSchema ,
6
+ OpenAPIArraySchema ,
7
+ OpenAPIBooleanSchema ,
8
+ OpenAPIEnumableSchema ,
9
+ OpenAPINullableSchema ,
6
10
OpenAPINumberSchema ,
7
11
OpenAPIObjectSchema ,
8
12
OpenAPIStringSchema ,
9
13
OpenAPIValueSchema ,
10
14
} from './types' ;
11
15
16
+ /**
17
+ * Compile a JSON schema into a validation function.
18
+ */
12
19
export function compileValueSchema ( compiler : Compiler , schema : OpenAPIValueSchema ) {
13
20
if ( 'anyOf' in schema ) {
14
21
return compileAnyOfSchema ( compiler , schema ) ;
@@ -22,6 +29,10 @@ export function compileValueSchema(compiler: Compiler, schema: OpenAPIValueSchem
22
29
return compileNumberSchema ( compiler , schema ) ;
23
30
case 'string' :
24
31
return compileStringSchema ( compiler , schema ) ;
32
+ case 'boolean' :
33
+ return compileBooleanSchema ( compiler , schema ) ;
34
+ case 'array' :
35
+ return compileArraySchema ( compiler , schema ) ;
25
36
}
26
37
}
27
38
@@ -74,6 +85,8 @@ function compileObjectSchema(compiler: Compiler, schema: OpenAPIObjectSchema) {
74
85
const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
75
86
const endNodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
76
87
88
+ nodes . push ( ...compileNullableCheck ( compiler , schema , value ) ) ;
89
+
77
90
// Define a variable to be all the keys in `value`
78
91
const keysIdentifier = builders . identifier ( 'keys' ) ;
79
92
@@ -296,10 +309,28 @@ function compileObjectSchema(compiler: Compiler, schema: OpenAPIObjectSchema) {
296
309
} ) ;
297
310
}
298
311
299
- function compileNumberSchema ( compiler : Compiler , schema : OpenAPINumberSchema ) {
312
+ function compileArraySchema ( compiler : Compiler , schema : OpenAPIArraySchema ) {
300
313
return compiler . defineValidationFunction ( schema , ( { value, error } ) => {
301
314
const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
302
315
316
+ nodes . push ( ...compileNullableCheck ( compiler , schema , value ) ) ;
317
+
318
+
319
+ nodes . push ( builders . returnStatement ( value ) ) ;
320
+
321
+ return nodes ;
322
+ } ) ;
323
+ }
324
+
325
+ function compileNumberSchema ( compiler : Compiler , schema : OpenAPINumberSchema ) {
326
+ return compiler . defineValidationFunction ( schema , ( { value, error } ) => {
327
+ const enumCheck = compileEnumableCheck ( compiler , schema , value , error ) ;
328
+ if ( enumCheck ) {
329
+ return enumCheck ;
330
+ }
331
+
332
+ const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
333
+ nodes . push ( ...compileNullableCheck ( compiler , schema , value ) ) ;
303
334
nodes . push (
304
335
builders . ifStatement (
305
336
builders . unaryExpression (
@@ -322,8 +353,14 @@ function compileNumberSchema(compiler: Compiler, schema: OpenAPINumberSchema) {
322
353
323
354
function compileStringSchema ( compiler : Compiler , schema : OpenAPIStringSchema ) {
324
355
return compiler . defineValidationFunction ( schema , ( { value, error } ) => {
325
- const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
356
+ const enumCheck = compileEnumableCheck ( compiler , schema , value , error ) ;
357
+ if ( enumCheck ) {
358
+ return enumCheck ;
359
+ }
360
+
326
361
362
+ const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
363
+ nodes . push ( ...compileNullableCheck ( compiler , schema , value ) ) ;
327
364
nodes . push (
328
365
builders . ifStatement (
329
366
builders . unaryExpression (
@@ -343,3 +380,74 @@ function compileStringSchema(compiler: Compiler, schema: OpenAPIStringSchema) {
343
380
return nodes ;
344
381
} ) ;
345
382
}
383
+
384
+ function compileBooleanSchema ( compiler : Compiler , schema : OpenAPIBooleanSchema ) {
385
+ return compiler . defineValidationFunction ( schema , ( { value, error } ) => {
386
+ const enumCheck = compileEnumableCheck ( compiler , schema , value , error ) ;
387
+ if ( enumCheck ) {
388
+ return enumCheck ;
389
+ }
390
+
391
+ const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
392
+ nodes . push ( ...compileNullableCheck ( compiler , schema , value ) ) ;
393
+ nodes . push (
394
+ builders . ifStatement (
395
+ builders . unaryExpression (
396
+ '!' ,
397
+ builders . binaryExpression (
398
+ '===' ,
399
+ builders . unaryExpression ( 'typeof' , value ) ,
400
+ builders . literal ( 'boolean' ) ,
401
+ ) ,
402
+ ) ,
403
+ builders . blockStatement ( [ builders . returnStatement ( error ( 'Expected a boolean' ) ) ] ) ,
404
+ ) ,
405
+ ) ;
406
+
407
+ nodes . push ( builders . returnStatement ( value ) ) ;
408
+
409
+ return nodes ;
410
+ } ) ;
411
+ }
412
+
413
+ function compileNullableCheck ( compiler : Compiler , schema : OpenAPINullableSchema , value : namedTypes . Identifier ) {
414
+ if ( ! schema . nullable ) {
415
+ return [ ] ;
416
+ }
417
+
418
+ return [
419
+ builders . ifStatement (
420
+ builders . binaryExpression ( '===' , value , builders . identifier ( 'null' ) ) ,
421
+ builders . blockStatement ( [ builders . returnStatement ( value ) ] ) ,
422
+ )
423
+ ]
424
+ }
425
+
426
+
427
+ function compileEnumableCheck ( compiler : Compiler , schema : OpenAPIEnumableSchema , value : namedTypes . Identifier , error : ( message : string ) => namedTypes . NewExpression ) {
428
+ if ( ! schema . enum ) {
429
+ return null ;
430
+ }
431
+
432
+ return [
433
+ builders . ifStatement (
434
+ schema . enum . reduce ( ( acc , val ) => {
435
+ const test = builders . binaryExpression ( '!==' , value , builders . literal ( val ) )
436
+
437
+ if ( ! acc ) {
438
+ return test ;
439
+ }
440
+
441
+ return builders . logicalExpression (
442
+ '&&' ,
443
+ acc ,
444
+ test
445
+ )
446
+ } , null as ( namedTypes . BinaryExpression | namedTypes . LogicalExpression | null ) ) ! ,
447
+ builders . blockStatement ( [ builders . returnStatement (
448
+ error ( 'Expected one of the enum value' )
449
+ ) ] ) ,
450
+ ) ,
451
+ builders . returnStatement ( value )
452
+ ]
453
+ }
0 commit comments