@@ -16,7 +16,17 @@ const _ = require('lodash'),
16
16
'date-time' : '<dateTime>' ,
17
17
password : '<password>'
18
18
} ,
19
- boolean : '<boolean>'
19
+ boolean : '<boolean>' ,
20
+ array : '<array>' ,
21
+ object : '<object>'
22
+ } ,
23
+ SCHEMA_TYPES = {
24
+ array : 'array' ,
25
+ boolean : 'boolean' ,
26
+ integer : 'integer' ,
27
+ number : 'number' ,
28
+ object : 'object' ,
29
+ string : 'string'
20
30
} ,
21
31
PARAMETER_SOURCE = {
22
32
REQUEST : 'REQUEST' ,
@@ -141,14 +151,6 @@ module.exports = {
141
151
return { value : ERR_TOO_MANY_LEVELS } ;
142
152
}
143
153
144
- // Update max stack reached for all current refs that's being resolved
145
- if ( ! _ . isEmpty ( this . _currentRefStack ) ) {
146
- _ . forEach ( this . _currentRefStack , ( refKey ) => {
147
- _ . set ( schemaResolutionCache , [ refKey , 'maxStack' ] ,
148
- Math . max ( _ . get ( schemaResolutionCache , [ refKey , 'maxStack' ] , 0 ) , stack ) ) ;
149
- } ) ;
150
- }
151
-
152
154
if ( ! schema ) {
153
155
return { value : '<Error: Schema not found>' } ;
154
156
}
@@ -177,10 +179,6 @@ module.exports = {
177
179
return this . resolveAllOf ( schema . allOf , parameterSourceOption , components , schemaResolutionCache , resolveFor ,
178
180
resolveTo , stack , _ . cloneDeep ( seenRef ) , stackLimit ) ;
179
181
}
180
- if ( schema . additionalProperties && ! _ . isBoolean ( schema . additionalProperties ) ) {
181
- schema . additionalProperties = this . resolveRefs ( schema . additionalProperties , parameterSourceOption ,
182
- components , schemaResolutionCache , resolveFor , resolveTo , stack , _ . cloneDeep ( seenRef ) , stackLimit ) ;
183
- }
184
182
if ( schema . $ref && _ . isFunction ( schema . $ref . split ) ) {
185
183
let refKey = schema . $ref ,
186
184
outerProperties = concreteUtils . getOuterPropsIfIsSupported ( schema ) ;
@@ -201,20 +199,6 @@ module.exports = {
201
199
return { value : 'reference ' + schema . $ref + ' not found in the OpenAPI spec' } ;
202
200
}
203
201
204
- if ( _ . get ( schemaResolutionCache , [ refKey , 'schema' ] ) ) {
205
- // maxStack for cached schema is how deep of nesting level we reached while resolving that schema
206
- let maxStack = _ . get ( schemaResolutionCache , [ refKey , 'maxStack' ] , 0 ) ,
207
- // resLevel of perticuler cached schema is nesting level at which schema was resolved
208
- resLevel = _ . get ( schemaResolutionCache , [ refKey , 'resLevel' ] , stackLimit ) ;
209
-
210
- /**
211
- * use cached schema if it was resolved at level lower or equal then at current stack level or
212
- * if cached schema is resolved fully (it does not contain ERR_TOO_MANY_LEVELS value in sub schema)
213
- */
214
- if ( resLevel <= stack || maxStack < stackLimit ) {
215
- return schemaResolutionCache [ refKey ] . schema ;
216
- }
217
- }
218
202
// something like #/components/schemas/PaginationEnvelope/properties/page
219
203
// will be resolved - we don't care about anything after the components part
220
204
// splitRef.slice(1) will return ['components', 'schemas', 'PaginationEnvelope', 'properties', 'page']
@@ -235,32 +219,33 @@ module.exports = {
235
219
resolvedSchema = concreteUtils . addOuterPropsToRefSchemaIfIsSupported ( resolvedSchema , outerProperties ) ;
236
220
}
237
221
if ( resolvedSchema ) {
238
- // add current ref that's being resolved in ref stack
239
- ! _ . isArray ( this . _currentRefStack ) && ( this . _currentRefStack = [ ] ) ;
240
- this . _currentRefStack . push ( refKey ) ;
241
-
242
222
let refResolvedSchema = this . resolveRefs ( resolvedSchema , parameterSourceOption ,
243
223
components , schemaResolutionCache , resolveFor , resolveTo , stack , _ . cloneDeep ( seenRef ) , stackLimit ) ;
244
224
245
- // remove current ref that's being resolved from stack as soon as resolved
246
- _ . isArray ( this . _currentRefStack ) && ( this . _currentRefStack . pop ( ) ) ;
247
-
248
- if ( refResolvedSchema && refResolvedSchema . value !== ERR_TOO_MANY_LEVELS ) {
249
- _ . set ( schemaResolutionCache , [ refKey , 'resLevel' ] , stack ) ;
250
- _ . set ( schemaResolutionCache , [ refKey , 'schema' ] , refResolvedSchema ) ;
251
- }
252
-
253
225
return refResolvedSchema ;
254
226
}
255
227
return { value : 'reference ' + schema . $ref + ' not found in the OpenAPI spec' } ;
256
228
}
257
- if ( concreteUtils . compareTypes ( schema . type , 'objects' ) || schema . hasOwnProperty ( 'properties' ) ) {
229
+ if ( concreteUtils . compareTypes ( schema . type , SCHEMA_TYPES . object ) || schema . hasOwnProperty ( 'properties' ) ||
230
+ schema . hasOwnProperty ( 'additionalProperties' ) ) {
258
231
// go through all props
259
- schema . type = ' object' ;
260
- if ( schema . hasOwnProperty ( 'properties' ) ) {
232
+ schema . type = SCHEMA_TYPES . object ;
233
+ if ( _ . has ( schema , 'properties' ) || _ . has ( schema , 'additionalProperties ') ) {
261
234
// shallow cloning schema object except properties object
262
- let tempSchema = _ . omit ( schema , 'properties' ) ;
263
- tempSchema . properties = { } ;
235
+ let tempSchema = _ . omit ( schema , [ 'properties' , 'additionalProperties' ] ) ;
236
+
237
+ if ( _ . has ( schema , 'additionalProperties' ) ) {
238
+ // don't resolve boolean values
239
+ if ( _ . isBoolean ( schema . additionalProperties ) ) {
240
+ tempSchema . additionalProperties = schema . additionalProperties ;
241
+ }
242
+ else {
243
+ tempSchema . additionalProperties = this . resolveRefs ( schema . additionalProperties , parameterSourceOption ,
244
+ components , schemaResolutionCache , resolveFor , resolveTo , stack , _ . cloneDeep ( seenRef ) , stackLimit ) ;
245
+ }
246
+ }
247
+
248
+ ! _ . isEmpty ( schema . properties ) && ( tempSchema . properties = { } ) ;
264
249
for ( prop in schema . properties ) {
265
250
if ( schema . properties . hasOwnProperty ( prop ) ) {
266
251
/* eslint-disable max-depth */
@@ -273,9 +258,17 @@ module.exports = {
273
258
}
274
259
275
260
if ( property . readOnly && parameterSourceOption === PARAMETER_SOURCE . REQUEST ) {
261
+ // remove property from required as it'll not be present in resolved schema
262
+ if ( _ . includes ( tempSchema . required , prop ) ) {
263
+ _ . remove ( tempSchema . required , _ . matches ( prop ) ) ;
264
+ }
276
265
continue ;
277
266
}
278
267
else if ( property . writeOnly && parameterSourceOption === PARAMETER_SOURCE . RESPONSE ) {
268
+ // remove property from required as it'll not be present in resolved schema
269
+ if ( _ . includes ( tempSchema . required , prop ) ) {
270
+ _ . remove ( tempSchema . required , _ . matches ( prop ) ) ;
271
+ }
279
272
continue ;
280
273
}
281
274
/* eslint-enable */
@@ -288,10 +281,10 @@ module.exports = {
288
281
289
282
// Override deefault value to appropriate type representation for parameter resolution to schema
290
283
if ( resolveFor === 'CONVERSION' && resolveTo === 'schema' ) {
291
- schema . default = '< object>' ;
284
+ schema . default = type . object ;
292
285
}
293
286
}
294
- else if ( concreteUtils . compareTypes ( schema . type , ' array' ) && schema . items ) {
287
+ else if ( concreteUtils . compareTypes ( schema . type , SCHEMA_TYPES . array ) && schema . items ) {
295
288
/*
296
289
For VALIDATION - keep minItems and maxItems properties defined by user in schema as is
297
290
FOR CONVERSION -
@@ -350,11 +343,11 @@ module.exports = {
350
343
}
351
344
else {
352
345
return {
353
- type : ' object'
346
+ type : SCHEMA_TYPES . object
354
347
} ;
355
348
}
356
349
if ( ! schema . type ) {
357
- schema . type = ' string' ;
350
+ schema . type = SCHEMA_TYPES . string ;
358
351
}
359
352
360
353
// Discard format if not supported by both json-schema-faker and ajv or pattern is also defined
0 commit comments