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 +14 -0
- package/index.js +1 -0
- package/lib/SOAP11.js +110 -0
- package/lib/SOAPHTTP.js +84 -0
- package/package.json +1 -1
- package/test/commons/dom-gosuslugi-ru-smev3-common.xsd +1 -1
- package/test/fns-inn-singular-ru-root.xsd +62 -0
- package/test/test.js +8 -55
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
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
|
package/lib/SOAPHTTP.js
ADDED
|
@@ -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
|
@@ -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
|
|
320
|
+
async function test_007_wsdl (fn) {
|
|
335
321
|
|
|
336
|
-
const
|
|
322
|
+
const soap = await SOAP11.fromFile ('test/20186.wsdl')
|
|
337
323
|
|
|
338
|
-
|
|
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
|
|
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
|
|