Skip to content

Commit

Permalink
Merge pull request #247 from postmanlabs/release/v1.14.0
Browse files Browse the repository at this point in the history
Release version v1.14.0
  • Loading branch information
aman-v-singh authored Dec 9, 2024
2 parents 845f91c + cc8740c commit de3517e
Show file tree
Hide file tree
Showing 13 changed files with 289 additions and 19 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## [Unreleased]

## [v1.14.0] - 2024-12-09

### Added

- [#10466](https://github.com/postmanlabs/postman-app-support/issues/10466) Added support for soap headers in request body

## [v1.13.1] - 2024-07-22

### Fixed
Expand Down Expand Up @@ -124,7 +130,9 @@ Newer releases follow the [Keep a Changelog](https://keepachangelog.com) format.
- Stable release
- Removed libxmljs from package.json

[Unreleased]: https://github.com/postmanlabs/wsdl-to-postman/compare/v1.13.1...HEAD
[Unreleased]: https://github.com/postmanlabs/wsdl-to-postman/compare/v1.14.0...HEAD

[v1.14.0]: https://github.com/postmanlabs/wsdl-to-postman/compare/v1.13.1...v1.14.0

[v1.13.1]: https://github.com/postmanlabs/wsdl-to-postman/compare/v1.13.0...v1.13.1

Expand Down
1 change: 1 addition & 0 deletions lib/WSDLObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Operation {
this.style = '';
this.url = '';
this.input = '';
this.header = '';
this.output = '';
this.fault = '';
this.portName = '';
Expand Down
51 changes: 51 additions & 0 deletions lib/WsdlInformationService11.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const
ATTRIBUTE_PART = 'part',
XML_POLICY = 'http://schemas.xmlsoap.org/ws/2004/09/policy',
INPUT_TAG = 'input',
HEADER_TAG = 'header',
OUTPUT_TAG = 'output',
FAULT_TAG = 'fault',
MIME_CONTENT_TAG = 'mime:content',
Expand Down Expand Up @@ -90,6 +91,7 @@ class WsdlInformationService11 {
constructor() {
this.version = '1.1';
this.InputTagName = INPUT_TAG;
this.HeaderTagName = HEADER_TAG;
this.NameTag = NAME_TAG;
this.OutputTagName = OUTPUT_TAG;
this.FaultTagName = FAULT_TAG;
Expand Down Expand Up @@ -261,6 +263,55 @@ class WsdlInformationService11 {
return [];
}

/**
* finds the element from the port type operation object
* @param {object} parsedXml the content file in javascript object representation
* @param {object} bindingOperation binding operation to find the element
* @param {object} elementsFromWSDL all the elements of the document
* @param {string} principalPrefix the principal prefix of the document
* @param {string} protocolPrefix the binding information for the binding
* @param {string} inputTag the tag for search of input
* @param {string} headerTag the tag for search of header
* @param {object} tnsNamespace tns namespace object
* @returns {object} the WSDLObject
*/
getElementFromBindingOperation(parsedXml, bindingOperation, elementsFromWSDL, principalPrefix, protocolPrefix,
inputTag, headerTag, tnsNamespace) {
let inputInformation = getNodeByName(bindingOperation, principalPrefix, inputTag),
headerInformation = getNodeByName(inputInformation, protocolPrefix, headerTag),
messageName, elementName,
elementsArray = [];
if (headerInformation) {
if (!Array.isArray(headerInformation)) {
headerInformation = [headerInformation];
}
headerInformation.forEach((header) => {
let foundElement;
messageName = getAttributeByName(header, ATTRIBUTE_MESSAGE);
elementName = this.getMessageElementNameByMessageName(parsedXml, principalPrefix, messageName, tnsNamespace);
if (elementName === EMPTY_ELEMENT_BY_DEFAULT) {
elementsArray.push(createEmptyElement(elementName));
return;
}
elementName = excludeSeparatorFromName(elementName);

if (Array.isArray(elementsFromWSDL)) {
foundElement = elementsFromWSDL.find((element) => {
return element.name === elementName;
});
}

if (foundElement === undefined) {
elementsArray.push(createErrorElement({}, elementName));
}
else {
elementsArray.push(foundElement);
}
});
return elementsArray;
}
return [];
}

/**
* finds the element from the port type operation object
Expand Down
52 changes: 52 additions & 0 deletions lib/WsdlInformationService20.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const
DOCUMENTATION_TAG = 'documentation',
NAME_TAG = 'name',
INPUT_TAG = 'input',
HEADER_TAG = 'header',
OUTPUT_TAG = 'output',
OUTFAULT_TAG = 'outfault',
ADDRESS_TAG = 'address',
Expand Down Expand Up @@ -68,6 +69,7 @@ class WsdlInformationService20 {
constructor() {
this.version = '2.0';
this.InputTagName = INPUT_TAG;
this.HeaderTagName = HEADER_TAG;
this.NameTag = NAME_TAG;
this.OutputTagName = OUTPUT_TAG;
this.FaultTagName = OUTFAULT_TAG;
Expand Down Expand Up @@ -504,6 +506,56 @@ class WsdlInformationService20 {
return this.getElementFromInterfaceOperationInOut(interfaceOperation, elementsFromWSDL, principalPrefix, tag);
}

/**
* finds the element from the port type operation object
* @param {object} parsedXml the content file in javascript object representation
* @param {object} bindingOperation binding operation to find the element
* @param {object} elementsFromWSDL all the elements of the document
* @param {string} principalPrefix the principal prefix of the document
* @param {string} protocolPrefix the binding information for the binding
* @param {string} inputTag the tag for search of input
* @param {string} headerTag the tag for search of header
* @param {object} tnsNamespace tns namespace object
* @returns {object} the WSDLObject
*/
getElementFromBindingOperation(parsedXml, bindingOperation, elementsFromWSDL, principalPrefix, protocolPrefix,
inputTag, headerTag, tnsNamespace) {
let inputInformation = getNodeByName(bindingOperation, principalPrefix, inputTag),
headerInformation = getNodeByName(inputInformation, protocolPrefix, headerTag),
messageName, elementName,
elementsArray = [];
if (headerInformation) {
if (!Array.isArray(headerInformation)) {
headerInformation = [headerInformation];
}
headerInformation.forEach((header) => {
let foundElement;
messageName = getAttributeByName(header, ATTRIBUTE_MESSAGE);
elementName = this.getMessageElementNameByMessageName(parsedXml, principalPrefix, messageName, tnsNamespace);
if (elementName === EMPTY_ELEMENT_BY_DEFAULT) {
elementsArray.push(createEmptyElement(elementName));
return;
}
elementName = excludeSeparatorFromName(elementName);

if (Array.isArray(elementsFromWSDL)) {
foundElement = elementsFromWSDL.find((element) => {
return element.name === elementName;
});
}

if (foundElement === undefined) {
elementsArray.push(createErrorElement({}, elementName));
}
else {
elementsArray.push(foundElement);
}
});
return elementsArray;
}
return [];
}

/**
* finds the element from the interface operation object when is called
* for input or output
Expand Down
10 changes: 10 additions & 0 deletions lib/WsdlParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,16 @@ class WsdlParser {
newWsdlObject.tnsNamespace,
portTypeInterfaceName
);
wsdlOperation.header = this.informationService.getElementFromBindingOperation(
parsedXml,
bindingOperation,
elements,
principalPrefix,
bindingTagInfo.protocolPrefix,
this.informationService.InputTagName,
this.informationService.HeaderTagName,
newWsdlObject.tnsNamespace,
);
wsdlOperation.output = this.informationService.getElementFromPortTypeInterfaceOperation(
parsedXml,
portTypeInterfaceOperation,
Expand Down
30 changes: 18 additions & 12 deletions lib/WsdlToPostmanCollectionBodyMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {*} elementToCreateBody the root node for the message parameters
* @param {array} securityPolicyArray An array with all security policies
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {array} soapBodyHeaders the headers for the soap body
* @returns {array} An array with all items generated in postman item definition format
*/
getBody(operation, elementToCreateBody, securityPolicyArray, xmlParser) {
getBody(operation, elementToCreateBody, securityPolicyArray, xmlParser, soapBodyHeaders) {
if (operation.protocol === SOAP_PROTOCOL ||
operation.protocol === SOAP12_PROTOCOL) {
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, operation.protocol);
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser,
operation.protocol, soapBodyHeaders);
}
if (operation.protocol === HTTP_PROTOCOL) {
return this.createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, true, xmlParser);
return this.createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, true,
xmlParser, soapBodyHeaders);
}
}

Expand All @@ -61,8 +64,7 @@ class WsdlToPostmanCollectionBodyMapper {
getResponseBody(operation, elementToCreateBody, securityPolicyArray, xmlParser) {
if (operation.protocol === SOAP_PROTOCOL ||
operation.protocol === SOAP12_PROTOCOL) {
return this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, operation.protocol,
xmlParser);
return this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, operation.protocol, xmlParser);
}
if (operation.protocol === HTTP_PROTOCOL) {
return this.createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, false, xmlParser);
Expand All @@ -77,13 +79,14 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {array} securityPolicyArray An array with all security policies
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {string} protocol the operation protocol
* @param {array} headers headers for soap body
* @returns {array} An array with all items generated in postman item definition format
*/
createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, protocol) {
createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, protocol, headers) {
return {
mode: 'raw',
raw: this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, protocol,
xmlParser),
xmlParser, headers),
options: {
raw: {
language: XML
Expand All @@ -100,9 +103,10 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {array} securityPolicyArray An array with all security policies
* @param {boolean} isInput if the body message corresponds to an input
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {array} soapBodyHeaders the headers for the soap body
* @returns {array} An array with all items generated in postman item definition format
*/
createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, isInput, xmlParser) {
createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, isInput, xmlParser, soapBodyHeaders) {
if (isInput) {
if (operation.method === GET_METHOD) {
return undefined;
Expand All @@ -114,14 +118,15 @@ class WsdlToPostmanCollectionBodyMapper {
urlencoded: helper.convertInputToURLEncoded(elementToCreateBody)
};
}
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, SOAP_PROTOCOL);
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser,
SOAP_PROTOCOL, soapBodyHeaders);
}
else if (!isInput) {
if (operation.mimeContentOutput && operation.mimeContentOutput.mimeType === MIME_TYPE_XML) {
return this.xMLMessageHelper.convertInputToMessage(elementToCreateBody, xmlParser);
}
return this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, SOAP_PROTOCOL,
xmlParser);
xmlParser, soapBodyHeaders);
}
}

