@sinete/nfe 0.1.0 → 0.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 +55 -50
- package/dist/build/build.d.ts +23 -23
- package/dist/build/build.d.ts.map +1 -1
- package/dist/build/destinatario.d.ts +2 -2
- package/dist/build/ibscbs.d.ts.map +1 -1
- package/dist/build/nfce.d.ts +5 -5
- package/dist/build/nfce.d.ts.map +1 -1
- package/dist/build/pl.d.ts +4 -4
- package/dist/build/pl.d.ts.map +1 -1
- package/dist/build/rejeicoes.d.ts +7 -7
- package/dist/build/rejeicoes.d.ts.map +1 -1
- package/dist/build/textos.d.ts +26 -0
- package/dist/build/textos.d.ts.map +1 -0
- package/dist/build/values.d.ts +8 -8
- package/dist/build/values.d.ts.map +1 -1
- package/dist/decimal.d.ts +2 -2
- package/dist/decimal.d.ts.map +1 -1
- package/dist/format.d.ts +19 -19
- package/dist/format.d.ts.map +1 -1
- package/dist/ibs-cbs.d.ts +10 -5
- package/dist/ibs-cbs.d.ts.map +1 -1
- package/dist/ibs-cbs.js +35 -35
- package/dist/ibs-cbs.js.map +3 -3
- package/dist/index.d.ts +18 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +796 -588
- package/dist/index.js.map +27 -26
- package/dist/issues.d.ts +10 -10
- package/dist/issues.d.ts.map +1 -1
- package/dist/model.d.ts +4 -4
- package/dist/ports.d.ts +15 -15
- package/dist/ports.d.ts.map +1 -1
- package/dist/rotulo.d.ts +2 -2
- package/dist/rotulo.d.ts.map +1 -1
- package/dist/rtc.d.ts +23 -23
- package/dist/rtc.d.ts.map +1 -1
- package/dist/services/client.d.ts +44 -40
- package/dist/services/client.d.ts.map +1 -1
- package/dist/services/gzip.d.ts +1 -1
- package/dist/services/gzip.d.ts.map +1 -1
- package/dist/services/index.d.ts +4 -4
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/outcome.d.ts +3 -3
- package/dist/services/outcome.d.ts.map +1 -1
- package/dist/services/proc.d.ts +6 -6
- package/dist/services/proc.d.ts.map +1 -1
- package/dist/services/recuperar.d.ts +8 -7
- package/dist/services/recuperar.d.ts.map +1 -1
- package/dist/services/resolver.d.ts +12 -11
- package/dist/services/resolver.d.ts.map +1 -1
- package/dist/services/soap.d.ts +8 -8
- package/dist/services/soap.d.ts.map +1 -1
- package/dist/time.d.ts +4 -4
- package/dist/time.d.ts.map +1 -1
- package/dist/versao-gerada.d.ts +1 -1
- package/package.json +9 -9
- package/src/build/build.ts +213 -203
- package/src/build/destinatario.ts +8 -8
- package/src/build/ibscbs.ts +10 -6
- package/src/build/icms.ts +6 -6
- package/src/build/nfce.ts +19 -19
- package/src/build/pl.ts +12 -12
- package/src/build/rejeicoes.ts +13 -13
- package/src/build/textos.ts +228 -0
- package/src/build/values.ts +14 -14
- package/src/data/arredondamento.json +1 -1
- package/src/data/cstat.json +6 -6
- package/src/data/fusos.json +1 -1
- package/src/data/nfce-urls.json +2 -2
- package/src/data/produtor-rural.json +1 -1
- package/src/data/resp-tec.json +1 -1
- package/src/decimal.ts +10 -9
- package/src/format.ts +29 -28
- package/src/ibs-cbs.ts +79 -74
- package/src/index.ts +29 -27
- package/src/issues.ts +11 -11
- package/src/model.ts +4 -4
- package/src/ports.ts +15 -15
- package/src/rotulo.ts +4 -4
- package/src/rtc.ts +91 -91
- package/src/services/client.ts +248 -217
- package/src/services/gzip.ts +7 -7
- package/src/services/index.ts +12 -10
- package/src/services/outcome.ts +9 -9
- package/src/services/proc.ts +50 -49
- package/src/services/recuperar.ts +29 -25
- package/src/services/resolver.ts +25 -23
- package/src/services/soap.ts +35 -35
- package/src/time.ts +6 -6
- package/src/versao-gerada.ts +1 -1
package/src/services/soap.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Chamada SOAP 1.2 a um web service da NF-e 4.00: monta o corpo com o namespace do WSDL (dado em `data/servicos.json`),
|
|
3
|
-
* envia pelo `
|
|
3
|
+
* envia pelo `Transporte` injetado e devolve o elemento de retorno como fatia da resposta, com a árvore para leitura.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Logger } from '@sinete/core';
|
|
7
|
-
import {
|
|
8
|
-
import type {
|
|
9
|
-
import {
|
|
10
|
-
import type {
|
|
11
|
-
import {
|
|
7
|
+
import { ErroRespostaInvalida } from '@sinete/core';
|
|
8
|
+
import type { DocumentoXml, ElementoXml } from '@sinete/core/xml';
|
|
9
|
+
import { descendentes, elementosFilhos, lerXml } from '@sinete/core/xml';
|
|
10
|
+
import type { EndpointResolvido, NfeServico, Transporte } from '@sinete/transport';
|
|
11
|
+
import { contentTypeSoap12, envelopeSoap12, lerSoapFault } from '@sinete/transport';
|
|
12
12
|
import servicos from '../data/servicos.json' with { type: 'json' };
|
|
13
13
|
import { NFE_NS } from './proc.ts';
|
|
14
14
|
|
|
@@ -29,7 +29,7 @@ const SERVICOS: Readonly<Record<string, ServicoInfo>> = servicos.servicos;
|
|
|
29
29
|
/** Namespace do WSDL e operação do serviço. */
|
|
30
30
|
export function servicoInfo(servico: NfeServico): ServicoInfo {
|
|
31
31
|
const s = SERVICOS[servico];
|
|
32
|
-
if (!s) throw new
|
|
32
|
+
if (!s) throw new ErroRespostaInvalida(`serviço sem descrição em data/servicos.json: ${servico}`);
|
|
33
33
|
return s;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -44,14 +44,14 @@ export function soapBodyFor(servico: NfeServico, mensagem: string, autorizador?:
|
|
|
44
44
|
|
|
45
45
|
/** Resposta de um serviço: o documento inteiro (para fatiar) e o elemento de retorno. */
|
|
46
46
|
export interface RespostaSoap {
|
|
47
|
-
readonly doc:
|
|
48
|
-
readonly ret:
|
|
47
|
+
readonly doc: DocumentoXml;
|
|
48
|
+
readonly ret: ElementoXml;
|
|
49
49
|
readonly status: number;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export interface ChamadaSoap {
|
|
53
|
-
readonly transport:
|
|
54
|
-
readonly endpoint:
|
|
53
|
+
readonly transport: Transporte;
|
|
54
|
+
readonly endpoint: EndpointResolvido;
|
|
55
55
|
readonly servico: NfeServico;
|
|
56
56
|
readonly mensagem: string;
|
|
57
57
|
/** Nome local do elemento de retorno (`retEnviNFe`, `retConsSitNFe`...). */
|
|
@@ -61,57 +61,57 @@ export interface ChamadaSoap {
|
|
|
61
61
|
readonly logger: Logger;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
/** Envia e devolve o elemento de retorno. Fault SOAP, retorno ausente ou XML malformado viram `
|
|
64
|
+
/** Envia e devolve o elemento de retorno. Fault SOAP, retorno ausente ou XML malformado viram `ErroRespostaInvalida`. */
|
|
65
65
|
export async function chamar(c: ChamadaSoap): Promise<RespostaSoap> {
|
|
66
66
|
const s = servicoInfo(c.servico);
|
|
67
67
|
const started = { servico: c.servico, autorizador: c.endpoint.autorizador, host: c.endpoint.host };
|
|
68
|
-
const res = await c.transport.
|
|
68
|
+
const res = await c.transport.enviar({
|
|
69
69
|
url: c.endpoint.url,
|
|
70
70
|
endpoint: c.endpoint,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
metodo: 'POST',
|
|
72
|
+
cabecalhos: { 'content-type': contentTypeSoap12(`${s.namespace}/${s.operacao}`) },
|
|
73
|
+
corpo: envelopeSoap12(soapBodyFor(c.servico, c.mensagem, c.endpoint.autorizador)),
|
|
74
74
|
...(c.timeoutMs === undefined ? {} : { timeoutMs: c.timeoutMs }),
|
|
75
75
|
...(c.signal === undefined ? {} : { signal: c.signal }),
|
|
76
76
|
});
|
|
77
|
-
const text = res.
|
|
78
|
-
const fault =
|
|
77
|
+
const text = res.texto();
|
|
78
|
+
const fault = lerSoapFault(text);
|
|
79
79
|
if (fault) {
|
|
80
80
|
c.logger.warn('nfe.soap.fault', { ...started, status: res.status, code: fault.code });
|
|
81
|
-
throw new
|
|
82
|
-
|
|
81
|
+
throw new ErroRespostaInvalida(`SOAP fault de ${c.endpoint.host}: ${fault.reason ?? fault.code ?? 'sem motivo'}`, {
|
|
82
|
+
detalhes: { status: res.status, code: fault.code, reason: fault.reason, servico: c.servico },
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
-
let doc:
|
|
85
|
+
let doc: DocumentoXml;
|
|
86
86
|
try {
|
|
87
|
-
doc =
|
|
87
|
+
doc = lerXml(text.replace(/^/, ''));
|
|
88
88
|
} catch (cause) {
|
|
89
|
-
throw new
|
|
89
|
+
throw new ErroRespostaInvalida(`resposta de ${c.endpoint.host} não é XML (HTTP ${res.status})`, {
|
|
90
90
|
cause,
|
|
91
|
-
|
|
91
|
+
detalhes: { status: res.status, servico: c.servico },
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
-
let ret:
|
|
95
|
-
for (const el of
|
|
94
|
+
let ret: ElementoXml | undefined;
|
|
95
|
+
for (const el of descendentes(doc.raiz)) {
|
|
96
96
|
if (el.local === c.retorno && el.ns === NFE_NS) {
|
|
97
97
|
ret = el;
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
if (!ret) ret = retornoForaDoNamespace(doc.
|
|
101
|
+
if (!ret) ret = retornoForaDoNamespace(doc.raiz, c.retorno);
|
|
102
102
|
if (ret && ret.ns !== NFE_NS) {
|
|
103
103
|
// A SEFAZ-MG devolve o <retConsCad> sem o namespace da NF-e: ele herda o default do WSDL do nfeResultMsg, e só
|
|
104
104
|
// os filhos declaram o da NF-e (visto em homologação e em produção em 28/09/2026). O conteúdo é o do leiaute.
|
|
105
105
|
c.logger.warn('nfe.soap.retorno_fora_do_namespace', { ...started, retorno: c.retorno, ns: ret.ns });
|
|
106
106
|
}
|
|
107
107
|
if (!ret) {
|
|
108
|
-
throw new
|
|
109
|
-
|
|
108
|
+
throw new ErroRespostaInvalida(`resposta de ${c.endpoint.host} sem <${c.retorno}> (HTTP ${res.status})`, {
|
|
109
|
+
detalhes: { status: res.status, servico: c.servico },
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
-
if (!Array.from(
|
|
113
|
-
throw new
|
|
114
|
-
|
|
112
|
+
if (!Array.from(descendentes(ret)).some((el) => el.local === 'cStat' && el.ns === NFE_NS)) {
|
|
113
|
+
throw new ErroRespostaInvalida(`<${c.retorno}> de ${c.endpoint.host} sem cStat (HTTP ${res.status})`, {
|
|
114
|
+
detalhes: { status: res.status, servico: c.servico },
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
c.logger.debug('nfe.soap.resposta', { ...started, status: res.status });
|
|
@@ -123,10 +123,10 @@ export async function chamar(c: ChamadaSoap): Promise<RespostaSoap> {
|
|
|
123
123
|
* NF-e: é o caso do autorizador que esquece o `xmlns` no elemento de retorno e o declara nos filhos. Com os filhos
|
|
124
124
|
* fora do namespace, a resposta continua recusada.
|
|
125
125
|
*/
|
|
126
|
-
function retornoForaDoNamespace(root:
|
|
127
|
-
for (const el of
|
|
126
|
+
function retornoForaDoNamespace(root: ElementoXml, retorno: string): ElementoXml | undefined {
|
|
127
|
+
for (const el of descendentes(root)) {
|
|
128
128
|
if (el.local !== retorno) continue;
|
|
129
|
-
const filhos =
|
|
129
|
+
const filhos = elementosFilhos(el);
|
|
130
130
|
if (filhos.length > 0 && filhos.every((f) => f.ns === NFE_NS)) return el;
|
|
131
131
|
}
|
|
132
132
|
return undefined;
|
package/src/time.ts
CHANGED
|
@@ -3,21 +3,21 @@
|
|
|
3
3
|
* tabela `data/fusos.json` pela UF, ou do chamador; nunca do fuso da máquina.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
import {
|
|
6
|
+
import type { Relogio, Uf } from '@sinete/core';
|
|
7
|
+
import { formatarDataHoraComFuso } from '@sinete/core';
|
|
8
8
|
import fusos from './data/fusos.json' with { type: 'json' };
|
|
9
9
|
|
|
10
10
|
/** Instante no tempo, como os relógios do `@sinete/core` o devolvem (o tipo `Date`, sem tocar no global). */
|
|
11
|
-
export type Instante = ReturnType<
|
|
11
|
+
export type Instante = ReturnType<Relogio['agora']>;
|
|
12
12
|
|
|
13
13
|
const UF_OFFSETS: Readonly<Record<string, number>> = fusos.ufs;
|
|
14
14
|
|
|
15
15
|
/** Deslocamento do horário legal da UF em minutos (`-180` para Brasília). */
|
|
16
|
-
export function
|
|
16
|
+
export function deslocamentoDaUf(uf: Uf): number {
|
|
17
17
|
return Object.hasOwn(UF_OFFSETS, uf) ? (UF_OFFSETS[uf] as number) : fusos.padrao;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/** `TDateTimeUTC` do instante no deslocamento dado. */
|
|
21
|
-
export function
|
|
22
|
-
return
|
|
21
|
+
export function formatarDh(data: Instante, deslocamentoMin: number): string {
|
|
22
|
+
return formatarDataHoraComFuso(data, deslocamentoMin);
|
|
23
23
|
}
|
package/src/versao-gerada.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// GERADO por scripts/versao-gerada.ts a partir do package.json. Não edite: rode `bun scripts/versao-gerada.ts`.
|
|
2
2
|
/** Versão de `@sinete/nfe`, para o padrão de `verProc`/`verAplic` (`formatarVerProc` do @sinete/core). */
|
|
3
|
-
export const VERSAO_PACOTE = '0.
|
|
3
|
+
export const VERSAO_PACOTE = '0.3.0';
|