node-sped-nfe 1.0.0 → 1.0.2

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.
Files changed (50) hide show
  1. package/README.md +1 -22
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.js +3 -0
  4. package/dist/utils/eventos.d.ts +4 -0
  5. package/{utils → dist/utils}/eventos.js +30 -32
  6. package/dist/utils/make.d.ts +81 -0
  7. package/dist/utils/make.js +682 -0
  8. package/dist/utils/sefaz.d.ts +1 -0
  9. package/dist/utils/sefaz.js +64 -0
  10. package/dist/utils/tools.d.ts +23 -0
  11. package/dist/utils/tools.js +269 -0
  12. package/dist/utils/xmllint.d.ts +4 -0
  13. package/dist/utils/xmllint.js +234520 -0
  14. package/package.json +24 -7
  15. package/saida.txt +4 -0
  16. package/src/index.ts +4 -0
  17. package/src/utils/eventos.ts +32 -0
  18. package/{utils/make.js → src/utils/make.ts} +77 -93
  19. package/{utils/tools.js → src/utils/tools.ts} +46 -30
  20. package/tsconfig.json +16 -0
  21. package/index.js +0 -5
  22. package/testes/assinar.js +0 -16
  23. package/testes/nfe.js +0 -166
  24. package/testes/nfe.json +0 -194
  25. package/testes/nfe.xml +0 -292
  26. package/testes/nfe_guara.xml +0 -1
  27. package/testes/nfe_guara_sign.xml +0 -1
  28. package/testes/nfe_guara_sign_lote.xml +0 -1
  29. package/testes/nfe_teste.json +0 -45
  30. package/utils/sefaz.js +0 -84
  31. package/utils/xmllint.js +0 -244195
  32. /package/{utils → src/utils}/schemas/consReciNFe_v4.00.xsd +0 -0
  33. /package/{utils → src/utils}/schemas/consSitNFe_v4.00.xsd +0 -0
  34. /package/{utils → src/utils}/schemas/consStatServ_v4.00.xsd +0 -0
  35. /package/{utils → src/utils}/schemas/enviNFe_v4.00.xsd +0 -0
  36. /package/{utils → src/utils}/schemas/inutNFe_v4.00.xsd +0 -0
  37. /package/{utils → src/utils}/schemas/leiauteConsSitNFe_v4.00.xsd +0 -0
  38. /package/{utils → src/utils}/schemas/leiauteConsStatServ_v4.00.xsd +0 -0
  39. /package/{utils → src/utils}/schemas/leiauteInutNFe_v4.00.xsd +0 -0
  40. /package/{utils → src/utils}/schemas/leiauteNFe_v4.00.xsd +0 -0
  41. /package/{utils → src/utils}/schemas/nfe_v4.00.xsd +0 -0
  42. /package/{utils → src/utils}/schemas/procInutNFe_v4.00.xsd +0 -0
  43. /package/{utils → src/utils}/schemas/procNFe_v4.00.xsd +0 -0
  44. /package/{utils → src/utils}/schemas/retConsReciNFe_v4.00.xsd +0 -0
  45. /package/{utils → src/utils}/schemas/retConsSitNFe_v4.00.xsd +0 -0
  46. /package/{utils → src/utils}/schemas/retConsStatServ_v4.00.xsd +0 -0
  47. /package/{utils → src/utils}/schemas/retEnviNFe_v4.00.xsd +0 -0
  48. /package/{utils → src/utils}/schemas/retInutNFe_v4.00.xsd +0 -0
  49. /package/{utils → src/utils}/schemas/tiposBasico_v4.00.xsd +0 -0
  50. /package/{utils → src/utils}/schemas/xmldsig-core-schema_v1.01.xsd +0 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ import axios from "axios";