Expand All @@ -134,12 +139,13 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {array} securityPolicyArray An array with all security policies
* @param {string} protocol the protocol to implement the message default 'soap'
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {array} headers the headers for soap body
* @returns {string} the message xml with the structure determined in the
* elements and the default values examples
*/
getSOAPBodyMessage(nodeElement, securityPolicyArray, protocol, xmlParser) {
getSOAPBodyMessage(nodeElement, securityPolicyArray, protocol, xmlParser, headers) {
return this.sOAPMessageHelper.convertInputToMessage(nodeElement, securityPolicyArray, protocol,
xmlParser);
xmlParser, headers);
}

}
Expand Down
2 changes: 1 addition & 1 deletion lib/WsdlToPostmanCollectionMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ class WsdlToPostmanCollectionMapper {
createItemsFromOperations(operations, urlVariablesData, securityPolicyArray, xmlParser) {
let items = operations.map((operation) => {
let requestBody = this.wsdlToPostmanCollectionBodyMapper
.getBody(operation, operation.input[0], securityPolicyArray, xmlParser),
.getBody(operation, operation.input[0], securityPolicyArray, xmlParser, operation.header),
postmanItem = {
name: operation.name,
request: {
Expand Down
20 changes: 18 additions & 2 deletions lib/utils/SOAPMessageHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ class SOAPMessageHelper {
* @param {Element} headerInfo node taken from parsedXml
* @param {string} protocol Protocol being used
* @param {Object} xmlParser the xml parser for the process
* @param {array} headers the headers for the soap body
* @returns {string} the rootParametersElement in xml string
*/
convertInputToMessage(rootParametersElement, headerInfo, protocol, xmlParser) {
convertInputToMessage(rootParametersElement, headerInfo, protocol, xmlParser, headers) {
let envelopeAndProtocol = protocol + envelopeName,
jObj = {},
headerElement = {},
bodyAndProtocol = protocol + bodyName,
resultMessage = '',
cacheKey = this.getHashedKey(rootParametersElement, headerInfo, protocol, this.getCompundKey,
Expand All @@ -99,7 +101,21 @@ class SOAPMessageHelper {
}
const soapParametersUtils = new SOAPBody(xmlParser),
soapHeaderUtils = new SOAPHeader(xmlParser);
jObj[envelopeAndProtocol][headerAndProtocol] = soapHeaderUtils.create(headerInfo, protocol);

if (headers && Array.isArray(headers) && headers.length > 0) {
headers.forEach((header) => {
headerElement = { ...headerElement, ...soapParametersUtils.create(header, protocol) };
});
headerElement = { ...headerElement,
...soapHeaderUtils.create(headerInfo, protocol) };

if (Object.keys(headerElement).length > 0) {
jObj[envelopeAndProtocol][headerAndProtocol] = headerElement;
}
}
else {
jObj[envelopeAndProtocol][headerAndProtocol] = soapHeaderUtils.create(headerInfo, protocol);
}
jObj[envelopeAndProtocol][bodyAndProtocol] = soapParametersUtils.create(rootParametersElement,
protocol);

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@postman/wsdl-to-postman",
"version": "1.13.1",
"version": "1.14.0",
"description": "Convert a given WSDL specification (1.1) to Postman Collection",
"main": "index.js",
"bin": {
Expand Down
5 changes: 5 additions & 0 deletions test/data/validWSDLs11/elementFormDefaultQualified.wsdl
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@
<xsd:element name="Xpath" type="xsd:string" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Workday_Common_HeaderType">
<xsd:sequence>
<xsd:element name="Include_Reference_Descriptors_In_Response" type="xsd:boolean" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:attribute name="version" type="xsd:string" wd:fixed="v39.0" />
</xsd:schema>
</wsdl:types>
Expand Down
Loading

0 comments on commit de3517e

Please sign in to comment.