@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.
Files changed (90) hide show
  1. package/README.md +55 -50
  2. package/dist/build/build.d.ts +23 -23
  3. package/dist/build/build.d.ts.map +1 -1
  4. package/dist/build/destinatario.d.ts +2 -2
  5. package/dist/build/ibscbs.d.ts.map +1 -1
  6. package/dist/build/nfce.d.ts +5 -5
  7. package/dist/build/nfce.d.ts.map +1 -1
  8. package/dist/build/pl.d.ts +4 -4
  9. package/dist/build/pl.d.ts.map +1 -1
  10. package/dist/build/rejeicoes.d.ts +7 -7
  11. package/dist/build/rejeicoes.d.ts.map +1 -1
  12. package/dist/build/textos.d.ts +26 -0
  13. package/dist/build/textos.d.ts.map +1 -0
  14. package/dist/build/values.d.ts +8 -8
  15. package/dist/build/values.d.ts.map +1 -1
  16. package/dist/decimal.d.ts +2 -2
  17. package/dist/decimal.d.ts.map +1 -1
  18. package/dist/format.d.ts +19 -19
  19. package/dist/format.d.ts.map +1 -1
  20. package/dist/ibs-cbs.d.ts +10 -5
  21. package/dist/ibs-cbs.d.ts.map +1 -1
  22. package/dist/ibs-cbs.js +35 -35
  23. package/dist/ibs-cbs.js.map +3 -3
  24. package/dist/index.d.ts +18 -18
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +796 -588
  27. package/dist/index.js.map +27 -26
  28. package/dist/issues.d.ts +10 -10
  29. package/dist/issues.d.ts.map +1 -1
  30. package/dist/model.d.ts +4 -4
  31. package/dist/ports.d.ts +15 -15
  32. package/dist/ports.d.ts.map +1 -1
  33. package/dist/rotulo.d.ts +2 -2
  34. package/dist/rotulo.d.ts.map +1 -1
  35. package/dist/rtc.d.ts +23 -23
  36. package/dist/rtc.d.ts.map +1 -1
  37. package/dist/services/client.d.ts +44 -40
  38. package/dist/services/client.d.ts.map +1 -1
  39. package/dist/services/gzip.d.ts +1 -1
  40. package/dist/services/gzip.d.ts.map +1 -1
  41. package/dist/services/index.d.ts +4 -4
  42. package/dist/services/index.d.ts.map +1 -1
  43. package/dist/services/outcome.d.ts +3 -3
  44. package/dist/services/outcome.d.ts.map +1 -1
  45. package/dist/services/proc.d.ts +6 -6
  46. package/dist/services/proc.d.ts.map +1 -1
  47. package/dist/services/recuperar.d.ts +8 -7
  48. package/dist/services/recuperar.d.ts.map +1 -1
  49. package/dist/services/resolver.d.ts +12 -11
  50. package/dist/services/resolver.d.ts.map +1 -1
  51. package/dist/services/soap.d.ts +8 -8
  52. package/dist/services/soap.d.ts.map +1 -1
  53. package/dist/time.d.ts +4 -4
  54. package/dist/time.d.ts.map +1 -1
  55. package/dist/versao-gerada.d.ts +1 -1
  56. package/package.json +9 -9
  57. package/src/build/build.ts +213 -203
  58. package/src/build/destinatario.ts +8 -8
  59. package/src/build/ibscbs.ts +10 -6
  60. package/src/build/icms.ts +6 -6
  61. package/src/build/nfce.ts +19 -19
  62. package/src/build/pl.ts +12 -12
  63. package/src/build/rejeicoes.ts +13 -13
  64. package/src/build/textos.ts +228 -0
  65. package/src/build/values.ts +14 -14
  66. package/src/data/arredondamento.json +1 -1
  67. package/src/data/cstat.json +6 -6
  68. package/src/data/fusos.json +1 -1
  69. package/src/data/nfce-urls.json +2 -2
  70. package/src/data/produtor-rural.json +1 -1
  71. package/src/data/resp-tec.json +1 -1
  72. package/src/decimal.ts +10 -9
  73. package/src/format.ts +29 -28
  74. package/src/ibs-cbs.ts +79 -74
  75. package/src/index.ts +29 -27
  76. package/src/issues.ts +11 -11
  77. package/src/model.ts +4 -4
  78. package/src/ports.ts +15 -15
  79. package/src/rotulo.ts +4 -4
  80. package/src/rtc.ts +91 -91
  81. package/src/services/client.ts +248 -217
  82. package/src/services/gzip.ts +7 -7
  83. package/src/services/index.ts +12 -10
  84. package/src/services/outcome.ts +9 -9
  85. package/src/services/proc.ts +50 -49
  86. package/src/services/recuperar.ts +29 -25
  87. package/src/services/resolver.ts +25 -23
  88. package/src/services/soap.ts +35 -35
  89. package/src/time.ts +6 -6
  90. package/src/versao-gerada.ts +1 -1
