@sinete/nfe 0.1.0 → 0.2.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 (87) hide show
  1. package/README.md +49 -48
  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/values.d.ts +8 -8
  13. package/dist/build/values.d.ts.map +1 -1
  14. package/dist/decimal.d.ts +2 -2
  15. package/dist/decimal.d.ts.map +1 -1
  16. package/dist/format.d.ts +19 -19
  17. package/dist/format.d.ts.map +1 -1
  18. package/dist/ibs-cbs.d.ts +5 -5
  19. package/dist/ibs-cbs.d.ts.map +1 -1
  20. package/dist/ibs-cbs.js +35 -35
  21. package/dist/ibs-cbs.js.map +2 -2
  22. package/dist/index.d.ts +18 -18
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +602 -573
  25. package/dist/index.js.map +25 -25
  26. package/dist/issues.d.ts +10 -10
  27. package/dist/issues.d.ts.map +1 -1
  28. package/dist/model.d.ts +4 -4
  29. package/dist/ports.d.ts +15 -15
  30. package/dist/ports.d.ts.map +1 -1
  31. package/dist/rotulo.d.ts +2 -2
  32. package/dist/rotulo.d.ts.map +1 -1
  33. package/dist/rtc.d.ts +23 -23
  34. package/dist/rtc.d.ts.map +1 -1
  35. package/dist/services/client.d.ts +44 -40
  36. package/dist/services/client.d.ts.map +1 -1
  37. package/dist/services/gzip.d.ts +1 -1
  38. package/dist/services/gzip.d.ts.map +1 -1
  39. package/dist/services/index.d.ts +4 -4
  40. package/dist/services/index.d.ts.map +1 -1
  41. package/dist/services/outcome.d.ts +3 -3
  42. package/dist/services/outcome.d.ts.map +1 -1
  43. package/dist/services/proc.d.ts +6 -6
  44. package/dist/services/proc.d.ts.map +1 -1
  45. package/dist/services/recuperar.d.ts +7 -7
  46. package/dist/services/recuperar.d.ts.map +1 -1
  47. package/dist/services/resolver.d.ts +10 -10
  48. package/dist/services/resolver.d.ts.map +1 -1
  49. package/dist/services/soap.d.ts +8 -8
  50. package/dist/services/soap.d.ts.map +1 -1
  51. package/dist/time.d.ts +4 -4
  52. package/dist/time.d.ts.map +1 -1
  53. package/dist/versao-gerada.d.ts +1 -1
  54. package/package.json +9 -9
  55. package/src/build/build.ts +202 -185
  56. package/src/build/destinatario.ts +8 -8
  57. package/src/build/ibscbs.ts +10 -6
  58. package/src/build/icms.ts +6 -6
  59. package/src/build/nfce.ts +19 -19
  60. package/src/build/pl.ts +12 -12
  61. package/src/build/rejeicoes.ts +13 -13
  62. package/src/build/values.ts +14 -14
  63. package/src/data/arredondamento.json +1 -1
  64. package/src/data/cstat.json +6 -6
  65. package/src/data/fusos.json +1 -1
  66. package/src/data/nfce-urls.json +2 -2
  67. package/src/data/produtor-rural.json +1 -1
  68. package/src/data/resp-tec.json +1 -1
  69. package/src/decimal.ts +10 -9
  70. package/src/format.ts +29 -28
  71. package/src/ibs-cbs.ts +74 -74
  72. package/src/index.ts +29 -27
  73. package/src/issues.ts +11 -11
  74. package/src/model.ts +4 -4
  75. package/src/ports.ts +15 -15
  76. package/src/rotulo.ts +4 -4
  77. package/src/rtc.ts +91 -91
  78. package/src/services/client.ts +248 -217
  79. package/src/services/gzip.ts +7 -7
  80. package/src/services/index.ts +12 -10
  81. package/src/services/outcome.ts +9 -9
  82. package/src/services/proc.ts +50 -49
  83. package/src/services/recuperar.ts +27 -25
  84. package/src/services/resolver.ts +22 -22
  85. package/src/services/soap.ts +35 -35
  86. package/src/time.ts +6 -6
  87. package/src/versao-gerada.ts +1 -1
@@ -4,7 +4,7 @@
4
4
  * cancelamento por substituição, CC-e, manifestação do destinatário no AN), inutilização, consulta cadastro e
5
5
  * Distribuição DF-e. Contingência SVC por dado: o autorizador SVC-AN ou SVC-RS de cada UF vem do `@sinete/transport`.
6
6
  *
