xml-toolkit 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,4 +76,18 @@ const xml = xs.stringify (data)
76
76
  */
77
77
  ```
78
78
 
79
+ * Invoking a [SOAP 1.1](https://github.com/do-/node-xml-toolkit/wiki/SOAP11) Web Service
80
+
81
+ ```js
82
+ const http = require ('http')
83
+ const {SOAP11} = require ('xml-toolkit')
84
+
85
+ const soap = await SOAP11.fromFile ('their.wsdl')
86
+
87
+ const {method, headers, body} = soap.http ({RequestElementNameOfTheirs: {amount: '0.01'}})
88
+
89
+ const rq = http.request (endpointURL, {method, headers})
90
+ rq.write (body)
91
+ ```
92
+
79
93
  More information available in [wiki docs](https://github.com/do-/node-xml-toolkit/wiki).
package/index.js CHANGED
@@ -7,5 +7,6 @@ for (const name of [
7
7
  'MoxyLikeJsonEncoder',
8
8
  'XMLNode',
9
9
  'XMLSchemata',
10
+ 'SOAP11',
10
11
 
11
12
  ]) module.exports [name] = require ('./lib/' + name)
package/lib/SOAP11.js ADDED
@@ -0,0 +1,110 @@
1
+ const fs = require ('fs')
2
+
3
+ const XMLSchemata = require ('./XMLSchemata.js')
4
+ const XMLReader = require ('./XMLReader.js')
5
+ const XMLNode = require ('./XMLNode.js')
6
+ const SOAPHTTP = require ('./SOAPHTTP.js')
7
+
8
+ const SOAP11 = class {
9
+
10
+ getMessageLocalNameByElementLocalName (elementLocalName) {
11
+
12
+ for (const m of this.definitions.children) if (m.localName === 'message')
13
+
14
+ for (const p of m.children) if (p.localName === 'part')
15
+
16
+ if (XMLNode.getLocalName (p.attributes.get ('element')) === elementLocalName)
17
+
18
+ return m.attributes.get ('name')
19
+
20
+ }
21
+
22
+ getOperationNameByMessageLocalName (messageLocalName) {
23
+
24
+ for (const p of this.definitions.children) if (p.localName === 'portType')
25
+
26
+ for (const o of p.children) if (o.localName === 'operation')
27
+
28
+ for (const i of o.children) if (i.localName === 'input')
29
+
30
+ if (XMLNode.getLocalName (i.attributes.get ('message')) === messageLocalName)
31
+
32
+ return o.attributes.get ('name')
33
+
34
+ }
35
+
36
+
37
+ getSoapActionByOperationName (operationName) {
38
+
39
+ for (const b of this.definitions.children) if (b.localName === 'binding')
40
+
41
+ for (const o of b.children) if (o.localName === 'operation' && o.attributes.get ('name') === operationName)
42
+
43
+ for (const so of o.children) if (o.localName === 'operation')
44
+
45
+ return so.attributes.get ('soapAction')
46
+
47
+ }
48
+
49
+
50
+ getSoapActionByElementLocalName (elementLocalName) {
51
+
52
+ return this.getSoapActionByOperationName (
53
+
54
+ this.getOperationNameByMessageLocalName (
55
+
56
+ this.getMessageLocalNameByElementLocalName (elementLocalName)
57
+
58
+ )
59
+
60
+ )
61
+
62
+ }
63
+
64
+ toSOAPHTTP (o) {
65
+
66
+ let rq = new SOAPHTTP ('1.1')
67
+
68
+ for (const elementLocalName in o) {
69
+
70
+ const SOAPAction = this.getSoapActionByElementLocalName (elementLocalName)
71
+
72
+ if (SOAPAction) rq.http.headers.SOAPAction = SOAPAction
73
+
74
+ }
75
+
76
+ rq.soap.Body.content = this.xs.stringify (o)
77
+
78
+ return rq.build ()
79
+
80
+ }
81
+
82
+ http (o) {
83
+
84
+ return this.toSOAPHTTP (o).http
85
+
86
+ }
87
+
88
+ }
89
+
90
+ const WSDL = {namespaceURI: 'http://schemas.xmlsoap.org/wsdl/'}
91
+
92
+ SOAP11.namespaceURI = 'http://schemas.xmlsoap.org/wsdl/soap/'
93
+
94
+ SOAP11.fromFile = async function (fn, options = {}) {
95
+
96
+ let s = new SOAP11 ()
97
+
98
+ s.xs = await XMLSchemata.fromFile (fn)
99
+
100
+ s.definitions = await new XMLReader ({
101
+ filterElements: e =>
102
+ e.namespaceURI === WSDL.namespaceURI &&
103
+ e.localName === 'definitions'
104
+ }).process (fs.createReadStream (fn)).findFirst ()
105
+
106
+ return s
107
+
108
+ }
109
+
110
+ module.exports = SOAP11
@@ -0,0 +1,84 @@
1
+ const zlib = require ('zlib')
2
+
3
+ const VER = {
4
+
5
+ '1.1': {
6
+ contentType : 'text/xml',
7
+ namespaceURI : 'http://schemas.xmlsoap.org/soap/envelope/',
8
+ },
9
+
10
+ '1.2': {
11
+ contentType : 'application/soap+xml',
12
+ namespaceURI : 'http://www.w3.org/2003/05/soap-envelope',
13
+ },
14
+
15
+ }
16
+
17
+ const SOAPHTTP = class {
18
+
19
+ constructor (versionNumber) {
20
+
21
+ if (!(versionNumber in VER)) throw new Exception ('Unknown SOAP version: ' + version)
22
+
23
+ const {contentType, namespaceURI} = VER [versionNumber]
24
+
25
+ this.charset = 'utf-8'
26
+
27
+ this.http = {
28
+ method : 'POST',
29
+ headers : {"Content-Type": contentType},
30
+ }
31
+
32
+ this.soap = {
33
+ Envelope: {attributes: `xmlns:soap="${namespaceURI}"`},
34
+ Header: {attributes: '', content: ''},
35
+ Body: {attributes: '', content: ''},
36
+ }
37
+
38
+ }
39
+
40
+ el (name) {
41
+
42
+ const {attributes, content} = this.soap [name]
43
+
44
+ const qName = 'soap:' + name
45
+
46
+ let s = '<' + qName
47
+
48
+ if (attributes) s += ' ' + attributes
49
+
50
+ if (!content) return s + '/>'
51
+
52
+ return s + '>' + content + '</' + qName + '>'
53
+
54
+ }
55
+
56
+ build () {
57
+
58
+ this.http.headers ['Content-Type'] += '; charset=' + this.charset
59
+
60
+ this.soap.Envelope.content = this.el ('Header') + this.el ('Body')
61
+
62
+ this.http.body = '<?xml version="1.0" encoding="' + this.charset + '"?>' + this.el ('Envelope')
63
+
64
+ return this
65
+
66
+ }
67
+
68
+ gzip (options = {}) {
69
+
70
+ if (!('level' in options)) options.level = 9
71
+
72
+ this.http.body = zlib.gzipSync (this.http.body, options)
73
+
74
+ this.http.headers ['Content-Encoding'] = 'gzip'
75
+
76
+ this.http.headers ['Content-Length'] = this.http.body.length
77
+
78
+ return this
79
+
80
+ }
81
+
82
+ }
83
+
84
+ module.exports = SOAPHTTP
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xml-toolkit",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Collection of classes for dealing with XML",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -462,4 +462,4 @@
462
462
  <xs:maxLength value="2048"/>
463
463
  </xs:restriction>
464
464
  </xs:simpleType>
465
- </xs:schema>
465
+ </xs:schema>
@@ -0,0 +1,62 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn://x-artefacts-fns-inn-singular/root/270-18/4.0.1" xmlns:tns="urn://x-artefacts-fns-inn/commons/4.0.0" targetNamespace="urn://x-artefacts-fns-inn-singular/root/270-18/4.0.1" elementFormDefault="qualified" attributeFormDefault="unqualified">
3
+ <xs:import namespace="urn://x-artefacts-fns-inn/commons/4.0.0" schemaLocation="commons/fns-common-types.xsd"/>
4
+ <xs:element name="FNSINNSingularRequest">
5
+ <xs:annotation>
6
+ <xs:documentation>Запрос в Федеральную налоговую службу об ИНН физического лица</xs:documentation>
7
+ </xs:annotation>
8
+ <xs:complexType>
9
+ <xs:sequence>
10
+ <xs:element name="СведЮЛ">
11
+ <xs:annotation>
12
+ <xs:documentation>Сведения о юридическом лице, осуществляющем запрос</xs:documentation>
13
+ </xs:annotation>
14
+ <xs:complexType>
15
+ <xs:attribute name="НаимОрг" type="tns:string-1000" use="required">
16
+ <xs:annotation>
17
+ <xs:documentation>Наименование организации</xs:documentation>
18
+ </xs:annotation>
19
+ </xs:attribute>
20
+ <xs:attribute name="ИННЮЛ" type="tns:ИННЮЛТип" use="required">
21
+ <xs:annotation>
22
+ <xs:documentation>ИНН юридического лица</xs:documentation>
23
+ </xs:annotation>
24
+ </xs:attribute>
25
+ <xs:attribute name="ОГРН" type="tns:ОГРН" use="required">
26
+ <xs:annotation>
27
+ <xs:documentation>Основной государственный регистрационный номер юридического лица</xs:documentation>
28
+ </xs:annotation>
29
+ </xs:attribute>
30
+ </xs:complexType>
31
+ </xs:element>
32
+ <xs:element name="СведФЛ" type="tns:СведФЛТип">
33
+ <xs:annotation>
34
+ <xs:documentation>Сведения о запрашиваемом физическом лице</xs:documentation>
35
+ </xs:annotation>
36
+ </xs:element>
37
+ </xs:sequence>
38
+ <xs:attribute name="ИдЗапрос" type="tns:ИдЗапросТип" use="required">
39
+ <xs:annotation>
40
+ <xs:documentation>Идентификатор запроса</xs:documentation>
41
+ </xs:annotation>
42
+ </xs:attribute>
43
+ </xs:complexType>
44
+ </xs:element>
45
+ <xs:element name="FNSINNSingularResponse">
46
+ <xs:annotation>
47
+ <xs:documentation>Ответ на запрос в Федеральную налоговую службу об ИНН физического лица</xs:documentation>
48
+ </xs:annotation>
49
+ <xs:complexType>
50
+ <xs:attribute name="ИдЗапрос" type="tns:ИдЗапросТип" use="required">
51
+ <xs:annotation>
52
+ <xs:documentation>Идентификатор запроса, на который предоставляется ответ</xs:documentation>
53
+ </xs:annotation>
54
+ </xs:attribute>
55
+ <xs:attribute name="ИННФЛ" type="tns:ИННФЛТип" use="optional">
56
+ <xs:annotation>
57
+ <xs:documentation>ИНН физического лица</xs:documentation>
58
+ </xs:annotation>
59
+ </xs:attribute>
60
+ </xs:complexType>
61
+ </xs:element>
62
+ </xs:schema>
package/test/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const fs = require ('fs')
2
2
  const assert = require ('assert')
3
- const {XMLReader, SAXEvent, XMLLexer, AttributesMap, XMLNode, XMLSchemata} = require ('../')
3
+ const {XMLReader, SAXEvent, XMLLexer, AttributesMap, XMLNode, XMLSchemata, SOAP11} = require ('../')
4
4
 
5
5
  async function test_001_lexer_sync (fn) {
6
6
 
@@ -97,24 +97,10 @@ console.log (xml)
97
97
  */
98
98
  //console.log ([xml, s])
99
99
 
100
-
101
- try {
102
-
103
-
104
-
105
100
  const v = await sax.process (xml).findFirst ()
106
101
 
107
102
  console.log (JSON.stringify (v, null, 2))
108
103
 
109
-
110
- }
111
- catch (x) {
112
- console.log ({x})
113
- }
114
-
115
-
116
-
117
-
118
104
  }
119
105
 
120
106
  async function test_004_schemata (fn) {
@@ -331,43 +317,11 @@ async function test_006_schemata (fn) {
331
317
 
332
318
  }
333
319
 
334
- async function test_007_schemata (fn) {
320
+ async function test_007_wsdl (fn) {
335
321
 
336
- const xs = await XMLSchemata.fromFile ('test/20186.wsdl')
322
+ const soap = await SOAP11.fromFile ('test/20186.wsdl')
337
323
 
338
- const data =
339
- {"GetForm9Sync":{
340
- "person": {"LastName":"КУПРИН","FirstName":"АНДРЕЙ","SecondName":"АНДРЕЙ","BirthDate":"1967-04-10"},
341
- "address":{"Region":{"Code":"78","Name":"Санкт-Петербург"},"Street":{"Code":"5381","Name":"Вокзальная ул"},"House":"д. 9 к. 3 литера В","Flat":"50"}
342
- }}
343
-
344
- // const m = xs.createMarshaller ('AppDataChildDotation', 'http://smev.gosuslugi.ru/rev111111')
345
-
346
- console.log (xs.stringify (data))
347
-
348
- }
349
-
350
- async function test_008_schemata (fn) {
351
-
352
- const xs = await XMLSchemata.fromFile ('test/fns-innfdrfio-root.xsd')
353
-
354
- const IDRequest = '0000000001'
355
-
356
- const PhysicalPersonINN = '520205004556'
357
-
358
- // const data = {INNFDRFIOResponse: {'IDRequest ': IDRequest, PhysicalPersonINN}}
359
- const data = {INNFDRFIORequest: {
360
- IDRequest: 1,
361
- DataPersonRequest: {
362
- BirthDate: "1992-07-28",
363
- FamilyName: "ИВАНОВ",
364
- FirstName: "МИХАИЛ",
365
- Patronymic: "АЛЕКСЕЕВИЧ",
366
- }
367
- }
368
- }
369
-
370
- console.log (xs.stringify (data))
324
+ console.log (soap.http ({GetForm9Sync: {address: {Region: {Code: 78}}}}))
371
325
 
372
326
  }
373
327
 
@@ -385,11 +339,10 @@ async function main () {
385
339
  // await test_003_emitter_sync ('not-sa01.xml')
386
340
  // await test_003_emitter_sync ('ent.xml')
387
341
  // await test_003_emitter_sync ('soap.xml')
388
- await test_004_schemata ()
389
- await test_005_schemata ()
390
- await test_006_schemata ()
391
- await test_007_schemata ()
392
- await test_008_schemata ()
342
+ // await test_004_schemata ()
343
+ // await test_005_schemata ()
344
+ // await test_006_schemata ()
345
+ await test_007_wsdl ()
393
346
 
394
347
  }
395
348