{"id":13468556,"url":"https://github.com/loopbackio/strong-soap","last_synced_at":"2025-05-14T05:10:50.612Z","repository":{"id":36978880,"uuid":"65925798","full_name":"loopbackio/strong-soap","owner":"loopbackio","description":"SOAP driver for Node.js (A complete rewrite of node-soap)","archived":false,"fork":false,"pushed_at":"2025-05-14T02:56:53.000Z","size":6871,"stargazers_count":400,"open_issues_count":42,"forks_count":163,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-05-14T04:05:43.215Z","etag":null,"topics":["hacktoberfest","loopback","loopback4","nodejs","soap"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loopbackio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-08-17T16:55:00.000Z","updated_at":"2025-05-14T02:56:26.000Z","dependencies_parsed_at":"2023-02-19T04:31:05.667Z","dependency_job_id":"21acd0b5-9383-4f50-9edb-be5b653babe2","html_url":"https://github.com/loopbackio/strong-soap","commit_stats":{"total_commits":1293,"total_committers":219,"mean_commits":5.904109589041096,"dds":0.6720804331013148,"last_synced_commit":"0f6cea9d4b61d308b7fc74afd8760d80102a7a13"},"previous_names":["strongloop/strong-soap"],"tags_count":85,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Fstrong-soap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Fstrong-soap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Fstrong-soap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Fstrong-soap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loopbackio","download_url":"https://codeload.github.com/loopbackio/strong-soap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254076850,"owners_count":22010611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","loopback","loopback4","nodejs","soap"],"created_at":"2024-07-31T15:01:13.488Z","updated_at":"2025-05-14T05:10:50.569Z","avatar_url":"https://github.com/loopbackio.png","language":"JavaScript","readme":"# strong-soap\n\n[![CI](https://github.com/loopbackio/strong-soap/actions/workflows/continuous-integration.yaml/badge.svg)](https://github.com/loopbackio/strong-soap/actions/workflows/continuous-integration.yaml)\n[![Coverage Status](https://coveralls.io/repos/github/loopbackio/strong-soap/badge.svg?branch=master)](https://coveralls.io/github/loopbackio/strong-soap?branch=master)\n\nThis module provides a Node.js SOAP client for invoking web services and a mock-up SOAP server capability to create and test your web service. This module is based on `node-soap` module.\n\n\u003c!-- Run `npm run toc` to update below section --\u003e\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n- [Overview](#overview)\n- [Install](#install)\n- [Client](#client)\n  - [Extra headers (optional)](#extra-headers-optional)\n  - [Client.describe()](#clientdescribe)\n  - [Client.setSecurity(security)](#clientsetsecuritysecurity)\n  - [Client.*method*(args, callback)](#clientmethodargs-callback)\n  - [Client.*service*.*port*.*method*(args, callback[, options[, extraHeaders]])](#clientserviceportmethodargs-callback-options-extraheaders)\n  - [Client.*lastRequest*](#clientlastrequest)\n  - [Client.setEndpoint(url)](#clientsetendpointurl)\n  - [Client Events](#client-events)\n  - [Security](#security)\n  - [BasicAuthSecurity](#basicauthsecurity)\n  - [BearerSecurity](#bearersecurity)\n  - [ClientSSLSecurity](#clientsslsecurity)\n  - [WSSecurity](#wssecurity)\n  - [WSSecurityCert](#wssecuritycert)\n- [XML Attributes](#xml-attributes)\n  - [Handling XML Attributes, Value and XML (wsdlOptions)](#handling-xml-attributes-value-and-xml-wsdloptions)\n  - [Overriding the value key](#overriding-the-value-key)\n  - [Overriding the xml key](#overriding-the-xml-key)\n  - [Overriding the `attributes` key](#overriding-the-attributes-key)\n- [XMLHandler](#xmlhandler)\n- [WSDL](#wsdl)\n  - [wsdl.open(wsdlURL, options, callback(err, wsdl))](#wsdlopenwsdlurl-options-callbackerr-wsdl)\n- [Server](#server)\n  - [soap.listen(*server*, *path*, *services*, *wsdl*)](#soaplistenserver-path-services-wsdl)\n  - [Options](#options)\n  - [Server logging](#server-logging)\n  - [Server events](#server-events)\n  - [SOAP Fault](#soap-fault)\n  - [Server security example using PasswordDigest](#server-security-example-using-passworddigest)\n  - [Server connection authorization](#server-connection-authorization)\n- [SOAP headers](#soap-headers)\n  - [Received SOAP headers](#received-soap-headers)\n  - [Outgoing SOAP headers](#outgoing-soap-headers)\n- [soap-stub](#soap-stub)\n  - [Example](#example)\n- [Contributors](#contributors)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Overview\n\nFeatures:\n\n* Full SOAP Client capability and mock-up SOAP server capability\n* Handles both RPC and Document styles\n* Handles both SOAP 1.1 and SOAP 1.2 Fault\n* APIs to parse XML into JSON and JSON into XML\n* API to describe WSDL document\n* Support for both synchronous and asynchronous method handlers\n* WS-Security (currently only UsernameToken and PasswordText encoding is supported)\n\n## Install\n\nInstall with [npm](https://github.com/npm/cli):\n\n```sh\nnpm install strong-soap\n```\n\n## Client\n\nStart with the WSDL for the web service you want to invoke. For example, the stock quote service http://www.webservicex.net/stockquote.asmx and the WSDL is http://www.webservicex.net/stockquote.asmx?WSDL\n\nCreate a new SOAP client from WSDL URL using `soap.createClient(url[, options], callback)`. Also supports a local file system path. An instance of `Client` is passed to the `soap.createClient` callback.  It is used to execute methods on the soap service.\n\n```js\n\"use strict\";\n\nvar soap = require('strong-soap').soap;\n// wsdl of the web service this client is going to invoke. For local wsdl you can use, url = './wsdls/stockquote.wsdl'\nvar url = 'http://www.webservicex.net/stockquote.asmx?WSDL';\n\nvar requestArgs = {\n  symbol: 'IBM'\n};\n\nvar options = {};\nsoap.createClient(url, options, function(err, client) {\n  var method = client['StockQuote']['StockQuoteSoap']['GetQuote'];\n  method(requestArgs, function(err, result, envelope, soapHeader) {\n    //response envelope\n    console.log('Response Envelope: \\n' + envelope);\n    //'result' is the response body\n    console.log('Result: \\n' + JSON.stringify(result));\n  });\n});\n\n```\n\nAs well as creating a client via a `url`, an existing [WSDL](#wsdl) object can be passed in via `options.WSDL_CACHE`.\n\n```js\nvar soap = require('strong-soap').soap;\nvar WSDL = soap.WSDL;\n\nvar url = 'http://www.webservicex.net/stockquote.asmx?WSDL';\n\n// Pass in WSDL options if any\n\nvar options = {};\nWSDL.open(url,options,\n  function(err, wsdl) {\n    // You should be able to get to any information of this WSDL from this object. Traverse\n    // the WSDL tree to get  bindings, operations, services, portTypes, messages,\n    // parts, and XSD elements/Attributes.\n\n    // Set the wsdl object in the cache. The key (e.g. 'stockquotewsdl')\n    // can be anything, but needs to match the parameter passed into soap.createClient()\n    var clientOptions = {\n      WSDL_CACHE : {\n        stockquotewsdl: wsdl\n      }\n    };\n    soap.createClient('stockquotewsdl', clientOptions, function(err, client) {\n      var method = client['StockQuote']['StockQuoteSoap']['GetQuote'];\n      method(requestArgs, function(err, result, envelope, soapHeader) {\n\n      //response envelope\n      console.log('Response Envelope: \\n' + envelope);\n      //'result' is the response body\n      console.log('Result: \\n' + JSON.stringify(result));\n    });\n  });\n});\n```\n\n\nThe Request envelope created by above service invocation:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?\u003e\n\u003csoap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"\u003e\n  \u003csoap:Header/\u003e\n  \u003csoap:Body\u003e\n    \u003cns1:GetQuote xmlns:ns1=\"http://www.webserviceX.NET/\"\u003e\n      \u003cns1:symbol\u003eIBM\u003c/ns1:symbol\u003e\n    \u003c/ns1:GetQuote\u003e\n  \u003c/soap:Body\u003e\n\u003c/soap:Envelope\u003e\n```\n\nThis WSDL operation is defined as document/literal-wrapped style. Hence the request in soap \u003cBody\u003e is wrapped in operation name. Refer to test cases [server-client-document-test](https://github.com/loopbackio/strong-soap/blob/master/test/server-client-document-test.js) and  [server-client-rpc-test](https://github.com/loopbackio/strong-soap/blob/master/test/server-client-rpc-test.js) to understand document and rpc styles and their\nRequest, Response and Fault samples.\n\nThe `options` argument allows you to customize the client with the following properties:\n\n- `endpoint`: to override the SOAP service's host specified in the `.wsdl` file.\n- `request`: to override the [request](https://github.com/request/request) module.\n- `httpClient`: to provide your own http client that implements `request(rurl, data, callback, exheaders, exoptions)`.\n- `envelopeKey`: to set specific key instead of \u003cpre\u003e\u003c\u003cb\u003esoap\u003c/b\u003e:Body\u003e\u003c/\u003cb\u003esoap\u003c/b\u003e:Body\u003e\u003c/pre\u003e\n- `wsdl_options`: custom options for the request module on WSDL requests.\n- `wsdl_headers`: custom HTTP headers to be sent on WSDL requests.\n\nNote: for versions of node \u003e0.10.X, you may need to specify `{connection: 'keep-alive'}` in SOAP headers to avoid truncation of longer chunked responses.\n\n### Extra headers (optional)\n\nUser can define extra HTTP headers to be sent on the request.\n\n```js\nvar clientOptions = {};\nsoap.createClient(url, clientOptions, function(err, client) {\n  var customRequestHeader = {customheader1: 'test1'};\n  // Custom request header\n  client.GetQuote(requestArgs, function(err, result, envelope) {\n    // Result in SOAP envelope body which is the wrapper element.\n    // In this case, result object corresponds to GetCityForecastByZIPResponse.\n    console.log(JSON.stringify(result));\n  }, null, customRequestHeader);\n});\n```\n\n### Client.describe()\n\nDescribes services, ports and methods as a JavaScript object.\n\n```js\n// Describes the entire WSDL in a JSON tree object form.\nvar description = client.describe();\n// Inspect GetQuote operation. You can inspect Service: {Port: {operation: {\nconsole.log(JSON.stringify(description.StockQuote.StockQuoteSoap.GetQuote));\n```\n\n### Client.setSecurity(security)\n\nUse the specified security protocol.\n\nRefer to test case [ssl-test](https://github.com/loopbackio/strong-soap/blob/master/test/ssl-test.js) for an example of using this API.\n\n### Client.*method*(args, callback)\n\nCall *method* on the SOAP service.\n\n```js\n  client.MyFunction({name: 'value'}, function(err, result, envelope, soapHeader) {\n      // Result is a javascript object\n      // Envelope is the response envelope from the Web Service\n      // soapHeader is the response soap header as a JavaScript object\n  })\n```\n\nA *method* can also be called as a promise.\n\n```js\n  client.MyFunction({name: 'value'}).then(function({result, envelope, soapHeader}){\n    // ...\n  }, function(err) {\n    // ...\n  });\n\n  // in async/await flavor\n  try {\n    const {result, envelope, soapHeader} = await client.MyFunction({name: 'value'});\n  } catch(err) {\n    // handle error\n  }\n```\n\n### Client.*service*.*port*.*method*(args, callback[, options[, extraHeaders]])\n\nCall a *method* using a specific *service* and *port*.\n\n```js\n  client.MyService.MyPort.MyFunction({name: 'value'}, function(err, result) {\n      // Result is a JavaScript object\n  })\n```\n\n#### Options (optional)\n\n Accepts any option that the request module accepts, see [request](https://github.com/request/request) module.\n\n For example, you could set a timeout of 5 seconds on the request like this:\n\n```js\n  client.MyService.MyPort.MyFunction({name: 'value'}, function(err, result) {\n      // result is a javascript object\n  }, {timeout: 5000})\n```\n\nYou can measure the elapsed time on the request by passing the time option:\n\n```js\n  client.MyService.MyPort.MyFunction({name: 'value'}, function(err, result) {\n      // client.lastElapsedTime - the elapsed time of the last request in milliseconds\n  }, {time: true})\n```\n\n#### Alternative method call using callback-last pattern\n\nTo align method call signature with Node's standard callback-last pattern and eventually allow promisification of method calls, the following method signatures are also supported:\n\n```js\nclient.MyService.MyPort.MyFunction({name: 'value'}, options, function (err, result) {\n  // result is a javascript object\n})\n\nclient.MyService.MyPort.MyFunction({name: 'value'}, options, extraHeaders, function (err, result) {\n  // result is a javascript object\n})\n```\n\n### Client.*lastRequest*\n\nThe property that contains last full soap request for client logging.\n\n### Client.setEndpoint(url)\n\nOverwrites the SOAP service endpoint address.\n\n### Client events\nClient instances emit the following events:\n\n* request - Emitted before a request is sent. The event handler receives the\nentire Soap request (Envelope) including headers.\n* message - Emitted before a request is sent. The event handler receives the\nSoap body contents. Useful if you don't want to log /store Soap headers.\n* soapError - Emitted when an erroneous response is received.\n  Useful if you want to globally log errors.\n* response - Emitted after a response is received. The event handler receives\nthe SOAP response body as well as the entire `IncomingMessage` response object.\nThis is emitted for all responses (both success and errors).\n\nFor an example of using this API, see  [ssl-test](https://github.com/loopbackio/strong-soap/blob/master/test/client-test.js).\n\nHere is an example of 'soapError' event\n\n```js\nsoap.createClient(__dirname + '/wsdl/default_namespace.wsdl', function (err, client) {\n  var didEmitEvent = false;\n  client.on('soapError', function(err) {\n    didEmitEvent = true;\n    assert.ok(err.root.Envelope.Body.Fault);\n  });\n  client.MyOperation({}, function(err, result) {\n    assert.ok(didEmitEvent);\n    done();\n  });\n}, baseUrl);\n```\n\n### Security\n\n`strong-soap` has several default security protocols.  You can easily add your own\nas well.  The interface is quite simple. Each protocol defines two methods:\n\n* `addOptions` - Method that accepts an options arg that is eventually passed directly to `request`\n* `toXML` - Method that returns a string of XML.\n\n### BasicAuthSecurity\n\n```js\n  client.setSecurity(new soap.BasicAuthSecurity('username', 'password'));\n```\n\n### BearerSecurity\n\n```js\n  client.setSecurity(new soap.BearerSecurity('token'));\n```\n\n### ClientSSLSecurity\n\n_Note_: If you run into issues using this protocol, consider passing these options\nas default request options to the constructor:\n* `rejectUnauthorized: false`\n* `strictSSL: false`\n* `secureOptions: constants.SSL_OP_NO_TLSv1_2` (this is likely needed for node \u003e= 10.0)\n\n```js\n  client.setSecurity(new soap.ClientSSLSecurity(\n    '/path/to/key'\n    , '/path/to/cert'\n    , {/*default request options*/}\n  ));\n```\n\n### WSSecurity\n\n`WSSecurity` implements WS-Security. UsernameToken and PasswordText/PasswordDigest is supported.\n\n```js\n  var wsSecurity = new WSSecurity(username, password, options)\n    //the 'options' object is optional and contains properties:\n    //passwordType: 'PasswordDigest' or 'PasswordText' default is PasswordText\n    //hasTimeStamp: true or false, default is true\n    //hasTokenCreated: true or false, default is true\n  client.setSecurity(wsSecurity);\n```\n\n### WSSecurityCert\n\nWS-Security X509 Certificate support.\n\n```js\n  var privateKey = fs.readFileSync(privateKeyPath);\n  var publicKey = fs.readFileSync(publicKeyPath);\n  var password = ''; // optional password\n  var wsSecurity = new soap.WSSecurityCert(privateKey, publicKey, password, 'utf8');\n  client.setSecurity(wsSecurity);\n```\n\n_Note_: Optional dependency 'ursa' is required to be installed successfully when WSSecurityCert is used.\n\n### ClientSSLSecurityPFX\n\n```js\n  const pfxSecurity = new soap.ClientSSLSecurityPFX(pathToPfxOrFileBuffer, passphrase)\n  client.setSecurity(pfxSecurity)\n```\n\n## XML attributes\n\n### Handling XML attributes, value, and XML (wsdlOptions)\n\nTo override the default behavior of `strong-soap`, use the `wsdlOptions` object, passed in the\n`createClient()` method.  The `wsdlOptions` has the following properties:\n\n```js\nvar wsdlOptions = {\n  attributesKey: 'theAttrs',\n  valueKey: 'theVal',\n  xmlKey: 'theXml'\n}\n```\n\nIf you call `createClient()` with no options (or an empty Object `{}`),  `strong-soap` defaults\nto the following:\n\n- `attributesKey` : `'$attributes'`\n- `valueKey` : `'$value'`\n- `xmlKey` : `'$xml'`\n\n### Overriding the value key\n\nBy default, `strong-soap` uses `$value` as key for any parsed XML value which may interfere with your other code as it\ncould be some reserved word, or the `$` in general cannot be used for a key to start with.\n\nYou can define your own `valueKey` by passing it in the `wsdl_options` to the createClient call like so:\n```js\nvar wsdlOptions = {\n  valueKey: 'theVal'\n};\n\nsoap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {\n  // your code\n});\n```\n\n### Overriding the xml key\nAs `valueKey`, `strong-soap` uses `$xml` as key. The xml key is used to pass XML Object without adding namespace or parsing the string.\n\nExample :\n\n```js\ndom = {\n     $xml: '\u003cparentnode type=\"type\"\u003e\u003cchildnode\u003e\u003c/childnode\u003e\u003c/parentnode\u003e'\n};\n```\n\n```xml\n\u003ctns:dom\u003e\n    \u003cparentnode type=\"type\"\u003e\n          \u003cchildnode\u003e\u003c/childnode\u003e\n    \u003c/parentnode\u003e\n\u003c/tns:dom\u003e\n```\n\nYou can define your own `xmlKey` by passing it in the `wsdl_options` to the createClient call like this:\n\n```js\nvar wsdlOptions = {\n  xmlKey: 'theXml'\n};\n\nsoap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {\n  // your code\n});\n```\n\n### Overriding the attributes key\n\nYou can achieve attributes like:\n\n```xml\n\u003cparentnode\u003e\n  \u003cchildnode name=\"childsname\"\u003e\n  \u003c/childnode\u003e\n\u003c/parentnode\u003e\n```\nBy attaching an attributes object to a node.\n\n```js\n{\n  parentnode: {\n    childnode: {\n      $attributes: {\n        name: 'childsname'\n      }\n    }\n  }\n}\n\n```\nHowever, \"attributes\" may be a reserved key for some systems that actually want a node:\n\n```xml\n\u003cattributes\u003e\n\u003c/attributes\u003e\n```\n\nIn this case you can configure the attributes key in the `wsdlOptions` like this:\n\n```js\nvar wsdlOptions = {\n  attributesKey: '$attributes'\n};\n```\n\nAdding xsiType\n\n```js\nsoap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {\n  client.*method*({\n    parentnode: {\n      childnode: {\n        $attributes: {\n          $xsiType: \"{xmlnsTy}Ty\"\n        }\n      }\n    }\n  });\n});\n```\n\nRemoving the xsiType. The resulting Request shouldn't have the attribute xsiType\n\n```js\nsoap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {\n  client.*method*({\n    parentnode: {\n      childnode: {\n        $attributes: {\n\n        }\n      }\n    }\n  });\n});\n```\n\nTo see it in practice, consider the sample in: [test/request-response-samples/addPets__force_namespaces](https://github.com/loopbackio/strong-soap/tree/master/test/request-response-samples/addPets__force_namespaces)\n\n## XMLHandler\n\nXMLHandler enables you to to convert a JSON object to XML and XML to a JSON object.  It can also parse an XML string or stream into the XMLBuilder tree.\n\nAPI to convert JSON object to XML and XML to JSON object:\n\n```js\nvar soap = require('..').soap;\nvar XMLHandler = soap.XMLHandler;\nvar xmlHandler = new XMLHandler();\nvar util = require('util');\nvar url = 'http://www.webservicex.net/stockquote.asmx?WSDL';\n\nvar requestArgs = {\n  symbol: 'IBM'\n};\n\nvar options = {};\nvar clientOptions = {};\nsoap.createClient(url, clientOptions, function(err, client) {\n  var customRequestHeader = {customheader1: 'test1'};\n  client.GetQuote(requestArgs, function(err, result, envelope, soapHeader) {\n    // Convert 'result' JSON object to XML\n    var node = xmlHandler.jsonToXml(null, null,\n      XMLHandler.createSOAPEnvelopeDescriptor('soap'), result);\n    var xml = node.end({pretty: true});\n    console.log(xml);\n\n    // Convert XML to JSON object\n    var root = xmlHandler.xmlToJson(null, xml, null);\n    console.log('%s', util.inspect(root, {depth: null}));\n\n  }, options, customRequestHeader);\n});\n```\n\nParse XML string or stream into the XMLBuilder tree:\n\n```js\nvar root = XMLHandler.parseXml(null, xmlString);\n```\n\n## WSDL\n\n### wsdl.open(wsdlURL, options, callback(err, wsdl))\n\nLoads WSDL into a tree form. Traverse through WSDL tree to get to bindings, services, ports, operations, and so on.\n\nParameters:\n\n- `wsdlURL` WSDL url to load.\n- `options` WSDL options\n- `callback` Error and WSDL loaded into object tree.\n\n```js\nvar soap = require('..').soap;\nvar WSDL = soap.WSDL;\nvar path = require('path');\n\n// Pass in WSDL options if any\n\nvar options = {};\nWSDL.open('./wsdls/stockquote.wsdl',options,\n  function(err, wsdl) {\n    // You should be able to get to any information of this WSDL from this object. Traverse\n    // the WSDL tree to get  bindings, operations, services, portTypes, messages,\n    // parts, and XSD elements/Attributes.\n\n    var getQuoteOp = wsdl.definitions.bindings.StockQuoteSoap.operations.GetQuote;\n    // print operation name\n    console.log(getQuoteOp.$name);\n    var service = wsdl.definitions.services['StockQuote'];\n    //print service name\n    console.log(service.$name);\n});\n```\n\n### wsdl.openSync(wsdlURL, options)\n\nLoads WSDL into a tree form directly from memory. It traverses through WSDL tree to get to bindings, services, ports, operations, and so on as long as you have your dependent WSDLs and schemas are loaded and available in the `options.WSDL_CACHE`. If any I/O is required to retrieve any dependencies this call will throw an error.\n\nParameters:\n\n- `wsdlURL` WSDL url to load as named in the cache.\n- `options` WSDL options\n\nAn example of loading WSDLs into your `options.WSDL_CACHE` and calling `wsdl.loadSync()` can be found in the test [test/wsdl-load-from-memory-test](https://github.com/loopbackio/strong-soap/tree/master/test/wsdl-load-from-memory-test.js)\n\n\n## Server\n\n### soap.listen(*server*, *path*, *services*, *wsdl*)\n\nCreates a new SOAP server that listens on *path* and provides *services*.\n\n*wsdl* is an xml string that defines the service.\n\n```js\n  var myService = {\n      MyService: {\n          MyPort: {\n              MyFunction: function(args) {\n                  return {\n                      name: args.name\n                  };\n              },\n\n              // This is how to define an asynchronous function.\n              MyAsyncFunction: function(args, callback) {\n                  // do some work\n                  callback({\n                      name: args.name\n                  });\n              },\n\n              // This is how to receive incoming headers\n              HeadersAwareFunction: function(args, cb, headers) {\n                  return {\n                      name: headers.Token\n                  };\n              },\n\n              // You can also inspect the original `req`\n              reallyDetailedFunction: function(args, cb, headers, req) {\n                  console.log('SOAP `reallyDetailedFunction` request from ' + req.connection.remoteAddress);\n                  return {\n                      name: headers.Token\n                  };\n              }\n          }\n      }\n  };\n\n  var xml = require('fs').readFileSync('myservice.wsdl', 'utf8'),\n      server = http.createServer(function(request,response) {\n          response.end(\"404: Not Found: \" + request.url);\n      });\n\n  server.listen(8000);\n  soap.listen(server, '/wsdl', myService, xml);\n```\n\nAn example of using the SOAP server is in [test/server-client-document-test](https://github.com/loopbackio/strong-soap/tree/master/test/server-client-document-test.js)\n\n### Options\n\nYou can pass in server and [WSDL Options](#handling-xml-attributes-value-and-xml-wsdloptions)\nusing an options hash.\n\n```js\nvar xml = require('fs').readFileSync('myservice.wsdl', 'utf8');\n\nsoap.listen(server, {\n    // Server options.\n    path: '/wsdl',\n    services: myService,\n    xml: xml,\n\n    // WSDL options.\n    attributesKey: 'theAttrs',\n    valueKey: 'theVal',\n    xmlKey: 'theXml'\n});\n```\n\n### Server logging\n\nIf the `log` method is defined it will be called with 'received' and 'replied'\nalong with data.\n\n```js\n  server = soap.listen(...)\n  server.log = function(type, data) {\n    // type is 'received' or 'replied'\n  };\n```\n\n### Server events\n\nServer instances emit the following events:\n\n* request - Emitted for every received messages.\n  The signature of the callback is `function(request, methodName)`.\n* headers - Emitted when the SOAP Headers are not empty.\n  The signature of the callback is `function(headers, methodName)`.\n\nThe sequence order of the calls is `request`, `headers` and then the dedicated\nservice method.\n\n```js\n    test.soapServer.on('request', function requestManager(request, methodName) {\n      assert.equal(methodName, 'GetLastTradePrice');\n      done();\n    });\n\n```\n\nAn example of using the SOAP server is in [test/server-test](https://github.com/loopbackio/strong-soap/tree/master/test/server-test.js)\n\n### SOAP Fault\n\nA service method can reply with a SOAP Fault to a client by `throw`ing an\nobject with a `Fault` property.\n\nExample SOAP 1.1 Fault:\n\n```js\n    test.service = {\n      DocLiteralWrappedService: {\n        DocLiteralWrappedPort: {\n          myMethod: function (args, cb, soapHeader) {\n            throw {\n              Fault: {\n                  faultcode: \"sampleFaultCode\",\n                  faultstring: \"sampleFaultString\",\n                  detail:\n                    { myMethodFault:\n                      {errorMessage: 'MyMethod Business Exception message', value: 10}\n                    }\n                }\n            }\n          }\n        }\n      }\n    }\n```\n\nSOAP 1.2 Fault:\n\n```js\n    test.service = {\n      DocLiteralWrappedService: {\n        DocLiteralWrappedPort: {\n          myMethod: function (args, cb, soapHeader) {\n            throw {\n              Fault: {\n                Code: {\n                  Value: \"soap:Sender\",\n                  Subcode: { Value: \"rpc:BadArguments\" }\n                },\n                Reason: { Text: \"Processing Error\" },\n                Detail:\n                {myMethodFault2:\n                   {errorMessage2: 'MyMethod Business Exception message', value2: 10}\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n```\n\n\nExamples of  SOAP 1.1/SOAP 1.2 Fault response can be found in test [test/server-client-document-test](https://github.com/loopbackio/strong-soap/tree/master/test/server-client-document-test.js)\n\n### Server security example using PasswordDigest\n\nIf `server.authenticate` is not defined then no authentication will take place.\n\n```js\n  server = soap.listen(...)\n  server.authenticate = function(security) {\n    var created, nonce, password, user, token;\n    token = security.UsernameToken, user = token.Username,\n            password = token.Password, nonce = token.Nonce, created = token.Created;\n    return user === 'user' \u0026\u0026 password === soap.passwordDigest(nonce, created, 'password');\n  };\n```\n\n### Server connection authorization\n\nThe `server.authorizeConnection` method is called prior to the soap service method.\nIf the method is defined and returns `false` then the incoming connection is\nterminated.\n\n```js\n  server = soap.listen(...)\n  server.authorizeConnection = function(req) {\n    return true; // or false\n  };\n```\n\n\n## SOAP headers\n\n### Received SOAP headers\n\nA service method can look at the SOAP headers by providing a third arguments.\n\n```js\n  {\n      HeadersAwareFunction: function(args, cb, headers) {\n          return {\n              name: headers.Token\n          };\n      }\n  }\n```\n\nIt is also possible to subscribe to the 'headers' event.\nThe event is triggered before the service method is called, and only when the\nSOAP Headers are not empty.\n\n```js\n  server = soap.listen(...)\n  server.on('headers', function(headers, methodName) {\n    // It is possible to change the value of the headers\n    // before they are handed to the service method.\n    // It is also possible to throw a SOAP Fault\n  });\n```\n\nFirst parameter is the Headers object;\nsecond parameter is the name of the SOAP method that will called\n(in case you need to handle the headers differently based on the method).\n\n### Outgoing SOAP headers\n\nBoth client and server can define SOAP headers that will be added to what they send.\nThey provide the following methods to manage the headers.\n\n#### addSoapHeader(value, qname)\n\nAdds soapHeader to soap:Header node.\n\nParameters:\n\n- `value` JSON object representing {headerName: headerValue} or XML string.\n- `qname` qname used for the header\n\n```\naddSoapHeader(value, qname, options);\n```\n\nReturns the index where the header is inserted.\n\n#### changeSoapHeader(index, value, qname)\n\nChanges an existing soapHeader.\n\nParameters:\n\n- `index` index of the header to replace with provided new value\n- `value` JSON object representing {headerName: headerValue} or XML string.\n- `qname` qname used for the header\n\n#### getSoapHeaders()\n\nReturns all defined headers.\n\n#### clearSoapHeaders()\n\nRemoves all defined headers.\n\nExamples of using SOAP header API are in: [test/server-test](https://github.com/loopbackio/strong-soap/tree/master/test/server-test.js) and  [test/server-test](https://github.com/loopbackio/strong-soap/tree/master/test/client-test.js)\n\n## soap-stub\n\nUnit testing services that use SOAP clients can be very cumbersome.  To get\naround this you can use `soap-stub` in conjunction with `sinon` to stub soap with\nyour clients.\n\n### Example\n\n```js\nvar sinon = require('sinon');\nvar soapStub = require('strong-soap/soap-stub');\n\nvar urlMyApplicationWillUseWithCreateClient = './example/stockquote.wsdl';\nvar clientStub = {\n  SomeOperation: sinon.stub()\n};\n\nclientStub.SomeOperation.respondWithError = soapStub.createRespondingStub({error: 'error'});\nclientStub.SomeOperation.respondWithSuccess = soapStub.createRespondingStub({success: 'success'});\n// or if you are using promises\nclientStub.SomeOperation.respondWithError = soapStub.createRespondingStubAsync({error: 'error'});\nclientStub.SomeOperation.respondWithSuccess = soapStub.createRespondingStubAsync({success: 'success'});\n\n\nsoapStub.registerClient('my client alias', urlMyApplicationWillUseWithCreateClient, clientStub);\n\n\nvar fs = require('fs'),\n  assert = require('assert'),\n  request = require('@cypress/request'),\n  http = require('http'),\n  lastReqAddress;\n\ndescribe('myService', function() {\n  var clientStub;\n  var myService;\n\n  beforeEach(function() {\n    clientStub = soapStub.getStub('my client alias');\n    soapStub.reset();\n    myService = clientStub;\n  });\n\n  describe('failures', function() {\n    beforeEach(function() {\n      clientStub.SomeOperation.respondWithError();\n    });\n\n    it('should handle error responses', function() {\n      myService.SomeOperation(function(err, response) {\n        // handle the error response.\n      });\n    });\n  });\n});\n\n```\n\n## Contributors\n\n * [All Contributors](https://github.com/loopbackio/strong-soap/graphs/contributors)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopbackio%2Fstrong-soap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floopbackio%2Fstrong-soap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopbackio%2Fstrong-soap/lists"}