@@ -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 `Transport` injetado e devolve o elemento de retorno como fatia da resposta, com a árvore para leitura.
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 { ProtocolError } from '@sinete/core';
8
- import type { XmlDocument, XmlElement } from '@sinete/core/xml';
9
- import { childElements, descendants, parseXml } from '@sinete/core/xml';
10
- import type { EndpointRef, NfeServico, Transport } from '@sinete/transport';
11
- import { soap12ContentType, soap12Envelope, soapFault } from '@sinete/transport';
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 ProtocolError(`serviço sem descrição em data/servicos.json: ${servico}`);
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: XmlDocument;
48
- readonly ret: XmlElement;
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: Transport;
54
- readonly endpoint: EndpointRef;
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 `ProtocolError`. */
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.send({
68
+ const res = await c.transport.enviar({
69
69
  url: c.endpoint.url,
70
70
  endpoint: c.endpoint,
71
- method: 'POST',
72
- headers: { 'content-type': soap12ContentType(`${s.namespace}/${s.operacao}`) },
73
- body: soap12Envelope(soapBodyFor(c.servico, c.mensagem, c.endpoint.autorizador)),
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.text();
78
- const fault = soapFault(text);
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 ProtocolError(`SOAP fault de ${c.endpoint.host}: ${fault.reason ?? fault.code ?? 'sem motivo'}`, {
82
- details: { status: res.status, code: fault.code, reason: fault.reason, servico: c.servico },
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: XmlDocument;
85
+ let doc: DocumentoXml;
86
86
  try {
87
- doc = parseXml(text.replace(/^/, ''));
87
+ doc = lerXml(text.replace(/^/, ''));
88
88
  } catch (cause) {
89
- throw new ProtocolError(`resposta de ${c.endpoint.host} não é XML (HTTP ${res.status})`, {
89
+ throw new ErroRespostaInvalida(`resposta de ${c.endpoint.host} não é XML (HTTP ${res.status})`, {
90
90
  cause,
91
- details: { status: res.status, servico: c.servico },
91
+ detalhes: { status: res.status, servico: c.servico },
92
92
  });
93
93
  }
94
- let ret: XmlElement | undefined;
95
- for (const el of descendants(doc.root)) {
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.root, c.retorno);
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 ProtocolError(`resposta de ${c.endpoint.host} sem <${c.retorno}> (HTTP ${res.status})`, {
109
- details: { status: res.status, servico: c.servico },
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(descendants(ret)).some((el) => el.local === 'cStat' && el.ns === NFE_NS)) {
113
- throw new ProtocolError(`<${c.retorno}> de ${c.endpoint.host} sem cStat (HTTP ${res.status})`, {
114
- details: { status: res.status, servico: c.servico },
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: XmlElement, retorno: string): XmlElement | undefined {
127
- for (const el of descendants(root)) {
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 = childElements(el);
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 { Clock, Uf } from '@sinete/core';
7
- import { formatDateTimeOffset } from '@sinete/core';
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<Clock['now']>;
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 offsetDaUf(uf: Uf): number {
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 formatDh(date: Instante, offsetMinutes: number): string {
22
- return formatDateTimeOffset(date, offsetMinutes);
21
+ export function formatarDh(data: Instante, deslocamentoMin: number): string {
22
+ return formatarDataHoraComFuso(data, deslocamentoMin);
23
23
  }
@@ -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.1.0';
3
+ export const VERSAO_PACOTE = '0.3.0';