7
- * Todo desfecho que chega a uma resposta da SEFAZ é um `SefazOutcome` do core (autorizado, rejeitado, denegado,
7
+ * Todo desfecho que chega a uma resposta da SEFAZ é um `ResultadoSefaz` do core (autorizado, rejeitado, denegado,
8
8
  * pendente), com a dica do `@sinete/rejeicoes` na rejeição. Os documentos processados (`nfeProc`, `procEventoNFe`,
9
9
  * `ProcInutNFe`) são montados por splice: o XML assinado entra byte a byte, o protocolo entra como fatia da resposta.
10
10
  *
@@ -13,23 +13,23 @@
13
13
  * número. Consulte a chave (`resolverEnvioSemResposta`) e, se ela não constar, reenvie exatamente os mesmos bytes.
14
14
  */
15
15
 
16
- import type { Ambiente, Clock, CUf, Logger, SefazOutcome, Signer, Uf } from '@sinete/core';
16
+ import type { Ambiente, Assinador, CUf, Logger, Relogio, ResultadoSefaz, Uf } from '@sinete/core';
17
17
  import {
18
- authorized,
19
- ConfigError,
20
- denied,
21
- noopLogger,
22
- ProtocolError,
23
- pending,
24
- tpAmbOf,
25
- ufByCUf,
26
- ufBySigla,
27
- ValidationError,
18
+ criarAutorizado,
19
+ criarDenegado,
20
+ criarPendente,
21
+ ErroDeConfiguracao,
22
+ ErroDeValidacao,
23
+ ErroRespostaInvalida,
24
+ loggerSilencioso,
25
+ tpAmbDoAmbiente,
26
+ ufPorCUf,
27
+ ufPorSigla,
28
28
  } from '@sinete/core';
29
- import type { XmlDocument, XmlElement } from '@sinete/core/xml';
30
- import { childElements, firstChild, parseXml, signXml, textOf } from '@sinete/core/xml';
31
- import type { ComplexType, SchemaIssue } from '@sinete/schemas';
32
- import { decode, decodeXml, serialize, serializeRoot, validate } from '@sinete/schemas';
29
+ import type { DocumentoXml, ElementoXml } from '@sinete/core/xml';
30
+ import { assinarXml, elementosFilhos, lerXml, primeiroFilho, textoDe } from '@sinete/core/xml';
31
+ import type { ComplexType, OcorrenciaSchema } from '@sinete/schemas';
32
+ import { decodificar, decodificarXml, serializar, serializarRaiz, validar } from '@sinete/schemas';
33
33
  import type { TRetConsCad_infCons_infCad } from '@sinete/schemas/nfe/consulta-cadastro/PL_010d';
34
34
  import { ConsCadElement, TRetConsCad } from '@sinete/schemas/nfe/consulta-cadastro/PL_010d';
35
35
  import { consSitNFeElement, TProtNFe, TRetConsSitNFe } from '@sinete/schemas/nfe/consulta-protocolo/PL_010d';
@@ -52,15 +52,15 @@ import { TEvento_infEvento as TEventoNaoRealizada } from '@sinete/schemas/nfe/ev
52
52
  import { TInutNFe_infInut, TRetInutNFe } from '@sinete/schemas/nfe/inutilizacao/PL_010d';
53
53
  import { TRetConsReciNFe, TRetEnviNFe } from '@sinete/schemas/nfe/PL_010f';
54
54
  import { consStatServElement, TRetConsStatServ } from '@sinete/schemas/nfe/status-servico/PL_009q';
55
- import type { EndpointRef, NfeServico, Transport } from '@sinete/transport';
55
+ import type { EndpointResolvido, NfeServico, Transporte } from '@sinete/transport';
56
56
  import { nfceEndpoint, nfeContingenciaDaUf, nfeEndpoint } from '@sinete/transport';
57
57
  import type { ChaveAcesso } from '@sinete/validators';
58
- import { parseChaveAcesso, parseCnpj, parseCpf } from '@sinete/validators';
59
- import { formatDh, offsetDaUf } from '../time.ts';
60
- import { gunzipBase64 } from './gzip.ts';
58
+ import { lerChaveAcesso, lerCnpj, lerCpf } from '@sinete/validators';
59
+ import { deslocamentoDaUf, formatarDh } from '../time.ts';
60
+ import { descomprimirGzipBase64 } from './gzip.ts';
61
61
  import { cstatEm, rejeitado } from './outcome.ts';
62
62
  import type { DocumentoAssinado } from './proc.ts';
63
- import { documentoAssinado, envelope, NFE_NS, sliceElement } from './proc.ts';
63
+ import { documentoAssinado, envelope, NFE_NS, recortarElemento } from './proc.ts';
64
64
  import type { RespostaSoap } from './soap.ts';
65
65
  import { chamar } from './soap.ts';
66
66
 
@@ -74,27 +74,27 @@ export type AutorDocumento =
74
74
  | { readonly CPF: string; readonly CNPJ?: never };
75
75
 
76
76
  /** Espera injetável (testes passam uma que não dorme). */
77
- export type Sleep = (ms: number, signal?: AbortSignal) => Promise<void>;
77
+ export type Espera = (ms: number, signal?: AbortSignal) => Promise<void>;
78
78
 
79
- export interface NfeClientOptions {
80
- readonly transport: Transport;
79
+ export interface ClienteNfeOpcoes {
80
+ readonly transporte: Transporte;
81
81
  /** Assina NF-e, eventos e inutilização (A1 WebCrypto, A3 via PKCS#11, HSM). */
82
- readonly signer: Signer;
82
+ readonly assinador: Assinador;
83
83
  readonly ambiente: Ambiente;
84
84
  /**
85
85
  * UF dos serviços que não partem de um documento: status do serviço, inutilização, recibo consultado sem a NF-e,
86
86
  * `cUFAutor` padrão da distribuição e fuso da manifestação. Autorização, consulta, recibo com a NF-e e eventos da
87
87
  * própria nota vão ao autorizador da chave (cUF e tpEmis), seja qual for esta UF; sem ela, os serviços que precisam
88
- * dela lançam `ConfigError`.
88
+ * dela lançam `ErroDeConfiguracao`.
89
89
  */
90
90
  readonly uf?: Uf;
91
91
  /** Relógio de emissão: `dhEvento`, número do lote. */
92
- readonly clock: Clock;
92
+ readonly relogio: Relogio;
93
93
  readonly logger?: Logger;
94
94
  /** Prazo por requisição; padrão o do transporte. */
95
95
  readonly timeoutMs?: number;
96
96
  /** Fuso do emitente em minutos; padrão o da UF da chave nos eventos e o de `uf` na manifestação (`data/fusos.json`). */
97
- readonly offsetMinutes?: number;
97
+ readonly deslocamentoMin?: number;
98
98
  /**
99
99
  * `svc`: o status do serviço e o recibo consultado sem a NF-e vão ao SVC-AN ou SVC-RS de `uf`. Não vale para o que
100
100
  * parte de um documento: a NF-e assinada em SVC (tpEmis 6 ou 7, na chave) vai ao SVC que a chave diz, e a assinada
@@ -103,21 +103,25 @@ export interface NfeClientOptions {
103
103
  readonly contingencia?: 'svc';
104
104
  /** CNPJ ou CPF do titular do certificado: autor da manifestação, interessado da distribuição, emitente da inutilização. */
105
105
  readonly autor?: AutorDocumento;
106
- readonly sleep?: Sleep;
106
+ readonly esperar?: Espera;
107
107
  /**
108
108
  * Sobrepõe o endpoint da NFC-e (modelo 65) por serviço e UF. Sem ela, vale a tabela da NFC-e do `@sinete/transport`
109
109
  * (`nfceEndpoint`), que em várias UFs (SP, MG, PR, RS, SVRS) é outro host que o da NF-e. A NFC-e não tem SVC: com
110
110
  * `contingencia: 'svc'`, o documento modelo 65 continua indo ao autorizador normal da NFC-e.
111
111
  */
112
- readonly nfceEndpoint?: (servico: NfeServico, uf: Uf) => EndpointRef;
112
+ readonly endpointNfce?: (servico: NfeServico, uf: Uf) => EndpointResolvido;
113
113
  /** Gerador de `idLote` (até 15 dígitos); padrão: os milissegundos do relógio. */
114
114
  readonly idLote?: () => string;
115
115
  }
116
116
 
117
- /** Opções da consulta de um recibo. */
118
- export interface ConsultaReciboOpcoes {
117
+ /** Opções de toda chamada que vai à rede. */
118
+ export interface EnvioOpcoes {
119
119
  /** Cancela a requisição em curso. */
120
120
  readonly signal?: AbortSignal;
121
+ }
122
+
123
+ /** Opções da consulta de um recibo. */
124
+ export interface ConsultaReciboOpcoes extends EnvioOpcoes {
121
125
  /**
122
126
  * Modelo do lote, para escolher o serviço (NFC-e vai pelo `nfceEndpoint`). Com a NF-e assinada o modelo vem da
123
127
  * chave e este campo, se vier, tem de bater; sem ela, é obrigatório para NFC-e e o padrão é 55.
@@ -170,8 +174,8 @@ export interface ProtocoloNfe {
170
174
  readonly nfeProc?: string;
171
175
  }
172
176
 
173
- /** Desfecho da autorização: autorizada, denegada (número consumido), rejeitada ou pendente (recibo em `ref`). */
174
- export type AutorizacaoOutcome = SefazOutcome<ProtocoloNfe, ProtocoloNfe>;
177
+ /** Desfecho da autorização: autorizada, denegada (número consumido), rejeitada ou pendente (recibo em `referencia`). */
178
+ export type ResultadoAutorizacao = ResultadoSefaz<ProtocoloNfe, ProtocoloNfe>;
175
179
 
176
180
  /** Situação da NF-e na consulta protocolo. */
177
181
  export interface ConsultaNfe {
@@ -184,7 +188,7 @@ export interface ConsultaNfe {
184
188
  readonly digValConfere?: boolean;
185
189
  }
186
190
 
187
- export type ConsultaOutcome = SefazOutcome<ConsultaNfe, ConsultaNfe>;
191
+ export type ResultadoConsulta = ResultadoSefaz<ConsultaNfe, ConsultaNfe>;
188
192
 
189
193
  /** Evento registrado (cStat 135, 136 ou 155). */
190
194
  export interface EventoRegistrado {
@@ -199,7 +203,7 @@ export interface EventoRegistrado {
199
203
  readonly procEventoNFe: string;
200
204
  }
201
205
 
202
- export type EventoOutcome = SefazOutcome<EventoRegistrado, never>;
206
+ export type ResultadoEvento = ResultadoSefaz<EventoRegistrado, never>;
203
207
 
204
208
  /** Inutilização homologada (cStat 102). */
205
209
  export interface Inutilizacao {
@@ -209,7 +213,7 @@ export interface Inutilizacao {
209
213
  readonly procInutNFe: string;
210
214
  }
211
215
 
212
- export type InutilizacaoOutcome = SefazOutcome<Inutilizacao, never>;
216
+ export type ResultadoInutilizacao = ResultadoSefaz<Inutilizacao, never>;
213
217
 
214
218
  export interface Cadastro {
215
219
  readonly UF: string;
@@ -238,11 +242,15 @@ export interface Distribuicao {
238
242
 
239
243
  export type ManifestacaoTipo = 'ciencia' | 'confirmacao' | 'desconhecimento' | 'nao-realizada';
240
244
 
241
- export interface AutorizarOpcoes {
245
+ export interface AutorizarOpcoes extends EnvioOpcoes {
242
246
  /** `indSinc` 1 (padrão) ou 0 (lote assíncrono com recibo). */
243
247
  readonly sincrono?: boolean;
244
- /** Cancela a requisição em curso. */
245
- readonly signal?: AbortSignal;
248
+ }
249
+
250
+ /** Opções do status do serviço. */
251
+ export interface StatusServicoOpcoes extends EnvioOpcoes {
252
+ /** `65` consulta o autorizador da NFC-e. Padrão 55. */
253
+ readonly mod?: '55' | '65';
246
254
  }
247
255
 
248
256
  export interface CancelamentoPedido {
@@ -303,38 +311,38 @@ export type DistribuicaoConsulta =
303
311
  | { readonly NSU: string | number }
304
312
  | { readonly chNFe: string };
305
313
 
306
- export interface DistribuicaoOpcoes {
314
+ export interface DistribuicaoOpcoes extends EnvioOpcoes {
307
315
  /** UF do interessado; padrão a UF do cliente. */
308
316
  readonly cUFAutor?: string;
309
317
  readonly autor?: AutorDocumento;
310
318
  }
311
319
 
312
- export interface NfeClient {
313
- readonly options: NfeClientOptions;
320
+ export interface ClienteNfe {
321
+ readonly opcoes: ClienteNfeOpcoes;
314
322
  /**
315
323
  * Status do serviço de autorização na UF das opções (MOC 7.0, tabela 4.4.1: 107 em operação, 108 e 109 paralisado).
316
324
  * Com `mod: '65'`, o do autorizador da NFC-e, que em várias UFs é outro host.
317
325
  */
318
- statusServico(opcoes?: { readonly mod?: '55' | '65' }): Promise<SefazOutcome<StatusServico, never>>;
326
+ statusServico(opcoes?: StatusServicoOpcoes): Promise<ResultadoSefaz<StatusServico, never>>;
319
327
  /** Envia uma NF-e assinada (a string devolvida pela assinatura, sem outra alteração). Padrão síncrono. */
320
- autorizar(nfeAssinada: string, opcoes?: AutorizarOpcoes): Promise<AutorizacaoOutcome>;
328
+ autorizar(nfeAssinada: string, opcoes?: AutorizarOpcoes): Promise<ResultadoAutorizacao>;
321
329
  /** Consulta o recibo de um lote assíncrono; com a NF-e assinada, monta o `nfeProc`. */
322
- consultarRecibo(nRec: string, nfeAssinada?: string, opcoes?: ConsultaReciboOpcoes): Promise<AutorizacaoOutcome>;
330
+ consultarRecibo(nRec: string, nfeAssinada?: string, opcoes?: ConsultaReciboOpcoes): Promise<ResultadoAutorizacao>;
323
331
  /** Consulta o recibo até sair de pendente ou esgotar a política. */
324
- aguardarRecibo(nRec: string, nfeAssinada?: string, politica?: PoliticaRecibo): Promise<AutorizacaoOutcome>;
325
- consultar(chave: string, nfeAssinada?: string): Promise<ConsultaOutcome>;
326
- cancelar(p: CancelamentoPedido): Promise<EventoOutcome>;
332
+ aguardarRecibo(nRec: string, nfeAssinada?: string, politica?: PoliticaRecibo): Promise<ResultadoAutorizacao>;
333
+ consultar(chave: string, nfeAssinada?: string, opcoes?: EnvioOpcoes): Promise<ResultadoConsulta>;
334
+ cancelar(p: CancelamentoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento>;
327
335
  /** Cancelamento por substituição (110112): só NFC-e (modelo 65). */
328
- cancelarPorSubstituicao(p: CancelamentoSubstituicaoPedido): Promise<EventoOutcome>;
329
- cartaCorrecao(p: CartaCorrecaoPedido): Promise<EventoOutcome>;
336
+ cancelarPorSubstituicao(p: CancelamentoSubstituicaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento>;
337
+ cartaCorrecao(p: CartaCorrecaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento>;
330
338
  /** Manifestação do destinatário, registrada no Ambiente Nacional (cOrgao 91). */
331
- manifestar(p: ManifestacaoPedido): Promise<EventoOutcome>;
332
- inutilizar(p: InutilizacaoPedido): Promise<InutilizacaoOutcome>;
333
- consultarCadastro(p: CadastroPedido): Promise<SefazOutcome<Cadastro, never>>;
339
+ manifestar(p: ManifestacaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento>;
340
+ inutilizar(p: InutilizacaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoInutilizacao>;
341
+ consultarCadastro(p: CadastroPedido, opcoes?: EnvioOpcoes): Promise<ResultadoSefaz<Cadastro, never>>;
334
342
  distribuicaoDFe(
335
343
  consulta: DistribuicaoConsulta,
336
344
  opcoes?: DistribuicaoOpcoes,
337
- ): Promise<SefazOutcome<Distribuicao, never>>;
345
+ ): Promise<ResultadoSefaz<Distribuicao, never>>;
338
346
  }
339
347
 
340
348
  // ---------------------------------------------------------------------------------------------------------------
@@ -350,7 +358,7 @@ export function autorizadorContingencia(
350
358
  return { autorizador, tpEmis: autorizador === 'SVC-AN' ? '6' : '7' };
351
359
  }
352
360
 
353
- const defaultSleep: Sleep = (ms: number, signal?: AbortSignal): Promise<void> =>
361
+ const defaultSleep: Espera = (ms: number, signal?: AbortSignal): Promise<void> =>
354
362
  new Promise<void>((resolve, reject) => {
355
363
  if (signal?.aborted) {
356
364
  reject(signal.reason);
@@ -369,28 +377,28 @@ const defaultSleep: Sleep = (ms: number, signal?: AbortSignal): Promise<void> =>
369
377
  });
370
378
 
371
379
  function chaveValida(chave: string, path: string): ChaveAcesso {
372
- const r = parseChaveAcesso(chave, { path });
373
- if (!r.ok) throw new ValidationError(`chave de acesso inválida: ${r.error.message}`, [r.error]);
374
- return r.value;
380
+ const r = lerChaveAcesso(chave, { caminho: path });
381
+ if (!r.ok) throw new ErroDeValidacao(`chave de acesso inválida: ${r.erro.mensagem}`, [r.erro]);
382
+ return r.valor;
375
383
  }
376
384
 
377
- function schemaIssues(what: string, issues: readonly SchemaIssue[]): void {
378
- if (issues.length > 0) throw new ValidationError(`${what} não confere com o schema`, issues);
385
+ function schemaIssues(what: string, issues: readonly OcorrenciaSchema[]): void {
386
+ if (issues.length > 0) throw new ErroDeValidacao(`${what} não confere com o schema`, issues);
379
387
  }
380
388
 
381
389
  function documentoAutor(a: AutorDocumento, path: string): { CNPJ: string } | { CPF: string } {
382
390
  if (a.CNPJ !== undefined) {
383
- const r = parseCnpj(a.CNPJ, { path: `${path}.CNPJ` });
384
- if (!r.ok) throw new ValidationError('CNPJ do autor inválido', [r.error]);
385
- return { CNPJ: r.value };
391
+ const r = lerCnpj(a.CNPJ, { caminho: `${path}.CNPJ` });
392
+ if (!r.ok) throw new ErroDeValidacao('CNPJ do autor inválido', [r.erro]);
393
+ return { CNPJ: r.valor };
386
394
  }
387
- const r = parseCpf(a.CPF ?? '', { path: `${path}.CPF` });
388
- if (!r.ok) throw new ValidationError('CPF do autor inválido', [r.error]);
389
- return { CPF: r.value };
395
+ const r = lerCpf(a.CPF ?? '', { caminho: `${path}.CPF` });
396
+ if (!r.ok) throw new ErroDeValidacao('CPF do autor inválido', [r.erro]);
397
+ return { CPF: r.valor };
390
398
  }
391
399
 
392
400
  function autorDaChave(c: ChaveAcesso): { CNPJ: string } | { CPF: string } {
393
- // parseChaveAcesso já exigiu CNPJ ou "000" + CPF válido nas 14 posições do emitente.
401
+ // lerChaveAcesso já exigiu CNPJ ou "000" + CPF válido nas 14 posições do emitente.
394
402
  return c.cnpj !== undefined ? { CNPJ: c.cnpj } : { CPF: c.cpf ?? c.emitente.slice(3) };
395
403
  }
396
404
 
@@ -404,11 +412,11 @@ function autorDoEmitente(a: AutorDocumento | undefined, c: ChaveAcesso): { CNPJ:
404
412
  const autor = documentoAutor(a, 'autor');
405
413
  const [campo, valor] = 'CNPJ' in autor ? ['CNPJ', autor.CNPJ] : ['CPF', autor.CPF];
406
414
  if (valor !== ('CNPJ' in daChave ? daChave.CNPJ : daChave.CPF) || campo !== ('CNPJ' in daChave ? 'CNPJ' : 'CPF')) {
407
- throw new ValidationError('o autor do evento não é o emitente da NF-e', [
415
+ throw new ErroDeValidacao('o autor do evento não é o emitente da NF-e', [
408
416
  {
409
- path: `autor.${campo}`,
417
+ caminho: `autor.${campo}`,
410
418
  code: 'autor_difere_do_emitente',
411
- message: `o autor de um evento do emitente é o ${'CNPJ' in daChave ? 'CNPJ' : 'CPF'} da chave (P12-44, rejeição 574)`,
419
+ mensagem: `o autor de um evento do emitente é o ${'CNPJ' in daChave ? 'CNPJ' : 'CPF'} da chave (P12-44, rejeição 574)`,
412
420
  origem: 'entrada',
413
421
  },
414
422
  ]);
@@ -424,14 +432,14 @@ const SVC_DO_TPEMIS: Readonly<Record<string, 'SVC-AN' | 'SVC-RS'>> = { '6': 'SVC
424
432
 
425
433
  /** Chave do documento assinado, lida para rotear: o emitente é conferido pela SEFAZ, não aqui. */
426
434
  function chaveDoDocumento(a: DocumentoAssinado): ChaveAcesso {
427
- const r = parseChaveAcesso(a.id.slice(3), { path: 'infNFe.Id', checkEmitente: false });
428
- if (!r.ok) throw new ConfigError(`Id da NF-e assinada não é uma chave de acesso: ${r.error.message}`);
429
- return r.value;
435
+ const r = lerChaveAcesso(a.id.slice(3), { caminho: 'infNFe.Id', conferirEmitente: false });
436
+ if (!r.ok) throw new ErroDeConfiguracao(`Id da NF-e assinada não é uma chave de acesso: ${r.erro.mensagem}`);
437
+ return r.valor;
430
438
  }
431
439
 
432
440
  /** Fatia autossuficiente (com o `xmlns` do elemento), para devolver ao chamador fora de um envelope. */
433
- function avulso(doc: XmlDocument, el: XmlElement): string {
434
- return sliceElement(doc, el, '');
441
+ function avulso(doc: DocumentoXml, el: ElementoXml): string {
442
+ return recortarElemento(doc, el, '');
435
443
  }
436
444
 
437
445
  /** Protocolo lido e a fatia sem `xmlns` redundante, para entrar no `nfeProc`. */
@@ -441,10 +449,10 @@ interface ProtocoloLido {
441
449
  }
442
450
 
443
451
  /** Monta o protocolo a partir do `protNFe` da resposta. */
444
- function lerProtocolo(doc: XmlDocument, el: XmlElement): ProtocoloLido {
445
- const { value } = decode(TProtNFe, el, doc.source);
452
+ function lerProtocolo(doc: DocumentoXml, el: ElementoXml): ProtocoloLido {
453
+ const { valor: value } = decodificar(TProtNFe, el, doc.texto);
446
454
  const inf = value.infProt;
447
- if (!inf) throw new ProtocolError('protNFe sem infProt');
455
+ if (!inf) throw new ErroRespostaInvalida('protNFe sem infProt');
448
456
  const p = {
449
457
  chNFe: inf.chNFe,
450
458
  cStat: inf.cStat,
@@ -455,15 +463,15 @@ function lerProtocolo(doc: XmlDocument, el: XmlElement): ProtocoloLido {
455
463
  ...(inf.nProt === undefined ? {} : { nProt: inf.nProt }),
456
464
  ...(inf.digVal === undefined ? {} : { digVal: inf.digVal }),
457
465
  };
458
- return { p, embutido: sliceElement(doc, el) };
466
+ return { p, embutido: recortarElemento(doc, el) };
459
467
  }
460
468
 
461
469
  /**
462
470
  * Protocolo de uma NF-e que este cliente enviou: o `digVal` tem de ser o DigestValue da nota assinada, senão o
463
- * protocolo é de outro conteúdo e nenhum `nfeProc` é montado (`ProtocolError`). Sem `digVal` não há como provar que o
471
+ * protocolo é de outro conteúdo e nenhum `nfeProc` é montado (`ErroRespostaInvalida`). Sem `digVal` não há como provar que o
464
472
  * protocolo é deste conteúdo: o desfecho volta sem `nfeProc` (confirme com `consultar`).
465
473
  */
466
- function desfechoDoProtocolo({ p, embutido }: ProtocoloLido, a: DocumentoAssinado | undefined): AutorizacaoOutcome {
474
+ function desfechoDoProtocolo({ p, embutido }: ProtocoloLido, a: DocumentoAssinado | undefined): ResultadoAutorizacao {
467
475
  const status = { cStat: p.cStat, xMotivo: p.xMotivo };
468
476
  const autorizada = cstatEm(p.cStat, 'autorizada');
469
477
  const denegada = cstatEm(p.cStat, 'denegada');
@@ -471,27 +479,27 @@ function desfechoDoProtocolo({ p, embutido }: ProtocoloLido, a: DocumentoAssinad
471
479
  let full: ProtocoloNfe = p;
472
480
  if (a) {
473
481
  if (`NFe${p.chNFe}` !== a.id) {
474
- throw new ProtocolError('protocolo de outra chave de acesso', { details: { chNFe: p.chNFe } });
482
+ throw new ErroRespostaInvalida('protocolo de outra chave de acesso', { detalhes: { chNFe: p.chNFe } });
475
483
  }
476
484
  if (p.digVal !== undefined && p.digVal !== a.digestValue) {
477
- throw new ProtocolError('digVal do protocolo difere do DigestValue da NF-e enviada', {
478
- details: { chNFe: p.chNFe, cStat: p.cStat },
485
+ throw new ErroRespostaInvalida('digVal do protocolo difere do DigestValue da NF-e enviada', {
486
+ detalhes: { chNFe: p.chNFe, cStat: p.cStat },
479
487
  });
480
488
  }
481
489
  if (p.digVal !== undefined) full = { ...p, nfeProc: envelope('nfeProc', '4.00', [a.xml, embutido]) };
482
490
  }
483
- return autorizada ? authorized(status, full) : denied(status, full);
491
+ return autorizada ? criarAutorizado(status, full) : criarDenegado(status, full);
484
492
  }
485
493
 
486
- function protNFeDaChave(parent: XmlElement, a: DocumentoAssinado | undefined): XmlElement | undefined {
487
- const prots = childElements(parent).filter((e) => e.local === 'protNFe' && e.ns === NFE_NS);
494
+ function protNFeDaChave(parent: ElementoXml, a: DocumentoAssinado | undefined): ElementoXml | undefined {
495
+ const prots = elementosFilhos(parent).filter((e) => e.local === 'protNFe' && e.ns === NFE_NS);
488
496
  if (!a) return prots[0];
489
497
  const chave = a.id.slice(3);
490
498
  return (
491
499
  prots.find((e) => {
492
- const inf = firstChild(e, 'infProt', NFE_NS);
493
- const ch = inf && firstChild(inf, 'chNFe', NFE_NS);
494
- return ch !== undefined && textOf(ch).trim() === chave;
500
+ const inf = primeiroFilho(e, 'infProt', NFE_NS);
501
+ const ch = inf && primeiroFilho(inf, 'chNFe', NFE_NS);
502
+ return ch !== undefined && textoDe(ch).trim() === chave;
495
503
  }) ?? (prots.length === 1 ? prots[0] : undefined)
496
504
  );
497
505
  }
@@ -523,52 +531,59 @@ interface EventoPedido {
523
531
  readonly cOrgao: string;
524
532
  readonly autor: { CNPJ: string } | { CPF: string };
525
533
  readonly detEvento: Readonly<Record<string, unknown>>;
526
- readonly endpoint: EndpointRef;
534
+ readonly endpoint: EndpointResolvido;
527
535
  /** Fuso do `dhEvento`. */
528
536
  readonly offsetMinutes: number;
537
+ readonly signal: AbortSignal | undefined;
529
538
  }
530
539
 
531
540
  /** Cria o cliente dos serviços da NF-e. */
532
- export function createNfeClient(options: NfeClientOptions): NfeClient {
533
- const logger = (options.logger ?? noopLogger).child({ modulo: 'nfe', ambiente: options.ambiente });
534
- const sleep = options.sleep ?? defaultSleep;
535
- const tpAmb = tpAmbOf(options.ambiente);
536
- const ufInfo = options.uf === undefined ? undefined : ufBySigla(options.uf);
537
- if (options.uf !== undefined && !ufInfo) throw new ConfigError(`UF inválida: ${String(options.uf)}`);
538
- /** UF dos serviços sem documento; sem `options.uf`, `ConfigError` nomeando o serviço. */
541
+ export function criarClienteNfe(opcoesDoCliente: ClienteNfeOpcoes): ClienteNfe {
542
+ const logger = (opcoesDoCliente.logger ?? loggerSilencioso).child({
543
+ modulo: 'nfe',
544
+ ambiente: opcoesDoCliente.ambiente,
545
+ });
546
+ const sleep = opcoesDoCliente.esperar ?? defaultSleep;
547
+ const tpAmb = tpAmbDoAmbiente(opcoesDoCliente.ambiente);
548
+ const ufInfo = opcoesDoCliente.uf === undefined ? undefined : ufPorSigla(opcoesDoCliente.uf);
549
+ if (opcoesDoCliente.uf !== undefined && !ufInfo)
550
+ throw new ErroDeConfiguracao(`UF inválida: ${String(opcoesDoCliente.uf)}`);
551
+ /** UF dos serviços sem documento; sem `opcoesDoCliente.uf`, `ErroDeConfiguracao` nomeando o serviço. */
539
552
  const ufPadrao = (servico: string): { readonly uf: Uf; readonly cUF: CUf } => {
540
- if (options.uf === undefined || ufInfo === undefined) {
541
- throw new ConfigError(`${servico} precisa da UF: informe NfeClientOptions.uf`);
553
+ if (opcoesDoCliente.uf === undefined || ufInfo === undefined) {
554
+ throw new ErroDeConfiguracao(`${servico} precisa da UF: informe ClienteNfeOpcoes.uf`);
542
555
  }
543
- return { uf: options.uf, cUF: ufInfo.cUF };
556
+ return { uf: opcoesDoCliente.uf, cUF: ufInfo.cUF };
544
557
  };
545
558
  /** Fuso de um evento pela UF de quem o registra. */
546
- const offsetDe = (uf: Uf): number => options.offsetMinutes ?? offsetDaUf(uf);
559
+ const offsetDe = (uf: Uf): number => opcoesDoCliente.deslocamentoMin ?? deslocamentoDaUf(uf);
547
560
 
548
561
  const idLote = (): string => {
549
- const id = options.idLote ? options.idLote() : String(options.clock.now().getTime()).slice(-15);
550
- if (!/^[0-9]{1,15}$/.test(id)) throw new ConfigError(`idLote inválido: ${id}`);
562
+ const id = opcoesDoCliente.idLote
563
+ ? opcoesDoCliente.idLote()
564
+ : String(opcoesDoCliente.relogio.agora().getTime()).slice(-15);
565
+ if (!/^[0-9]{1,15}$/.test(id)) throw new ErroDeConfiguracao(`idLote inválido: ${id}`);
551
566
  return id;
552
567
  };
553
568
 
554
- /** Endpoint da NFC-e: a opção `nfceEndpoint` ou a tabela da NFC-e do transporte, sempre no autorizador normal. */
555
- const endpointNfce = (servico: NfeServico, uf: Uf): EndpointRef =>
556
- options.nfceEndpoint
557
- ? options.nfceEndpoint(servico, uf)
558
- : nfceEndpoint({ ambiente: options.ambiente, servico, uf });
569
+ /** Endpoint da NFC-e: a opção `endpointNfce` ou a tabela da NFC-e do transporte, sempre no autorizador normal. */
570
+ const endpointNfce = (servico: NfeServico, uf: Uf): EndpointResolvido =>
571
+ opcoesDoCliente.endpointNfce
572
+ ? opcoesDoCliente.endpointNfce(servico, uf)
573
+ : nfceEndpoint({ ambiente: opcoesDoCliente.ambiente, servico, uf });
559
574
 
560
575
  /**
561
576
  * Endpoint de um serviço sem documento, pela UF das opções: NF-e com SVC quando `contingencia` pede; NFC-e no
562
577
  * autorizador normal.
563
578
  */
564
- const endpoint = (servico: NfeServico, mod = '55'): EndpointRef => {
579
+ const endpoint = (servico: NfeServico, mod = '55'): EndpointResolvido => {
565
580
  const { uf } = ufPadrao(servico);
566
581
  if (mod === '65') return endpointNfce(servico, uf);
567
582
  return nfeEndpoint({
568
- ambiente: options.ambiente,
583
+ ambiente: opcoesDoCliente.ambiente,
569
584
  servico,
570
585
  uf,
571
- ...(options.contingencia === undefined ? {} : { contingencia: options.contingencia }),
586
+ ...(opcoesDoCliente.contingencia === undefined ? {} : { contingencia: opcoesDoCliente.contingencia }),
572
587
  });
573
588
  };
574
589
 
@@ -577,37 +592,37 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
577
592
  * autorizou a nota. `naUf` força o autorizador da UF (a CC-e não existe no SVC). A NFC-e vai sempre ao autorizador
578
593
  * normal da NFC-e.
579
594
  */
580
- const endpointDaChave = (servico: NfeServico, c: ChaveAcesso, naUf = false): EndpointRef => {
595
+ const endpointDaChave = (servico: NfeServico, c: ChaveAcesso, naUf = false): EndpointResolvido => {
581
596
  if (c.mod === '65') return endpointNfce(servico, c.uf);
582
597
  const svc = naUf || c.tpEmis === undefined ? undefined : SVC_DO_TPEMIS[c.tpEmis];
583
598
  return nfeEndpoint({
584
- ambiente: options.ambiente,
599
+ ambiente: opcoesDoCliente.ambiente,
585
600
  servico,
586
601
  ...(svc === undefined ? { uf: c.uf } : { autorizador: svc }),
587
602
  });
588
603
  };
589
604
 
590
605
  const call = (
591
- ep: EndpointRef,
606
+ ep: EndpointResolvido,
592
607
  servico: NfeServico,
593
608
  mensagem: string,
594
609
  retorno: string,
595
610
  signal?: AbortSignal,
596
611
  ): Promise<RespostaSoap> =>
597
612
  chamar({
598
- transport: options.transport,
613
+ transport: opcoesDoCliente.transporte,
599
614
  endpoint: ep,
600
615
  servico,
601
616
  mensagem,
602
617
  retorno,
603
618
  logger,
604
- ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
619
+ ...(opcoesDoCliente.timeoutMs === undefined ? {} : { timeoutMs: opcoesDoCliente.timeoutMs }),
605
620
  ...(signal === undefined ? {} : { signal }),
606
621
  });
607
622
 
608
623
  const autorPadrao = (a: AutorDocumento | undefined, path: string): { CNPJ: string } | { CPF: string } => {
609
- const autor = a ?? options.autor;
610
- if (!autor) throw new ConfigError(`informe o CNPJ ou CPF do autor (${path} ou NfeClientOptions.autor)`);
624
+ const autor = a ?? opcoesDoCliente.autor;
625
+ if (!autor) throw new ErroDeConfiguracao(`informe o CNPJ ou CPF do autor (${path} ou ClienteNfeOpcoes.autor)`);
611
626
  return documentoAutor(autor, path);
612
627
  };
613
628
 
@@ -615,42 +630,42 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
615
630
  nRec: string,
616
631
  nfeAssinada?: string,
617
632
  opcoes: ConsultaReciboOpcoes = {},
618
- ): Promise<AutorizacaoOutcome> {
619
- if (!/^[0-9]{15}$/.test(nRec)) throw new ConfigError(`número de recibo inválido: ${nRec}`);
633
+ ): Promise<ResultadoAutorizacao> {
634
+ if (!/^[0-9]{15}$/.test(nRec)) throw new ErroDeConfiguracao(`número de recibo inválido: ${nRec}`);
620
635
  const a = nfeAssinada === undefined ? undefined : documentoAssinado(nfeAssinada, 'NFe', 'infNFe');
621
636
  const c = a === undefined ? undefined : chaveDoDocumento(a);
622
637
  if (c !== undefined && opcoes.mod !== undefined && opcoes.mod !== c.mod) {
623
- throw new ConfigError(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
638
+ throw new ErroDeConfiguracao(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
624
639
  }
625
640
  const msg = envelope('consReciNFe', '4.00', [`<tpAmb>${tpAmb}</tpAmb><nRec>${nRec}</nRec>`]);
626
641
  // O recibo é do autorizador que recebeu o lote: com a NF-e, o da chave; sem ela, o das opções.
627
642
  const ep =
628
643
  c === undefined ? endpoint('NFeRetAutorizacao', opcoes.mod ?? '55') : endpointDaChave('NFeRetAutorizacao', c);
629
644
  const r = await call(ep, 'NFeRetAutorizacao', msg, 'retConsReciNFe', opcoes.signal);
630
- const v = decode(TRetConsReciNFe, r.ret, r.doc.source).value;
645
+ const v = decodificar(TRetConsReciNFe, r.ret, r.doc.texto).valor;
631
646
  if (v.nRec !== undefined && v.nRec !== nRec) {
632
- throw new ProtocolError('retorno de outro recibo', { details: { nRec: v.nRec } });
647
+ throw new ErroRespostaInvalida('retorno de outro recibo', { detalhes: { nRec: v.nRec } });
633
648
  }
634
649
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
635
650
  logger.info('nfe.recibo', { nRec, cStat: v.cStat });
636
651
  if (cstatEm(v.cStat, 'loteEmProcessamento') || cstatEm(v.cStat, 'loteRecebido'))
637
- return pending(status, { ref: nRec });
652
+ return criarPendente(status, { referencia: nRec });
638
653
  if (cstatEm(v.cStat, 'loteProcessado')) {
639
654
  const el = protNFeDaChave(r.ret, a);
640
- if (!el) throw new ProtocolError('lote processado sem o protNFe da NF-e', { details: { nRec } });
655
+ if (!el) throw new ErroRespostaInvalida('lote processado sem o protNFe da NF-e', { detalhes: { nRec } });
641
656
  return desfechoDoProtocolo(lerProtocolo(r.doc, el), a);
642
657
  }
643
658
  return rejeitado(status);
644
659
  }
645
660
 
646
- async function consultar(chave: string, nfeAssinada?: string): Promise<ConsultaOutcome> {
661
+ async function consultar(chave: string, nfeAssinada?: string, opcoes?: EnvioOpcoes): Promise<ResultadoConsulta> {
647
662
  const c = chaveValida(chave, 'chNFe');
648
663
  const a = nfeAssinada === undefined ? undefined : documentoAssinado(nfeAssinada, 'NFe', 'infNFe');
649
- if (a && a.id !== `NFe${c.chave}`) throw new ConfigError('a NF-e assinada não é a da chave consultada');
650
- const msg = serializeRoot(consSitNFeElement, { versao: '4.00', tpAmb, xServ: 'CONSULTAR', chNFe: c.chave });
664
+ if (a && a.id !== `NFe${c.chave}`) throw new ErroDeConfiguracao('a NF-e assinada não é a da chave consultada');
665
+ const msg = serializarRaiz(consSitNFeElement, { versao: '4.00', tpAmb, xServ: 'CONSULTAR', chNFe: c.chave });
651
666
  const ep = endpointDaChave('NfeConsultaProtocolo', c);
652
- const r = await call(ep, 'NfeConsultaProtocolo', msg, 'retConsSitNFe');
653
- const v = decode(TRetConsSitNFe, r.ret, r.doc.source).value;
667
+ const r = await call(ep, 'NfeConsultaProtocolo', msg, 'retConsSitNFe', opcoes?.signal);
668
+ const v = decodificar(TRetConsSitNFe, r.ret, r.doc.texto).valor;
654
669
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
655
670
  logger.info('nfe.consulta', { chNFe: c.chave, cStat: v.cStat });
656
671
  const situacao = cstatEm(v.cStat, 'autorizada')
@@ -661,8 +676,8 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
661
676
  ? 'denegada'
662
677
  : undefined;
663
678
  if (situacao === undefined) return rejeitado(status);
664
- const protEl = firstChild(r.ret, 'protNFe', NFE_NS);
665
- const eventos = childElements(r.ret)
679
+ const protEl = primeiroFilho(r.ret, 'protNFe', NFE_NS);
680
+ const eventos = elementosFilhos(r.ret)
666
681
  .filter((e) => e.local === 'procEventoNFe' && e.ns === NFE_NS)
667
682
  .map((e) => avulso(r.doc, e));
668
683
  let protocolo: ProtocoloNfe | undefined;
@@ -670,7 +685,9 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
670
685
  if (protEl) {
671
686
  const { p, embutido } = lerProtocolo(r.doc, protEl);
672
687
  if (p.chNFe !== c.chave) {
673
- throw new ProtocolError('protocolo de outra chave de acesso na consulta', { details: { chNFe: p.chNFe } });
688
+ throw new ErroRespostaInvalida('protocolo de outra chave de acesso na consulta', {
689
+ detalhes: { chNFe: p.chNFe },
690
+ });
674
691
  }
675
692
  protocolo = p;
676
693
  if (a) {
@@ -685,12 +702,12 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
685
702
  ...(protocolo === undefined ? {} : { protocolo }),
686
703
  ...(digValConfere === undefined ? {} : { digValConfere }),
687
704
  };
688
- return situacao === 'denegada' ? denied(status, value) : authorized(status, value);
705
+ return situacao === 'denegada' ? criarDenegado(status, value) : criarAutorizado(status, value);
689
706
  }
690
707
 
691
- async function enviarEvento(p: EventoPedido): Promise<EventoOutcome> {
708
+ async function enviarEvento(p: EventoPedido): Promise<ResultadoEvento> {
692
709
  const nSeq = p.nSeqEvento;
693
- if (!Number.isInteger(nSeq) || nSeq < 1 || nSeq > 99) throw new ConfigError(`nSeqEvento inválido: ${nSeq}`);
710
+ if (!Number.isInteger(nSeq) || nSeq < 1 || nSeq > 99) throw new ErroDeConfiguracao(`nSeqEvento inválido: ${nSeq}`);
694
711
  const nSeqEvento = String(nSeq);
695
712
  // Id = "ID" + tpEvento + chave + nSeqEvento com 2 dígitos (leiaute do evento, atributo Id de infEvento).
696
713
  const id = `ID${p.tpEvento}${p.chave}${nSeqEvento.padStart(2, '0')}`;
@@ -700,25 +717,25 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
700
717
  tpAmb,
701
718
  ...p.autor,
702
719
  chNFe: p.chave,
703
- dhEvento: formatDh(options.clock.now(), p.offsetMinutes),
720
+ dhEvento: formatarDh(opcoesDoCliente.relogio.agora(), p.offsetMinutes),
704
721
  tpEvento: p.tpEvento,
705
722
  nSeqEvento,
706
723
  verEvento: EVENTO_VERSAO,
707
724
  detEvento: p.detEvento,
708
725
  };
709
- const infXml = serialize(p.ct, 'infEvento', inf, NFE_NS);
726
+ const infXml = serializar(p.ct, 'infEvento', inf, NFE_NS);
710
727
  const evento = `<evento xmlns="${NFE_NS}" versao="${EVENTO_VERSAO}">${infXml}</evento>`;
711
- const infEl = firstChild(parseXml(evento).root, 'infEvento', NFE_NS) as XmlElement;
712
- schemaIssues('evento', validate(p.ct, infEl));
713
- const assinado = await signXml(evento, { id }, options.signer);
728
+ const infEl = primeiroFilho(lerXml(evento).raiz, 'infEvento', NFE_NS) as ElementoXml;
729
+ schemaIssues('evento', validar(p.ct, infEl));
730
+ const assinado = await assinarXml(evento, { id }, opcoesDoCliente.assinador);
714
731
  const msg = envelope('envEvento', EVENTO_VERSAO, [`<idLote>${idLote()}</idLote>`, assinado]);
715
- const r = await call(p.endpoint, 'RecepcaoEvento', msg, 'retEnvEvento');
716
- const v = decode(TRetEnvEvento, r.ret, r.doc.source).value;
732
+ const r = await call(p.endpoint, 'RecepcaoEvento', msg, 'retEnvEvento', p.signal);
733
+ const v = decodificar(TRetEnvEvento, r.ret, r.doc.texto).valor;
717
734
  logger.info('nfe.evento', { chNFe: p.chave, tpEvento: p.tpEvento, cStat: v.cStat });
718
735
  if (!cstatEm(v.cStat, 'loteEventoProcessado')) return rejeitado({ cStat: v.cStat, xMotivo: v.xMotivo });
719
- const retEl = childElements(r.ret).find((e) => e.local === 'retEvento' && e.ns === NFE_NS);
736
+ const retEl = elementosFilhos(r.ret).find((e) => e.local === 'retEvento' && e.ns === NFE_NS);
720
737
  const ret = v.retEvento?.[0]?.infEvento;
721
- if (!retEl || !ret) throw new ProtocolError('lote de evento processado sem retEvento');
738
+ if (!retEl || !ret) throw new ErroRespostaInvalida('lote de evento processado sem retEvento');
722
739
  // O retorno tem de ser deste evento: chave, tipo e sequência, quando vierem, iguais aos enviados.
723
740
  const divergentes = (
724
741
  [
@@ -728,35 +745,41 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
728
745
  ] as const
729
746
  ).filter(([, veio, enviado]) => veio !== undefined && veio !== enviado);
730
747
  if (divergentes.length > 0) {
731
- throw new ProtocolError('retEvento de outro evento', {
732
- details: Object.fromEntries(divergentes.map(([k, veio]) => [k, veio])),
748
+ throw new ErroRespostaInvalida('retEvento de outro evento', {
749
+ detalhes: Object.fromEntries(divergentes.map(([k, veio]) => [k, veio])),
733
750
  });
734
751
  }
735
752
  const status = { cStat: ret.cStat, xMotivo: ret.xMotivo };
736
753
  if (!cstatEm(ret.cStat, 'eventoRegistrado')) return rejeitado(status);
737
- return authorized(status, {
754
+ return criarAutorizado(status, {
738
755
  chNFe: p.chave,
739
756
  tpEvento: p.tpEvento,
740
757
  nSeqEvento,
741
758
  dhRegEvento: ret.dhRegEvento,
742
759
  retEvento: avulso(r.doc, retEl),
743
- procEventoNFe: envelope('procEventoNFe', EVENTO_VERSAO, [assinado, sliceElement(r.doc, retEl)]),
760
+ procEventoNFe: envelope('procEventoNFe', EVENTO_VERSAO, [assinado, recortarElemento(r.doc, retEl)]),
744
761
  ...(ret.nProt === undefined ? {} : { nProt: ret.nProt }),
745
762
  });
746
763
  }
747
764
 
748
- const client: NfeClient = {
749
- options,
765
+ const client: ClienteNfe = {
766
+ opcoes: opcoesDoCliente,
750
767
 
751
- async statusServico(opcoes?: { readonly mod?: '55' | '65' }): Promise<SefazOutcome<StatusServico, never>> {
768
+ async statusServico(opcoes?: StatusServicoOpcoes): Promise<ResultadoSefaz<StatusServico, never>> {
752
769
  const { cUF } = ufPadrao('NfeStatusServico');
753
- const msg = serializeRoot(consStatServElement, { versao: '4.00', tpAmb, cUF, xServ: 'STATUS' });
754
- const r = await call(endpoint('NfeStatusServico', opcoes?.mod), 'NfeStatusServico', msg, 'retConsStatServ');
755
- const v = decode(TRetConsStatServ, r.ret, r.doc.source).value;
770
+ const msg = serializarRaiz(consStatServElement, { versao: '4.00', tpAmb, cUF, xServ: 'STATUS' });
771
+ const r = await call(
772
+ endpoint('NfeStatusServico', opcoes?.mod),
773
+ 'NfeStatusServico',
774
+ msg,
775
+ 'retConsStatServ',
776
+ opcoes?.signal,
777
+ );
778
+ const v = decodificar(TRetConsStatServ, r.ret, r.doc.texto).valor;
756
779
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
757
780
  logger.info('nfe.status', { cStat: v.cStat });
758
781
  if (!cstatEm(v.cStat, 'servicoEmOperacao')) return rejeitado(status);
759
- return authorized(status, {
782
+ return criarAutorizado(status, {
760
783
  cUF: v.cUF,
761
784
  verAplic: v.verAplic,
762
785
  dhRecbto: v.dhRecbto,
@@ -766,7 +789,7 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
766
789
  });
767
790
  },
768
791
 
769
- async autorizar(nfeAssinada: string, opcoes: AutorizarOpcoes = {}): Promise<AutorizacaoOutcome> {
792
+ async autorizar(nfeAssinada: string, opcoes: AutorizarOpcoes = {}): Promise<ResultadoAutorizacao> {
770
793
  const a = documentoAssinado(nfeAssinada, 'NFe', 'infNFe');
771
794
  const sincrono = opcoes.sincrono ?? true;
772
795
  const msg = envelope('enviNFe', '4.00', [
@@ -776,14 +799,14 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
776
799
  // O autorizador é o do documento: a UF do cUF e, assinada em SVC (tpEmis 6 ou 7), o SVC da chave.
777
800
  const ep = endpointDaChave('NFeAutorizacao', chaveDoDocumento(a));
778
801
  const r = await call(ep, 'NFeAutorizacao', msg, 'retEnviNFe', opcoes.signal);
779
- const v = decode(TRetEnviNFe, r.ret, r.doc.source).value;
802
+ const v = decodificar(TRetEnviNFe, r.ret, r.doc.texto).valor;
780
803
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
781
804
  logger.info('nfe.autorizacao', { chNFe: a.id.slice(3), cStat: v.cStat, sincrono });
782
805
  if (cstatEm(v.cStat, 'loteRecebido')) {
783
806
  const nRec = v.infRec?.nRec;
784
- if (!nRec) throw new ProtocolError('lote recebido sem número de recibo');
807
+ if (!nRec) throw new ErroRespostaInvalida('lote recebido sem número de recibo');
785
808
  const tMed = Number(v.infRec?.tMed ?? '0');
786
- return pending(status, { ref: nRec, retryAfterMs: Math.max(1, tMed) * 1000 });
809
+ return criarPendente(status, { referencia: nRec, aguardarMs: Math.max(1, tMed) * 1000 });
787
810
  }
788
811
  const protEl = protNFeDaChave(r.ret, a);
789
812
  if (protEl) return desfechoDoProtocolo(lerProtocolo(r.doc, protEl), a);
@@ -796,29 +819,31 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
796
819
  nRec: string,
797
820
  nfeAssinada?: string,
798
821
  politica: PoliticaRecibo = {},
799
- ): Promise<AutorizacaoOutcome> {
822
+ ): Promise<ResultadoAutorizacao> {
800
823
  const max = politica.maxTentativas ?? 10;
801
824
  const minimo = politica.esperaMinimaMs ?? 2000;
802
825
  const mult = politica.multiplicador ?? 1.5;
803
826
  const teto = politica.esperaMaximaMs ?? 30_000;
804
827
  if (!(max >= 1) || !(minimo >= 0) || !(mult >= 1) || !(teto >= minimo)) {
805
- throw new ConfigError('política de consulta do recibo inválida', { details: { max, minimo, mult, teto } });
828
+ throw new ErroDeConfiguracao('política de consulta do recibo inválida', {
829
+ detalhes: { max, minimo, mult, teto },
830
+ });
806
831
  }
807
832
  let espera = minimo;
808
- let ultimo: AutorizacaoOutcome | undefined;
833
+ let ultimo: ResultadoAutorizacao | undefined;
809
834
  for (let i = 0; i < max; i++) {
810
835
  await sleep(espera, politica.signal);
811
836
  // O mesmo signal cancela a espera e a requisição em curso.
812
837
  ultimo = await consultarRecibo(nRec, nfeAssinada, politica);
813
- if (ultimo.status !== 'pending') return ultimo;
814
- espera = Math.min(teto, Math.max(minimo, Math.round(espera * mult), ultimo.retryAfterMs ?? 0));
838
+ if (ultimo.tipo !== 'pendente') return ultimo;
839
+ espera = Math.min(teto, Math.max(minimo, Math.round(espera * mult), ultimo.aguardarMs ?? 0));
815
840
  }
816
- return ultimo as AutorizacaoOutcome;
841
+ return ultimo as ResultadoAutorizacao;
817
842
  },
818
843
 
819
844
  consultar,
820
845
 
821
- async cancelar(p: CancelamentoPedido): Promise<EventoOutcome> {
846
+ async cancelar(p: CancelamentoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento> {
822
847
  const c = chaveValida(p.chave, 'chave');
823
848
  return enviarEvento({
824
849
  ct: TEventoCanc,
@@ -831,17 +856,18 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
831
856
  // No autorizador da nota: o SVC só cancela a NF-e que ele autorizou, e a da UF só se cancela na UF.
832
857
  endpoint: endpointDaChave('RecepcaoEvento', c),
833
858
  offsetMinutes: offsetDe(c.uf),
859
+ signal: opcoes?.signal,
834
860
  });
835
861
  },
836
862
 
837
- async cancelarPorSubstituicao(p: CancelamentoSubstituicaoPedido): Promise<EventoOutcome> {
863
+ async cancelarPorSubstituicao(p: CancelamentoSubstituicaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento> {
838
864
  const c = chaveValida(p.chave, 'chave');
839
865
  if (c.mod !== '65') {
840
- throw new ValidationError('cancelamento por substituição só existe para NFC-e', [
866
+ throw new ErroDeValidacao('cancelamento por substituição só existe para NFC-e', [
841
867
  {
842
- path: 'chave',
868
+ caminho: 'chave',
843
869
  code: 'modelo_nao_suportado',
844
- message: 'O evento 110112 é exclusivo da NFC-e (modelo 65)',
870
+ mensagem: 'O evento 110112 é exclusivo da NFC-e (modelo 65)',
845
871
  },
846
872
  ]);
847
873
  }
@@ -867,13 +893,14 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
867
893
  detEvento,
868
894
  endpoint: endpointDaChave('RecepcaoEvento', c),
869
895
  offsetMinutes: offsetDe(c.uf),
896
+ signal: opcoes?.signal,
870
897
  });
871
898
  },
872
899
 
873
- async cartaCorrecao(p: CartaCorrecaoPedido): Promise<EventoOutcome> {
900
+ async cartaCorrecao(p: CartaCorrecaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento> {
874
901
  const c = chaveValida(p.chave, 'chave');
875
902
  if (!Number.isInteger(p.nSeqEvento) || p.nSeqEvento < 1 || p.nSeqEvento > 20) {
876
- throw new ConfigError(`nSeqEvento da CC-e vai de 1 a 20: ${p.nSeqEvento}`);
903
+ throw new ErroDeConfiguracao(`nSeqEvento da CC-e vai de 1 a 20: ${p.nSeqEvento}`);
877
904
  }
878
905
  return enviarEvento({
879
906
  ct: TEventoCce,
@@ -891,13 +918,14 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
891
918
  // A CC-e vai sempre à UF: o SVC só recebe o cancelamento (NT 2013.007).
892
919
  endpoint: endpointDaChave('RecepcaoEvento', c, true),
893
920
  offsetMinutes: offsetDe(c.uf),
921
+ signal: opcoes?.signal,
894
922
  });
895
923
  },
896
924
 
897
- async manifestar(p: ManifestacaoPedido): Promise<EventoOutcome> {
925
+ async manifestar(p: ManifestacaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoEvento> {
898
926
  const c = chaveValida(p.chave, 'chave');
899
927
  const m = MANIFESTACOES[p.tipo];
900
- if (!m) throw new ConfigError(`tipo de manifestação desconhecido: ${String(p.tipo)}`);
928
+ if (!m) throw new ErroDeConfiguracao(`tipo de manifestação desconhecido: ${String(p.tipo)}`);
901
929
  return enviarEvento({
902
930
  ct: m.ct,
903
931
  tpEvento: m.tpEvento,
@@ -911,22 +939,23 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
911
939
  descEvento: m.descEvento,
912
940
  ...(p.xJust === undefined ? {} : { xJust: p.xJust }),
913
941
  },
914
- endpoint: nfeEndpoint({ ambiente: options.ambiente, servico: 'RecepcaoEvento', autorizador: 'AN' }),
942
+ endpoint: nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: 'RecepcaoEvento', autorizador: 'AN' }),
915
943
  // Quem manifesta é o destinatário: o fuso é o da UF dele, quando informada.
916
- offsetMinutes: offsetDe(options.uf ?? c.uf),
944
+ offsetMinutes: offsetDe(opcoesDoCliente.uf ?? c.uf),
945
+ signal: opcoes?.signal,
917
946
  });
918
947
  },
919
948
 
920
- async inutilizar(p: InutilizacaoPedido): Promise<InutilizacaoOutcome> {
949
+ async inutilizar(p: InutilizacaoPedido, opcoes?: EnvioOpcoes): Promise<ResultadoInutilizacao> {
921
950
  const autor = autorPadrao(p.autor, 'autor');
922
951
  // NT 2018.001 v1.10, item 6.1: o controle de inutilização não se aplica ao emitente pessoa física, e o leiaute do
923
952
  // pedido não prevê o CPF; a série 910 a 969 (emitente CPF) é rejeitada com 266 (regra I02a, item 6.2).
924
953
  if (!('CNPJ' in autor)) {
925
- throw new ValidationError('inutilização não se aplica ao emitente pessoa física', [
954
+ throw new ErroDeValidacao('inutilização não se aplica ao emitente pessoa física', [
926
955
  {
927
- path: 'autor.CPF',
956
+ caminho: 'autor.CPF',
928
957
  code: 'inutilizacao_emitente_cpf',
929
- message: 'O pedido de inutilização só existe para emitente CNPJ (NT 2018.001 v1.10, item 6.1)',
958
+ mensagem: 'O pedido de inutilização só existe para emitente CNPJ (NT 2018.001 v1.10, item 6.1)',
930
959
  },
931
960
  ]);
932
961
  }
@@ -944,15 +973,16 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
944
973
  ['nNFIni', ini, /^[1-9][0-9]{0,8}$/],
945
974
  ['nNFFin', fin, /^[1-9][0-9]{0,8}$/],
946
975
  ] as const) {
947
- if (!re.test(x)) throw new ConfigError(`${k} inválido para inutilização: ${x}`);
976
+ if (!re.test(x)) throw new ErroDeConfiguracao(`${k} inválido para inutilização: ${x}`);
948
977
  }
949
- if (Number(fin) < Number(ini)) throw new ConfigError('nNFFin menor que nNFIni');
978
+ if (Number(fin) < Number(ini)) throw new ErroDeConfiguracao('nNFFin menor que nNFIni');
950
979
  if (Number(serie) >= 910 && Number(serie) <= 969) {
951
- throw new ValidationError('série de emitente pessoa física não se inutiliza', [
980
+ throw new ErroDeValidacao('série de emitente pessoa física não se inutiliza', [
952
981
  {
953
- path: 'serie',
982
+ caminho: 'serie',
954
983
  code: 'inutilizacao_serie_cpf',
955
- message: 'Série 910 a 969 identifica emitente CPF: a SEFAZ rejeita com 266 (NT 2018.001 v1.10, regra I02a)',
984
+ mensagem:
985
+ 'Série 910 a 969 identifica emitente CPF: a SEFAZ rejeita com 266 (NT 2018.001 v1.10, regra I02a)',
956
986
  },
957
987
  ]);
958
988
  }
@@ -971,18 +1001,18 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
971
1001
  nNFFin: fin,
972
1002
  xJust: p.xJust,
973
1003
  };
974
- const infXml = serialize(TInutNFe_infInut, 'infInut', inf, NFE_NS);
1004
+ const infXml = serializar(TInutNFe_infInut, 'infInut', inf, NFE_NS);
975
1005
  const inut = envelope('inutNFe', '4.00', [infXml]);
976
- const infEl = firstChild(parseXml(inut).root, 'infInut', NFE_NS) as XmlElement;
977
- schemaIssues('pedido de inutilização', validate(TInutNFe_infInut, infEl));
978
- const assinado = await signXml(inut, { id }, options.signer);
1006
+ const infEl = primeiroFilho(lerXml(inut).raiz, 'infInut', NFE_NS) as ElementoXml;
1007
+ schemaIssues('pedido de inutilização', validar(TInutNFe_infInut, infEl));
1008
+ const assinado = await assinarXml(inut, { id }, opcoesDoCliente.assinador);
979
1009
  // A inutilização não existe no SVC (o SVC-RS nem publica o serviço): vai sempre ao autorizador normal da UF.
980
1010
  const ep =
981
1011
  mod === '65'
982
1012
  ? endpointNfce('NfeInutilizacao', uf)
983
- : nfeEndpoint({ ambiente: options.ambiente, servico: 'NfeInutilizacao', uf });
984
- const r = await call(ep, 'NfeInutilizacao', assinado, 'retInutNFe');
985
- const v = decode(TRetInutNFe, r.ret, r.doc.source).value;
1013
+ : nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: 'NfeInutilizacao', uf });
1014
+ const r = await call(ep, 'NfeInutilizacao', assinado, 'retInutNFe', opcoes?.signal);
1015
+ const v = decodificar(TRetInutNFe, r.ret, r.doc.texto).valor;
986
1016
  const status = { cStat: v.infInut.cStat, xMotivo: v.infInut.xMotivo };
987
1017
  logger.info('nfe.inutilizacao', { id, cStat: status.cStat });
988
1018
  if (!cstatEm(status.cStat, 'inutilizacaoHomologada')) return rejeitado(status);
@@ -999,44 +1029,44 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
999
1029
  ];
1000
1030
  const fora = confere.filter(([, veio, pedido]) => veio !== undefined && veio !== pedido);
1001
1031
  if (fora.length > 0) {
1002
- throw new ProtocolError('retInutNFe de outra faixa', {
1003
- details: Object.fromEntries(fora.map(([k, v]) => [k, v])),
1032
+ throw new ErroRespostaInvalida('retInutNFe de outra faixa', {
1033
+ detalhes: Object.fromEntries(fora.map(([k, v]) => [k, v])),
1004
1034
  });
1005
1035
  }
1006
- return authorized(status, {
1036
+ return criarAutorizado(status, {
1007
1037
  dhRecbto: v.infInut.dhRecbto,
1008
1038
  retInutNFe: avulso(r.doc, r.ret),
1009
- procInutNFe: envelope('ProcInutNFe', '4.00', [assinado, sliceElement(r.doc, r.ret)]),
1039
+ procInutNFe: envelope('ProcInutNFe', '4.00', [assinado, recortarElemento(r.doc, r.ret)]),
1010
1040
  ...(v.infInut.nProt === undefined ? {} : { nProt: v.infInut.nProt }),
1011
1041
  });
1012
1042
  },
1013
1043
 
1014
- async consultarCadastro(p: CadastroPedido): Promise<SefazOutcome<Cadastro, never>> {
1044
+ async consultarCadastro(p: CadastroPedido, opcoes?: EnvioOpcoes): Promise<ResultadoSefaz<Cadastro, never>> {
1015
1045
  const doc =
1016
1046
  'CNPJ' in p
1017
1047
  ? documentoAutor({ CNPJ: p.CNPJ }, 'CNPJ')
1018
1048
  : 'CPF' in p
1019
1049
  ? documentoAutor({ CPF: p.CPF }, 'CPF')
1020
1050
  : { IE: p.IE.replace(/[^0-9A-Za-z]/g, '').toUpperCase() };
1021
- const msg = serializeRoot(ConsCadElement, { versao: '2.00', infCons: { xServ: 'CONS-CAD', UF: p.uf, ...doc } });
1022
- const ep = nfeEndpoint({ ambiente: options.ambiente, servico: 'NfeConsultaCadastro', uf: p.uf });
1023
- const r = await call(ep, 'NfeConsultaCadastro', msg, 'retConsCad');
1024
- const v = decode(TRetConsCad, r.ret, r.doc.source).value;
1051
+ const msg = serializarRaiz(ConsCadElement, { versao: '2.00', infCons: { xServ: 'CONS-CAD', UF: p.uf, ...doc } });
1052
+ const ep = nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: 'NfeConsultaCadastro', uf: p.uf });
1053
+ const r = await call(ep, 'NfeConsultaCadastro', msg, 'retConsCad', opcoes?.signal);
1054
+ const v = decodificar(TRetConsCad, r.ret, r.doc.texto).valor;
1025
1055
  const i = v.infCons;
1026
1056
  const status = { cStat: i.cStat, xMotivo: i.xMotivo };
1027
1057
  logger.info('nfe.cadastro', { uf: p.uf, cStat: i.cStat });
1028
1058
  if (!cstatEm(i.cStat, 'cadastroEncontrado')) return rejeitado(status);
1029
- return authorized(status, { UF: i.UF, dhCons: i.dhCons, infCad: i.infCad ?? [] });
1059
+ return criarAutorizado(status, { UF: i.UF, dhCons: i.dhCons, infCad: i.infCad ?? [] });
1030
1060
  },
1031
1061
 
1032
1062
  async distribuicaoDFe(
1033
1063
  consulta: DistribuicaoConsulta,
1034
1064
  opcoes: DistribuicaoOpcoes = {},
1035
- ): Promise<SefazOutcome<Distribuicao, never>> {
1065
+ ): Promise<ResultadoSefaz<Distribuicao, never>> {
1036
1066
  const autor = autorPadrao(opcoes.autor, 'autor');
1037
1067
  const nsu = (x: string | number, k: string): string => {
1038
1068
  const s = String(x);
1039
- if (!/^[0-9]{1,15}$/.test(s)) throw new ConfigError(`${k} inválido: ${s}`);
1069
+ if (!/^[0-9]{1,15}$/.test(s)) throw new ErroDeConfiguracao(`${k} inválido: ${s}`);
1040
1070
  return s.padStart(15, '0');
1041
1071
  };
1042
1072
  const grupo =
@@ -1046,28 +1076,28 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
1046
1076
  ? { consNSU: { NSU: nsu(consulta.NSU, 'NSU') } }
1047
1077
  : { consChNFe: { chNFe: chaveValida(consulta.chNFe, 'chNFe').chave } };
1048
1078
  const cUFAutor = opcoes.cUFAutor ?? ufPadrao('NFeDistribuicaoDFe').cUF;
1049
- if (ufByCUf(cUFAutor) === undefined) throw new ConfigError(`cUFAutor inválido: ${cUFAutor}`);
1050
- const msg = serializeRoot(distDFeIntElement, {
1079
+ if (ufPorCUf(cUFAutor) === undefined) throw new ErroDeConfiguracao(`cUFAutor inválido: ${cUFAutor}`);
1080
+ const msg = serializarRaiz(distDFeIntElement, {
1051
1081
  versao: '1.01',
1052
1082
  tpAmb,
1053
1083
  cUFAutor: cUFAutor as CUf,
1054
1084
  ...autor,
1055
1085
  ...grupo,
1056
1086
  } as distDFeInt);
1057
- const ep = nfeEndpoint({ ambiente: options.ambiente, servico: 'NFeDistribuicaoDFe' });
1058
- const r = await call(ep, 'NFeDistribuicaoDFe', msg, 'retDistDFeInt');
1059
- const v = decode(retDistDFeInt, r.ret, r.doc.source).value;
1087
+ const ep = nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: 'NFeDistribuicaoDFe' });
1088
+ const r = await call(ep, 'NFeDistribuicaoDFe', msg, 'retDistDFeInt', opcoes.signal);
1089
+ const v = decodificar(retDistDFeInt, r.ret, r.doc.texto).valor;
1060
1090
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
1061
1091
  logger.info('nfe.distribuicao', { cStat: v.cStat, ultNSU: v.ultNSU, maxNSU: v.maxNSU });
1062
1092
  const base = { ultNSU: v.ultNSU, maxNSU: v.maxNSU, dhResp: v.dhResp };
1063
- if (cstatEm(v.cStat, 'distribuicaoNenhumDocumento')) return authorized(status, { ...base, documentos: [] });
1093
+ if (cstatEm(v.cStat, 'distribuicaoNenhumDocumento')) return criarAutorizado(status, { ...base, documentos: [] });
1064
1094
  if (!cstatEm(v.cStat, 'distribuicaoDocumentos')) return rejeitado(status);
1065
1095
  const documentos: DocumentoDistribuido[] = [];
1066
1096
  for (const z of v.loteDistDFeInt?.docZip ?? []) {
1067
- const xml = await gunzipBase64(z.$text);
1097
+ const xml = await descomprimirGzipBase64(z.$text);
1068
1098
  documentos.push(documentoDistribuido(z.NSU ?? '', z.schema, xml));
1069
1099
  }
1070
- return authorized(status, { ...base, documentos });
1100
+ return criarAutorizado(status, { ...base, documentos });
1071
1101
  },
1072
1102
  };
1073
1103
  return client;
@@ -1077,8 +1107,9 @@ export function createNfeClient(options: NfeClientOptions): NfeClient {
1077
1107
  function documentoDistribuido(NSU: string, schema: string, xml: string): DocumentoDistribuido {
1078
1108
  const nome = schema.replace(/_v?\d.*$/, '');
1079
1109
  const base = { NSU, schema, xml };
1080
- if (nome === 'resNFe') return { ...base, tipo: 'resNFe', resNFe: decodeXml(resNFeElement, xml).value };
1081
- if (nome === 'resEvento') return { ...base, tipo: 'resEvento', resEvento: decodeXml(resEventoElement, xml).value };
1110
+ if (nome === 'resNFe') return { ...base, tipo: 'resNFe', resNFe: decodificarXml(resNFeElement, xml).valor };
1111
+ if (nome === 'resEvento')
1112
+ return { ...base, tipo: 'resEvento', resEvento: decodificarXml(resEventoElement, xml).valor };
1082
1113
  if (nome === 'procNFe') return { ...base, tipo: 'procNFe' };
1083
1114
  if (nome === 'procEventoNFe') return { ...base, tipo: 'procEventoNFe' };
1084
1115
  return { ...base, tipo: 'outro' };