Skip to content

Commit 01caef0

Browse files
authored
Merge pull request #670 from postmanlabs/release/4.7.0
Release v4.7.0
2 parents ed0b8f8 + b9eeb64 commit 01caef0

14 files changed

+286
-169
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# OpenAPI-Postman Changelog
22

3+
#### v4.7.0 (January 16, 2023)
4+
* Fixed an issue where same schema was being validated against examples multiple times during a conversion - using local cache here.
5+
* Added a way to return analytics along with the result for better observability into the kind of schemas we get for conversion.
6+
* Refactored the resolveRefs and resolveAll to take in an options object as an argument.
7+
38
#### v4.6.0 (December 30, 2022)
49
* Fixed issue where bundling of multi-file definition was not working correctly for more than 10 params correctly.
510
* Fixed issue where request name was not using operation description if available.

OPTIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ requestParametersResolution|enum|Example, Schema|Schema|Select whether to genera
88
exampleParametersResolution|enum|Example, Schema|Example|Select whether to generate the response parameters based on the [schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schemaObject) or the [example](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#exampleObject) in the schema.|CONVERSION
99
folderStrategy|enum|Paths, Tags|Paths|Select whether to create folders according to the spec’s paths or tags.|CONVERSION
1010
schemaFaker|boolean|-|true|Whether or not schemas should be faked.|CONVERSION
11-
stackLimit|integer|-|8|Number of nesting limit till which schema resolution will happen. Increasing this limit may result in more time to convert collection depending on complexity of specification. (To make sure this option works correctly "optimizeConversion" option needs to be disabled)|CONVERSION
11+
stackLimit|integer|-|10|Number of nesting limit till which schema resolution will happen. Increasing this limit may result in more time to convert collection depending on complexity of specification. (To make sure this option works correctly "optimizeConversion" option needs to be disabled)|CONVERSION
1212
includeAuthInfoInExample|boolean|-|true|Select whether to include authentication parameters in the example request|CONVERSION
1313
shortValidationErrors|boolean|-|false|Whether detailed error messages are required for request <> schema validation operations.|VALIDATION
1414
validationPropertiesToIgnore|array|-|[]|Specific properties (parts of a request/response pair) to ignore during validation. Must be sent as an array of strings. Valid inputs in the array: PATHVARIABLE, QUERYPARAM, HEADER, BODY, RESPONSE_HEADER, RESPONSE_BODY|VALIDATION

assets/json-schema-faker.js

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ var _ = require('lodash'),
1515
{
1616
handleExclusiveMaximum,
1717
handleExclusiveMinimum
18-
} = require('./../lib/common/schemaUtilsCommon');
18+
} = require('./../lib/common/schemaUtilsCommon'),
19+
hash = require('object-hash');
1920

