Skip to content

Commit f3ea0d8

Browse files
committed
Update schemapack to return analytics from the module and refactor deref
1 parent 70e779d commit f3ea0d8

File tree

6 files changed

+183
-110
lines changed

6 files changed

+183
-110
lines changed

lib/deref.js

Lines changed: 111 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -84,36 +84,36 @@ module.exports = {
8484
/**
8585
* Creates a schema that's a union of all input schemas (only type: object is supported)
8686
*
87-
* @param {array} schemaArr - array of schemas, all of which must be valid in the returned object
88-
* @param {string} parameterSourceOption tells that the schema object is of request or response
89-
* @param {*} components components in openapi spec.
90-
* @param {object} schemaResolutionCache stores already resolved references
91-
* @param {*} resolveFor - resolve refs for validation/conversion (value to be one of VALIDATION/CONVERSION)
92-
* @param {string} resolveTo The desired JSON-generation mechanism (schema: prefer using the JSONschema to
87+
* @param {array} schemaArr REQUIRED - array of schemas, all of which must be valid in the returned object
88+
* @param {string} parameterSourceOption REQUIRED tells that the schema object is of request or response
89+
* @param {*} components REQUIRED components in openapi spec.
90+
* @param {object} options - REQUIRED a list of options to indicate the type of resolution needed.
91+
* @param {*} options.resolveFor - resolve refs for validation/conversion (value to be one of VALIDATION/CONVERSION)
92+
* @param {string} options.resolveTo The desired JSON-generation mechanism (schema: prefer using the JSONschema to
9393
generate a fake object, example: use specified examples as-is). Default: schema
94-
* @param {*} stack counter which keeps a tab on nested schemas
95-
* @param {*} seenRef References that are repeated. Used to identify circular references.
96-
* @param {*} stackLimit Depth to which the schema should be resolved.
94+
* @param {*} options.stack counter which keeps a tab on nested schemas
95+
* @param {*} options.seenRef References that are repeated. Used to identify circular references.
96+
* @param {*} options.stackLimit Depth to which the schema should be resolved.
9797
* @returns {*} schema - schema that adheres to all individual schemas in schemaArr
9898
*/
99-
resolveAllOf: function (schemaArr, parameterSourceOption, components, schemaResolutionCache,
100-
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef, stackLimit) {
99+
resolveAllOf: function (schemaArr, parameterSourceOption, components,
100+
{ resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef = {}, stackLimit = 10, analytics = {} }) {
101101

102102
if (!(schemaArr instanceof Array)) {
103103
return null;
104104
}
105105

106106
if (schemaArr.length === 1) {
107107
// for just one entry in allOf, don't need to enforce type: object restriction
108-
return this.resolveRefs(schemaArr[0], parameterSourceOption, components, schemaResolutionCache, resolveFor,
109-
resolveTo, stack, seenRef, stackLimit);
108+
return this.resolveRefs(schemaArr[0], parameterSourceOption, components,
109+
{ stack, seenRef: _.cloneDeep(seenRef), resolveFor, resolveTo, stackLimit, analytics });
110110
}
111111

112112
try {
113113
return mergeAllOf({
114114
allOf: schemaArr.map((schema) => {
115-
return this.resolveRefs(schema, parameterSourceOption, components, schemaResolutionCache, resolveFor,
116-
resolveTo, stack, seenRef, stackLimit, true);
115+
return this.resolveRefs(schema, parameterSourceOption, components,
116+
{ stack, seenRef: _.cloneDeep(seenRef), resolveFor, resolveTo, stackLimit, isAllOf: true, analytics });
117117
})
118118
}, {
119119
resolvers: {
@@ -130,33 +130,35 @@ module.exports = {
130130

131131
/**
132132
* Resolves references to components for a given schema.
133-
* @param {*} schema (openapi) to resolve references.
134-
* @param {string} parameterSourceOption tells that the schema object is of request or response
135-
* @param {*} components components in openapi spec.
136-
* @param {object} schemaResolutionCache stores already resolved references - more structure detail below
137-
* {'schema reference key': {
138-
* maxStack {Integer} : Defined as how deep of nesting level we reached while resolving schema that's being cached
139-
* resLevel {Integer} : Defined as nesting level at which schema that's being cached was resolved
140-
* schema {Object} : resolved schema that will be cached
141-
* }}
142-
* @param {*} resolveFor - resolve refs for validation/conversion (value to be one of VALIDATION/CONVERSION)
143-
* @param {string} resolveTo The desired JSON-generation mechanism (schema: prefer using the JSONschema to
133+
* @param {*} schema REQUIRED (openapi) to resolve references.
134+
* @param {string} parameterSourceOption REQUIRED tells that the schema object is of request or response
135+
* @param {*} components REQUIRED components in openapi spec.
136+
* @param {object} options REQUIRED a list of options to indicate the type of resolution needed
137+
* @param {*} options.resolveFor - resolve refs for validation/conversion (value to be one of VALIDATION/CONVERSION)
138+
* @param {string} options.resolveTo The desired JSON-generation mechanism (schema: prefer using the JSONschema to
144139
generate a fake object, example: use specified examples as-is). Default: schema
145-
* @param {*} stack counter which keeps a tab on nested schemas
146-
* @param {*} seenRef - References that are repeated. Used to identify circular references.
147-
* @param {*} stackLimit Depth to which the schema should be resolved.
148-
* @returns {*} schema satisfying JSON-schema-faker.
140+
* @param {number} options.stack counter which keeps a tab on nested schemas
141+
* @param {*} otions.seenRef - References that are repeated. Used to identify circular references.
142+
* @param {number} options.stackLimit Depth to which the schema should be resolved.
143+
* @param {Boolean} options.isAllOf
144+
* @param {object} options.analytics
145+
* @returns {*} schema satisfying JSON-schema-faker.
149146
*/
150147

151-
resolveRefs: function (schema, parameterSourceOption, components, schemaResolutionCache,
152-
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef = {}, stackLimit = 10, isAllOf = false) {
148+
resolveRefs: function (schema, parameterSourceOption, components, {
149+
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef = {}, stackLimit = 10,
150+
isAllOf = false, analytics = {}
151+
}) {
153152
var resolvedSchema, prop, splitRef,
154153
ERR_TOO_MANY_LEVELS = '<Error: Too many levels of nesting to fake this schema>';
155154
let concreteUtils = components && components.hasOwnProperty('concreteUtils') ?
156155
components.concreteUtils :
157156
DEFAULT_SCHEMA_UTILS;
158157
stack++;
159-
schemaResolutionCache = schemaResolutionCache || {};
158+
159+
if (analytics.actualStack < stack) {
160+
analytics.actualStack = stack;
161+
}
160162

161163
if (stack > stackLimit) {
162164
return { value: ERR_TOO_MANY_LEVELS };
@@ -168,23 +170,43 @@ module.exports = {
168170

169171
if (schema.anyOf) {
170172
if (resolveFor === 'CONVERSION') {
171-
return this.resolveRefs(schema.anyOf[0], parameterSourceOption, components, schemaResolutionCache, resolveFor,
172-
resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
173+
return this.resolveRefs(schema.anyOf[0], parameterSourceOption, components, {
174+
resolveFor,
175+
resolveTo,
176+
stack,
177+
seenRef: _.cloneDeep(seenRef),
178+
stackLimit,
179+
analytics
180+
});
173181
}
174182
return { anyOf: _.map(schema.anyOf, (schemaElement) => {
175183
PROPERTIES_TO_ASSIGN_ON_CASCADE.forEach((prop) => {
176184
if (_.isNil(schemaElement[prop]) && !_.isNil(schema[prop])) {
177185
schemaElement[prop] = schema[prop];
178186
}
179187
});
180-
return this.resolveRefs(schemaElement, parameterSourceOption, components, schemaResolutionCache, resolveFor,
181-
resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
188+
return this.resolveRefs(schemaElement, parameterSourceOption, components,
189+
{
190+
resolveFor,
191+
resolveTo,
192+
stack,
193+
seenRef: _.cloneDeep(seenRef),
194+
stackLimit,
195+
analytics
196+
});
182197
}) };
183198
}
184199
if (schema.oneOf) {
185200
if (resolveFor === 'CONVERSION') {
186-
return this.resolveRefs(schema.oneOf[0], parameterSourceOption, components, schemaResolutionCache, resolveFor,
187-
resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
201+
return this.resolveRefs(schema.oneOf[0], parameterSourceOption, components,
202+
{
203+
resolveFor,
204+
resolveTo,
205+
stack,
206+
seenRef: _.cloneDeep(seenRef),
207+
stackLimit,
208+
analytics
209+
});
188210
}
189211
return { oneOf: _.map(schema.oneOf, (schemaElement) => {
190212
PROPERTIES_TO_ASSIGN_ON_CASCADE.forEach((prop) => {
@@ -193,13 +215,27 @@ module.exports = {
193215
}
194216
});
195217

196-
return this.resolveRefs(schemaElement, parameterSourceOption, components, schemaResolutionCache,
197-
resolveFor, resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
218+
return this.resolveRefs(schemaElement, parameterSourceOption, components,
219+
{
220+
resolveFor,
221+
resolveTo,
222+
stack,
223+
seenRef: _.cloneDeep(seenRef),
224+
stackLimit,
225+
analytics
226+
});
198227
}) };
199228
}
200229
if (schema.allOf) {
201-
return this.resolveAllOf(schema.allOf, parameterSourceOption, components, schemaResolutionCache, resolveFor,
202-
resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
230+
return this.resolveAllOf(schema.allOf, parameterSourceOption, components,
231+
{
232+
resolveFor,
233+
resolveTo,
234+
stack,
235+
seenRef: _.cloneDeep(seenRef),
236+
stackLimit,
237+
analytics
238+
});
203239
}
204240
if (schema.$ref && _.isFunction(schema.$ref.split)) {
205241
let refKey = schema.$ref,
@@ -241,7 +277,14 @@ module.exports = {
241277
}
242278
if (resolvedSchema) {
243279
let refResolvedSchema = this.resolveRefs(resolvedSchema, parameterSourceOption,
244-
components, schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
280+
components, {
281+
resolveFor,
282+
resolveTo,
283+
stack,
284+
seenRef: _.cloneDeep(seenRef),
285+
stackLimit,
286+
analytics
287+
});
245288

246289
return refResolvedSchema;
247290
}
@@ -266,7 +309,14 @@ module.exports = {
266309
}
267310
else {
268311
tempSchema.additionalProperties = this.resolveRefs(schema.additionalProperties, parameterSourceOption,
269-
components, schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
312+
components, {
313+
resolveFor,
314+
resolveTo,
315+
stack,
316+
seenRef: _.cloneDeep(seenRef),
317+
stackLimit,
318+
analytics
319+
});
270320
}
271321
}
272322

@@ -300,7 +350,14 @@ module.exports = {
300350
tempSchema.properties[prop] = _.isEmpty(property) ?
301351
{} :
302352
this.resolveRefs(property, parameterSourceOption, components,
303-
schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
353+
{
354+
resolveFor,
355+
resolveTo,
356+
stack,
357+
seenRef: _.cloneDeep(seenRef),
358+
stackLimit,
359+
analytics
360+
});
304361
}
305362
}
306363
return tempSchema;
@@ -339,7 +396,14 @@ module.exports = {
339396
let tempSchema = _.omit(schema, ['items', 'additionalProperties']);
340397

341398
tempSchema.items = this.resolveRefs(schema.items, parameterSourceOption,
342-
components, schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef), stackLimit);
399+
components, {
400+
resolveFor,
401+
resolveTo,
402+
stack,
403+
seenRef: _.cloneDeep(seenRef),
404+
stackLimit,
405+
analytics
406+
});
343407
return tempSchema;
344408
}
345409
else if (!schema.hasOwnProperty('default')) {

0 commit comments

Comments
 (0)