Skip to content

Commit 14bc40b

Browse files
committed
Merge branch 'release/4.10.0'
2 parents e255040 + ba0edb3 commit 14bc40b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+236928
-147
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.10.0 (March 08, 2023)
4+
* Added support for convertV2() interface which has more stacklimit for schema resolution.
5+
* Added support for validateTransactionV2() interface uses same v2 interface for resolving schema.
6+
* Fixed multiple issues for urlencoded body with anyOf and oneOf schemas where valid data was reported as mismatches.
7+
38
#### v4.9.0 (February 06, 2023)
49
* Fixed issue [#660](https://github.com/postmanlabs/openapi-to-postman/issues/660) where for certain XML request bodies, conversion was failing with TypeError.
510
* Fixed issue where for some definitions having non-string URLs were failing conversion with TypeErrors.

OPTIONS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ collapseFolders|boolean|-|true|Importing will collapse all folders that have onl
66
optimizeConversion|boolean|-|true|Optimizes conversion for large specification, disabling this option might affect the performance of conversion.|CONVERSION
77
requestParametersResolution|enum|Example, Schema|Schema|Select whether to generate the request 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
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
9+
disabledParametersValidation|boolean|-|true|Whether disabled parameters of collection should be validated|VALIDATION
10+
parametersResolution|enum|Example, Schema|Schema|Select whether to generate the request and 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
911
folderStrategy|enum|Paths, Tags|Paths|Select whether to create folders according to the spec’s paths or tags.|CONVERSION
1012
schemaFaker|boolean|-|true|Whether or not schemas should be faked.|CONVERSION
1113
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

assets/json-schema-faker.js

Lines changed: 73 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -23468,7 +23468,12 @@ function extend() {
2346823468
var context = {};
2346923469
while (length--) {
2347023470
var fn = keys[length].replace(/^x-/, '');
23471-
var gen = this.support[fn];
23471+
23472+
/**
23473+
* CHANGE: This Makes sure that we're not using Object's prototype properties,
23474+
* while accessing certain keys like 'constructor'
23475+
*/
23476+
var gen = this.support.hasOwnProperty(fn) && this.support[fn];
2347223477
if (typeof gen === 'function') {
2347323478
if (typeof schema[fn] === 'object' && schema[fn].hasOwnProperty('type')) {
2347423479
continue;
@@ -23814,6 +23819,14 @@ function extend() {
2381423819
}
2381523820
// execute generator
2381623821
var value = callback(params);
23822+
23823+
/**
23824+
* CHANGE: This Makes sure that we're not typecasting null to "null"
23825+
*/
23826+
if (_.get(schema, 'nullable') && value === null) {
23827+
return value;
23828+
}
23829+
2381723830
// normalize output value
2381823831
switch (schema.type) {
2381923832
case 'number':
@@ -23830,7 +23843,11 @@ function extend() {
2383023843
var min = Math.max(params.minLength || 0, 0);
2383123844
var max = Math.min(params.maxLength || Infinity, Infinity);
2383223845
while (value.length < min) {
23833-
value += ' ' + value;
23846+
/**
23847+
* CHANGE: This Makes sure that we're not adding extra spaces in generated value,
23848+
* As such behaviour generates invalid data when pattern is mentioned.
23849+
*/
23850+
value += (schema.pattern ? '' : ' ') + value;
2383423851
}
2383523852
if (value.length > max) {
2383623853
value = value.substr(0, max);
@@ -24236,24 +24253,24 @@ function extend() {
2423624253
// Updated objectType definition to latest version (0.5.0-rcv.41)
2423724254
var objectType = function objectType(value, path, resolve, traverseCallback, seenSchemaCache) {
2423824255
const props = {};
24239-
24256+
2424024257
const properties = value.properties || {};
2424124258
const patternProperties = value.patternProperties || {};
2424224259
const requiredProperties = typeof value.required === 'boolean' ? [] : (value.required || []).slice();
2424324260
const allowsAdditional = value.additionalProperties !== false;
24244-
24261+
2424524262
const propertyKeys = Object.keys(properties);
2424624263
const patternPropertyKeys = Object.keys(patternProperties);
2424724264
const optionalProperties = propertyKeys.concat(patternPropertyKeys).reduce((_response, _key) => {
2424824265
if (requiredProperties.indexOf(_key) === -1) _response.push(_key);
2424924266
return _response;
2425024267
}, []);
2425124268
const allProperties = requiredProperties.concat(optionalProperties);
24252-
24269+
2425324270
const additionalProperties = allowsAdditional // eslint-disable-line
2425424271
? (value.additionalProperties === true ? anyType : value.additionalProperties)
2425524272
: value.additionalProperties;
24256-
24273+
2425724274
if (!allowsAdditional
2425824275
&& propertyKeys.length === 0
2425924276
&& patternPropertyKeys.length === 0
@@ -24262,50 +24279,50 @@ function extend() {
2426224279
// just nothing
2426324280
return null;
2426424281
}
24265-
24282+
2426624283
if (optionAPI('requiredOnly') === true) {
2426724284
requiredProperties.forEach(key => {
2426824285
if (properties[key]) {
2426924286
props[key] = properties[key];
2427024287
}
2427124288
});
24272-
24289+
2427324290
return traverseCallback(props, path.concat(['properties']), resolve, value, seenSchemaCache);
2427424291
}
24275-
24292+
2427624293
const optionalsProbability = optionAPI('alwaysFakeOptionals') === true ? 1.0 : optionAPI('optionalsProbability');
2427724294
const fixedProbabilities = optionAPI('alwaysFakeOptionals') || optionAPI('fixedProbabilities') || false;
2427824295
const ignoreProperties = optionAPI('ignoreProperties') || [];
2427924296
const reuseProps = optionAPI('reuseProperties');
2428024297
const fillProps = optionAPI('fillProperties');
24281-
24298+
2428224299
const max = value.maxProperties || (allProperties.length + (allowsAdditional ? random.number(1, 5) : 0));
24283-
24300+
2428424301
let min = Math.max(value.minProperties || 0, requiredProperties.length);
2428524302
let neededExtras = Math.max(0, allProperties.length - min);
24286-
24303+
2428724304
if (optionalsProbability !== null) {
2428824305
if (fixedProbabilities === true) {
2428924306
neededExtras = Math.round((min - requiredProperties.length) + (optionalsProbability * (allProperties.length - min)));
2429024307
} else {
2429124308
neededExtras = random.number(min - requiredProperties.length, optionalsProbability * (allProperties.length - min));
2429224309
}
2429324310
}
24294-
24311+
2429524312
const extraPropertiesRandomOrder = random.shuffle(optionalProperties).slice(0, neededExtras);
2429624313
const extraProperties = optionalProperties.filter(_item => {
2429724314
return extraPropertiesRandomOrder.indexOf(_item) !== -1;
2429824315
});
24299-
24316+
2430024317
// properties are read from right-to-left
2430124318
const _limit = optionalsProbability !== null || requiredProperties.length === max ? max : random.number(0, max);
2430224319
const _props = requiredProperties.concat(extraProperties).slice(0, max);
2430324320
const _defns = [];
24304-
24321+
2430524322
if (value.dependencies) {
2430624323
Object.keys(value.dependencies).forEach(prop => {
2430724324
const _required = value.dependencies[prop];
24308-
24325+
2430924326
if (_props.indexOf(prop) !== -1) {
2431024327
if (Array.isArray(_required)) {
2431124328
// property-dependencies
@@ -24319,20 +24336,20 @@ function extend() {
2431924336
}
2432024337
}
2432124338
});
24322-
24339+
2432324340
// schema-dependencies
2432424341
if (_defns.length) {
2432524342
delete value.dependencies;
24326-
24343+
2432724344
return traverseCallback({
2432824345
allOf: _defns.concat(value),
2432924346
}, path.concat(['properties']), resolve, value, seenSchemaCache);
2433024347
}
2433124348
}
24332-
24349+
2433324350
const skipped = [];
2433424351
const missing = [];
24335-
24352+
2433624353
_props.forEach(key => {
2433724354
for (let i = 0; i < ignoreProperties.length; i += 1) {
2433824355
if ((ignoreProperties[i] instanceof RegExp && ignoreProperties[i].test(key))
@@ -24342,38 +24359,38 @@ function extend() {
2434224359
return;
2434324360
}
2434424361
}
24345-
24362+
2434624363
if (additionalProperties === false) {
2434724364
if (requiredProperties.indexOf(key) !== -1) {
2434824365
props[key] = properties[key];
2434924366
}
2435024367
}
24351-
24368+
2435224369
if (properties[key]) {
2435324370
props[key] = properties[key];
2435424371
}
24355-
24372+
2435624373
let found;
24357-
24374+
2435824375
// then try patternProperties
2435924376
patternPropertyKeys.forEach(_key => {
2436024377
if (key.match(new RegExp(_key))) {
2436124378
found = true;
24362-
24379+
2436324380
if (props[key]) {
2436424381
utils.merge(props[key], patternProperties[_key]);
2436524382
} else {
2436624383
props[random.randexp(key)] = patternProperties[_key];
2436724384
}
2436824385
}
2436924386
});
24370-
24387+
2437124388
if (!found) {
2437224389
// try patternProperties again,
2437324390
const subschema = patternProperties[key] || additionalProperties;
24374-
24391+
2437524392
// FIXME: allow anyType as fallback when no subschema is given?
24376-
24393+
2437724394
if (subschema && additionalProperties !== false) {
2437824395
// otherwise we can use additionalProperties?
2437924396
props[patternProperties[key] ? random.randexp(key) : key] = properties[key] || subschema;
@@ -24382,103 +24399,103 @@ function extend() {
2438224399
}
2438324400
}
2438424401
});
24385-
24402+
2438624403
// discard already ignored props if they're not required to be filled...
2438724404
let current = Object.keys(props).length + (fillProps ? 0 : skipped.length);
24388-
24405+
2438924406
// generate dynamic suffix for additional props...
2439024407
const hash = suffix => random.randexp(`_?[_a-f\\d]{1,3}${suffix ? '\\$?' : ''}`);
24391-
24408+
2439224409
function get(from) {
2439324410
let one;
24394-
24411+
2439524412
do {
2439624413
if (!from.length) break;
2439724414
one = from.shift();
2439824415
} while (props[one]);
24399-
24416+
2440024417
return one;
2440124418
}
24402-
24419+
2440324420
let minProps = min;
2440424421
if (allowsAdditional && !requiredProperties.length) {
2440524422
minProps = Math.max(optionalsProbability === null || additionalProperties ? random.number(fillProps ? 1 : 0, max) : 0, min);
2440624423
}
24407-
24424+
2440824425
while (fillProps) {
2440924426
if (!(patternPropertyKeys.length || allowsAdditional)) {
2441024427
break;
2441124428
}
24412-
24429+
2441324430
if (current >= minProps) {
2441424431
break;
2441524432
}
24416-
24433+
2441724434
if (allowsAdditional) {
2441824435
if (reuseProps && ((propertyKeys.length - current) > minProps)) {
2441924436
let count = 0;
2442024437
let key;
24421-
24438+
2442224439
do {
2442324440
count += 1;
24424-
24441+
2442524442
// skip large objects
2442624443
if (count > 1000) {
2442724444
break;
2442824445
}
24429-
24446+
2443024447
key = get(requiredProperties) || random.pick(propertyKeys);
2443124448
} while (typeof props[key] !== 'undefined');
24432-
24449+
2443324450
if (typeof props[key] === 'undefined') {
2443424451
props[key] = properties[key];
2443524452
current += 1;
2443624453
}
2443724454
} else if (patternPropertyKeys.length && !additionalProperties) {
2443824455
const prop = random.pick(patternPropertyKeys);
2443924456
const word = random.randexp(prop);
24440-
24457+
2444124458
if (!props[word]) {
2444224459
props[word] = patternProperties[prop];
2444324460
current += 1;
2444424461
}
2444524462
} else {
2444624463
const word = get(requiredProperties) || (wordsGenerator(1) + hash());
24447-
24464+
2444824465
if (!props[word]) {
2444924466
props[word] = additionalProperties || anyType;
2445024467
current += 1;
2445124468
}
2445224469
}
2445324470
}
24454-
24471+
2445524472
for (let i = 0; current < min && i < patternPropertyKeys.length; i += 1) {
2445624473
const _key = patternPropertyKeys[i];
2445724474
const word = random.randexp(_key);
24458-
24459-
24475+
24476+
2446024477
if (!props[word]) {
2446124478
props[word] = patternProperties[_key];
2446224479
current += 1;
2446324480
}
2446424481
}
2446524482
}
24466-
24483+
2446724484
// fill up-to this value and no more!
2446824485
if (requiredProperties.length === 0 && (!allowsAdditional || optionalsProbability === false)) {
2446924486
const maximum = random.number(min, max);
24470-
24487+
2447124488
for (; current < maximum;) {
2447224489
const word = get(propertyKeys);
24473-
24490+
2447424491
if (word) {
2447524492
props[word] = properties[word];
2447624493
}
24477-
24494+
2447824495
current += 1;
2447924496
}
2448024497
}
24481-
24498+
2448224499
return traverseCallback(props, path.concat(['properties']), resolve, value, seenSchemaCache);
2448324500
};
2448424501

@@ -24571,7 +24588,11 @@ function extend() {
2457124588

2457224589
// types from draft-0[67] (?)
2457324590
'uri-reference': `${URI_PATTERN}${PARAM_PATTERN}`,
24574-
'uri-template': URI_PATTERN.replace('(?:', '(?:/\\{[a-z][:a-zA-Z0-9-]*\\}|'),
24591+
/**
24592+
* CHANGE: Corrected uri-template format to be inline with RFC-6570
24593+
* https://www.rfc-editor.org/rfc/rfc6570#section-2
24594+
*/
24595+
'uri-template': URI_PATTERN.replace('(?:', '(?:/\\{[a-z][a-zA-Z0-9]*\\}|'),
2457524596
'json-pointer': `(/(?:${FRAGMENT.replace(']*', '/]*')}|~[01]))+`,
2457624597

2457724598
// some types from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#data-types (?)

index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict';
22

3+
const { MODULE_VERSION } = require('./lib/schemapack.js');
4+
35
const _ = require('lodash'),
46
SchemaPack = require('./lib/schemapack.js').SchemaPack;
57

@@ -14,6 +16,16 @@ module.exports = {
1416
return cb(null, schema.validationResult);
1517
},
1618

19+
convertV2: function(input, options, cb) {
20+
var schema = new SchemaPack(input, options, MODULE_VERSION.V2);
21+
22+
if (schema.validated) {
23+
return schema.convertV2(cb);
24+
}
25+
26+
return cb(null, schema.validationResult);
27+
},
28+
1729
validate: function (input) {
1830
var schema = new SchemaPack(input);
1931
return schema.validationResult;

0 commit comments

Comments
 (0)