@@ -2,13 +2,16 @@ import { namedTypes, builders } from 'ast-types';
2
2
3
3
import type { Compiler } from './compiler' ;
4
4
import {
5
+ OpenAPIAllOfSchema ,
5
6
OpenAPIAnyOfSchema ,
6
7
OpenAPIArraySchema ,
7
8
OpenAPIBooleanSchema ,
8
9
OpenAPIEnumableSchema ,
10
+ OpenAPIIntegerSchema ,
9
11
OpenAPINullableSchema ,
10
12
OpenAPINumberSchema ,
11
13
OpenAPIObjectSchema ,
14
+ OpenAPIOneOfSchema ,
12
15
OpenAPIStringSchema ,
13
16
OpenAPIValueSchema ,
14
17
} from './types' ;
@@ -26,10 +29,19 @@ export function compileValueSchema(compiler: Compiler, schema: OpenAPIValueSchem
26
29
return compileAnyOfSchema ( compiler , schema ) ;
27
30
}
28
31
32
+ if ( 'oneOf' in schema ) {
33
+ return compileOneOfSchema ( compiler , schema ) ;
34
+ }
35
+
36
+ if ( 'allOf' in schema ) {
37
+ return compileAllOfSchema ( compiler , schema ) ;
38
+ }
39
+
29
40
if ( 'type' in schema ) {
30
41
switch ( schema . type ) {
31
42
case 'object' :
32
43
return compileObjectSchema ( compiler , schema ) ;
44
+ case 'integer' :
33
45
case 'number' :
34
46
return compileNumberSchema ( compiler , schema ) ;
35
47
case 'string' :
@@ -38,10 +50,13 @@ export function compileValueSchema(compiler: Compiler, schema: OpenAPIValueSchem
38
50
return compileBooleanSchema ( compiler , schema ) ;
39
51
case 'array' :
40
52
return compileArraySchema ( compiler , schema ) ;
53
+ default :
54
+ throw new Error ( `Unsupported schema: ${ JSON . stringify ( schema ) } ` ) ;
41
55
}
42
56
}
43
57
44
- throw new Error ( `Unsupported schema: ${ JSON . stringify ( schema ) } ` ) ;
58
+ return compileAnySchema ( compiler , schema ) ;
59
+
45
60
}
46
61
47
62
function compileAnyOfSchema ( compiler : Compiler , schema : OpenAPIAnyOfSchema ) {
@@ -85,6 +100,113 @@ function compileAnyOfSchema(compiler: Compiler, schema: OpenAPIAnyOfSchema) {
85
100
} ) ;
86
101
}
87
102
103
+ function compileOneOfSchema ( compiler : Compiler , schema : OpenAPIOneOfSchema ) {
104
+ return compiler . defineValidationFunction ( schema , ( { value, path, error } ) => {
105
+ const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
106
+
107
+ // Declare the variable to use as a result, then iterate over each schema
108
+ const resultIdentifier = builders . identifier ( 'result' ) ;
109
+ nodes . push (
110
+ builders . variableDeclaration ( 'let' , [ builders . variableDeclarator ( resultIdentifier ) ] ) ,
111
+ ) ;
112
+
113
+ schema . oneOf . forEach ( ( subSchema , index ) => {
114
+ const fnIdentifier = compileValueSchema ( compiler , subSchema ) ;
115
+ const altIdentifier = builders . identifier ( `alt${ index } ` ) ;
116
+
117
+ // Allocate a variable for the result of the schema alternative
118
+ nodes . push (
119
+ builders . variableDeclaration ( 'const' , [
120
+ builders . variableDeclarator (
121
+ altIdentifier ,
122
+ builders . callExpression ( fnIdentifier , [ path , value ] ) ,
123
+ ) ,
124
+ ] ) ,
125
+ ) ;
126
+
127
+ nodes . push (
128
+ builders . ifStatement (
129
+ builders . unaryExpression (
130
+ '!' ,
131
+ builders . binaryExpression (
132
+ 'instanceof' ,
133
+ altIdentifier ,
134
+ ValidationErrorIdentifier ,
135
+ ) ,
136
+ ) ,
137
+ builders . blockStatement ( [
138
+ builders . expressionStatement (
139
+ builders . assignmentExpression ( '=' , resultIdentifier , altIdentifier ) ,
140
+ ) ,
141
+ ...( index > 0
142
+ ? [
143
+ builders . ifStatement (
144
+ builders . binaryExpression (
145
+ '!==' ,
146
+ resultIdentifier ,
147
+ builders . identifier ( 'undefined' ) ,
148
+ ) ,
149
+ builders . blockStatement ( [
150
+ builders . returnStatement (
151
+ error ( 'Expected to only match one of the schemas' ) ,
152
+ ) ,
153
+ ] ) ,
154
+ ) ,
155
+ ]
156
+ : [ ] ) ,
157
+ ] ) ,
158
+ ) ,
159
+ ) ;
160
+ } ) ;
161
+
162
+ nodes . push ( builders . returnStatement ( resultIdentifier ) ) ;
163
+
164
+ return nodes ;
165
+ } ) ;
166
+ }
167
+
168
+ function compileAllOfSchema ( compiler : Compiler , schema : OpenAPIAllOfSchema ) {
169
+ return compiler . defineValidationFunction ( schema , ( { value, path, error } ) => {
170
+ const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
171
+
172
+ const resultIdentifier = builders . identifier ( 'result' ) ;
173
+ nodes . push (
174
+ builders . variableDeclaration ( 'let' , [ builders . variableDeclarator ( resultIdentifier , value ) ] ) ,
175
+ ) ;
176
+
177
+ schema . allOf . forEach ( ( subSchema , index ) => {
178
+ const fnIdentifier = compileValueSchema ( compiler , subSchema ) ;
179
+
180
+ nodes . push (
181
+ builders . expressionStatement (
182
+ builders . assignmentExpression (
183
+ '=' ,
184
+ resultIdentifier ,
185
+ builders . callExpression ( fnIdentifier , [ path , resultIdentifier ] ) ,
186
+ ) ,
187
+ ) ,
188
+ ) ;
189
+
190
+ nodes . push (
191
+ builders . ifStatement (
192
+ builders . binaryExpression (
193
+ 'instanceof' ,
194
+ resultIdentifier ,
195
+ ValidationErrorIdentifier ,
196
+ ) ,
197
+ builders . blockStatement ( [
198
+ builders . returnStatement ( resultIdentifier ) ,
199
+ ] ) ,
200
+ )
201
+ )
202
+ } ) ;
203
+
204
+ nodes . push ( builders . returnStatement ( resultIdentifier ) ) ;
205
+
206
+ return nodes ;
207
+ } ) ;
208
+ }
209
+
88
210
function compileObjectSchema ( compiler : Compiler , schema : OpenAPIObjectSchema ) {
89
211
return compiler . defineValidationFunction ( schema , ( { path, value, error } ) => {
90
212
const nodes : namedTypes . BlockStatement [ 'body' ] = [ ] ;
@@ -326,7 +448,10 @@ function compileArraySchema(compiler: Compiler, schema: OpenAPIArraySchema) {
326
448
} ) ;
327
449
}
328
450
329
- function compileNumberSchema ( compiler : Compiler , schema : OpenAPINumberSchema ) {
451
+ function compileNumberSchema (
452
+ compiler : Compiler ,
453
+ schema : OpenAPINumberSchema | OpenAPIIntegerSchema ,
454
+ ) {
330
455
return compiler . defineValidationFunction ( schema , ( { value, error } ) => {
331
456
const enumCheck = compileEnumableCheck ( compiler , schema , value , error ) ;
332
457
if ( enumCheck ) {
@@ -413,6 +538,15 @@ function compileBooleanSchema(compiler: Compiler, schema: OpenAPIBooleanSchema)
413
538
} ) ;
414
539
}
415
540
541
+
542
+ function compileAnySchema ( compiler : Compiler , schema : object ) {
543
+ return compiler . defineValidationFunction ( schema , ( { value } ) => {
544
+ return [
545
+ builders . returnStatement ( value )
546
+ ] ;
547
+ } ) ;
548
+ }
549
+
416
550
function compileNullableCheck (
417
551
compiler : Compiler ,
418
552
schema : OpenAPINullableSchema ,
0 commit comments