UNPKG

ang-soap

Version:

SOAP client

166 lines (150 loc) 6.1 kB
const _ = require('lodash'); const https = require('https'); const axios = require('axios'); const xmlParser = require('fast-xml-parser'); const jsonPathFinding = require('jsonpath'); const JsonParser = require('fast-xml-parser').j2xParser; const defaultOptions = require('./config').defaultOptions; const {errorMessages, debugMessages,encoding} = require('./config/constants'); /** * This function uses axios http client to perform request. * @param options * @returns {Promise<AxiosResponse<any>>} */ const performHttpRequest = async (options) => { let response; try { response = await axios(options.axios); } catch (error) { throw error; } return response; }; /** * This is the main function. It is used to create a new instance of ang-soap * @param options * @constructor */ function SoapClient(options) { this.options = _.merge(defaultOptions, options); } /** * This method calculates and sets Authorisation Http header * @param username * @param password */ SoapClient.prototype.setBasicAuthSecurity = function (username, password) { const token = Buffer.from(`${username}:${password}`, encoding.utf8).toString(encoding.base64); this.options.axios.headers.Authorization = `${encoding.basic} ${token}`; }; /** * This method disable SSL when performing an axios request */ SoapClient.prototype.disableSSL = function () { this.options.axios.httpsAgent = new https.Agent({rejectUnauthorized: false}); }; /** * This method enable SSL when performing an axios request * By default SSL is enabled */ SoapClient.prototype.enableSSL = function () { this.options.fastXmlParser.httpsAgent = new https.Agent({rejectUnauthorized: true}); }; /** * By default,arrayMode is false. A tag with single occurrence is parsed as an object but as an array in case of multiple occurences. * If you need to parse a specific tag as array only, you can use this method. Example of value: `/^yourTagName$/` * @param value */ SoapClient.prototype.setArrayMode = function (value) { this.options.fastXmlParser.xmlParser.arrayMode = value; }; /** * When you call multiple SOAP methods, each response probably has its own data structure. * So if you use the jsonPath option, you may need to set it before performing each request. * Example of JsonPath: `$..Envelope.Body.YourTargetObject` * @param value */ SoapClient.prototype.setJsonPath = function (value) { this.options.jsonPath = value; }; /** * This methods gets the request parameters and : * 1 - Parse the request body from JSON to XML * 2 - Perform the http call using axios * 3 - Parse the response from XML to JSON * 4 - Logs all the previous steps when debug is enabled. * @param soapUrl * @param jsonData * @returns {Promise<*|T>} */ SoapClient.prototype.performRequest = async function (soapUrl, jsonData) { const debug = this.options.debug; const isRequestDataXML = this.options.isRequestDataXML; const isResponseXML = this.options.isResponseXML; let httpResponse, convertedJson; this.options.axios.url = soapUrl; // If isRequestDataXML option is true we do not parse JSON to XML if (isRequestDataXML) { this.options.axios.data = jsonData; } else { try { // Use use fast-xml-parser to parse JSON to XML const jsonParser = new JsonParser(this.options.fastXmlParser.jsonParser); const xml = jsonParser.parse(jsonData); debug && console.log(debugMessages.xmlRequestBody, xml); this.options.axios.data = xml; } catch (error) { const parsingError = {message: errorMessages.convertingJsontoXml, error}; debug && console.log(debugMessages.parsingError, parsingError); throw parsingError; } } // Once the request body is parsed, perform the http request try { httpResponse = await performHttpRequest(this.options); debug && console.log(debugMessages.httpResponse, httpResponse); } catch (error) { const axiosError = {message: errorMessages.performingHttpRequest, error}; debug && console.log(debugMessages.axiosError, axiosError); throw axiosError; } // if isResponseXML option is true, we do not parse the response to JSON if (isResponseXML) { return httpResponse.data; } else { try { // Use use fast-xml-parser to parse XML to JSON convertedJson = xmlParser.parse(httpResponse.data, this.options.fastXmlParser.xmlParser); debug && console.log(debugMessages.convertedJson, convertedJson); if (!convertedJson) { const error = Error(errorMessages.emptyResult); const parsingError = {message: '', error}; debug && console.log(debugMessages.parsingError, parsingError); throw parsingError; } } catch (error) { const parsingError = {message: errorMessages.convertingXmlToJson, error}; debug && console.log(debugMessages.parsingError, parsingError); throw parsingError; } const jsonPath = this.options.jsonPath; if (jsonPath) { try { const targetJson = jsonPathFinding.value(convertedJson, jsonPath); debug && console.log(debugMessages.targetJson, targetJson); if (!targetJson) { const error = Error(errorMessages.emptyResult); const jsonPathError = {message: errorMessages.targetObjectNotFound, error}; debug && console.log(debugMessages.jsonPathError, jsonPathError); throw jsonPathError; } return targetJson; } catch (error) { const jsonPathError = {message:errorMessages.findingTheTargetObject , error}; debug && console.log(debugMessages.jsonPathError, jsonPathError); throw jsonPathError; } } else return convertedJson; } }; module.exports = SoapClient;