Skip to content

Commit b032215

Browse files
author
Vishal Shingala
committed
Merge branch 'release/4.1.0' of github.com:postmanlabs/openapi-to-postman
2 parents e35074c + a91c2f2 commit b032215

Some content is hidden

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

43 files changed

+4173
-127
lines changed

.npmignore

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,16 @@ test/data/.temp
4343

4444
# Prevent unit test coverage reports from being added
4545
.coverage
46-
.nyc_output
46+
.nyc_output
47+
48+
# - Prevent config and test files from being added
49+
.git*
50+
.github/
51+
scripts/
52+
test/
53+
examples/
54+
.eslintrc
55+
.eslintignore
56+
.nycrc
57+
.editorconfig
58+
.jsdoc-config.json

CHANGELOG.md

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

3+
#### v4.1.0 (July 20, 2022)
4+
* Fixed issue where conversion was failing for definitions with info object as null.
5+
* Fixed issue where generated collection did not have correct examples value from XML type of content.
6+
* Fixed issue [#518](https://github.com/postmanlabs/openapi-to-postman/issues/518) where generated collection were having NaN as value for integer query params with enum values.
7+
* Fixed issue [#496](https://github.com/postmanlabs/openapi-to-postman/issues/496) where validateTransactions() was returning missing endpoints even though corresponding requests are present in collection.
8+
* Fixed issue [#478](https://github.com/postmanlabs/openapi-to-postman/issues/478) where updation of path parameter in collection resulted in MISSING_IN_REQUEST error.
9+
* Fixed issue [#559](https://github.com/postmanlabs/openapi-to-postman/issues/559) where parameter description was undefined for formdata type of content even if defined.
10+
* Fixed issue where bundle() API didn't handle circular references correctly.
11+
* Added non-required files to be published as npm module in .npmignore
12+
* Fixed issue where disableBodyPruning option was not set for requests with no request body.
13+
314
#### v4.0.0 (July 12, 2022)
415
* Added support for new multi-file API detectRootFiles() for OpenAPI 3 and Swagger 2 formats to support detection of root files among multiple files.
516
* Added support for new multi-file API detectRelatedFiles() for OpenAPI 3 and Swagger 2 formats to support detection of related files for a provided root file amongst multiple files.

assets/json-schema-faker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23782,7 +23782,7 @@ function extend() {
2378223782
var min = Math.max(params.minimum || 0, 0);
2378323783
var max = Math.min(params.maximum || Infinity, Infinity);
2378423784
min = handleExclusiveMinimum(schema, min);
23785-
max = handleExclusiveMaximum(schema, min);
23785+
max = handleExclusiveMaximum(schema, max);
2378623786
// discard out-of-bounds enumerations
2378723787
schema.enum = schema.enum.filter(function (x) {
2378823788
if (x >= min && x <= max) {

lib/bundle.js

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ let path = require('path'),
2222
{ DFS } = require('./dfs'),
2323
deref = require('./deref.js'),
2424
{ isSwagger, getBundleRulesDataByVersion } = require('./common/versionUtils'),
25-
CIRCULAR_REF_EXT_PROP = 'x-circularRef';
25+
CIRCULAR_OR_REF_EXT_PROP = 'x-orRef';
2626

2727

2828
/**
@@ -481,6 +481,34 @@ function findReferenceByMainKeyInTraceFromContext(documentContext, mainKeyInTrac
481481
return relatedRef;
482482
}
483483

484+
/**
485+
* Verifies if a node has same content as one of the parents so it is a circular ref
486+
* @param {function} traverseContext - The context of the traverse function
487+
* @param {object} contentFromTrace - The resolved content of the node to deref
488+
* @returns {boolean} whether is circular reference or not.
489+
*/
490+
function isCircularReference(traverseContext, contentFromTrace) {
491+
return traverseContext.parents.find((parent) => { return parent.node === contentFromTrace; }) !== undefined;
492+
}
493+
494+
/**
495+
* Modifies content of a node if it is circular reference.
496+
*
497+
* @param {function} traverseContext - The context of the traverse function
498+
* @param {object} documentContext The document context from root
499+
* @returns {undefined} nothing
500+
*/
501+
function handleCircularReference(traverseContext, documentContext) {
502+
let relatedRef = '';
503+
if (traverseContext.circular) {
504+
relatedRef = findReferenceByMainKeyInTraceFromContext(documentContext, traverseContext.circular.key);
505+
traverseContext.update({ $ref: relatedRef });
506+
}
507+
if (traverseContext.keys && traverseContext.keys.includes(CIRCULAR_OR_REF_EXT_PROP)) {
508+
traverseContext.update({ $ref: traverseContext.node[CIRCULAR_OR_REF_EXT_PROP] });
509+
}
510+
}
511+
484512
/**
485513
* Generates the components object from the documentContext data
486514
* @param {object} documentContext The document context from root
@@ -492,8 +520,9 @@ function findReferenceByMainKeyInTraceFromContext(documentContext, mainKeyInTrac
492520
*/
493521
function generateComponentsObject (documentContext, rootContent, refTypeResolver, components, version) {
494522
let notInLine = Object.entries(documentContext.globalReferences).filter(([, value]) => {
495-
return value.keyInComponents.length !== 0;
496-
});
523+
return value.keyInComponents.length !== 0;
524+
}),
525+
circularRefsSet = new Set();
497526
const { COMPONENTS_KEYS } = getBundleRulesDataByVersion(version);
498527
notInLine.forEach(([key, value]) => {
499528
let [, partial] = key.split(localPointer);
@@ -541,6 +570,17 @@ function generateComponentsObject (documentContext, rootContent, refTypeResolver
541570
if (!contentFromTrace) {
542571
refData.nodeContent = { $ref: `${localPointer + local}` };
543572
}
573+
else if (isCircularReference(this, contentFromTrace)) {
574+
if (refData.inline) {
575+
refData.nodeContent = { [CIRCULAR_OR_REF_EXT_PROP]: tempRef };
576+
circularRefsSet.add(tempRef);
577+
}
578+
else {
579+
refData.node = { [CIRCULAR_OR_REF_EXT_PROP]: refData.reference };
580+
refData.nodeContent = contentFromTrace;
581+
circularRefsSet.add(refData.reference);
582+
}
583+
}
544584
else {
545585
refData.nodeContent = contentFromTrace;
546586
}
@@ -551,39 +591,30 @@ function generateComponentsObject (documentContext, rootContent, refTypeResolver
551591
refData.node = hasSiblings ?
552592
_.merge(referenceSiblings, refData.nodeContent) :
553593
refData.nodeContent;
554-
documentContext.globalReferences[property.$ref].reference =
594+
documentContext.globalReferences[tempRef].reference =
555595
resolveJsonPointerInlineNodes(this.parents, this.key);
556596
}
557-
this.update(refData.node);
558-
if (!refData.inline) {
559-
if (documentContext.globalReferences[tempRef].refHasContent) {
560-
setValueInComponents(
561-
refData.keyInComponents,
562-
components,
563-
refData.nodeContent,
564-
COMPONENTS_KEYS
565-
);
566-
}
597+
else if (refData.refHasContent) {
598+
setValueInComponents(
599+
refData.keyInComponents,
600+
components,
601+
refData.nodeContent,
602+
COMPONENTS_KEYS
603+
);
567604
}
605+
this.update(refData.node);
568606
}
569607
}
570608
});
571609
});
572610
return {
573611
resRoot: traverseUtility(rootContent).map(function () {
574-
let relatedRef = '';
575-
if (this.circular) {
576-
relatedRef = findReferenceByMainKeyInTraceFromContext(documentContext, this.circular.key);
577-
this.update({ $ref: relatedRef, [CIRCULAR_REF_EXT_PROP]: true });
578-
}
612+
handleCircularReference(this, documentContext);
579613
}),
580614
newComponents: traverseUtility(components).map(function () {
581-
let relatedRef = '';
582-
if (this.circular) {
583-
relatedRef = findReferenceByMainKeyInTraceFromContext(documentContext, this.circular.key);
584-
this.update({ $ref: relatedRef, [CIRCULAR_REF_EXT_PROP]: true });
585-
}
586-
})
615+
handleCircularReference(this, documentContext);
616+
}),
617+
circularRefs: [...circularRefsSet]
587618
};
588619
}
589620

@@ -618,7 +649,7 @@ function generateComponentsWrapper(parsedOasObject, version, nodesContent = {})
618649
}
619650

620651
/**
621-
* Generates a map of generated refernce to the original reference
652+
* Generates a map of generated reference to the original reference
622653
*
623654
* @param {object} globalReferences - Global references present at each root file context
624655
* @returns {object} reference map
@@ -712,7 +743,8 @@ module.exports = {
712743
fileContent: finalElements.resRoot,
713744
components: finalElements.newComponents,
714745
fileName: specRoot.fileName,
715-
referenceMap: getReferenceMap(rootContextData.globalReferences)
746+
referenceMap: getReferenceMap(rootContextData.globalReferences),
747+
circularRefs: finalElements.circularRefs
716748
};
717749
},
718750
getReferences,

lib/common/schemaUtilsCommon.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ function removeWordFromLastPosition(schemaPath, word) {
6363
* "<integer>"
6464
*
6565
* @param {string} value - Value to check for
66-
* @param {string} type - The type in the schemna
66+
* @param {string} type - The type in the schema
6767
* @returns {Boolean} the value is the representation of its type
6868
*/
6969
function compareType(value, type) {
@@ -75,7 +75,7 @@ function compareType(value, type) {
7575
* "<integer>"
7676
* Works in array types
7777
* @param {string} value - Value to check for
78-
* @param {*} types - The types in the schemna
78+
* @param {*} types - The types in the schema
7979
* @returns {Boolean} the value is the representation of its type
8080
*/
8181
function isTypeValueArrayCheck(value, types) {
@@ -89,7 +89,7 @@ function isTypeValueArrayCheck(value, types) {
8989
* "<integer>"
9090
* Works in array types
9191
* @param {string} value - Value to check for
92-
* @param {*} types - The types in the schemna
92+
* @param {*} types - The types in the schema
9393
* @returns {Boolean} the value is the representation of its type
9494
*/
9595
function checkValueOnlyTypes(value, types) {
@@ -118,7 +118,7 @@ function getDefaultFromTypeAndFormat(type, format) {
118118
* @returns {Boolean} the value is the representation of its type
119119
*/
120120
function checkValueTypesAndFormat(value, types, format) {
121-
let typesNotInMapp = [],
121+
let typesNotInMap = [],
122122
typesArray = Array.isArray(types) ? types : [types],
123123
found = typesArray.find((type) => {
124124
let defaultValue;
@@ -132,7 +132,7 @@ function checkValueTypesAndFormat(value, types, format) {
132132
}
133133
}
134134
else {
135-
typesNotInMapp.push(type);
135+
typesNotInMap.push(type);
136136
}
137137
return defaultValue === value;
138138
});
@@ -141,7 +141,7 @@ function checkValueTypesAndFormat(value, types, format) {
141141
return true;
142142
}
143143

144-
found = typesNotInMapp.find((type) => {
144+
found = typesNotInMap.find((type) => {
145145
let defaultValue;
146146
defaultValue = '<' + type + (format ? ('-' + format) : '') + '>';
147147
return defaultValue === value;
@@ -185,7 +185,7 @@ function isTypeValue(value, schema) {
185185
}
186186

187187
/**
188-
* Checks if value is correcta according to schema
188+
* Checks if value is correct according to schema
189189
* If the value should be numeric, it tries to convert and then validate
190190
* also validates if the value is a correct representation in the form of
191191
* <long> or <integer> etc for integers format 32 or format 64
@@ -332,7 +332,7 @@ module.exports = {
332332
isTypeValue,
333333

334334
/**
335-
* Checks if value is correcta according to schema
335+
* Checks if value is correct according to schema
336336
* If the value should be numeric, it tries to convert and then validate
337337
* also validates if the value is a correct representation in the form of
338338
* <long> or <integer> etc for integers format 32 or format 64
@@ -345,5 +345,16 @@ module.exports = {
345345

346346
isKnownType: function(schema) {
347347
return typeof schemaTypeToJsValidator[schema.type] === 'function';
348+
},
349+
350+
getServersPathVars: function(servers) {
351+
return servers.reduce((acc, current) => {
352+
const newVarNames = current.hasOwnProperty('variables') ?
353+
Object.keys(current.variables).filter((varName) => {
354+
return !acc.includes(varName);
355+
}) :
356+
[];
357+
return [...acc, ...newVarNames];
358+
}, []);
348359
}
349360
};

0 commit comments

Comments
 (0)