Socket
Socket
Sign inDemoInstall

openapi-to-postmanv2

Package Overview
Dependencies
87
Maintainers
9
Versions
168
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.16.0-beta.1 to 4.16.0

16

CHANGELOG.md

@@ -5,2 +5,8 @@ # OpenAPI-Postman Changelog

## [v4.16.0] - 2023-08-18
### Added
- Added support for remote $ref resolution in bundle() API.
## [v4.15.0] - 2023-06-27

@@ -45,3 +51,3 @@

- Fixed issue where for certain path segments, collection generation failed.
- Fixed TypeError occurring while checking typeof bodyContent in getXmlVersionContent.
- Fixed TypeError occurring while checking typeof bodyContent in getXmlVersionContent.

@@ -300,3 +306,3 @@ ## [v4.12.0] - 2023-05-04

- Add supported formats for schema resolution (deref).
- Fix for [#7643](https://github.com/postmanlabs/postman-app-support/issues/7643), [#7914](https://github.com/postmanlabs/postman-app-support/issues/7914), [#9004](https://github.com/postmanlabs/postman-app-support/issues/9004) - Added support for Auth params in response/example.
- Fix for [#7643](https://github.com/postmanlabs/postman-app-support/issues/7643), [#7914](https://github.com/postmanlabs/postman-app-support/issues/7914), [#9004](https://github.com/postmanlabs/postman-app-support/issues/9004) - Added support for Auth params in response/example.
- Bumped up multiple dependecies and dev-dependencies versions to keep them up-to-date.

@@ -388,3 +394,3 @@ - Updated code coverage tool from deprecated istanbul to nyc.

- Added support for detailed validation body mismatches with option detailedBlobValidation.
- Fix for [#8098](https://github.com/postmanlabs/postman-app-support/issues/8098) - Unable to validate schema with type array.
- Fix for [#8098](https://github.com/postmanlabs/postman-app-support/issues/8098) - Unable to validate schema with type array.
- Fixed URIError for invalid URI in transaction.

@@ -595,4 +601,6 @@ - Fix for [#152](https://github.com/postmanlabs/openapi-to-postman/issues/152) - Path references not resolved due to improver handling of special characters.

[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.15.0...HEAD
[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.16.0...HEAD
[v4.16.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.15.0...v4.16.0
[v4.15.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.14.0...v4.15.0

@@ -599,0 +607,0 @@

const _ = require('lodash'),
{
isExtRef,
isExtURLRef,
stringIsAValidUrl,
isExtRemoteRef,
getKeyInComponents,

@@ -8,2 +11,3 @@ getJsonPointerRelationToRoot,

localPointer,
httpSeparator,
jsonPointerLevelSeparator,

@@ -87,11 +91,18 @@ isLocalRef,

function findNodeFromPath(referencePath, allData) {
const partialComponents = referencePath.split(localPointer);
let isPartial = partialComponents.length > 1,
node = allData.find((node) => {
if (isPartial) {
referencePath = partialComponents[0];
}
return comparePaths(node.fileName, referencePath);
});
const isReferenceRemoteURL = stringIsAValidUrl(referencePath),
partialComponents = referencePath.split(localPointer),
isPartial = partialComponents.length > 1;
let node = allData.find((node) => {
if (isPartial && !isReferenceRemoteURL) {
referencePath = partialComponents[0];
}
if (isReferenceRemoteURL) {
return _.startsWith(node.path, referencePath);
}
return comparePaths(node.fileName, referencePath);
});
return node;

@@ -295,10 +306,83 @@ }

* @param {object} globalReferences - The accumulated global references from all nodes
* @param {function} remoteRefResolver - The function that would be called to fetch remote ref contents
* @returns {object} - The references in current node and the new content from the node
*/
function getReferences (currentNode, isOutOfRoot, pathSolver, parentFilename, version, rootMainKeys,
commonPathFromData, allData, globalReferences) {
async function getReferences (currentNode, isOutOfRoot, pathSolver, parentFilename, version, rootMainKeys,
commonPathFromData, allData, globalReferences, remoteRefResolver) {
let referencesInNode = [],
nodeReferenceDirectory = {},
mainKeys = {};
mainKeys = {},
remoteRefContentMap = new Map(),
remoteRefSet = new Set(),
remoteRefResolutionPromises = [];
remoteRefResolver && traverseUtility(currentNode).forEach(function (property) {
if (property) {
let hasReferenceTypeKey;
hasReferenceTypeKey = Object.keys(property)
.find(
(key) => {
const isExternal = isExtURLRef(property, key),
isReferenciable = isExternal;
return isReferenciable;
}
);
if (hasReferenceTypeKey) {
const tempRef = calculatePath(parentFilename, property.$ref),
isRefEncountered = remoteRefSet.has(tempRef);
if (isRefEncountered) {
return;
}
remoteRefResolutionPromises.push(
new Promise(async (resolveInner) => {
/**
* Converts contents received from remoteRefResolver into stringified JSON
* @param {string | object} content - contents from remoteRefResolver
* @returns {string} Stringified JSON contents
*/
function convertToJSONString (content) {
if (typeof content === 'object') {
return JSON.stringify(content);
}
const parsedFile = parseFile(content);
return JSON.stringify(parsedFile.oasObject);
}
try {
let contentFromRemote = await remoteRefResolver(property.$ref),
nodeTemp = {
fileName: tempRef,
path: tempRef,
content: convertToJSONString(contentFromRemote),
href: property.$ref
};
remoteRefContentMap.set(tempRef, contentFromRemote);
allData.push(nodeTemp);
}
catch (err) {
// swallow the err
}
finally {
resolveInner();
}
})
);
remoteRefSet.add(tempRef);
}
}
});
await Promise.all(remoteRefResolutionPromises);
traverseUtility(currentNode).forEach(function (property) {

@@ -377,2 +461,90 @@ if (property) {

}
const hasRemoteReferenceTypeKey = Object.keys(property)
.find(
(key) => {
const isExternal = isExtURLRef(property, key),
// Only process URL refs if remoteRefResolver is provided and a valid function
isReferenciable = isExternal && _.isFunction(remoteRefResolver);
return isReferenciable;
}
),
handleRemoteURLReference = () => {
const tempRef = calculatePath(parentFilename, property.$ref);
if (remoteRefContentMap.get(tempRef) === undefined) {
return;
}
let nodeTrace = handleLocalCollisions(
getTraceFromParentKeyInComponents(this, tempRef, mainKeys, version, commonPathFromData),
rootMainKeys
),
componentKey = nodeTrace[nodeTrace.length - 1],
referenceInDocument = getJsonPointerRelationToRoot(
tempRef,
nodeTrace,
version
),
traceToParent = [...this.parents.map((item) => {
return item.key;
}).filter((item) => {
return item !== undefined;
}), this.key],
newValue = Object.assign({}, this.node),
[, local] = tempRef.split(localPointer),
nodeFromData,
refHasContent = false,
parseResult,
newRefInDoc,
inline,
contentFromRemote = remoteRefContentMap.get(tempRef),
nodeTemp = {
fileName: tempRef,
path: tempRef,
content: contentFromRemote
};
nodeFromData = nodeTemp;
if (nodeFromData && nodeFromData.content) {
parseResult = parseFile(JSON.stringify(nodeFromData.content));
if (parseResult.result) {
newValue.$ref = referenceInDocument;
refHasContent = true;
nodeFromData.parsed = parseResult;
}
}
this.update({ $ref: tempRef });
if (nodeTrace.length === 0) {
inline = true;
}
if (_.isNil(globalReferences[tempRef])) {
nodeReferenceDirectory[tempRef] = {
local,
keyInComponents: nodeTrace,
node: newValue,
reference: inline ? newRefInDoc : referenceInDocument,
traceToParent,
parentNodeKey: parentFilename,
mainKeyInTrace: nodeTrace[nodeTrace.length - 1],
refHasContent,
inline
};
}
mainKeys[componentKey] = tempRef;
if (!added(property.$ref, referencesInNode)) {
referencesInNode.push({ path: pathSolver(property), keyInComponents: nodeTrace, newValue: this.node });
}
};
if (hasRemoteReferenceTypeKey) {
handleRemoteURLReference();
}
}

@@ -393,6 +565,7 @@ });

* @param {object} globalReferences - The accumulated global refernces from all nodes
* @param {function} remoteRefResolver - The function that would be called to fetch remote ref contents
* @returns {object} - Detect root files result object
*/
function getNodeContentAndReferences (currentNode, allData, specRoot, version, rootMainKeys,
commonPathFromData, globalReferences) {
async function getNodeContentAndReferences (currentNode, allData, specRoot, version, rootMainKeys,
commonPathFromData, globalReferences, remoteRefResolver) {
let graphAdj = [],

@@ -414,3 +587,3 @@ missingNodes = [],

const { referencesInNode, nodeReferenceDirectory } = getReferences(
const { referencesInNode, nodeReferenceDirectory } = await getReferences(
nodeContent,

@@ -424,3 +597,4 @@ currentNode.fileName !== specRoot.fileName,

allData,
globalReferences
globalReferences,
remoteRefResolver
);

@@ -526,5 +700,7 @@

* @param {string} version - The current version
* @param {function} remoteRefResolver - The function that would be called to fetch remote ref contents
* @returns {object} The components object related to the file
*/
function generateComponentsObject (documentContext, rootContent, refTypeResolver, components, version) {
function generateComponentsObject(documentContext, rootContent,
refTypeResolver, components, version, remoteRefResolver) {
let notInLine = Object.entries(documentContext.globalReferences).filter(([, value]) => {

@@ -566,2 +742,3 @@ return value.keyInComponents.length !== 0;

});
if (isMissingNode) {

@@ -574,2 +751,25 @@ refData.nodeContent = refData.node;

}
else if (!isExtRef(property, '$ref') && isExtURLRef(property, '$ref')) {
let splitPathByHttp = property.$ref.split(httpSeparator),
prefix = splitPathByHttp
.slice(0, splitPathByHttp.length - 1).join(httpSeparator) +
httpSeparator + splitPathByHttp[splitPathByHttp.length - 1]
.split(localPointer)[0],
separatedPaths = [prefix, splitPathByHttp[splitPathByHttp.length - 1].split(localPointer)[1]];
nodeRef = separatedPaths[0];
local = separatedPaths[1];
refData.nodeContent = documentContext.nodeContents[nodeRef];
const isReferenceRemoteURL = stringIsAValidUrl(nodeRef);
if (isReferenceRemoteURL && _.isFunction(remoteRefResolver)) {
Object.keys(documentContext.nodeContents).forEach((key) => {
if (_.startsWith(key, nodeRef) && !key.split(nodeRef)[1].includes(httpSeparator)) {
refData.nodeContent = documentContext.nodeContents[key];
}
});
}
}
else {

@@ -710,5 +910,6 @@ refData.nodeContent = documentContext.nodeContents[nodeRef];

* @param {string} version - The version we are using
* @param {function} remoteRefResolver - The function that would be called to fetch remote ref contents
* @returns {object} - Detect root files result object
*/
getBundleContentAndComponents: function (specRoot, allData, origin, version) {
getBundleContentAndComponents: async function (specRoot, allData, origin, version, remoteRefResolver) {
if (origin === BROWSER) {

@@ -730,3 +931,3 @@ path = pathBrowserify;

}));
rootContextData = algorithm.traverseAndBundle(specRoot, (currentNode, globalReferences) => {
rootContextData = await algorithm.traverseAndBundle(specRoot, (currentNode, globalReferences) => {
return getNodeContentAndReferences(

@@ -739,3 +940,4 @@ currentNode,

commonPathFromData,
globalReferences
globalReferences,
remoteRefResolver
);

@@ -751,6 +953,8 @@ });

rootContextData.nodeContents[specRoot.fileName],
isExtRef,
isExtRemoteRef,
components,
version
version,
remoteRefResolver
);
return {

@@ -757,0 +961,0 @@ fileContent: finalElements.resRoot,

@@ -32,3 +32,3 @@ class DFS {

traverseAndBundle(node, getAdjacentAndBundle) {
async traverseAndBundle(node, getAdjacentAndBundle) {
let traverseOrder = [],

@@ -39,9 +39,20 @@ stack = [],

nodeContents = {},
globalReferences = {};
globalReferences = {},
hrefsVisited = new Set();
stack.push(node);
while (stack.length > 0) {
node = stack.pop();
if (!visited.has(node)) {
if (!visited.has(node) &&
/**
* For nodes that are fetched for remote URLs we ensure they
* aren't visited more than once
*/
(!node.href || (!hrefsVisited.has(node.href)))
) {
traverseOrder.push(node);
visited.add(node);
node.href && hrefsVisited.add(node.href);
let {

@@ -53,3 +64,3 @@ graphAdj,

nodeName
} = getAdjacentAndBundle(node, globalReferences);
} = await getAdjacentAndBundle(node, globalReferences);
nodeContents[nodeName] = nodeContent;

@@ -56,0 +67,0 @@ Object.entries(nodeReferenceDirectory).forEach(([key, data]) => {

@@ -6,2 +6,3 @@ const slashes = /\//g,

localPointer = '#',
httpSeparator = 'http',
escapedTilde = /~0/g,

@@ -174,2 +175,31 @@ jsonPointerLevelSeparator = '/',

/**
* Determines if a value of a given key property of an object
* is an external reference with key $ref and value that does not start with #
* @param {object} obj - parent object of the $ref property
* @param {string} key - property key to check
* @returns {boolean} - true if the property key is $ref and the value does not start with #
* otherwise false
*/
function isExtURLRef(obj, key) {
return key === '$ref' &&
typeof obj[key] === 'string' &&
obj[key] !== undefined &&
!obj[key].startsWith(localPointer) &&
stringIsAValidUrl(obj[key]);
}
/**
* Determines if a value of a given key property of an object
* is an external reference with key $ref and value that does not start with #
* @param {object} obj - parent object of the $ref property
* @param {string} key - property key to check
* @returns {boolean} - true if the property key is $ref and the value does not start with #
* otherwise false
*/
function isExtRemoteRef(obj, key) {
return isExtRef(obj, key) || isExtURLRef(obj, key);
}
/**
* Removes the local pointer inside a path

@@ -238,2 +268,4 @@ * aab.yaml#component returns aab.yaml

isExtRef,
isExtURLRef,
isExtRemoteRef,
removeLocalReferenceFromPath,

@@ -244,4 +276,6 @@ isLocalRef,

localPointer,
httpSeparator,
jsonPointerLevelSeparator,
generateObjectName
generateObjectName,
stringIsAValidUrl
};

@@ -711,60 +711,2 @@ 'use strict';

/**
* Used to resolve any kind of OAS3 JSON schema
*
* @param {Object} schema Schema to be resolved
* @returns {Object} Resolved schema for a given OAS
*/
resolveSchema(schema) {
this.concreteUtils = concreteUtils;
this.specComponents = concreteUtils.getRequiredData(this.openapi);
let resolvedSchema;
try {
resolvedSchema = v2.resolveSchema(this, schema);
}
catch (e) {
return {
result: false,
message: e.message,
error: e
};
}
return {
result: true,
value: resolvedSchema
};
}
/**
* Generate faked data from a resolved schema
*
* @param {*} schema Resolved schema to be faked
* @returns {*} fakedValue
*/
fakeSchema(schema) {
this.concreteUtils = concreteUtils;
this.specComponents = concreteUtils.getRequiredData(this.openapi);
let fakedSchema;
try {
fakedSchema = v2.fakeSchema(this, schema);
}
catch (e) {
return {
result: false,
message: e.message,
error: e
};
}
return {
result: true,
value: fakedSchema
};
}
static getOptions(mode, criteria) {

@@ -771,0 +713,0 @@ return getOptions(mode, criteria);

@@ -18,3 +18,3 @@ /* eslint-disable one-var */

const { resolvePostmanRequest, resolveSchema, fakeSchema } = require('./schemaUtils');
const { resolvePostmanRequest } = require('./schemaUtils');
const { generateRequestItemObject, fixPathVariablesInUrl } = require('./utils');

@@ -299,15 +299,3 @@

});
},
resolveSchema(context, schema) {
context.schemaCache = context.schemaCache || {};
return resolveSchema(context, schema);
},
fakeSchema(context, resolvedSchema) {
context.schemaCache = context.schemaCache || {};
return fakeSchema(context, resolvedSchema);
}
};

@@ -1907,4 +1907,3 @@ const generateAuthForCollectionFromOpenAPI = require('./helpers/collection/generateAuthForCollectionFromOpenAPI');

resolveRefFromSchema,
resolveSchema,
fakeSchema
resolveSchema
};
{
"name": "openapi-to-postmanv2",
"version": "4.16.0-beta.1",
"version": "4.16.0",
"description": "Convert a given OpenAPI specification to Postman Collection v2.0",

@@ -119,3 +119,3 @@ "homepage": "https://github.com/postmanlabs/openapi-to-postman",

"dependencies": {
"ajv": "8.5.0",
"ajv": "8.11.0",
"ajv-draft-04": "1.0.0",

@@ -140,3 +140,2 @@ "ajv-formats": "2.1.1",

"devDependencies": {
"@stoplight/json-ref-resolver": "3.1.6",
"chai": "4.3.6",

@@ -143,0 +142,0 @@ "editorconfig": "0.15.3",

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc