nfe-lib-node 1.0.0 → 1.3.0

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
@@ -1,87 +1,113 @@
1
- # nfe-lib-node 🚀
2
-
3
- Uma biblioteca Node.js em TypeScript para emissão de Nota Fiscal Eletrônica (NF-e) focada em simplicidade, segurança e sem dependência de serviços terceiros (SaaS).
4
-
5
- Pague apenas os seus impostos, não pela emissão! 😉
6
-
7
- ## 📦 Instalação
8
-
9
- Como o projeto está no início, faça o clone e instale as dependências localmente:
10
-
11
- ```bash
12
- git clone https://github.com/SEU_USUARIO/nfe-lib-node.git
13
- cd nfe-lib-node
14
- npm install
15
- ```
16
-
17
- ## 🚀 Como usar
18
-
19
- A arquitetura foi pensada para ser o mais simples possível. Você só precisa do seu Certificado Digital A1 (`.pfx`).
20
-
21
- ### 1. Consultar Status do Serviço (SEFAZ)
22
-
23
- ```typescript
24
- import { NFe, Certificado } from 'nfe-lib-node';
25
- import fs from 'fs';
26
-
27
- async function testarSefaz() {
28
- const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
29
- const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
30
-
31
- const status = await nfe.consultarStatus();
32
- console.log(status.xml);
33
- }
34
- ```
35
-
36
- ### 2. Emitir uma NF-e (Autorização)
37
-
38
- A biblioteca foca na infraestrutura (Assinatura XMLDSig e SOAP). Você fornece um objeto com a estrutura da SEFAZ, e a biblioteca cuida da dor de cabeça da criptografia:
39
-
40
- ```typescript
41
- import { NFe, Certificado, DadosNFe } from 'nfe-lib-node';
42
- import fs from 'fs';
43
-
44
- async function emitirNota() {
45
- const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
46
- const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
47
-
48
- const nota: DadosNFe = {
49
- infNFe: {
50
- '@Id': 'NFe5326...',
51
- '@versao': '4.00',
52
- ide: { /* ... */ },
53
- emit: { /* ... */ },
54
- dest: { /* ... */ },
55
- det: { /* ... */ },
56
- total: { /* ... */ },
57
- transp: { /* ... */ },
58
- pag: { /* ... */ }
59
- }
60
- };
61
-
62
- const resposta = await nfe.emitir(nota);
63
- console.log(resposta.xml); // Autorizado!
64
- }
65
- ```
66
-
67
- testarSefaz();
68
-
69
- ## 🛡️ Segurança
70
-
71
- * **Nunca** faça commit do seu arquivo `.pfx` ou da sua senha para o GitHub.
72
- * O arquivo `.gitignore` já vem configurado para ignorar extensões de certificados por padrão.
73
-
74
- ## 🤝 Contribuições
75
-
76
- Este projeto está no início (Fase 1: Comunicação Base). As próximas etapas envolvem a construção dos Builders de XML e a Assinatura Digital (XMLDSig). Toda contribuição da comunidade Node.js brasileira é bem-vinda!
77
-
78
- ## 👨‍💻 Autor
79
-
80
- Criado e idealizado por **Rafael Conrado**.
81
- Se você curtiu o projeto, me dê um "Alô" nas redes:
82
- * [GitHub - @rafconrado](https://github.com/rafconrado)
83
- * [LinkedIn](https://www.linkedin.com/in/rafconradoo/)
84
-
85
- ## 📝 Licença
86
-
87
- MIT License
1
+ # nfe-lib-node 🚀
2
+
3
+ Uma biblioteca Node.js em TypeScript para emissão de Nota Fiscal Eletrônica (NF-e) focada em simplicidade, segurança e sem dependência de serviços terceiros (SaaS).
4
+
5
+ Pague apenas os seus impostos, não pela emissão! 😉
6
+
7
+ ## 📦 Instalação
8
+
9
+ Instale diretamente via NPM:
10
+
11
+ ```bash
12
+ npm install nfe-lib-node
13
+ ```
14
+
15
+ Ou, para clonar e rodar localmente:
16
+
17
+ ```bash
18
+ git clone https://github.com/rafconrado/nfe-lib-node.git
19
+ cd nfe-lib-node
20
+ npm install
21
+ ```
22
+
23
+ ## 🚀 Como usar
24
+
25
+ A arquitetura foi pensada para ser o mais simples possível. Você só precisa do seu Certificado Digital A1 (`.pfx`).
26
+
27
+ ### 1. Validar Certificado e Consultar Status do Serviço (SEFAZ)
28
+
29
+ ```typescript
30
+ import { NFe, Certificado } from 'nfe-lib-node';
31
+ import fs from 'fs';
32
+
33
+ async function testarSefaz() {
34
+ const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
35
+
36
+ // Opcional: Inspecionar dados e validade do Certificado A1 (ICP-Brasil)
37
+ const dadosCert = certificado.getDados();
38
+ console.log(`Titular: ${dadosCert.nomeComum} (${dadosCert.cnpjOuCpf})`);
39
+ console.log(`Válido: ${dadosCert.estaValido} (${dadosCert.diasParaVencer} dias restantes)`);
40
+
41
+ const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
42
+
43
+ const status = await nfe.consultarStatus();
44
+ console.log(status.xml);
45
+ }
46
+ ```
47
+
48
+ ### 2. Emitir uma NF-e (Autorização) e Gerar DANFE em PDF
49
+
50
+ A biblioteca cuida da infraestrutura completa (Tipagem do Layout 4.00, Assinatura XMLDSig, comunicação SOAP e geração de DANFE em PDF sem dependências pesadas):
51
+
52
+ ```typescript
53
+ import { NFe, Certificado, Danfe, type DadosNFe } from 'nfe-lib-node';
54
+ import fs from 'fs';
55
+
56
+ async function emitirNota() {
57
+ const certificado = new Certificado(fs.readFileSync('./certificado.pfx'), 'SENHA_DO_CERTIFICADO');
58
+ const nfe = new NFe({ uf: 'DF', ambiente: 'homologacao', certificado });
59
+
60
+ const nota: DadosNFe = {
61
+ infNFe: {
62
+ '@Id': 'NFe5326...',
63
+ '@versao': '4.00',
64
+ ide: { /* ... */ },
65
+ emit: { /* ... */ },
66
+ dest: { /* ... */ },
67
+ det: [ /* ... */ ],
68
+ total: { /* ... */ },
69
+ transp: { /* ... */ },
70
+ pag: { /* ... */ }
71
+ }
72
+ };
73
+
74
+ const resposta = await nfe.emitir(nota);
75
+ console.log(`Status: ${resposta.status} - ${resposta.motivo}`);
76
+
77
+ // Gera o PDF do DANFE diretamente a partir do XML assinado + retorno da SEFAZ
78
+ if (resposta.xmlAssinado) {
79
+ const pdfBuffer = Danfe.fromXml(resposta.xmlAssinado, resposta.xml);
80
+ fs.writeFileSync('./danfe.pdf', pdfBuffer);
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## ✨ Funcionalidades Atuais
86
+
87
+ * 🔐 **Certificado Digital A1 (`.pfx`)**: Extração com cache em memória, inspeção de validade/titular (`getDados()`, `estaValido()`) e configuração de mTLS.
88
+ * 🔑 **Chave de Acesso (Módulo 11)**: Geração e validação da chave de 44 dígitos e cálculo automático do `cDV` (`gerarChaveAcesso`, `validarChaveAcesso`, `calcularDigitoVerificador`).
89
+ * ✍️ **Assinatura Digital XMLDSig**: Assinatura no padrão exigido pela SEFAZ (`rsa-sha1` / `enveloped-signature` / `c14n`).
90
+ * 🗺️ **Mapeamento Completo de WebServices por UF**: Resolução automática das URLs oficiais da NF-e 4.00 para todas as 27 UFs (Autorizadores próprios: AM, BA, GO, MG, MS, MT, PE, PR, RS, SP + SVAN, SVRS e contingência SVC-AN / SVC-RS).
91
+ * 📡 **Comunicação SEFAZ (SOAP 1.2)**: Consulta de status do serviço (`consultarStatus`) e autorização síncrona de NF-e (`emitir`) com geração automática do `<nfeProc>`.
92
+ * 📄 **Gerador de DANFE em PDF**: Geração nativa de PDF com código de barras `Code128C` via `Danfe.fromXml()`.
93
+ * 📘 **Tipagem TypeScript Completa**: Interfaces completas da NF-e / NFC-e 4.00 (incluindo os novos grupos de IBS/CBS da Reforma Tributária).
94
+
95
+ ## 🛡️ Segurança
96
+
97
+ * **Nunca** faça commit do seu arquivo `.pfx` ou da sua senha para o GitHub.
98
+ * O arquivo `.gitignore` já vem configurado para ignorar extensões de certificados por padrão.
99
+
100
+ ## 🤝 Contribuições
101
+
102
+ As próximas etapas envolvem suporte a eventos (Cancelamento, Carta de Correção), Consulta de Protocolo por chave e Inutilização. Toda contribuição da comunidade Node.js brasileira é bem-vinda!
103
+
104
+ ## 👨‍💻 Autor
105
+
106
+ Criado e idealizado por **Rafael Conrado**.
107
+ Se você curtiu o projeto, me dê um "Alô" nas redes:
108
+ * [GitHub - @rafconrado](https://github.com/rafconrado)
109
+ * [LinkedIn](https://www.linkedin.com/in/rafconradoo/)
110
+
111
+ ## 📝 Licença
112
+
113
+ MIT License
@@ -0,0 +1,11 @@
1
+ import { Certificado } from './Certificado.js';
2
+ export declare class Assinador {
3
+ private privateKeyPem;
4
+ private publicCertPem;
5
+ constructor(certificadoOuPfx: Certificado | Buffer, password?: string | undefined);
6
+ /**
7
+ * Assina o XML da Nota Fiscal Eletrônica no padrão SEFAZ (XMLDSig)
8
+ */
9
+ assinarXmlNFe(xmlCru: string): string;
10
+ }
11
+ //# sourceMappingURL=Assinador.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Assinador.d.ts","sourceRoot":"","sources":["../src/Assinador.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,qBAAa,SAAS;IACpB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAS;IAE9B,YAAY,gBAAgB,EAAE,WAAW,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,EAQhF;IAED;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqC3C;CACF"}
@@ -0,0 +1,51 @@
1
+ import { SignedXml } from 'xml-crypto';
2
+ import { DOMParser } from '@xmldom/xmldom';
3
+ import { Certificado } from './Certificado.js';
4
+ export class Assinador {
5
+ privateKeyPem;
6
+ publicCertPem;
7
+ constructor(certificadoOuPfx, password) {
8
+ const cert = certificadoOuPfx instanceof Certificado
9
+ ? certificadoOuPfx
10
+ : new Certificado(certificadoOuPfx, password);
11
+ const { privateKey, certificate } = cert.getPem();
12
+ this.privateKeyPem = privateKey;
13
+ this.publicCertPem = certificate;
14
+ }
15
+ /**
16
+ * Assina o XML da Nota Fiscal Eletrônica no padrão SEFAZ (XMLDSig)
17
+ */
18
+ assinarXmlNFe(xmlCru) {
19
+ const doc = new DOMParser().parseFromString(xmlCru, 'text/xml');
20
+ const infNFe = doc.getElementsByTagName('infNFe')[0];
21
+ if (!infNFe) {
22
+ throw new Error('Tag <infNFe> não encontrada no XML. O XML fornecido não é uma NF-e válida.');
23
+ }
24
+ const id = infNFe.getAttribute('Id');
25
+ if (!id) {
26
+ throw new Error('A tag <infNFe> precisa ter o atributo Id (ex: Id="NFe12345...")');
27
+ }
28
+ const sig = new SignedXml();
29
+ // A SEFAZ exige URI=#IdDaNota e essas duas transforms
30
+ sig.addReference({
31
+ xpath: `//*[@Id='${id}']`,
32
+ transforms: [
33
+ 'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
34
+ 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315',
35
+ ],
36
+ digestAlgorithm: 'http://www.w3.org/2000/09/xmldsig#sha1',
37
+ uri: `#${id}`,
38
+ });
39
+ sig.privateKey = this.privateKeyPem;
40
+ sig.signatureAlgorithm = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
41
+ sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
42
+ // Em xml-crypto v6, basta passar o publicCert
43
+ sig.publicCert = Buffer.from(this.publicCertPem);
44
+ sig.computeSignature(xmlCru, {
45
+ prefix: '',
46
+ location: { reference: `//*[local-name(.)='NFe']`, action: 'append' },
47
+ });
48
+ return sig.getSignedXml();
49
+ }
50
+ }
51
+ //# sourceMappingURL=Assinador.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Assinador.js","sourceRoot":"","sources":["../src/Assinador.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,OAAO,SAAS;IACZ,aAAa,CAAS;IACtB,aAAa,CAAS;IAE9B,YAAY,gBAAsC,EAAE,QAA6B;QAC/E,MAAM,IAAI,GACR,gBAAgB,YAAY,WAAW;YACrC,CAAC,CAAC,gBAAgB;YAClB,CAAC,CAAC,IAAI,WAAW,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAClD,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC;QAChC,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC;IACnC,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,MAAc;QACjC,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,GAAG,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAChG,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,sDAAsD;QACtD,GAAG,CAAC,YAAY,CAAC;YACf,KAAK,EAAE,YAAY,EAAE,IAAI;YACzB,UAAU,EAAE;gBACV,uDAAuD;gBACvD,iDAAiD;aAClD;YACD,eAAe,EAAE,wCAAwC;YACzD,GAAG,EAAE,IAAI,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC;QACpC,GAAG,CAAC,kBAAkB,GAAG,4CAA4C,CAAC;QACtE,GAAG,CAAC,yBAAyB,GAAG,iDAAiD,CAAC;QAElF,8CAA8C;QAC9C,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEjD,GAAG,CAAC,gBAAgB,CAAC,MAAM,EAAE;YAC3B,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE,SAAS,EAAE,0BAA0B,EAAE,MAAM,EAAE,QAAQ,EAAE;SACtE,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,39 @@
1
+ import https from 'https';
2
+ export interface DadosCertificado {
3
+ nomeComum: string;
4
+ cnpjOuCpf?: string | undefined;
5
+ emissor: string;
6
+ validoDe: Date;
7
+ validoAte: Date;
8
+ estaValido: boolean;
9
+ diasParaVencer: number;
10
+ }
11
+ export declare class Certificado {
12
+ pfxBuffer: Buffer;
13
+ password?: string | undefined;
14
+ private cacheExtraido?;
15
+ constructor(pfxBuffer: Buffer, password?: string | undefined);
16
+ /**
17
+ * Retorna a chave privada e o certificado público em formato PEM.
18
+ */
19
+ getPem(): {
20
+ privateKey: string;
21
+ certificate: string;
22
+ };
23
+ /**
24
+ * Retorna um https.Agent configurado com o certificado para autenticação mútua TLS (exigida pela SEFAZ).
25
+ */
26
+ getHttpsAgent(): https.Agent;
27
+ /**
28
+ * Retorna metadados e informações de validade do certificado A1 (ICP-Brasil).
29
+ */
30
+ getDados(): DadosCertificado;
31
+ /**
32
+ * Indica se o certificado está dentro do prazo de validade na data atual.
33
+ */
34
+ estaValido(): boolean;
35
+ private extractFromPfx;
36
+ private getLeafCert;
37
+ private getAttrValue;
38
+ }
39
+ //# sourceMappingURL=Certificado.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Certificado.d.ts","sourceRoot":"","sources":["../src/Certificado.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAQD,qBAAa,WAAW;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,OAAO,CAAC,aAAa,CAAC,CAA0B;IAEhD,YAAY,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,EAG3D;IAED;;OAEG;IACI,MAAM,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAG3D;IAED;;OAEG;IACI,aAAa,IAAI,KAAK,CAAC,KAAK,CAOlC;IAED;;OAEG;IACI,QAAQ,IAAI,gBAAgB,CAyBlC;IAED;;OAEG;IACI,UAAU,IAAI,OAAO,CAE3B;IAED,OAAO,CAAC,cAAc;IA+BtB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,YAAY;CAOrB"}
@@ -0,0 +1,100 @@
1
+ import https from 'https';
2
+ import forge from 'node-forge';
3
+ export class Certificado {
4
+ pfxBuffer;
5
+ password;
6
+ cacheExtraido;
7
+ constructor(pfxBuffer, password) {
8
+ this.pfxBuffer = pfxBuffer;
9
+ this.password = password;
10
+ }
11
+ /**
12
+ * Retorna a chave privada e o certificado público em formato PEM.
13
+ */
14
+ getPem() {
15
+ const { privateKey, certificate } = this.extractFromPfx();
16
+ return { privateKey, certificate };
17
+ }
18
+ /**
19
+ * Retorna um https.Agent configurado com o certificado para autenticação mútua TLS (exigida pela SEFAZ).
20
+ */
21
+ getHttpsAgent() {
22
+ const { privateKey, certificate } = this.getPem();
23
+ return new https.Agent({
24
+ cert: certificate,
25
+ key: privateKey,
26
+ rejectUnauthorized: false, // Em ambientes de homologação da Sefaz, a cadeia pode ser inválida
27
+ });
28
+ }
29
+ /**
30
+ * Retorna metadados e informações de validade do certificado A1 (ICP-Brasil).
31
+ */
32
+ getDados() {
33
+ const { leafCert } = this.extractFromPfx();
34
+ const nomeComum = this.getAttrValue(leafCert.subject.attributes, 'CN');
35
+ const emissor = this.getAttrValue(leafCert.issuer.attributes, 'CN') ||
36
+ this.getAttrValue(leafCert.issuer.attributes, 'O');
37
+ const matchDoc = nomeComum.match(/:(\d{11}|\d{14})\b/) ?? nomeComum.match(/\b(\d{14})\b/);
38
+ const cnpjOuCpf = matchDoc?.[1];
39
+ const validoDe = leafCert.validity.notBefore;
40
+ const validoAte = leafCert.validity.notAfter;
41
+ const agora = new Date();
42
+ const estaValido = agora >= validoDe && agora <= validoAte;
43
+ const diasParaVencer = Math.floor((validoAte.getTime() - agora.getTime()) / (1000 * 60 * 60 * 24));
44
+ return {
45
+ nomeComum,
46
+ cnpjOuCpf,
47
+ emissor,
48
+ validoDe,
49
+ validoAte,
50
+ estaValido,
51
+ diasParaVencer,
52
+ };
53
+ }
54
+ /**
55
+ * Indica se o certificado está dentro do prazo de validade na data atual.
56
+ */
57
+ estaValido() {
58
+ return this.getDados().estaValido;
59
+ }
60
+ extractFromPfx() {
61
+ if (this.cacheExtraido) {
62
+ return this.cacheExtraido;
63
+ }
64
+ const p12Asn1 = forge.asn1.fromDer(this.pfxBuffer.toString('binary'));
65
+ const p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, this.password ?? '');
66
+ const certBagOid = forge.pki.oids.certBag;
67
+ const certBags = p12.getBags({ bagType: certBagOid })[certBagOid] ?? [];
68
+ const cert = this.getLeafCert(certBags);
69
+ const certPem = cert ? forge.pki.certificateToPem(cert) : '';
70
+ const keyBagOid = forge.pki.oids.pkcs8ShroudedKeyBag;
71
+ const keyBags = p12.getBags({ bagType: keyBagOid })[keyBagOid] ?? [];
72
+ const key = keyBags[0]?.key;
73
+ const privateKeyPem = key ? forge.pki.privateKeyToPem(key) : '';
74
+ if (!privateKeyPem || !certPem || !cert) {
75
+ throw new Error('Não foi possível extrair a chave privada ou o certificado do PFX.');
76
+ }
77
+ this.cacheExtraido = {
78
+ privateKey: privateKeyPem,
79
+ certificate: certPem,
80
+ leafCert: cert,
81
+ };
82
+ return this.cacheExtraido;
83
+ }
84
+ getLeafCert(certBags) {
85
+ for (const bag of certBags) {
86
+ if (!bag.cert)
87
+ continue;
88
+ const isCa = bag.cert.extensions?.some((ext) => ext.name === 'basicConstraints' && ext.cA === true);
89
+ if (!isCa) {
90
+ return bag.cert;
91
+ }
92
+ }
93
+ return certBags[0]?.cert;
94
+ }
95
+ getAttrValue(attributes, shortName) {
96
+ const field = attributes.find((attr) => attr.shortName === shortName);
97
+ return typeof field?.value === 'string' ? field.value : '';
98
+ }
99
+ }
100
+ //# sourceMappingURL=Certificado.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Certificado.js","sourceRoot":"","sources":["../src/Certificado.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare class Danfe {
2
+ static fromXml(xmlNFe: string, xmlRetornoSefaz?: string): Buffer;
3
+ private static getDescricaoFrete;
4
+ private static getDescricaoPagamento;
5
+ private static formatDecimal;
6
+ private static getTag;
7
+ private static formatDoc;
8
+ private static formatDateTime;
9
+ private static drawSectionHeader;
10
+ private static drawBox;
11
+ private static drawText;
12
+ private static escapePdfText;
13
+ private static drawCode128C;
14
+ private static buildPdfBuffer;
15
+ }
16
+ //# sourceMappingURL=Danfe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Danfe.d.ts","sourceRoot":"","sources":["../src/Danfe.ts"],"names":[],"mappings":"AAwDA,qBAAa,KAAK;IAChB,OAAc,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CA4OtE;IAED,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAYhC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAcpC,OAAO,CAAC,MAAM,CAAC,aAAa;IAM5B,OAAO,CAAC,MAAM,CAAC,MAAM;IAYrB,OAAO,CAAC,MAAM,CAAC,SAAS;IAWxB,OAAO,CAAC,MAAM,CAAC,cAAc;IAO7B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAIhC,OAAO,CAAC,MAAM,CAAC,OAAO;IAoBtB,OAAO,CAAC,MAAM,CAAC,QAAQ;IAMvB,OAAO,CAAC,MAAM,CAAC,aAAa;IAS5B,OAAO,CAAC,MAAM,CAAC,YAAY;IAgC3B,OAAO,CAAC,MAAM,CAAC,cAAc;CA6B9B"}