2
+ import https from "https";
3
+ class Instance {
4
+ constructor(opts) {
5
+ const { baseURL, ca, cert, key } = opts;
6
+ const AgentOptions = Object.assign({
7
+ cert: cert,
8
+ key: key,
9
+ ca: ca,
10
+ }, { ...opts.httpsOptions });
11
+ const httpsAgent = new https.Agent(AgentOptions);
12
+ const requestOptions = Object.assign({
13
+ baseURL: baseURL,
14
+ headers: {
15
+ 'User-Agent': `node-nfe/1.0`,
16
+ 'Content-Type': 'application/soap+xml; charset=utf-8',
17
+ },
18
+ httpsAgent: httpsAgent,
19
+ timeout: 60000,
20
+ }, { ...opts.requestOptions });
21
+ const instance = axios.create({
22
+ ...requestOptions,
23
+ });
24
+ this.instance = instance;
25
+ }
26
+ /**
27
+ * @returns {Promise<{status: number, data: string}>}
28
+ */
29
+ async request(config) {
30
+ try {
31
+ const response = await this.instance(config);
32
+ const { status, data } = response;
33
+ return { status, data };
34
+ }
35
+ catch (error) {
36
+ if (error.response) {
37
+ const { status, data } = error.response;
38
+ return { status, data };
39
+ }
40
+ else if (error.request) {
41
+ if (error.code === 'ECONNABORTED') {
42
+ const retorno = {
43
+ status: 504,
44
+ data: `<error>${error.message || error}</error>`,
45
+ };
46
+ return retorno;
47
+ }
48
+ const retorno = {
49
+ status: 502,
50
+ data: `<error>${error.message || error}</error>`,
51
+ };
52
+ return retorno;
53
+ }
54
+ else {
55
+ const retorno = {
56
+ status: 500,
57
+ data: `<error>${error.message || error}</error>`,
58
+ };
59
+ return retorno;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ module.exports = Instance;
@@ -0,0 +1,23 @@
1
+ declare class Tools {
2
+ #private;
3
+ constructor(config?: {
4
+ mod: string;
5
+ xmllint: string;
6
+ cUF: string;
7
+ tpAmb: number;
8
+ }, certificado?: {
9
+ pfx: string;
10
+ senha: string;
11
+ });
12
+ sefazEnviaLote(xml: string, data?: {
13
+ idLote: number;
14
+ indSinc: number;
15
+ compactar: boolean;
16
+ }): Promise<unknown>;
17
+ xmlSign(xmlJSON: string, data: any): Promise<unknown>;
18
+ xml2json(xml: string): Promise<object>;
19
+ json2xml(obj: object): Promise<string>;
20
+ getCertificado(): Promise<unknown>;
21
+ sefazStatus(): Promise<unknown>;
22
+ }
23
+ export { Tools };
@@ -0,0 +1,269 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _Tools_instances, _Tools_cert, _Tools_xmlTools, _Tools_pem, _Tools_config, _Tools_xmlValido, _Tools_certTools;
13
+ import { XMLParser, XMLBuilder } from "fast-xml-parser";
14
+ import pem from "pem";
15
+ import https from "https";
16
+ import { spawnSync } from "child_process";
17
+ import tmp from "tmp";
18
+ import crypto from "crypto";
19
+ import { urlServicos } from "./eventos.js";
20
+ import fs from "fs";
21
+ class Tools {
22
+ constructor(config = { mod: "", xmllint: 'xmllint', cUF: '51', tpAmb: 2 }, certificado = { pfx: "", senha: "" }) {
23
+ _Tools_instances.add(this);
24
+ _Tools_cert.set(this, void 0);
25
+ _Tools_xmlTools.set(this, {
26
+ XMLBuilder: {},
27
+ XMLParser: {}
28
+ });
29
+ _Tools_pem.set(this, {});
30
+ _Tools_config.set(this, void 0);
31
+ //Configurar certificado
32
+ __classPrivateFieldSet(this, _Tools_config, config, "f");
33
+ __classPrivateFieldSet(this, _Tools_cert, certificado, "f");
34
+ __classPrivateFieldGet(this, _Tools_xmlTools, "f").XMLBuilder = new XMLBuilder({
35
+ ignoreAttributes: false,
36
+ attributeNamePrefix: "@",
37
+ });
38
+ __classPrivateFieldGet(this, _Tools_xmlTools, "f").XMLParser = new XMLParser({
39
+ ignoreAttributes: false,
40
+ attributeNamePrefix: "@",
41
+ parseTagValue: false, // Evita conversão automática de valores
42
+ });
43
+ }
44
+ sefazEnviaLote(xml, data = { idLote: 1, indSinc: 0, compactar: false }) {
45
+ return new Promise(async (resvol, reject) => {
46
+ if (typeof data.idLote == "undefined")
47
+ data.idLote = 1;
48
+ if (typeof data.indSinc == "undefined")
49
+ data.indSinc = 0;
50
+ if (typeof data.compactar == "undefined")
51
+ data.compactar = false;
52
+ await __classPrivateFieldGet(this, _Tools_instances, "m", _Tools_certTools).call(this);
53
+ let jsonXmlLote = {
54
+ "soap:Envelope": {
55
+ "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
56
+ "@xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
57
+ "@xmlns:soap": "http://www.w3.org/2003/05/soap-envelope",
58
+ "soap:Body": {
59
+ "nfeDadosMsg": {
60
+ "@xmlns": "http://www.portalfiscal.inf.br/nfe/wsdl/NFeAutorizacao4",
61
+ "enviNFe": {
62
+ ...{
63
+ "@xmlns": "http://www.portalfiscal.inf.br/nfe",
64
+ "@versao": "4.00",
65
+ "idLote": data.idLote,
66
+ "indSinc": data.indSinc,
67
+ },
68
+ ...(await this.xml2json(xml))
69
+ }
70
+ }
71
+ }
72
+ },
73
+ };
74
+ let xmlLote = await this.json2xml(jsonXmlLote);
75
+ fs.writeFileSync("testes/nfe_guara_sign_lote.xml", xmlLote, { encoding: "utf8" });
76
+ try {
77
+ const req = https.request(urlServicos[`${__classPrivateFieldGet(this, _Tools_config, "f").cUF}`][`mod_${__classPrivateFieldGet(this, _Tools_config, "f").mod}`].NFeAutorizacao[(__classPrivateFieldGet(this, _Tools_config, "f").tpAmb == 1 ? "producao" : "homologacao")], {
78
+ ...{
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/soap+xml; charset=utf-8',
82
+ 'Content-Length': xmlLote.length,
83
+ },
84
+ rejectUnauthorized: false
85
+ },
86
+ ...__classPrivateFieldGet(this, _Tools_pem, "f")
87
+ }, (res) => {
88
+ let data = '';
89
+ res.on('data', (chunk) => {
90
+ data += chunk;
91
+ });
92
+ res.on('end', () => {
93
+ resvol(data);
94
+ });
95
+ });
96
+ req.on('error', (erro) => {
97
+ reject(erro);
98
+ });
99
+ req.write(xmlLote);
100
+ req.end();
101
+ }
102
+ catch (erro) {
103
+ reject(erro);
104
+ }
105
+ });
106
+ }
107
+ async xmlSign(xmlJSON, data) {
108
+ return new Promise(async (resvol, reject) => {
109
+ if (data.tag === undefined)
110
+ data.tag = "infNFe";
111
+ //Obter a tag que ira ser assinada
112
+ let xml = await this.xml2json(xmlJSON);
113
+ let pem = await this.getCertificado();
114
+ const sign = crypto.createSign('RSA-SHA1'); // Correção: Alterado para RSA-SHA1
115
+ let signedInfo = {
116
+ "SignedInfo": {
117
+ "@xmlns": "http://www.w3.org/2000/09/xmldsig#",
118
+ "CanonicalizationMethod": {
119
+ "@Algorithm": "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
120
+ },
121
+ "SignatureMethod": {
122
+ "@Algorithm": "http://www.w3.org/2000/09/xmldsig#rsa-sha1" // Mantém SHA1
123
+ },
124
+ "Reference": {
125
+ "@URI": `#${xml.NFe.infNFe['@Id']}`,
126
+ "Transforms": {
127
+ "Transform": [
128
+ {
129
+ "@Algorithm": "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
130
+ },
131
+ {
132
+ "@Algorithm": "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
133
+ },
134
+ ]
135
+ },
136
+ "DigestMethod": {
137
+ "@Algorithm": "http://www.w3.org/2000/09/xmldsig#sha1" // Mantém SHA1
138
+ },
139
+ "DigestValue": crypto.createHash('sha1').update(await this.json2xml({ infNFe: xml.NFe.infNFe }), 'utf8') // Mantém Hash SHA1
140
+ .digest('base64')
141
+ }
142
+ }
143
+ };
144
+ sign.update(await this.json2xml(signedInfo), 'utf8');
145
+ xml.NFe.Signature = {
146
+ ...signedInfo,
147
+ ...{
148
+ "SignatureValue": sign.sign(pem.key, 'base64'),
149
+ "KeyInfo": {
150
+ "X509Data": {
151
+ "X509Certificate": pem.cert.replace(/-----BEGIN CERTIFICATE-----/g, '').replace(/-----END CERTIFICATE-----/g, '').replace(/\r\n/g, '')
152
+ }
153
+ },
154
+ "@xmlns": "http://www.w3.org/2000/09/xmldsig#"
155
+ }
156
+ };
157
+ this.json2xml(xml).then(async (res) => {
158
+ __classPrivateFieldGet(this, _Tools_instances, "m", _Tools_xmlValido).call(this, res);
159
+ resvol(res);
160
+ }).catch(err => {
161
+ reject(err);
162
+ });
163
+ });
164
+ }
165
+ async xml2json(xml) {
166
+ return new Promise((resvol, reject) => {
167
+ resvol(__classPrivateFieldGet(this, _Tools_xmlTools, "f").XMLParser.parse(xml));
168
+ });
169
+ }
170
+ async json2xml(obj) {
171
+ return new Promise((resvol, reject) => {
172
+ resvol(__classPrivateFieldGet(this, _Tools_xmlTools, "f").XMLBuilder.build(obj));
173
+ });
174
+ }
175
+ async getCertificado() {
176
+ return new Promise(async (resvol, reject) => {
177
+ await __classPrivateFieldGet(this, _Tools_instances, "m", _Tools_certTools).call(this).then(resvol).catch(reject);
178
+ });
179
+ }
180
+ //Consulta status sefaz
181
+ async sefazStatus() {
182
+ return new Promise(async (resvol, reject) => {
183
+ await __classPrivateFieldGet(this, _Tools_instances, "m", _Tools_certTools).call(this);
184
+ if (typeof __classPrivateFieldGet(this, _Tools_config, "f").cUF == "undefined")
185
+ throw "sefazStatus({...cUF}) -> não definido!";
186
+ if (typeof __classPrivateFieldGet(this, _Tools_config, "f").tpAmb == "undefined")
187
+ throw "sefazStatus({...tpAmb}) -> não definido!";
188
+ if (typeof __classPrivateFieldGet(this, _Tools_config, "f").mod == "undefined")
189
+ throw "sefazStatus({...mod}) -> não definido!";
190
+ let xmlObj = {
191
+ "soap:Envelope": {
192
+ "@xmlns:soap": "http://www.w3.org/2003/05/soap-envelope",
193
+ "@xmlns:nfe": "http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4",
194
+ "soap:Body": {
195
+ "nfe:nfeDadosMsg": {
196
+ "consStatServ": {
197
+ "@versao": "4.00",
198
+ "@xmlns": "http://www.portalfiscal.inf.br/nfe",
199
+ "tpAmb": __classPrivateFieldGet(this, _Tools_config, "f").tpAmb,
200
+ "cUF": __classPrivateFieldGet(this, _Tools_config, "f").cUF,
201
+ "xServ": "STATUS"
202
+ }
203
+ }
204
+ }
205
+ }
206
+ };
207
+ try {
208
+ let tempBuild = new XMLBuilder({
209
+ ignoreAttributes: false,
210
+ attributeNamePrefix: "@"
211
+ });
212
+ let xml = tempBuild.build(xmlObj);
213
+ const req = https.request(urlServicos[`${__classPrivateFieldGet(this, _Tools_config, "f").cUF}`][`mod_${__classPrivateFieldGet(this, _Tools_config, "f").mod}`].NfeStatusServico[(__classPrivateFieldGet(this, _Tools_config, "f").tpAmb == 1 ? "producao" : "homologacao")], {
214
+ ...{
215
+ method: 'POST',
216
+ headers: {
217
+ 'Content-Type': 'application/soap+xml; charset=utf-8',
218
+ 'Content-Length': xml.length,
219
+ },
220
+ rejectUnauthorized: false
221
+ },
222
+ ...__classPrivateFieldGet(this, _Tools_pem, "f")
223
+ }, (res) => {
224
+ let data = '';
225
+ res.on('data', (chunk) => {
226
+ data += chunk;
227
+ });
228
+ res.on('end', () => {
229
+ resvol(data);
230
+ });
231
+ });
232
+ req.on('error', (erro) => {
233
+ reject(erro);
234
+ });
235
+ req.write(xml);
236
+ req.end();
237
+ }
238
+ catch (erro) {
239
+ reject(erro);
240
+ }
241
+ });
242
+ }
243
+ }
244
+ _Tools_cert = new WeakMap(), _Tools_xmlTools = new WeakMap(), _Tools_pem = new WeakMap(), _Tools_config = new WeakMap(), _Tools_instances = new WeakSet(), _Tools_xmlValido =
245
+ //Validar XML da NFe, somente apos assinar
246
+ async function _Tools_xmlValido(xml) {
247
+ const xmlFile = tmp.fileSync({ mode: 0o644, prefix: 'xml-', postfix: '.xml' });
248
+ fs.writeFileSync(xmlFile.name, xml, { encoding: 'utf8' });
249
+ const verif = spawnSync(__classPrivateFieldGet(this, _Tools_config, "f").xmllint, ['--noout', '--schema', './utils/schemas/nfe_v4.00.xsd', xmlFile.name], { encoding: 'utf8' });
250
+ xmlFile.removeCallback();
251
+ // Aqui, usamos o operador de encadeamento opcional (?.)
252
+ if (verif.error) {
253
+ throw new Error("Biblioteca xmllint não encontrada!");
254
+ }
255
+ else if (!verif.stderr.includes(".xml validates")) {
256
+ throw new Error(verif.stderr);
257
+ }
258
+ return 1;
259
+ }, _Tools_certTools = function _Tools_certTools() {
260
+ return new Promise(async (resvol, reject) => {
261
+ if (__classPrivateFieldGet(this, _Tools_pem, "f") != null)
262
+ resvol(__classPrivateFieldGet(this, _Tools_pem, "f"));
263
+ pem.readPkcs12(__classPrivateFieldGet(this, _Tools_cert, "f").pfx, { p12Password: __classPrivateFieldGet(this, _Tools_cert, "f").senha }, (err, myPem) => {
264
+ __classPrivateFieldSet(this, _Tools_pem, myPem, "f");
265
+ resvol(myPem);
266
+ });
267
+ });
268
+ };
269
+ export { Tools };
@@ -0,0 +1,4 @@
1
+ declare const validateXML: (options: any) => {
2
+ errors: any;
3
+ };
4
+ export { validateXML };