2021
(function (global, factory) {
2122
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -24100,7 +24101,7 @@ function extend() {
2410024101
var nullType = nullGenerator;
2410124102

2410224103
// TODO provide types
24103-
function unique(path, items, value, sample, resolve, traverseCallback) {
24104+
function unique(path, items, value, sample, resolve, traverseCallback, seenSchemaCache) {
2410424105
var tmp = [], seen = [];
2410524106
function walk(obj) {
2410624107
var json = JSON.stringify(obj);
@@ -24113,15 +24114,15 @@ function extend() {
2411324114
// TODO: find a better solution?
2411424115
var limit = 10;
2411524116
while (tmp.length !== items.length) {
24116-
walk(traverseCallback(value.items || sample, path, resolve));
24117+
walk(traverseCallback(value.items || sample, path, resolve, null, seenSchemaCache));
2411724118
if (!limit--) {
2411824119
break;
2411924120
}
2412024121
}
2412124122
return tmp;
2412224123
}
2412324124
// TODO provide types
24124-
var arrayType = function arrayType(value, path, resolve, traverseCallback) {
24125+
var arrayType = function arrayType(value, path, resolve, traverseCallback, seenSchemaCache) {
2412524126
var items = [];
2412624127
if (!(value.items || value.additionalItems)) {
2412724128
if (utils.hasProperties(value, 'minItems', 'maxItems', 'uniqueItems')) {
@@ -24136,7 +24137,7 @@ function extend() {
2413624137
if (tmpItems instanceof Array) {
2413724138
return Array.prototype.concat.call(items, tmpItems.map(function (item, key) {
2413824139
var itemSubpath = path.concat(['items', key + '']);
24139-
return traverseCallback(item, itemSubpath, resolve);
24140+
return traverseCallback(item, itemSubpath, resolve, null, seenSchemaCache);
2414024141
}));
2414124142
}
2414224143
var minItems = value.minItems;
@@ -24165,11 +24166,11 @@ function extend() {
2416524166
sample = typeof value.additionalItems === 'object' ? value.additionalItems : {};
2416624167
for (var current = items.length; current < length; current++) {
2416724168
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);
2416924170
items.push(element);
2417024171
}
2417124172
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);
2417324174
}
2417424175
return items;
2417524176
};
@@ -24233,7 +24234,7 @@ function extend() {
2423324234
var anyType = { type: ['string', 'number', 'integer', 'boolean'] };
2423424235
// TODO provide types
2423524236
// 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) {
2423724238
const props = {};
2423824239

2423924240
const properties = value.properties || {};
@@ -24269,7 +24270,7 @@ function extend() {
2426924270
}
2427024271
});
2427124272

24272-
return traverseCallback(props, path.concat(['properties']), resolve, value);
24273+
return traverseCallback(props, path.concat(['properties']), resolve, value, seenSchemaCache);
2427324274
}
2427424275

2427524276
const optionalsProbability = optionAPI('alwaysFakeOptionals') === true ? 1.0 : optionAPI('optionalsProbability');
@@ -24325,7 +24326,7 @@ function extend() {
2432524326

2432624327
return traverseCallback({
2432724328
allOf: _defns.concat(value),
24328-
}, path.concat(['properties']), resolve, value);
24329+
}, path.concat(['properties']), resolve, value, seenSchemaCache);
2432924330
}
2433024331
}
2433124332

@@ -24478,7 +24479,7 @@ function extend() {
2447824479
}
2447924480
}
2448024481

24481-
return traverseCallback(props, path.concat(['properties']), resolve, value);
24482+
return traverseCallback(props, path.concat(['properties']), resolve, value, seenSchemaCache);
2448224483
};
2448324484

2448424485
/**
@@ -24664,31 +24665,42 @@ function extend() {
2466424665
};
2466524666

2466624667
// TODO provide types
24667-
function traverse(schema, path, resolve, rootSchema) {
24668+
function traverse(schema, path, resolve, rootSchema, seenSchemaCache) {
2466824669
schema = resolve(schema);
2466924670
if (!schema) {
24670-
return;
24671+
return;
2467124672
}
2467224673
if (optionAPI('useExamplesValue') && 'example' in schema) {
2467324674
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);
2468124678

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);
2468424681
}
2468524682
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);
2468824700
}
2468924701

2469024702
// Use example only if valid
24691-
if (result && result.length === 0) {
24703+
if (isExampleValid) {
2469224704
return schema.example;
2469324705
}
2469424706
}
@@ -24707,7 +24719,7 @@ function extend() {
2470724719
}
2470824720
// thunks can return sub-schemas
2470924721
if (typeof schema.thunk === 'function') {
24710-
return traverse(schema.thunk(), path, resolve);
24722+
return traverse(schema.thunk(), path, resolve, null, seenSchemaCache);
2471124723
}
2471224724
if (typeof schema.generate === 'function') {
2471324725
return utils.typecast(schema, function () { return schema.generate(rootSchema); });
@@ -24735,7 +24747,7 @@ function extend() {
2473524747
}
2473624748
else {
2473724749
try {
24738-
var result = typeMap[type](schema, path, resolve, traverse);
24750+
var result = typeMap[type](schema, path, resolve, traverse, seenSchemaCache);
2473924751
var required = schema.items
2474024752
? schema.items.required
2474124753
: schema.required;
@@ -24755,7 +24767,7 @@ function extend() {
2475524767
}
2475624768
for (var prop in schema) {
2475724769
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);
2475924771
}
2476024772
else {
2476124773
copy[prop] = schema[prop];
@@ -24825,7 +24837,7 @@ function extend() {
2482524837
return obj;
2482624838
}
2482724839
// TODO provide types
24828-
function run(refs, schema, container) {
24840+
function run(refs, schema, container, seenSchemaCache) {
2482924841
try {
2483024842
var result = traverse(schema, [], function reduce(sub, maxReduceDepth) {
2483124843
if (typeof maxReduceDepth === 'undefined') {
@@ -24894,7 +24906,7 @@ function extend() {
2489424906
}
2489524907
}
2489624908
return container.wrap(sub);
24897-
});
24909+
}, null, seenSchemaCache);
2489824910
if (optionAPI('resolveJsonPath')) {
2489924911
return resolve(result);
2490024912
}
@@ -24936,7 +24948,7 @@ function extend() {
2493624948
}
2493724949
}
2493824950
}
24939-
var jsf = function (schema, refs) {
24951+
var jsf = function (schema, refs, seenSchemaCache) {
2494024952
var ignore = optionAPI('ignoreMissingRefs');
2494124953
var $ = deref(function (id, refs) {
2494224954
// FIXME: allow custom callback?
@@ -24945,7 +24957,7 @@ function extend() {
2494524957
}
2494624958
});
2494724959
var $refs = getRefs(refs);
24948-
return run($refs, $(schema, $refs, true), container);
24960+
return run($refs, $(schema, $refs, true), container, seenSchemaCache);
2494924961
};
2495024962
jsf.resolve = function (schema, refs, cwd) {
2495124963
if (typeof refs === 'string') {

0 commit comments

Comments
 (0)