@@ -15,7 +15,8 @@ var _ = require('lodash'),
15
15
{
16
16
handleExclusiveMaximum,
17
17
handleExclusiveMinimum
18
- } = require('./../lib/common/schemaUtilsCommon');
18
+ } = require('./../lib/common/schemaUtilsCommon'),
19
+ hash = require('object-hash');
19
20
20
21
(function (global, factory) {
21
22
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -24100,7 +24101,7 @@ function extend() {
24100
24101
var nullType = nullGenerator;
24101
24102
24102
24103
// TODO provide types
24103
- function unique(path, items, value, sample, resolve, traverseCallback) {
24104
+ function unique(path, items, value, sample, resolve, traverseCallback, seenSchemaCache ) {
24104
24105
var tmp = [], seen = [];
24105
24106
function walk(obj) {
24106
24107
var json = JSON.stringify(obj);
@@ -24113,15 +24114,15 @@ function extend() {
24113
24114
// TODO: find a better solution?
24114
24115
var limit = 10;
24115
24116
while (tmp.length !== items.length) {
24116
- walk(traverseCallback(value.items || sample, path, resolve));
24117
+ walk(traverseCallback(value.items || sample, path, resolve, null, seenSchemaCache ));
24117
24118
if (!limit--) {
24118
24119
break;
24119
24120
}
24120
24121
}
24121
24122
return tmp;
24122
24123
}
24123
24124
// TODO provide types
24124
- var arrayType = function arrayType(value, path, resolve, traverseCallback) {
24125
+ var arrayType = function arrayType(value, path, resolve, traverseCallback, seenSchemaCache ) {
24125
24126
var items = [];
24126
24127
if (!(value.items || value.additionalItems)) {
24127
24128
if (utils.hasProperties(value, 'minItems', 'maxItems', 'uniqueItems')) {
@@ -24136,7 +24137,7 @@ function extend() {
24136
24137
if (tmpItems instanceof Array) {
24137
24138
return Array.prototype.concat.call(items, tmpItems.map(function (item, key) {
24138
24139
var itemSubpath = path.concat(['items', key + '']);
24139
- return traverseCallback(item, itemSubpath, resolve);
24140
+ return traverseCallback(item, itemSubpath, resolve, null, seenSchemaCache );
24140
24141
}));
24141
24142
}
24142
24143
var minItems = value.minItems;
@@ -24165,11 +24166,11 @@ function extend() {
24165
24166
sample = typeof value.additionalItems === 'object' ? value.additionalItems : {};
24166
24167
for (var current = items.length; current < length; current++) {
24167
24168
var itemSubpath = path.concat(['items', current + '']);
24168
- var element = traverseCallback(value.items || sample, itemSubpath, resolve);
24169
+ var element = traverseCallback(value.items || sample, itemSubpath, resolve, null, seenSchemaCache );
24169
24170
items.push(element);
24170
24171
}
24171
24172
if (value.uniqueItems) {
24172
- return unique(path.concat(['items']), items, value, sample, resolve, traverseCallback);
24173
+ return unique(path.concat(['items']), items, value, sample, resolve, traverseCallback, seenSchemaCache );
24173
24174
}
24174
24175
return items;
24175
24176
};
@@ -24233,7 +24234,7 @@ function extend() {
24233
24234
var anyType = { type: ['string', 'number', 'integer', 'boolean'] };
24234
24235
// TODO provide types
24235
24236
// Updated objectType definition to latest version (0.5.0-rcv.41)
24236
- var objectType = function objectType(value, path, resolve, traverseCallback) {
24237
+ var objectType = function objectType(value, path, resolve, traverseCallback, seenSchemaCache ) {
24237
24238
const props = {};
24238
24239
24239
24240
const properties = value.properties || {};
@@ -24269,7 +24270,7 @@ function extend() {
24269
24270
}
24270
24271
});
24271
24272
24272
- return traverseCallback(props, path.concat(['properties']), resolve, value);
24273
+ return traverseCallback(props, path.concat(['properties']), resolve, value, seenSchemaCache );
24273
24274
}
24274
24275
24275
24276
const optionalsProbability = optionAPI('alwaysFakeOptionals') === true ? 1.0 : optionAPI('optionalsProbability');
@@ -24325,7 +24326,7 @@ function extend() {
24325
24326
24326
24327
return traverseCallback({
24327
24328
allOf: _defns.concat(value),
24328
- }, path.concat(['properties']), resolve, value);
24329
+ }, path.concat(['properties']), resolve, value, seenSchemaCache );
24329
24330
}
24330
24331
}
24331
24332
@@ -24478,7 +24479,7 @@ function extend() {
24478
24479
}
24479
24480
}
24480
24481
24481
- return traverseCallback(props, path.concat(['properties']), resolve, value);
24482
+ return traverseCallback(props, path.concat(['properties']), resolve, value, seenSchemaCache );
24482
24483
};
24483
24484
24484
24485
/**
@@ -24664,31 +24665,42 @@ function extend() {
24664
24665
};
24665
24666
24666
24667
// TODO provide types
24667
- function traverse(schema, path, resolve, rootSchema) {
24668
+ function traverse(schema, path, resolve, rootSchema, seenSchemaCache ) {
24668
24669
schema = resolve(schema);
24669
24670
if (!schema) {
24670
- return;
24671
+ return;
24671
24672
}
24672
24673
if (optionAPI('useExamplesValue') && 'example' in schema) {
24673
24674
var clonedSchema,
24674
- result;
24675
-
24676
- // avoid minItems and maxItems while checking for valid examples
24677
- if (optionAPI('avoidExampleItemsLength') && _.get(schema, 'type') === 'array') {
24678
- clonedSchema = _.clone(schema);
24679
- _.unset(clonedSchema, 'minItems');
24680
- _.unset(clonedSchema, 'maxItems');
24675
+ result,
24676
+ isExampleValid,
24677
+ hashSchema = hash(schema);
24681
24678
24682
- // avoid validation of values that are in pm variable format (i.e. '{{userId}}')
24683
- result = validateSchema(clonedSchema, schema.example, { ignoreUnresolvedVariables: true } );
24679
+ if(seenSchemaCache && seenSchemaCache.has(hashSchema)) {
24680
+ isExampleValid = seenSchemaCache.get(hashSchema );
24684
24681
}
24685
24682
else {
24686
- // avoid validation of values that are in pm variable format (i.e. '{{userId}}')
24687
- result = validateSchema(schema, schema.example, { ignoreUnresolvedVariables: true });
24683
+ // avoid minItems and maxItems while checking for valid examples
24684
+ if (optionAPI('avoidExampleItemsLength') && _.get(schema, 'type') === 'array') {
24685
+ clonedSchema = _.clone(schema);
24686
+ _.unset(clonedSchema, 'minItems');
24687
+ _.unset(clonedSchema, 'maxItems');
24688
+
24689
+ // avoid validation of values that are in pm variable format (i.e. '{{userId}}')
24690
+ result = validateSchema(clonedSchema, schema.example, { ignoreUnresolvedVariables: true });
24691
+ }
24692
+ else {
24693
+ // avoid validation of values that are in pm variable format (i.e. '{{userId}}')
24694
+ result = validateSchema(schema, schema.example, { ignoreUnresolvedVariables: true });
24695
+ }
24696
+
24697
+ // Store the final result that needs to be used in the seen map
24698
+ isExampleValid = result && result.length === 0;
24699
+ seenSchemaCache && seenSchemaCache.set(hashSchema, isExampleValid);
24688
24700
}
24689
24701
24690
24702
// Use example only if valid
24691
- if (result && result.length === 0 ) {
24703
+ if (isExampleValid ) {
24692
24704
return schema.example;
24693
24705
}
24694
24706
}
@@ -24707,7 +24719,7 @@ function extend() {
24707
24719
}
24708
24720
// thunks can return sub-schemas
24709
24721
if (typeof schema.thunk === 'function') {
24710
- return traverse(schema.thunk(), path, resolve);
24722
+ return traverse(schema.thunk(), path, resolve, null, seenSchemaCache );
24711
24723
}
24712
24724
if (typeof schema.generate === 'function') {
24713
24725
return utils.typecast(schema, function () { return schema.generate(rootSchema); });
@@ -24735,7 +24747,7 @@ function extend() {
24735
24747
}
24736
24748
else {
24737
24749
try {
24738
- var result = typeMap[type](schema, path, resolve, traverse);
24750
+ var result = typeMap[type](schema, path, resolve, traverse, seenSchemaCache );
24739
24751
var required = schema.items
24740
24752
? schema.items.required
24741
24753
: schema.required;
@@ -24755,7 +24767,7 @@ function extend() {
24755
24767
}
24756
24768
for (var prop in schema) {
24757
24769
if (typeof schema[prop] === 'object' && prop !== 'definitions') {
24758
- copy[prop] = traverse(schema[prop], path.concat([prop]), resolve, copy);
24770
+ copy[prop] = traverse(schema[prop], path.concat([prop]), resolve, copy, seenSchemaCache );
24759
24771
}
24760
24772
else {
24761
24773
copy[prop] = schema[prop];
@@ -24825,7 +24837,7 @@ function extend() {
24825
24837
return obj;
24826
24838
}
24827
24839
// TODO provide types
24828
- function run(refs, schema, container) {
24840
+ function run(refs, schema, container, seenSchemaCache ) {
24829
24841
try {
24830
24842
var result = traverse(schema, [], function reduce(sub, maxReduceDepth) {
24831
24843
if (typeof maxReduceDepth === 'undefined') {
@@ -24894,7 +24906,7 @@ function extend() {
24894
24906
}
24895
24907
}
24896
24908
return container.wrap(sub);
24897
- });
24909
+ }, null, seenSchemaCache );
24898
24910
if (optionAPI('resolveJsonPath')) {
24899
24911
return resolve(result);
24900
24912
}
@@ -24936,7 +24948,7 @@ function extend() {
24936
24948
}
24937
24949
}
24938
24950
}
24939
- var jsf = function (schema, refs) {
24951
+ var jsf = function (schema, refs, seenSchemaCache ) {
24940
24952
var ignore = optionAPI('ignoreMissingRefs');
24941
24953
var $ = deref(function (id, refs) {
24942
24954
// FIXME: allow custom callback?
@@ -24945,7 +24957,7 @@ function extend() {
24945
24957
}
24946
24958
});
24947
24959
var $refs = getRefs(refs);
24948
- return run($refs, $(schema, $refs, true), container);
24960
+ return run($refs, $(schema, $refs, true), container, seenSchemaCache );
24949
24961
};
24950
24962
jsf.resolve = function (schema, refs, cwd) {
24951
24963
if (typeof refs === 'string') {
0 commit comments