UNPKG

@postman/wsdl-to-postman

Version:

Convert a given WSDL specification (1.1) to Postman Collection

252 lines (236 loc) 9.2 kB
/* eslint-disable no-restricted-modules */ /* eslint-disable block-scoped-var */ const { WSDLParserFactory } = require('../WSDLParserFactory'), { getPrincipalPrefix, getWSDLImports, getWSDLIncludes, getAttributeByName, ATTRIBUTE_NAMESPACE, ATTRIBUTE_LOCATION, ATTRIBUTE_SCHEMALOCATION, SCHEMA_TAG, TARGET_NAMESPACE_SPEC } = require('../WsdlParserCommon'), { stringIsValidURLFilePath, getAbsoultePathFromRelativeAndBase, getLastSegmentURL } = require('../../lib/utils/textUtils'), { WSDLMerger } = require('./WSDLMerger'), validExtensions = ['wsdl', 'xsd']; var promises = []; /** * Receives a string and determines if is an absolute path of a wsdl or xsd file * @param {string} filePath string path * @return {boolean} true if is a correct file path to a wsdl or xsd otherwise false */ function validateIsWSDLOrXSDFilePath(filePath) { return stringIsValidURLFilePath(filePath, validExtensions); } /** * Calculates download path and if needed new parentBaseURL * @param {string} schemaLocation schema location or location from the import or include tag * @param {string} parentBaseURL the base URL of the previous processed file * @param {string} optionProcessURL the option set for the user for process url * @returns {object} A valid Result object with format {parentBaseURL: <string>, downloadPath: <string>} */ function calculateDowloadPathAndParentBaseURL(schemaLocation, parentBaseURL, optionProcessURL) { let downloadPath, calculatedParentBaseURL; if (validateIsWSDLOrXSDFilePath(schemaLocation)) { downloadPath = schemaLocation; calculatedParentBaseURL = getFolderNameFromPath(schemaLocation); } else if (parentBaseURL) { downloadPath = getAbsoultePathFromRelativeAndBase(parentBaseURL, schemaLocation); downloadPath = validateIsWSDLOrXSDFilePath(downloadPath) ? downloadPath : ''; calculatedParentBaseURL = parentBaseURL; } else if (optionProcessURL) { downloadPath = getAbsoultePathFromRelativeAndBase(optionProcessURL, schemaLocation); downloadPath = validateIsWSDLOrXSDFilePath(downloadPath) ? downloadPath : ''; calculatedParentBaseURL = optionProcessURL; } return { parentBaseURL: calculatedParentBaseURL, downloadPath }; } /** * Receives a WSDL Resolve remote references in imported tags from a WSDL * @param {string} filesToProcess string representation of the file to process * @param {object} xmlParser the utility to parse xml to js object * @param {Array} downloadedReferences the already downloaded references to avoid re download * @param {string} parentBaseURL url for download files if the first file could be either the option * or empty * @param {string} optionProcessURL the option set for the user for process url * @param {string} origin app's context * @return {promise} promise to resolve file downloadings */ function processAFile(filesToProcess, xmlParser, downloadedReferences, parentBaseURL, optionProcessURL, origin) { let parserFactory, parsedRootFile, wsdlRootTagName, principalPrefix, promise, remoteReferencesToResolve = [], WSDLSpecVersion, ignoreIOErrors = true, parsedRootFileNS, localPromises = [], downloadPath = '', processingFile = filesToProcess; if (origin !== 'browser') { var fetch = require('node-fetch'); } parsedRootFile = xmlParser.safeParseToObject(processingFile); parserFactory = new WSDLParserFactory(); WSDLSpecVersion = parserFactory.getSafeWsdlVersion(processingFile); if (!WSDLSpecVersion) { wsdlRootTagName = SCHEMA_TAG; principalPrefix = getPrincipalPrefix(parsedRootFile, wsdlRootTagName); parsedRootFileNS = getAttributeByName(parsedRootFile, TARGET_NAMESPACE_SPEC); } else { wsdlParser = parserFactory.getParserByVersion(WSDLSpecVersion); wsdlRootTagName = wsdlParser.informationService.RootTagName; parsedRootFileNS = getAttributeByName(parsedRootFile, ATTRIBUTE_NAMESPACE); principalPrefix = getPrincipalPrefix(parsedRootFile, wsdlRootTagName); } imports = getWSDLImports(parsedRootFile, principalPrefix, wsdlRootTagName); includes = getWSDLIncludes(parsedRootFile, principalPrefix, wsdlRootTagName); imports.forEach((importInformation) => { let schemaLocation = getAttributeByName(importInformation, ATTRIBUTE_LOCATION); if (!schemaLocation) { schemaLocation = getAttributeByName(importInformation, ATTRIBUTE_SCHEMALOCATION); } ({ parentBaseURL, downloadPath } = calculateDowloadPathAndParentBaseURL(schemaLocation, parentBaseURL, optionProcessURL)); if (downloadPath) { const alreadyDownloaded = downloadedReferences.find((downloadedReference) => { return downloadedReference.schemaLocation === downloadPath; }); if (!alreadyDownloaded) { remoteReferencesToResolve.push({ namespace: getAttributeByName(importInformation, ATTRIBUTE_NAMESPACE), schemaLocation: downloadPath }); } } }); includes.forEach((importInformation) => { let schemaLocation = getAttributeByName(importInformation, ATTRIBUTE_SCHEMALOCATION); ({ parentBaseURL, downloadPath } = calculateDowloadPathAndParentBaseURL(schemaLocation, parentBaseURL, optionProcessURL)); if (downloadPath) { const alreadyDownloaded = downloadedReferences.find((downloadedReference) => { return downloadedReference.schemaLocation === downloadPath; }); if (!alreadyDownloaded) { remoteReferencesToResolve.push({ namespace: parsedRootFileNS, schemaLocation: downloadPath }); } } }); remoteReferencesToResolve.forEach((remoteReference) => { localPromises.push(fetch(remoteReference.schemaLocation).then(function (res) { const { schemaLocation } = remoteReference; if (res.status !== 200) { if (ignoreIOErrors) { return '{"$ref":}' + remoteReference.schemaLocation; } throw new Error(`Received status code ${res.status}: ${schemaLocation}`); } return res.text(); })); }); promise = Promise.all(localPromises).then((values) => { values.forEach((content, index) => { downloadedReferences.push({ content: content, schemaLocation: remoteReferencesToResolve[index].schemaLocation, namespace: remoteReferencesToResolve[index].namespace, fileName: getLastSegmentURL(remoteReferencesToResolve[index].schemaLocation) }); if (!content.includes('{"$ref":}')) { return processAFile(content, xmlParser, downloadedReferences, parentBaseURL, optionProcessURL, origin); } }); }); promises.push(promise); return promise; } /** * Receives a WSDL Resolve remote references in imported tags from a WSDL * @param {string} wsdl the wsdl in string xml representation * @param {object} xmlParser the parser class to parse xml to object or vice versa * @param {object} options contains options to the process * @param {Array} downloadedReferences already downloaded files * @param {string} origin app's context * @return {promise} a promise to execute after all processing */ function processRemoteReferences(wsdl, xmlParser, options = {}, downloadedReferences, origin) { const { resolveRemoteRefs, sourceUrl } = options; let filesToProcess = [], promise; if (!resolveRemoteRefs) { return wsdl; } filesToProcess.push(wsdl); promise = processAFile(wsdl, xmlParser, downloadedReferences, '', sourceUrl, origin); return promise; } /** * Receives a WSDL Resolve remote references in imported tags from a WSDL * @param {object} input the process input * @param {object} xmlParser the parser class to parse xml to object or vice versa * @param {object} options contains options to the process * @param {function} cb callback * @return {string} a merged file and its parsed rep */ function resolveRemoteRefs(input, xmlParser, options = {}, cb) { let downloadedReferences = [], { data, origin } = input, downloadedInfo = []; if (options.resolveRemoteRefs) { try { return processRemoteReferences(data, xmlParser, options, downloadedReferences, input.origin) .then(function () { Promise.all(promises).then(() => { let merger = new WSDLMerger(), mergedFile = data; downloadedInfo = downloadedReferences.map((downloaded) => { return { content: downloaded.content, fileName: downloaded.fileName }; }); try { downloadedInfo.push({ content: data, fileName: '' }); mergedFile = merger.processMergeFiles(downloadedInfo, xmlParser, origin); newParsed = xmlParser.parseToObject(mergedFile); return cb({ mergedFile, newParsed }); } catch (err) { return cb({ err }); } }); }) .catch(function (err) { return cb({ err }); }); } catch (err) { return cb({ err }); } } return cb({ mergedFile: data }); } module.exports = { resolveRemoteRefs, calculateDowloadPathAndParentBaseURL };