node-sped-nfe 1.0.1 → 1.0.3

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