@pairus/product-data 1.14.0 → 1.16.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
@@ -277,10 +277,44 @@ const inut = await client.emissao.inutilizar({
277
277
  console.log('Inutilização homologada:', inut.sucesso);
278
278
  ```
279
279
 
280
+ #### Consulta da Nota Emitida e Referência da Venda
281
+ Informe `referencia_externa` na emissão. Ela volta na resposta e em todo webhook, junto com `cnpj_emitente`, e localiza a nota mesmo quando a resposta da emissão se perdeu:
282
+ ```typescript
283
+ const notas = await client.emissao.buscarPorReferencia('12345678000195', 'pedido-8841');
284
+ if (notas.length === 0) {
285
+ // nenhuma nota gravada para a venda: é seguro emitir
286
+ }
287
+ const nota = await client.emissao.consultar(notas[0].chave_acesso, { incluirXml: true });
288
+ const pdf = await client.emissao.baixarDanfe(nota.chave_acesso);
289
+ ```
290
+
291
+ #### CSC da NFC-e
292
+ ```typescript
293
+ const status = await client.empresas.configurarCsc('12345678000195', {
294
+ ambiente: 'producao', csc_id: '000001', csc_codigo: 'SEU_CSC_DA_SEFAZ',
295
+ });
296
+ console.log(status.producao.configurado); // o código nunca é devolvido
297
+ ```
298
+
280
299
  ### 6. 📥 DF-e Inbound & Captura SEFAZ Nacional (Gestão de Compras)
281
300
 
282
301
  Capture ativamente as notas fiscais emitidas por fornecedores contra o seu CNPJ via WebService `NFeDistribuicaoDFe` da SEFAZ Nacional, com controle incremental de NSU, descompactação automática de lotes `docZip` e Manifestação do Destinatário.
283
302
 
303
+ #### Certificado Digital A1 (pré-requisito)
304
+ A captura e a emissão usam o certificado A1 da conta. Instale ou renove direto pelo SDK e confira o vencimento:
305
+ ```typescript
306
+ import { readFileSync } from 'node:fs';
307
+
308
+ const instalado = await client.dfe.enviarCertificado({
309
+ alias: 'Matriz',
310
+ pfx_base64: readFileSync('certificado.pfx').toString('base64'),
311
+ senha: process.env.SENHA_PFX!,
312
+ });
313
+
314
+ const status = await client.dfe.consultarCertificado('12345678000195');
315
+ if (status.status === 'ativo') console.log(`Vence em ${status.dias_restantes} dias`);
316
+ ```
317
+
284
318
  #### A. Sincronizar Documentos com a SEFAZ
285
319
  ```typescript
286
320
  const sync = await client.dfe.sincronizar({
package/dist/index.d.mts CHANGED
@@ -101,6 +101,34 @@ interface ManifestarDFeResponse {
101
101
  manifestacao_status?: string;
102
102
  detalhes?: Record<string, any>;
103
103
  }
104
+ /** Metadados do Certificado Digital A1 da conta (nunca inclui a chave privada nem a senha). */
105
+ interface CertificadoDFe {
106
+ certificado_id?: string;
107
+ cnpj?: string;
108
+ razao_social?: string;
109
+ alias?: string;
110
+ dias_restantes?: number;
111
+ /** Data e hora de vencimento (ISO 8601). */
112
+ data_vencimento?: string;
113
+ }
114
+ interface StatusCertificadoDFeResponse extends CertificadoDFe {
115
+ /** 'ativo' ou 'nao_configurado'. */
116
+ status: 'ativo' | 'nao_configurado' | string;
117
+ mensagem?: string;
118
+ }
119
+ interface EnviarCertificadoDFeInput {
120
+ /** Apelido da empresa (2 a 120 caracteres). */
121
+ alias: string;
122
+ /** Arquivo .pfx codificado em Base64. */
123
+ pfx_base64: string;
124
+ /** Senha do certificado (só trafega na requisição; não é devolvida). */
125
+ senha: string;
126
+ }
127
+ interface EnviarCertificadoDFeResponse {
128
+ status: string;
129
+ message: string;
130
+ certificado?: CertificadoDFe;
131
+ }
104
132
 
105
133
  declare class DFeResource extends BaseResource {
106
134
  /**
@@ -138,6 +166,20 @@ declare class DFeResource extends BaseResource {
138
166
  * @returns ArrayBuffer contendo o PDF binário
139
167
  */
140
168
  baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer>;
169
+ /**
170
+ * Consulta se há Certificado Digital A1 ativo para o CNPJ e quando ele vence.
171
+ *
172
+ * @param cnpj CNPJ do estabelecimento (com ou sem máscara)
173
+ * @returns `status` 'ativo' (com vencimento e dias restantes) ou 'nao_configurado'
174
+ */
175
+ consultarCertificado(cnpj: string): Promise<StatusCertificadoDFeResponse>;
176
+ /**
177
+ * Instala ou atualiza o Certificado Digital A1 da conta, usado na DF-e e na emissão de NF-e.
178
+ *
179
+ * @param input Apelido, arquivo .pfx em Base64 e senha
180
+ * @returns Metadados do certificado validado e instalado
181
+ */
182
+ enviarCertificado(input: EnviarCertificadoDFeInput): Promise<EnviarCertificadoDFeResponse>;
141
183
  }
142
184
 
143
185
  /**
@@ -229,6 +271,8 @@ interface EmissaoNFeInput {
229
271
  cnpj: string;
230
272
  id_cadastro: string;
231
273
  };
274
+ /** Identificador da venda no seu sistema; volta nos webhooks e localiza a nota em `buscarPorReferencia`. */
275
+ referencia_externa?: string;
232
276
  [key: string]: any;
233
277
  }
234
278
  /** Opções de envio da emissão. */
@@ -259,6 +303,8 @@ interface EmissaoNFeResponse {
259
303
  data_emissao?: string | null;
260
304
  ambiente?: string;
261
305
  tipo_documento?: string;
306
+ /** Identificador da venda informado na emissão. */
307
+ referencia_externa?: string | null;
262
308
  autocura_aplicada?: boolean;
263
309
  xml_autorizado_base64?: string | null;
264
310
  danfe_pdf_base64?: string | null;
@@ -299,6 +345,48 @@ interface InutilizacaoInput {
299
345
  /** '55' (NF-e) ou '65' (NFC-e). */
300
346
  modelo?: '55' | '65' | 55 | 65;
301
347
  }
348
+ /** Situação atual de uma nota emitida (`GET /v1/nfe/{chave}` e `GET /v1/nfe?referencia_externa=`). */
349
+ interface NotaEmitidaResponse {
350
+ chave_acesso: string;
351
+ tipo_documento?: 'NFE' | 'NFCE' | null;
352
+ serie?: number | null;
353
+ numero?: number | null;
354
+ /** 'AUTORIZADA', 'PENDENTE_RETORNO', 'CONTINGENCIA', 'CANCELADA', 'REJEITADA'... */
355
+ status_sefaz?: string | null;
356
+ cStat?: number | null;
357
+ xMotivo?: string | null;
358
+ protocolo?: string | null;
359
+ data_emissao?: string | null;
360
+ ambiente?: string | null;
361
+ cnpj_emitente?: string | null;
362
+ referencia_externa?: string | null;
363
+ valor_total?: number | null;
364
+ qrcode_url?: string | null;
365
+ substituida_por?: string | null;
366
+ chave_substituida?: string | null;
367
+ prazo_transmissao?: string | null;
368
+ /** procNFe em Base64, só com `incluirXml: true`. */
369
+ xml_autorizado_base64?: string | null;
370
+ }
371
+ /** Situação do CSC em um ambiente. O código nunca é devolvido pela API. */
372
+ interface CscAmbienteStatus {
373
+ configurado: boolean;
374
+ csc_id?: string | null;
375
+ }
376
+ /** Situação do CSC da NFC-e do estabelecimento (`/v1/empresas/{cnpj}/csc`). */
377
+ interface CscNFCeStatus {
378
+ cnpj: string;
379
+ producao: CscAmbienteStatus;
380
+ homologacao: CscAmbienteStatus;
381
+ }
382
+ /** CSC gerado no portal da SEFAZ da UF, por ambiente. */
383
+ interface CscNFCeInput {
384
+ ambiente: 'producao' | 'homologacao';
385
+ /** Identificador do CSC (ex: '000001'). */
386
+ csc_id: string;
387
+ /** Código do CSC (16 a 36 letras e números). */
388
+ csc_codigo: string;
389
+ }
302
390
 
303
391
  declare class EmissaoResource extends BaseResource {
304
392
  /**
@@ -325,6 +413,35 @@ declare class EmissaoResource extends BaseResource {
325
413
  * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).
326
414
  */
327
415
  inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse>;
416
+ /**
417
+ * Consulta a situação atual de uma NF-e ou NFC-e emitida pela sua conta.
418
+ *
419
+ * @param chaveAcesso Chave de 44 dígitos da nota
420
+ * @param options `incluirXml` traz o procNFe em Base64
421
+ */
422
+ consultar(chaveAcesso: string, options?: {
423
+ incluirXml?: boolean;
424
+ }): Promise<NotaEmitidaResponse>;
425
+ /**
426
+ * Localiza as notas emitidas para uma venda pela `referencia_externa` informada na emissão.
427
+ * Lista vazia: nenhuma nota gravada para a venda, é seguro emitir.
428
+ */
429
+ buscarPorReferencia(cnpjEmitente: string, referenciaExterna: string): Promise<NotaEmitidaResponse[]>;
430
+ /**
431
+ * Baixa o DANFE em PDF de uma nota emitida (na contingência ainda não transmitida, com a tarja).
432
+ */
433
+ baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer>;
434
+ }
435
+
436
+ /** Cadastro de empresas emitentes (CSC da NFC-e). */
437
+ declare class EmpresasResource extends BaseResource {
438
+ /**
439
+ * Grava o CSC da NFC-e do estabelecimento (gerado no portal da SEFAZ da UF).
440
+ * O estabelecimento precisa de certificado próprio na conta; o código nunca é devolvido.
441
+ */
442
+ configurarCsc(cnpj: string, input: CscNFCeInput): Promise<CscNFCeStatus>;
443
+ /** Indica, por ambiente, se o CSC da NFC-e está configurado (sem devolver o código). */
444
+ consultarCsc(cnpj: string): Promise<CscNFCeStatus>;
328
445
  }
329
446
 
330
447
  /**
@@ -825,6 +942,7 @@ declare class PairusProductData {
825
942
  readonly emissao: EmissaoResource;
826
943
  readonly nfse: NFSeResource;
827
944
  readonly dfe: DFeResource;
945
+ readonly empresas: EmpresasResource;
828
946
  constructor(options?: PairusClientOptions);
829
947
  }
830
948
 
@@ -855,4 +973,4 @@ declare class NetworkError extends PairusError {
855
973
  constructor(message: string);
856
974
  }
857
975
 
858
- export { AuthenticationError, type CancelamentoInput, type CancelamentoNFSeInput, type CancelamentoNFSeResponse, type CartaCorrecaoInput, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DFeResource, type DocumentoDFe, type EmissaoDestinatarioInput, type EmissaoItemInput, type EmissaoNFeInput, type EmissaoNFeResponse, type EmissaoOptions, type EmissaoPagamentoInput, EmissaoResource, type EnderecoNFSeInput, type EventoNFeResponse, FiscalResource, type FiscalSanitizeItemInput, type FiscalSanitizeItemResult, type FiscalSanitizeResponse, type FuelData, type IBSCBSData, type InutilizacaoInput, InvalidSignatureError, type ListarDocumentosDFeParams, type ListarDocumentosDFeResponse, type ManifestarDFeInput, type ManifestarDFeResponse, type NFSeEmissaoInput, type NFSeEmissaoResponse, NFSeResource, NetworkError, PairusAPIError, type PairusClientOptions, PairusError, PairusProductData, type PrestadorNFSeInput, type ProductDetails, type ProductEnrichedDetails, type ProductResponse, type ProductSearchResponse, type ProductSearchResultItem, ProductsResource, RateLimitError, type ReformaTributariaServicoInput, type RetencoesFederaisInput, type SelectiveTaxData, type ServicoNFSeInput, type SincronizarDFeInput, type SincronizarDFeResponse, type TaxPredictionData, type TaxPredictionItemInput, type TaxPredictionItemResult, type TaxPredictionParams, type TaxPredictionResponse, type TipoManifestacaoDFe, type TomadorNFSeInput, type WebhookEvent, Webhooks };
976
+ export { AuthenticationError, type CancelamentoInput, type CancelamentoNFSeInput, type CancelamentoNFSeResponse, type CartaCorrecaoInput, type CertificadoDFe, type CscAmbienteStatus, type CscNFCeInput, type CscNFCeStatus, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DFeResource, type DocumentoDFe, type EmissaoDestinatarioInput, type EmissaoItemInput, type EmissaoNFeInput, type EmissaoNFeResponse, type EmissaoOptions, type EmissaoPagamentoInput, EmissaoResource, EmpresasResource, type EnderecoNFSeInput, type EnviarCertificadoDFeInput, type EnviarCertificadoDFeResponse, type EventoNFeResponse, FiscalResource, type FiscalSanitizeItemInput, type FiscalSanitizeItemResult, type FiscalSanitizeResponse, type FuelData, type IBSCBSData, type InutilizacaoInput, InvalidSignatureError, type ListarDocumentosDFeParams, type ListarDocumentosDFeResponse, type ManifestarDFeInput, type ManifestarDFeResponse, type NFSeEmissaoInput, type NFSeEmissaoResponse, NFSeResource, NetworkError, type NotaEmitidaResponse, PairusAPIError, type PairusClientOptions, PairusError, PairusProductData, type PrestadorNFSeInput, type ProductDetails, type ProductEnrichedDetails, type ProductResponse, type ProductSearchResponse, type ProductSearchResultItem, ProductsResource, RateLimitError, type ReformaTributariaServicoInput, type RetencoesFederaisInput, type SelectiveTaxData, type ServicoNFSeInput, type SincronizarDFeInput, type SincronizarDFeResponse, type StatusCertificadoDFeResponse, type TaxPredictionData, type TaxPredictionItemInput, type TaxPredictionItemResult, type TaxPredictionParams, type TaxPredictionResponse, type TipoManifestacaoDFe, type TomadorNFSeInput, type WebhookEvent, Webhooks };
package/dist/index.d.ts CHANGED
@@ -101,6 +101,34 @@ interface ManifestarDFeResponse {
101
101
  manifestacao_status?: string;
102
102
  detalhes?: Record<string, any>;
103
103
  }
104
+ /** Metadados do Certificado Digital A1 da conta (nunca inclui a chave privada nem a senha). */
105
+ interface CertificadoDFe {
106
+ certificado_id?: string;
107
+ cnpj?: string;
108
+ razao_social?: string;
109
+ alias?: string;
110
+ dias_restantes?: number;
111
+ /** Data e hora de vencimento (ISO 8601). */
112
+ data_vencimento?: string;
113
+ }
114
+ interface StatusCertificadoDFeResponse extends CertificadoDFe {
115
+ /** 'ativo' ou 'nao_configurado'. */
116
+ status: 'ativo' | 'nao_configurado' | string;
117
+ mensagem?: string;
118
+ }
119
+ interface EnviarCertificadoDFeInput {
120
+ /** Apelido da empresa (2 a 120 caracteres). */
121
+ alias: string;
122
+ /** Arquivo .pfx codificado em Base64. */
123
+ pfx_base64: string;
124
+ /** Senha do certificado (só trafega na requisição; não é devolvida). */
125
+ senha: string;
126
+ }
127
+ interface EnviarCertificadoDFeResponse {
128
+ status: string;
129
+ message: string;
130
+ certificado?: CertificadoDFe;
131
+ }
104
132
 
105
133
  declare class DFeResource extends BaseResource {
106
134
  /**
@@ -138,6 +166,20 @@ declare class DFeResource extends BaseResource {
138
166
  * @returns ArrayBuffer contendo o PDF binário
139
167
  */
140
168
  baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer>;
169
+ /**
170
+ * Consulta se há Certificado Digital A1 ativo para o CNPJ e quando ele vence.
171
+ *
172
+ * @param cnpj CNPJ do estabelecimento (com ou sem máscara)
173
+ * @returns `status` 'ativo' (com vencimento e dias restantes) ou 'nao_configurado'
174
+ */
175
+ consultarCertificado(cnpj: string): Promise<StatusCertificadoDFeResponse>;
176
+ /**
177
+ * Instala ou atualiza o Certificado Digital A1 da conta, usado na DF-e e na emissão de NF-e.
178
+ *
179
+ * @param input Apelido, arquivo .pfx em Base64 e senha
180
+ * @returns Metadados do certificado validado e instalado
181
+ */
182
+ enviarCertificado(input: EnviarCertificadoDFeInput): Promise<EnviarCertificadoDFeResponse>;
141
183
  }
142
184
 
143
185
  /**
@@ -229,6 +271,8 @@ interface EmissaoNFeInput {
229
271
  cnpj: string;
230
272
  id_cadastro: string;
231
273
  };
274
+ /** Identificador da venda no seu sistema; volta nos webhooks e localiza a nota em `buscarPorReferencia`. */
275
+ referencia_externa?: string;
232
276
  [key: string]: any;
233
277
  }
234
278
  /** Opções de envio da emissão. */
@@ -259,6 +303,8 @@ interface EmissaoNFeResponse {
259
303
  data_emissao?: string | null;
260
304
  ambiente?: string;
261
305
  tipo_documento?: string;
306
+ /** Identificador da venda informado na emissão. */
307
+ referencia_externa?: string | null;
262
308
  autocura_aplicada?: boolean;
263
309
  xml_autorizado_base64?: string | null;
264
310
  danfe_pdf_base64?: string | null;
@@ -299,6 +345,48 @@ interface InutilizacaoInput {
299
345
  /** '55' (NF-e) ou '65' (NFC-e). */
300
346
  modelo?: '55' | '65' | 55 | 65;
301
347
  }
348
+ /** Situação atual de uma nota emitida (`GET /v1/nfe/{chave}` e `GET /v1/nfe?referencia_externa=`). */
349
+ interface NotaEmitidaResponse {
350
+ chave_acesso: string;
351
+ tipo_documento?: 'NFE' | 'NFCE' | null;
352
+ serie?: number | null;
353
+ numero?: number | null;
354
+ /** 'AUTORIZADA', 'PENDENTE_RETORNO', 'CONTINGENCIA', 'CANCELADA', 'REJEITADA'... */
355
+ status_sefaz?: string | null;
356
+ cStat?: number | null;
357
+ xMotivo?: string | null;
358
+ protocolo?: string | null;
359
+ data_emissao?: string | null;
360
+ ambiente?: string | null;
361
+ cnpj_emitente?: string | null;
362
+ referencia_externa?: string | null;
363
+ valor_total?: number | null;
364
+ qrcode_url?: string | null;
365
+ substituida_por?: string | null;
366
+ chave_substituida?: string | null;
367
+ prazo_transmissao?: string | null;
368
+ /** procNFe em Base64, só com `incluirXml: true`. */
369
+ xml_autorizado_base64?: string | null;
370
+ }
371
+ /** Situação do CSC em um ambiente. O código nunca é devolvido pela API. */
372
+ interface CscAmbienteStatus {
373
+ configurado: boolean;
374
+ csc_id?: string | null;
375
+ }
376
+ /** Situação do CSC da NFC-e do estabelecimento (`/v1/empresas/{cnpj}/csc`). */
377
+ interface CscNFCeStatus {
378
+ cnpj: string;
379
+ producao: CscAmbienteStatus;
380
+ homologacao: CscAmbienteStatus;
381
+ }
382
+ /** CSC gerado no portal da SEFAZ da UF, por ambiente. */
383
+ interface CscNFCeInput {
384
+ ambiente: 'producao' | 'homologacao';
385
+ /** Identificador do CSC (ex: '000001'). */
386
+ csc_id: string;
387
+ /** Código do CSC (16 a 36 letras e números). */
388
+ csc_codigo: string;
389
+ }
302
390
 
303
391
  declare class EmissaoResource extends BaseResource {
304
392
  /**
@@ -325,6 +413,35 @@ declare class EmissaoResource extends BaseResource {
325
413
  * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).
326
414
  */
327
415
  inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse>;
416
+ /**
417
+ * Consulta a situação atual de uma NF-e ou NFC-e emitida pela sua conta.
418
+ *
419
+ * @param chaveAcesso Chave de 44 dígitos da nota
420
+ * @param options `incluirXml` traz o procNFe em Base64
421
+ */
422
+ consultar(chaveAcesso: string, options?: {
423
+ incluirXml?: boolean;
424
+ }): Promise<NotaEmitidaResponse>;
425
+ /**
426
+ * Localiza as notas emitidas para uma venda pela `referencia_externa` informada na emissão.
427
+ * Lista vazia: nenhuma nota gravada para a venda, é seguro emitir.
428
+ */
429
+ buscarPorReferencia(cnpjEmitente: string, referenciaExterna: string): Promise<NotaEmitidaResponse[]>;
430
+ /**
431
+ * Baixa o DANFE em PDF de uma nota emitida (na contingência ainda não transmitida, com a tarja).
432
+ */
433
+ baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer>;
434
+ }
435
+
436
+ /** Cadastro de empresas emitentes (CSC da NFC-e). */
437
+ declare class EmpresasResource extends BaseResource {
438
+ /**
439
+ * Grava o CSC da NFC-e do estabelecimento (gerado no portal da SEFAZ da UF).
440
+ * O estabelecimento precisa de certificado próprio na conta; o código nunca é devolvido.
441
+ */
442
+ configurarCsc(cnpj: string, input: CscNFCeInput): Promise<CscNFCeStatus>;
443
+ /** Indica, por ambiente, se o CSC da NFC-e está configurado (sem devolver o código). */
444
+ consultarCsc(cnpj: string): Promise<CscNFCeStatus>;
328
445
  }
329
446
 
330
447
  /**
@@ -825,6 +942,7 @@ declare class PairusProductData {
825
942
  readonly emissao: EmissaoResource;
826
943
  readonly nfse: NFSeResource;
827
944
  readonly dfe: DFeResource;
945
+ readonly empresas: EmpresasResource;
828
946
  constructor(options?: PairusClientOptions);
829
947
  }
830
948
 
@@ -855,4 +973,4 @@ declare class NetworkError extends PairusError {
855
973
  constructor(message: string);
856
974
  }
857
975
 
858
- export { AuthenticationError, type CancelamentoInput, type CancelamentoNFSeInput, type CancelamentoNFSeResponse, type CartaCorrecaoInput, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DFeResource, type DocumentoDFe, type EmissaoDestinatarioInput, type EmissaoItemInput, type EmissaoNFeInput, type EmissaoNFeResponse, type EmissaoOptions, type EmissaoPagamentoInput, EmissaoResource, type EnderecoNFSeInput, type EventoNFeResponse, FiscalResource, type FiscalSanitizeItemInput, type FiscalSanitizeItemResult, type FiscalSanitizeResponse, type FuelData, type IBSCBSData, type InutilizacaoInput, InvalidSignatureError, type ListarDocumentosDFeParams, type ListarDocumentosDFeResponse, type ManifestarDFeInput, type ManifestarDFeResponse, type NFSeEmissaoInput, type NFSeEmissaoResponse, NFSeResource, NetworkError, PairusAPIError, type PairusClientOptions, PairusError, PairusProductData, type PrestadorNFSeInput, type ProductDetails, type ProductEnrichedDetails, type ProductResponse, type ProductSearchResponse, type ProductSearchResultItem, ProductsResource, RateLimitError, type ReformaTributariaServicoInput, type RetencoesFederaisInput, type SelectiveTaxData, type ServicoNFSeInput, type SincronizarDFeInput, type SincronizarDFeResponse, type TaxPredictionData, type TaxPredictionItemInput, type TaxPredictionItemResult, type TaxPredictionParams, type TaxPredictionResponse, type TipoManifestacaoDFe, type TomadorNFSeInput, type WebhookEvent, Webhooks };
976
+ export { AuthenticationError, type CancelamentoInput, type CancelamentoNFSeInput, type CancelamentoNFSeResponse, type CartaCorrecaoInput, type CertificadoDFe, type CscAmbienteStatus, type CscNFCeInput, type CscNFCeStatus, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DFeResource, type DocumentoDFe, type EmissaoDestinatarioInput, type EmissaoItemInput, type EmissaoNFeInput, type EmissaoNFeResponse, type EmissaoOptions, type EmissaoPagamentoInput, EmissaoResource, EmpresasResource, type EnderecoNFSeInput, type EnviarCertificadoDFeInput, type EnviarCertificadoDFeResponse, type EventoNFeResponse, FiscalResource, type FiscalSanitizeItemInput, type FiscalSanitizeItemResult, type FiscalSanitizeResponse, type FuelData, type IBSCBSData, type InutilizacaoInput, InvalidSignatureError, type ListarDocumentosDFeParams, type ListarDocumentosDFeResponse, type ManifestarDFeInput, type ManifestarDFeResponse, type NFSeEmissaoInput, type NFSeEmissaoResponse, NFSeResource, NetworkError, type NotaEmitidaResponse, PairusAPIError, type PairusClientOptions, PairusError, PairusProductData, type PrestadorNFSeInput, type ProductDetails, type ProductEnrichedDetails, type ProductResponse, type ProductSearchResponse, type ProductSearchResultItem, ProductsResource, RateLimitError, type ReformaTributariaServicoInput, type RetencoesFederaisInput, type SelectiveTaxData, type ServicoNFSeInput, type SincronizarDFeInput, type SincronizarDFeResponse, type StatusCertificadoDFeResponse, type TaxPredictionData, type TaxPredictionItemInput, type TaxPredictionItemResult, type TaxPredictionParams, type TaxPredictionResponse, type TipoManifestacaoDFe, type TomadorNFSeInput, type WebhookEvent, Webhooks };
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ __export(index_exports, {
36
36
  DEFAULT_TIMEOUT_MS: () => DEFAULT_TIMEOUT_MS,
37
37
  DFeResource: () => DFeResource,
38
38
  EmissaoResource: () => EmissaoResource,
39
+ EmpresasResource: () => EmpresasResource,
39
40
  FiscalResource: () => FiscalResource,
40
41
  InvalidSignatureError: () => InvalidSignatureError,
41
42
  NFSeResource: () => NFSeResource,
@@ -125,7 +126,7 @@ var BaseResource = class {
125
126
  const reqHeaders = {
126
127
  "Accept": "application/json",
127
128
  "X-API-Key": this.apiKey,
128
- "User-Agent": "Pairus-NodeJS-SDK/1.14.0",
129
+ "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
129
130
  ...options.headers || {}
130
131
  };
131
132
  const isFormData = typeof FormData !== "undefined" && options.body instanceof FormData;
@@ -196,7 +197,7 @@ var BaseResource = class {
196
197
  const reqHeaders = {
197
198
  "Accept": "*/*",
198
199
  "X-API-Key": this.apiKey,
199
- "User-Agent": "Pairus-NodeJS-SDK/1.14.0",
200
+ "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
200
201
  ...options.headers || {}
201
202
  };
202
203
  let lastError = null;
@@ -255,7 +256,7 @@ var BaseResource = class {
255
256
  const reqHeaders = {
256
257
  "Accept": "*/*",
257
258
  "X-API-Key": this.apiKey,
258
- "User-Agent": "Pairus-NodeJS-SDK/1.14.0",
259
+ "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
259
260
  ...options.headers || {}
260
261
  };
261
262
  let lastError = null;
@@ -388,6 +389,35 @@ var DFeResource = class extends BaseResource {
388
389
  path: `/v1/dfe/danfe/${chaveAcesso}`
389
390
  });
390
391
  }
392
+ /**
393
+ * Consulta se há Certificado Digital A1 ativo para o CNPJ e quando ele vence.
394
+ *
395
+ * @param cnpj CNPJ do estabelecimento (com ou sem máscara)
396
+ * @returns `status` 'ativo' (com vencimento e dias restantes) ou 'nao_configurado'
397
+ */
398
+ async consultarCertificado(cnpj) {
399
+ return this.request({
400
+ method: "GET",
401
+ path: "/v1/dfe/certificado",
402
+ params: { cnpj }
403
+ });
404
+ }
405
+ /**
406
+ * Instala ou atualiza o Certificado Digital A1 da conta, usado na DF-e e na emissão de NF-e.
407
+ *
408
+ * @param input Apelido, arquivo .pfx em Base64 e senha
409
+ * @returns Metadados do certificado validado e instalado
410
+ */
411
+ async enviarCertificado(input) {
412
+ if (!input.alias || input.alias.trim().length < 2) {
413
+ throw new Error("O apelido (alias) do certificado deve ter ao menos 2 caracteres.");
414
+ }
415
+ return this.request({
416
+ method: "POST",
417
+ path: "/v1/dfe/certificado",
418
+ body: { alias: input.alias, pfx_base64: input.pfx_base64, senha: input.senha }
419
+ });
420
+ }
391
421
  };
392
422
 
393
423
  // src/resources/emissao.ts
@@ -474,6 +504,51 @@ var EmissaoResource = class extends BaseResource {
474
504
  }
475
505
  });
476
506
  }
507
+ /**
508
+ * Consulta a situação atual de uma NF-e ou NFC-e emitida pela sua conta.
509
+ *
510
+ * @param chaveAcesso Chave de 44 dígitos da nota
511
+ * @param options `incluirXml` traz o procNFe em Base64
512
+ */
513
+ async consultar(chaveAcesso, options) {
514
+ return this.request({
515
+ method: "GET",
516
+ path: `/v1/nfe/${chaveAcesso}`,
517
+ params: { incluir_xml: String(options?.incluirXml ?? false) }
518
+ });
519
+ }
520
+ /**
521
+ * Localiza as notas emitidas para uma venda pela `referencia_externa` informada na emissão.
522
+ * Lista vazia: nenhuma nota gravada para a venda, é seguro emitir.
523
+ */
524
+ async buscarPorReferencia(cnpjEmitente, referenciaExterna) {
525
+ return this.request({
526
+ method: "GET",
527
+ path: "/v1/nfe",
528
+ params: { cnpj_emitente: cnpjEmitente, referencia_externa: referenciaExterna }
529
+ });
530
+ }
531
+ /**
532
+ * Baixa o DANFE em PDF de uma nota emitida (na contingência ainda não transmitida, com a tarja).
533
+ */
534
+ async baixarDanfe(chaveAcesso) {
535
+ return this.requestBinary({ method: "GET", path: `/v1/nfe/${chaveAcesso}/danfe` });
536
+ }
537
+ };
538
+
539
+ // src/resources/empresas.ts
540
+ var EmpresasResource = class extends BaseResource {
541
+ /**
542
+ * Grava o CSC da NFC-e do estabelecimento (gerado no portal da SEFAZ da UF).
543
+ * O estabelecimento precisa de certificado próprio na conta; o código nunca é devolvido.
544
+ */
545
+ async configurarCsc(cnpj, input) {
546
+ return this.request({ method: "PUT", path: `/v1/empresas/${cnpj}/csc`, body: input });
547
+ }
548
+ /** Indica, por ambiente, se o CSC da NFC-e está configurado (sem devolver o código). */
549
+ async consultarCsc(cnpj) {
550
+ return this.request({ method: "GET", path: `/v1/empresas/${cnpj}/csc` });
551
+ }
477
552
  };
478
553
 
479
554
  // src/resources/fiscal.ts
@@ -796,6 +871,7 @@ var PairusProductData = class {
796
871
  emissao;
797
872
  nfse;
798
873
  dfe;
874
+ empresas;
799
875
  constructor(options) {
800
876
  const apiKey = options?.apiKey || (typeof process !== "undefined" ? process.env.PAIRUS_API_KEY : void 0);
801
877
  if (!apiKey) {
@@ -811,6 +887,7 @@ var PairusProductData = class {
811
887
  this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);
812
888
  this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);
813
889
  this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);
890
+ this.empresas = new EmpresasResource(apiKey, baseUrl, timeoutMs, maxRetries);
814
891
  }
815
892
  };
816
893
  // Annotate the CommonJS export names for ESM import in node:
@@ -821,6 +898,7 @@ var PairusProductData = class {
821
898
  DEFAULT_TIMEOUT_MS,
822
899
  DFeResource,
823
900
  EmissaoResource,
901
+ EmpresasResource,
824
902
  FiscalResource,
825
903
  InvalidSignatureError,
826
904
  NFSeResource,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["export { PairusProductData } from './client.js';\r\nexport { Webhooks } from './webhooks.js';\r\nexport { ProductsResource } from './resources/products.js';\r\nexport { FiscalResource } from './resources/fiscal.js';\r\nexport { EmissaoResource } from './resources/emissao.js';\r\nexport { NFSeResource } from './resources/nfse.js';\r\nexport { DFeResource } from './resources/dfe.js';\r\nexport * from './errors.js';\r\nexport * from './config.js';\r\nexport * from './types/index.js';\r\n\r\n","/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.14.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;\r\n\r\n if (options.body && !isFormData && !reqHeaders['Content-Type']) {\r\n reqHeaders['Content-Type'] = 'application/json';\r\n }\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const bodyData = isFormData\r\n ? options.body\r\n : options.body\r\n ? JSON.stringify(options.body)\r\n : undefined;\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n body: bodyData,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return (await response.json()) as T;\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n // 502/503/504 e, com Idempotency-Key, o 409 de venda ainda em processamento: retry com a mesma chave\r\n const vendaEmProcessamento = response.status === 409 && 'Idempotency-Key' in reqHeaders;\r\n if (([502, 503, 504].includes(response.status) || vendaEmProcessamento) && attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestText(options: RequestOptions): Promise<string> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.14.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.text();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestBinary(options: RequestOptions): Promise<ArrayBuffer> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.14.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n ListarDocumentosDFeParams,\n ListarDocumentosDFeResponse,\n ManifestarDFeInput,\n ManifestarDFeResponse,\n SincronizarDFeInput,\n SincronizarDFeResponse,\n} from '../types/dfe.js';\n\nexport class DFeResource extends BaseResource {\n /**\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\n *\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\n */\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\n return this.request<SincronizarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/sincronizar',\n body: {\n cnpj: input.cnpj,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\n *\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\n * @returns Lista de documentos fiscais capturados e status de manifestação\n */\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\n const queryParams: Record<string, string> = {\n cnpj: params.cnpj,\n ambiente: params.ambiente || 'producao',\n };\n if (params.limite) {\n queryParams.limite = String(params.limite);\n }\n\n return this.request<ListarDocumentosDFeResponse>({\n method: 'GET',\n path: '/v1/dfe/documentos',\n params: queryParams,\n });\n }\n\n /**\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\n *\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\n * @returns Protocolo de homologação do evento na SEFAZ\n */\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\n return this.request<ManifestarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/manifestar',\n body: {\n cnpj: input.cnpj,\n chave_acesso: input.chave_acesso,\n tipo_evento: input.tipo_evento,\n justificativa: input.justificativa,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns Conteúdo do XML em formato string\n */\n public async baixarXml(chaveAcesso: string): Promise<string> {\n return this.requestText({\n method: 'GET',\n path: `/v1/dfe/xml/${chaveAcesso}`,\n });\n }\n\n /**\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns ArrayBuffer contendo o PDF binário\n */\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\n return this.requestBinary({\n method: 'GET',\n path: `/v1/dfe/danfe/${chaveAcesso}`,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoNFSeInput,\r\n CancelamentoNFSeResponse,\r\n NFSeEmissaoInput,\r\n NFSeEmissaoResponse,\r\n} from '../types/nfse.js';\r\n\r\nexport class NFSeResource extends BaseResource {\r\n /**\r\n * Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).\r\n * Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.\r\n */\r\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/emitir',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\r\n */\r\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.\r\n * Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.\r\n */\r\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\r\n return this.request<CancelamentoNFSeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/cancelar',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\r\n * Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.\r\n */\r\n async consultar(chaveOuNumero: string, opcoes: { sincronizar?: boolean } = {}): Promise<Record<string, any>> {\r\n return this.request<Record<string, any>>({\r\n method: 'GET',\r\n path: `/v1/nfse/${chaveOuNumero}`,\r\n params: opcoes.sincronizar ? { sincronizar: 'true' } : undefined,\r\n });\r\n }\r\n}\r\n\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n ProductDetails,\r\n ProductEnrichedDetails,\r\n ProductSearchResponse,\r\n ProductSearchResultItem,\r\n} from '../types/product.js';\r\n\r\n/** Primeiro valor preenchido (ignora undefined, null e texto vazio). */\r\nfunction primeiro<T>(...valores: Array<T | undefined | null | ''>): T | undefined {\r\n return valores.find((v) => v !== undefined && v !== null && v !== '') as T | undefined;\r\n}\r\n\r\nfunction numero(valor: any): number | undefined {\r\n const n = valor === undefined || valor === null || valor === '' ? NaN : Number(valor);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\n/** Converte o produto da API (layout NF-e + `infoAdicional`) para `ProductDetails`. */\r\nfunction produtoDaApi(data: any, gtinFallback = ''): ProductDetails {\r\n const prod = data?.produto || data || {};\r\n const info = prod.infoAdicional || {};\r\n return {\r\n gtin: String(primeiro(prod.GTIN, prod.gtin, gtinFallback) ?? ''),\r\n xProd: primeiro(prod.xProd, prod.descricao) || 'Descrição Indisponível',\r\n ncm: primeiro(prod.NCM, prod.ncm),\r\n cest: primeiro(prod.CEST, prod.cest),\r\n marca: primeiro(prod.marca, info.xMarca),\r\n fabricante: prod.fabricante,\r\n categoria: primeiro(prod.categoria, info.xCategoria),\r\n imagemUrl: primeiro(prod.imagem_url, prod.thumbnail, info.urlImagem),\r\n pesoBruto: numero(primeiro(prod.peso_bruto, info.pesoBruto)),\r\n pesoLiquido: numero(primeiro(prod.peso_liquido, info.pesoLiquido)),\r\n quantidadeEmbalagem: Number(prod.quantidade_embalagem || 1),\r\n tpGTIN: prod.tpGTIN ?? undefined,\r\n fonte: prod.fonte ?? undefined,\r\n infoAdicional: prod.infoAdicional ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte o produto enriquecido (`/v2/gtin`, scan ou item da busca) para `ProductEnrichedDetails`. */\r\nfunction produtoEnriquecidoDaApi(data: any, gtinFallback = ''): ProductEnrichedDetails {\r\n const prod = data?.produto || data || {};\r\n const base = produtoDaApi(prod, gtinFallback);\r\n const enriquecimento = prod.enriquecimentoIA || {};\r\n const atributos = enriquecimento.atributos || {};\r\n const temAtributos = Object.keys(atributos).length > 0;\r\n return {\r\n gtin: base.gtin,\r\n xProd: base.xProd,\r\n xProd_higienizado: enriquecimento.xProd_higienizado,\r\n descricao_completa: primeiro(prod.descricao_completa, enriquecimento.descricao_seo),\r\n ficha_tecnica: prod.ficha_tecnica ?? (temAtributos ? atributos : undefined),\r\n palavras_chave: prod.palavras_chave,\r\n ncm: base.ncm,\r\n cest: base.cest,\r\n marca: primeiro(prod.marca, atributos.marca, base.marca),\r\n categoria: primeiro(prod.categoria, enriquecimento.categoria_comercial, base.categoria),\r\n imagem_url: base.imagemUrl,\r\n peso_bruto: base.pesoBruto,\r\n peso_liquido: primeiro(numero(prod.peso_liquido), numero(atributos.peso_liquido), base.pesoLiquido),\r\n dados_tributarios_sugeridos: prod.dados_tributarios_sugeridos ?? prod.tributacaoIA ?? undefined,\r\n tpGTIN: base.tpGTIN,\r\n fonte: base.fonte,\r\n infoAdicional: base.infoAdicional,\r\n enriquecimentoIA: prod.enriquecimentoIA ?? undefined,\r\n tributacaoIA: prod.tributacaoIA ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte `/v2/gtin/search` (`resultados[].produto`; aceita o legado `produtos`). */\r\nfunction buscaDaApi(data: any, query: string): ProductSearchResponse {\r\n const itens: ProductSearchResultItem[] = (data?.resultados || data?.produtos || []).map((item: any) => {\r\n const prod = produtoEnriquecidoDaApi(item.produto || item);\r\n return {\r\n gtin: prod.gtin,\r\n xProd: prod.xProd,\r\n marca: prod.marca,\r\n categoria: prod.categoria,\r\n score: item.score !== undefined && item.score !== null ? Number(item.score) : undefined,\r\n justificativa: item.justificativa ?? undefined,\r\n ncm: prod.ncm,\r\n cest: prod.cest,\r\n imagem_url: prod.imagem_url,\r\n };\r\n });\r\n return {\r\n status: data?.status || 'success',\r\n provider: data?.provider || 'PAIRUS',\r\n total_encontrados: itens.length,\r\n termo_buscado: data?.query || query,\r\n motor_busca: data?.motor_busca,\r\n produtos: itens,\r\n };\r\n}\r\n\r\nexport class ProductsResource extends BaseResource {\r\n /**\r\n * Consulta dados oficiais de um produto por código de barras GTIN/EAN (V1).\r\n * @param gtin Código numérico de 8 a 14 dígitos.\r\n */\r\n public async get(gtin: string): Promise<ProductDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v1/gtin/${gtinLimpo}` });\r\n return produtoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Consulta dados enriquecidos por IA, com SEO e ficha técnica estruturada (V2).\r\n * @param gtin Código numérico do produto.\r\n */\r\n public async getEnriched(gtin: string): Promise<ProductEnrichedDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v2/gtin/${gtinLimpo}` });\r\n return produtoEnriquecidoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Executa busca semântica por intenção/linguagem natural (V2).\r\n * @param query Termo livre de busca (ex: 'refrigerante zero lata').\r\n */\r\n public async search(query: string): Promise<ProductSearchResponse> {\r\n const data = await this.request<any>({ method: 'GET', path: '/v2/gtin/search', params: { q: query } });\r\n return buscaDaApi(data, query);\r\n }\r\n\r\n /**\r\n * Reconhece código de barras por visão computacional a partir de foto JPEG (OCR V2).\r\n * @param file Blob, Buffer ou FormData com a imagem JPEG.\r\n */\r\n public async scan(file: Blob | Buffer | FormData): Promise<ProductEnrichedDetails> {\r\n let formData: FormData;\r\n\r\n if (typeof FormData !== 'undefined' && file instanceof FormData) {\r\n formData = file;\r\n } else {\r\n formData = new FormData();\r\n if (typeof Blob !== 'undefined' && file instanceof Blob) {\r\n formData.append('file', file, 'barcode.jpg');\r\n } else {\r\n // Node Buffer\r\n const blob = new Blob([file as any], { type: 'image/jpeg' });\r\n formData.append('file', blob, 'barcode.jpg');\r\n }\r\n }\r\n\r\n const data = await this.request<any>({ method: 'POST', path: '/v2/gtin/scan', body: formData });\r\n return produtoEnriquecidoDaApi(data);\r\n }\r\n}\r\n","import * as crypto from 'crypto';\r\nimport { InvalidSignatureError } from './errors.js';\r\nimport { WebhookEvent } from './types/webhook.js';\r\n\r\n/** Prefixo do formato legado dos eventos de emissão (aceito até 27/12/2026). */\r\nconst PREFIXO_ASSINATURA = 'sha256=';\r\n\r\n/**\r\n * Helper oficial de webhooks. Aceita os dois formatos enviados pela PAIRUS durante a transição:\r\n * oficial (`{event, timestamp, data}` e assinatura hex) e legado da emissão de NF-e/NFC-e/NFS-e\r\n * (`{evento, dados}` e assinatura `sha256=<hex>`).\r\n */\r\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada (hexadecimal, sem prefixo) para o payload informado.\r\n */\r\n public static computeSignature(payload: string | Buffer, secret: string): string {\r\n return crypto\r\n .createHmac('sha256', secret)\r\n .update(payload)\r\n .digest('hex');\r\n }\r\n\r\n /**\r\n * Verifica de forma segura (resistente a timing attacks) a assinatura de um webhook.\r\n * Prefira sempre o corpo bruto: um objeto é reserializado e pode não reproduzir os bytes enviados.\r\n */\r\n public static verifySignature(\r\n payload: string | Buffer | Record<string, any>,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): boolean {\r\n if (!signature || !secret) {\r\n return false;\r\n }\r\n\r\n let payloadBuffer: Buffer;\r\n if (Buffer.isBuffer(payload)) {\r\n payloadBuffer = payload;\r\n } else if (typeof payload === 'string') {\r\n payloadBuffer = Buffer.from(payload, 'utf-8');\r\n } else {\r\n payloadBuffer = Buffer.from(JSON.stringify(payload), 'utf-8');\r\n }\r\n\r\n let recebida = signature.trim();\r\n if (recebida.toLowerCase().startsWith(PREFIXO_ASSINATURA)) {\r\n recebida = recebida.slice(PREFIXO_ASSINATURA.length);\r\n }\r\n\r\n const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(recebida, 'hex');\r\n const expectedBuf = Buffer.from(expectedSignature, 'hex');\r\n\r\n if (sigBuf.length !== expectedBuf.length) {\r\n return false;\r\n }\r\n\r\n return crypto.timingSafeEqual(sigBuf, expectedBuf);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Converte o envelope legado `{evento, dados}` para `{event, timestamp, data}`.\r\n */\r\n public static normalizeEvent<T = Record<string, any>>(raw: Record<string, any>): WebhookEvent<T> {\r\n if (!('event' in raw) && 'evento' in raw) {\r\n return { event: raw.evento, timestamp: raw.timestamp ?? null, data: (raw.dados ?? {}) as T };\r\n }\r\n return raw as WebhookEvent<T>;\r\n }\r\n\r\n /**\r\n * Valida a assinatura e converte o payload em objeto tipado WebhookEvent.\r\n */\r\n public static constructEvent<T = Record<string, any>>(\r\n payload: string | Buffer,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): WebhookEvent<T> {\r\n if (!this.verifySignature(payload, signature, secret)) {\r\n throw new InvalidSignatureError(\"Assinatura do webhook ('X-Pairus-Signature') é inválida.\");\r\n }\r\n\r\n const rawStr = Buffer.isBuffer(payload) ? payload.toString('utf-8') : payload;\r\n return this.normalizeEvent<T>(JSON.parse(rawStr));\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/empresas.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["export { PairusProductData } from './client.js';\r\nexport { Webhooks } from './webhooks.js';\r\nexport { ProductsResource } from './resources/products.js';\r\nexport { FiscalResource } from './resources/fiscal.js';\r\nexport { EmissaoResource } from './resources/emissao.js';\r\nexport { NFSeResource } from './resources/nfse.js';\r\nexport { DFeResource } from './resources/dfe.js';\r\nexport { EmpresasResource } from './resources/empresas.js';\r\nexport * from './errors.js';\r\nexport * from './config.js';\r\nexport * from './types/index.js';\r\n\r\n","/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.16.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;\r\n\r\n if (options.body && !isFormData && !reqHeaders['Content-Type']) {\r\n reqHeaders['Content-Type'] = 'application/json';\r\n }\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const bodyData = isFormData\r\n ? options.body\r\n : options.body\r\n ? JSON.stringify(options.body)\r\n : undefined;\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n body: bodyData,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return (await response.json()) as T;\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n // 502/503/504 e, com Idempotency-Key, o 409 de venda ainda em processamento: retry com a mesma chave\r\n const vendaEmProcessamento = response.status === 409 && 'Idempotency-Key' in reqHeaders;\r\n if (([502, 503, 504].includes(response.status) || vendaEmProcessamento) && attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestText(options: RequestOptions): Promise<string> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.16.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.text();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestBinary(options: RequestOptions): Promise<ArrayBuffer> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.16.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n EnviarCertificadoDFeInput,\r\n EnviarCertificadoDFeResponse,\r\n ListarDocumentosDFeParams,\r\n ListarDocumentosDFeResponse,\r\n ManifestarDFeInput,\r\n ManifestarDFeResponse,\r\n SincronizarDFeInput,\r\n SincronizarDFeResponse,\r\n StatusCertificadoDFeResponse,\r\n} from '../types/dfe.js';\r\n\r\nexport class DFeResource extends BaseResource {\r\n /**\r\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\r\n *\r\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\r\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\r\n */\r\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\r\n return this.request<SincronizarDFeResponse>({\r\n method: 'POST',\r\n path: '/v1/dfe/sincronizar',\r\n body: {\r\n cnpj: input.cnpj,\r\n ambiente: input.ambiente || 'producao',\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\r\n *\r\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\r\n * @returns Lista de documentos fiscais capturados e status de manifestação\r\n */\r\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\r\n const queryParams: Record<string, string> = {\r\n cnpj: params.cnpj,\r\n ambiente: params.ambiente || 'producao',\r\n };\r\n if (params.limite) {\r\n queryParams.limite = String(params.limite);\r\n }\r\n\r\n return this.request<ListarDocumentosDFeResponse>({\r\n method: 'GET',\r\n path: '/v1/dfe/documentos',\r\n params: queryParams,\r\n });\r\n }\r\n\r\n /**\r\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\r\n *\r\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\r\n * @returns Protocolo de homologação do evento na SEFAZ\r\n */\r\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\r\n return this.request<ManifestarDFeResponse>({\r\n method: 'POST',\r\n path: '/v1/dfe/manifestar',\r\n body: {\r\n cnpj: input.cnpj,\r\n chave_acesso: input.chave_acesso,\r\n tipo_evento: input.tipo_evento,\r\n justificativa: input.justificativa,\r\n ambiente: input.ambiente || 'producao',\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\r\n *\r\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\r\n * @returns Conteúdo do XML em formato string\r\n */\r\n public async baixarXml(chaveAcesso: string): Promise<string> {\r\n return this.requestText({\r\n method: 'GET',\r\n path: `/v1/dfe/xml/${chaveAcesso}`,\r\n });\r\n }\r\n\r\n /**\r\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\r\n *\r\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\r\n * @returns ArrayBuffer contendo o PDF binário\r\n */\r\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\r\n return this.requestBinary({\r\n method: 'GET',\r\n path: `/v1/dfe/danfe/${chaveAcesso}`,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta se há Certificado Digital A1 ativo para o CNPJ e quando ele vence.\r\n *\r\n * @param cnpj CNPJ do estabelecimento (com ou sem máscara)\r\n * @returns `status` 'ativo' (com vencimento e dias restantes) ou 'nao_configurado'\r\n */\r\n public async consultarCertificado(cnpj: string): Promise<StatusCertificadoDFeResponse> {\r\n return this.request<StatusCertificadoDFeResponse>({\r\n method: 'GET',\r\n path: '/v1/dfe/certificado',\r\n params: { cnpj },\r\n });\r\n }\r\n\r\n /**\r\n * Instala ou atualiza o Certificado Digital A1 da conta, usado na DF-e e na emissão de NF-e.\r\n *\r\n * @param input Apelido, arquivo .pfx em Base64 e senha\r\n * @returns Metadados do certificado validado e instalado\r\n */\r\n public async enviarCertificado(input: EnviarCertificadoDFeInput): Promise<EnviarCertificadoDFeResponse> {\r\n if (!input.alias || input.alias.trim().length < 2) {\r\n throw new Error('O apelido (alias) do certificado deve ter ao menos 2 caracteres.');\r\n }\r\n return this.request<EnviarCertificadoDFeResponse>({\r\n method: 'POST',\r\n path: '/v1/dfe/certificado',\r\n body: { alias: input.alias, pfx_base64: input.pfx_base64, senha: input.senha },\r\n });\r\n }\r\n}\r\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n NotaEmitidaResponse,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Consulta a situação atual de uma NF-e ou NFC-e emitida pela sua conta.\r\n *\r\n * @param chaveAcesso Chave de 44 dígitos da nota\r\n * @param options `incluirXml` traz o procNFe em Base64\r\n */\r\n public async consultar(chaveAcesso: string, options?: { incluirXml?: boolean }): Promise<NotaEmitidaResponse> {\r\n return this.request<NotaEmitidaResponse>({\r\n method: 'GET',\r\n path: `/v1/nfe/${chaveAcesso}`,\r\n params: { incluir_xml: String(options?.incluirXml ?? false) },\r\n });\r\n }\r\n\r\n /**\r\n * Localiza as notas emitidas para uma venda pela `referencia_externa` informada na emissão.\r\n * Lista vazia: nenhuma nota gravada para a venda, é seguro emitir.\r\n */\r\n public async buscarPorReferencia(cnpjEmitente: string, referenciaExterna: string): Promise<NotaEmitidaResponse[]> {\r\n return this.request<NotaEmitidaResponse[]>({\r\n method: 'GET',\r\n path: '/v1/nfe',\r\n params: { cnpj_emitente: cnpjEmitente, referencia_externa: referenciaExterna },\r\n });\r\n }\r\n\r\n /**\r\n * Baixa o DANFE em PDF de uma nota emitida (na contingência ainda não transmitida, com a tarja).\r\n */\r\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\r\n return this.requestBinary({ method: 'GET', path: `/v1/nfe/${chaveAcesso}/danfe` });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport { CscNFCeInput, CscNFCeStatus } from '../types/emissao.js';\r\n\r\n/** Cadastro de empresas emitentes (CSC da NFC-e). */\r\nexport class EmpresasResource extends BaseResource {\r\n /**\r\n * Grava o CSC da NFC-e do estabelecimento (gerado no portal da SEFAZ da UF).\r\n * O estabelecimento precisa de certificado próprio na conta; o código nunca é devolvido.\r\n */\r\n public async configurarCsc(cnpj: string, input: CscNFCeInput): Promise<CscNFCeStatus> {\r\n return this.request<CscNFCeStatus>({ method: 'PUT', path: `/v1/empresas/${cnpj}/csc`, body: input });\r\n }\r\n\r\n /** Indica, por ambiente, se o CSC da NFC-e está configurado (sem devolver o código). */\r\n public async consultarCsc(cnpj: string): Promise<CscNFCeStatus> {\r\n return this.request<CscNFCeStatus>({ method: 'GET', path: `/v1/empresas/${cnpj}/csc` });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoNFSeInput,\r\n CancelamentoNFSeResponse,\r\n NFSeEmissaoInput,\r\n NFSeEmissaoResponse,\r\n} from '../types/nfse.js';\r\n\r\nexport class NFSeResource extends BaseResource {\r\n /**\r\n * Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).\r\n * Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.\r\n */\r\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/emitir',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\r\n */\r\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.\r\n * Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.\r\n */\r\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\r\n return this.request<CancelamentoNFSeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/cancelar',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\r\n * Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.\r\n */\r\n async consultar(chaveOuNumero: string, opcoes: { sincronizar?: boolean } = {}): Promise<Record<string, any>> {\r\n return this.request<Record<string, any>>({\r\n method: 'GET',\r\n path: `/v1/nfse/${chaveOuNumero}`,\r\n params: opcoes.sincronizar ? { sincronizar: 'true' } : undefined,\r\n });\r\n }\r\n}\r\n\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n ProductDetails,\r\n ProductEnrichedDetails,\r\n ProductSearchResponse,\r\n ProductSearchResultItem,\r\n} from '../types/product.js';\r\n\r\n/** Primeiro valor preenchido (ignora undefined, null e texto vazio). */\r\nfunction primeiro<T>(...valores: Array<T | undefined | null | ''>): T | undefined {\r\n return valores.find((v) => v !== undefined && v !== null && v !== '') as T | undefined;\r\n}\r\n\r\nfunction numero(valor: any): number | undefined {\r\n const n = valor === undefined || valor === null || valor === '' ? NaN : Number(valor);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\n/** Converte o produto da API (layout NF-e + `infoAdicional`) para `ProductDetails`. */\r\nfunction produtoDaApi(data: any, gtinFallback = ''): ProductDetails {\r\n const prod = data?.produto || data || {};\r\n const info = prod.infoAdicional || {};\r\n return {\r\n gtin: String(primeiro(prod.GTIN, prod.gtin, gtinFallback) ?? ''),\r\n xProd: primeiro(prod.xProd, prod.descricao) || 'Descrição Indisponível',\r\n ncm: primeiro(prod.NCM, prod.ncm),\r\n cest: primeiro(prod.CEST, prod.cest),\r\n marca: primeiro(prod.marca, info.xMarca),\r\n fabricante: prod.fabricante,\r\n categoria: primeiro(prod.categoria, info.xCategoria),\r\n imagemUrl: primeiro(prod.imagem_url, prod.thumbnail, info.urlImagem),\r\n pesoBruto: numero(primeiro(prod.peso_bruto, info.pesoBruto)),\r\n pesoLiquido: numero(primeiro(prod.peso_liquido, info.pesoLiquido)),\r\n quantidadeEmbalagem: Number(prod.quantidade_embalagem || 1),\r\n tpGTIN: prod.tpGTIN ?? undefined,\r\n fonte: prod.fonte ?? undefined,\r\n infoAdicional: prod.infoAdicional ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte o produto enriquecido (`/v2/gtin`, scan ou item da busca) para `ProductEnrichedDetails`. */\r\nfunction produtoEnriquecidoDaApi(data: any, gtinFallback = ''): ProductEnrichedDetails {\r\n const prod = data?.produto || data || {};\r\n const base = produtoDaApi(prod, gtinFallback);\r\n const enriquecimento = prod.enriquecimentoIA || {};\r\n const atributos = enriquecimento.atributos || {};\r\n const temAtributos = Object.keys(atributos).length > 0;\r\n return {\r\n gtin: base.gtin,\r\n xProd: base.xProd,\r\n xProd_higienizado: enriquecimento.xProd_higienizado,\r\n descricao_completa: primeiro(prod.descricao_completa, enriquecimento.descricao_seo),\r\n ficha_tecnica: prod.ficha_tecnica ?? (temAtributos ? atributos : undefined),\r\n palavras_chave: prod.palavras_chave,\r\n ncm: base.ncm,\r\n cest: base.cest,\r\n marca: primeiro(prod.marca, atributos.marca, base.marca),\r\n categoria: primeiro(prod.categoria, enriquecimento.categoria_comercial, base.categoria),\r\n imagem_url: base.imagemUrl,\r\n peso_bruto: base.pesoBruto,\r\n peso_liquido: primeiro(numero(prod.peso_liquido), numero(atributos.peso_liquido), base.pesoLiquido),\r\n dados_tributarios_sugeridos: prod.dados_tributarios_sugeridos ?? prod.tributacaoIA ?? undefined,\r\n tpGTIN: base.tpGTIN,\r\n fonte: base.fonte,\r\n infoAdicional: base.infoAdicional,\r\n enriquecimentoIA: prod.enriquecimentoIA ?? undefined,\r\n tributacaoIA: prod.tributacaoIA ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte `/v2/gtin/search` (`resultados[].produto`; aceita o legado `produtos`). */\r\nfunction buscaDaApi(data: any, query: string): ProductSearchResponse {\r\n const itens: ProductSearchResultItem[] = (data?.resultados || data?.produtos || []).map((item: any) => {\r\n const prod = produtoEnriquecidoDaApi(item.produto || item);\r\n return {\r\n gtin: prod.gtin,\r\n xProd: prod.xProd,\r\n marca: prod.marca,\r\n categoria: prod.categoria,\r\n score: item.score !== undefined && item.score !== null ? Number(item.score) : undefined,\r\n justificativa: item.justificativa ?? undefined,\r\n ncm: prod.ncm,\r\n cest: prod.cest,\r\n imagem_url: prod.imagem_url,\r\n };\r\n });\r\n return {\r\n status: data?.status || 'success',\r\n provider: data?.provider || 'PAIRUS',\r\n total_encontrados: itens.length,\r\n termo_buscado: data?.query || query,\r\n motor_busca: data?.motor_busca,\r\n produtos: itens,\r\n };\r\n}\r\n\r\nexport class ProductsResource extends BaseResource {\r\n /**\r\n * Consulta dados oficiais de um produto por código de barras GTIN/EAN (V1).\r\n * @param gtin Código numérico de 8 a 14 dígitos.\r\n */\r\n public async get(gtin: string): Promise<ProductDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v1/gtin/${gtinLimpo}` });\r\n return produtoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Consulta dados enriquecidos por IA, com SEO e ficha técnica estruturada (V2).\r\n * @param gtin Código numérico do produto.\r\n */\r\n public async getEnriched(gtin: string): Promise<ProductEnrichedDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v2/gtin/${gtinLimpo}` });\r\n return produtoEnriquecidoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Executa busca semântica por intenção/linguagem natural (V2).\r\n * @param query Termo livre de busca (ex: 'refrigerante zero lata').\r\n */\r\n public async search(query: string): Promise<ProductSearchResponse> {\r\n const data = await this.request<any>({ method: 'GET', path: '/v2/gtin/search', params: { q: query } });\r\n return buscaDaApi(data, query);\r\n }\r\n\r\n /**\r\n * Reconhece código de barras por visão computacional a partir de foto JPEG (OCR V2).\r\n * @param file Blob, Buffer ou FormData com a imagem JPEG.\r\n */\r\n public async scan(file: Blob | Buffer | FormData): Promise<ProductEnrichedDetails> {\r\n let formData: FormData;\r\n\r\n if (typeof FormData !== 'undefined' && file instanceof FormData) {\r\n formData = file;\r\n } else {\r\n formData = new FormData();\r\n if (typeof Blob !== 'undefined' && file instanceof Blob) {\r\n formData.append('file', file, 'barcode.jpg');\r\n } else {\r\n // Node Buffer\r\n const blob = new Blob([file as any], { type: 'image/jpeg' });\r\n formData.append('file', blob, 'barcode.jpg');\r\n }\r\n }\r\n\r\n const data = await this.request<any>({ method: 'POST', path: '/v2/gtin/scan', body: formData });\r\n return produtoEnriquecidoDaApi(data);\r\n }\r\n}\r\n","import * as crypto from 'crypto';\r\nimport { InvalidSignatureError } from './errors.js';\r\nimport { WebhookEvent } from './types/webhook.js';\r\n\r\n/** Prefixo do formato legado dos eventos de emissão (aceito até 27/12/2026). */\r\nconst PREFIXO_ASSINATURA = 'sha256=';\r\n\r\n/**\r\n * Helper oficial de webhooks. Aceita os dois formatos enviados pela PAIRUS durante a transição:\r\n * oficial (`{event, timestamp, data}` e assinatura hex) e legado da emissão de NF-e/NFC-e/NFS-e\r\n * (`{evento, dados}` e assinatura `sha256=<hex>`).\r\n */\r\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada (hexadecimal, sem prefixo) para o payload informado.\r\n */\r\n public static computeSignature(payload: string | Buffer, secret: string): string {\r\n return crypto\r\n .createHmac('sha256', secret)\r\n .update(payload)\r\n .digest('hex');\r\n }\r\n\r\n /**\r\n * Verifica de forma segura (resistente a timing attacks) a assinatura de um webhook.\r\n * Prefira sempre o corpo bruto: um objeto é reserializado e pode não reproduzir os bytes enviados.\r\n */\r\n public static verifySignature(\r\n payload: string | Buffer | Record<string, any>,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): boolean {\r\n if (!signature || !secret) {\r\n return false;\r\n }\r\n\r\n let payloadBuffer: Buffer;\r\n if (Buffer.isBuffer(payload)) {\r\n payloadBuffer = payload;\r\n } else if (typeof payload === 'string') {\r\n payloadBuffer = Buffer.from(payload, 'utf-8');\r\n } else {\r\n payloadBuffer = Buffer.from(JSON.stringify(payload), 'utf-8');\r\n }\r\n\r\n let recebida = signature.trim();\r\n if (recebida.toLowerCase().startsWith(PREFIXO_ASSINATURA)) {\r\n recebida = recebida.slice(PREFIXO_ASSINATURA.length);\r\n }\r\n\r\n const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(recebida, 'hex');\r\n const expectedBuf = Buffer.from(expectedSignature, 'hex');\r\n\r\n if (sigBuf.length !== expectedBuf.length) {\r\n return false;\r\n }\r\n\r\n return crypto.timingSafeEqual(sigBuf, expectedBuf);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Converte o envelope legado `{evento, dados}` para `{event, timestamp, data}`.\r\n */\r\n public static normalizeEvent<T = Record<string, any>>(raw: Record<string, any>): WebhookEvent<T> {\r\n if (!('event' in raw) && 'evento' in raw) {\r\n return { event: raw.evento, timestamp: raw.timestamp ?? null, data: (raw.dados ?? {}) as T };\r\n }\r\n return raw as WebhookEvent<T>;\r\n }\r\n\r\n /**\r\n * Valida a assinatura e converte o payload em objeto tipado WebhookEvent.\r\n */\r\n public static constructEvent<T = Record<string, any>>(\r\n payload: string | Buffer,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): WebhookEvent<T> {\r\n if (!this.verifySignature(payload, signature, secret)) {\r\n throw new InvalidSignatureError(\"Assinatura do webhook ('X-Pairus-Signature') é inválida.\");\r\n }\r\n\r\n const rawStr = Buffer.isBuffer(payload) ? payload.toString('utf-8') : payload;\r\n return this.normalizeEvent<T>(JSON.parse(rawStr));\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { EmpresasResource } from './resources/empresas.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n public readonly empresas: EmpresasResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.empresas = new EmpresasResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -74,7 +74,7 @@ var BaseResource = class {
74
74
  const reqHeaders = {
75
75
  "Accept": "application/json",
76
76
  "X-API-Key": this.apiKey,
77
- "User-Agent": "Pairus-NodeJS-SDK/1.14.0",
77
+ "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
78
78
  ...options.headers || {}
79
79
  };
80
80
  const isFormData = typeof FormData !== "undefined" && options.body instanceof FormData;
@@ -145,7 +145,7 @@ var BaseResource = class {
145
145
  const reqHeaders = {
146
146
  "Accept": "*/*",
147
147
  "X-API-Key": this.apiKey,
148
- "User-Agent": "Pairus-NodeJS-SDK/1.14.0",
148
+ "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
149
149
  ...options.headers || {}
150
150
  };
151
151
  let lastError = null;
@@ -204,7 +204,7 @@ var BaseResource = class {
204
204
  const reqHeaders = {
205
205
  "Accept": "*/*",
206
206
  "X-API-Key": this.apiKey,
207
- "User-Agent": "Pairus-NodeJS-SDK/1.14.0",
207
+ "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
208
208
  ...options.headers || {}
209
209
  };
210
210
  let lastError = null;
@@ -337,6 +337,35 @@ var DFeResource = class extends BaseResource {
337
337
  path: `/v1/dfe/danfe/${chaveAcesso}`
338
338
  });
339
339
  }
340
+ /**
341
+ * Consulta se há Certificado Digital A1 ativo para o CNPJ e quando ele vence.
342
+ *
343
+ * @param cnpj CNPJ do estabelecimento (com ou sem máscara)
344
+ * @returns `status` 'ativo' (com vencimento e dias restantes) ou 'nao_configurado'
345
+ */
346
+ async consultarCertificado(cnpj) {
347
+ return this.request({
348
+ method: "GET",
349
+ path: "/v1/dfe/certificado",
350
+ params: { cnpj }
351
+ });
352
+ }
353
+ /**
354
+ * Instala ou atualiza o Certificado Digital A1 da conta, usado na DF-e e na emissão de NF-e.
355
+ *
356
+ * @param input Apelido, arquivo .pfx em Base64 e senha
357
+ * @returns Metadados do certificado validado e instalado
358
+ */
359
+ async enviarCertificado(input) {
360
+ if (!input.alias || input.alias.trim().length < 2) {
361
+ throw new Error("O apelido (alias) do certificado deve ter ao menos 2 caracteres.");
362
+ }
363
+ return this.request({
364
+ method: "POST",
365
+ path: "/v1/dfe/certificado",
366
+ body: { alias: input.alias, pfx_base64: input.pfx_base64, senha: input.senha }
367
+ });
368
+ }
340
369
  };
341
370
 
342
371
  // src/resources/emissao.ts
@@ -423,6 +452,51 @@ var EmissaoResource = class extends BaseResource {
423
452
  }
424
453
  });
425
454
  }
455
+ /**
456
+ * Consulta a situação atual de uma NF-e ou NFC-e emitida pela sua conta.
457
+ *
458
+ * @param chaveAcesso Chave de 44 dígitos da nota
459
+ * @param options `incluirXml` traz o procNFe em Base64
460
+ */
461
+ async consultar(chaveAcesso, options) {
462
+ return this.request({
463
+ method: "GET",
464
+ path: `/v1/nfe/${chaveAcesso}`,
465
+ params: { incluir_xml: String(options?.incluirXml ?? false) }
466
+ });
467
+ }
468
+ /**
469
+ * Localiza as notas emitidas para uma venda pela `referencia_externa` informada na emissão.
470
+ * Lista vazia: nenhuma nota gravada para a venda, é seguro emitir.
471
+ */
472
+ async buscarPorReferencia(cnpjEmitente, referenciaExterna) {
473
+ return this.request({
474
+ method: "GET",
475
+ path: "/v1/nfe",
476
+ params: { cnpj_emitente: cnpjEmitente, referencia_externa: referenciaExterna }
477
+ });
478
+ }
479
+ /**
480
+ * Baixa o DANFE em PDF de uma nota emitida (na contingência ainda não transmitida, com a tarja).
481
+ */
482
+ async baixarDanfe(chaveAcesso) {
483
+ return this.requestBinary({ method: "GET", path: `/v1/nfe/${chaveAcesso}/danfe` });
484
+ }
485
+ };
486
+
487
+ // src/resources/empresas.ts
488
+ var EmpresasResource = class extends BaseResource {
489
+ /**
490
+ * Grava o CSC da NFC-e do estabelecimento (gerado no portal da SEFAZ da UF).
491
+ * O estabelecimento precisa de certificado próprio na conta; o código nunca é devolvido.
492
+ */
493
+ async configurarCsc(cnpj, input) {
494
+ return this.request({ method: "PUT", path: `/v1/empresas/${cnpj}/csc`, body: input });
495
+ }
496
+ /** Indica, por ambiente, se o CSC da NFC-e está configurado (sem devolver o código). */
497
+ async consultarCsc(cnpj) {
498
+ return this.request({ method: "GET", path: `/v1/empresas/${cnpj}/csc` });
499
+ }
426
500
  };
427
501
 
428
502
  // src/resources/fiscal.ts
@@ -745,6 +819,7 @@ var PairusProductData = class {
745
819
  emissao;
746
820
  nfse;
747
821
  dfe;
822
+ empresas;
748
823
  constructor(options) {
749
824
  const apiKey = options?.apiKey || (typeof process !== "undefined" ? process.env.PAIRUS_API_KEY : void 0);
750
825
  if (!apiKey) {
@@ -760,6 +835,7 @@ var PairusProductData = class {
760
835
  this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);
761
836
  this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);
762
837
  this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);
838
+ this.empresas = new EmpresasResource(apiKey, baseUrl, timeoutMs, maxRetries);
763
839
  }
764
840
  };
765
841
  export {
@@ -769,6 +845,7 @@ export {
769
845
  DEFAULT_TIMEOUT_MS,
770
846
  DFeResource,
771
847
  EmissaoResource,
848
+ EmpresasResource,
772
849
  FiscalResource,
773
850
  InvalidSignatureError,
774
851
  NFSeResource,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.14.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;\r\n\r\n if (options.body && !isFormData && !reqHeaders['Content-Type']) {\r\n reqHeaders['Content-Type'] = 'application/json';\r\n }\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const bodyData = isFormData\r\n ? options.body\r\n : options.body\r\n ? JSON.stringify(options.body)\r\n : undefined;\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n body: bodyData,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return (await response.json()) as T;\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n // 502/503/504 e, com Idempotency-Key, o 409 de venda ainda em processamento: retry com a mesma chave\r\n const vendaEmProcessamento = response.status === 409 && 'Idempotency-Key' in reqHeaders;\r\n if (([502, 503, 504].includes(response.status) || vendaEmProcessamento) && attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestText(options: RequestOptions): Promise<string> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.14.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.text();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestBinary(options: RequestOptions): Promise<ArrayBuffer> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.14.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n ListarDocumentosDFeParams,\n ListarDocumentosDFeResponse,\n ManifestarDFeInput,\n ManifestarDFeResponse,\n SincronizarDFeInput,\n SincronizarDFeResponse,\n} from '../types/dfe.js';\n\nexport class DFeResource extends BaseResource {\n /**\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\n *\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\n */\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\n return this.request<SincronizarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/sincronizar',\n body: {\n cnpj: input.cnpj,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\n *\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\n * @returns Lista de documentos fiscais capturados e status de manifestação\n */\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\n const queryParams: Record<string, string> = {\n cnpj: params.cnpj,\n ambiente: params.ambiente || 'producao',\n };\n if (params.limite) {\n queryParams.limite = String(params.limite);\n }\n\n return this.request<ListarDocumentosDFeResponse>({\n method: 'GET',\n path: '/v1/dfe/documentos',\n params: queryParams,\n });\n }\n\n /**\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\n *\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\n * @returns Protocolo de homologação do evento na SEFAZ\n */\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\n return this.request<ManifestarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/manifestar',\n body: {\n cnpj: input.cnpj,\n chave_acesso: input.chave_acesso,\n tipo_evento: input.tipo_evento,\n justificativa: input.justificativa,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns Conteúdo do XML em formato string\n */\n public async baixarXml(chaveAcesso: string): Promise<string> {\n return this.requestText({\n method: 'GET',\n path: `/v1/dfe/xml/${chaveAcesso}`,\n });\n }\n\n /**\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns ArrayBuffer contendo o PDF binário\n */\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\n return this.requestBinary({\n method: 'GET',\n path: `/v1/dfe/danfe/${chaveAcesso}`,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoNFSeInput,\r\n CancelamentoNFSeResponse,\r\n NFSeEmissaoInput,\r\n NFSeEmissaoResponse,\r\n} from '../types/nfse.js';\r\n\r\nexport class NFSeResource extends BaseResource {\r\n /**\r\n * Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).\r\n * Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.\r\n */\r\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/emitir',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\r\n */\r\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.\r\n * Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.\r\n */\r\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\r\n return this.request<CancelamentoNFSeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/cancelar',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\r\n * Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.\r\n */\r\n async consultar(chaveOuNumero: string, opcoes: { sincronizar?: boolean } = {}): Promise<Record<string, any>> {\r\n return this.request<Record<string, any>>({\r\n method: 'GET',\r\n path: `/v1/nfse/${chaveOuNumero}`,\r\n params: opcoes.sincronizar ? { sincronizar: 'true' } : undefined,\r\n });\r\n }\r\n}\r\n\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n ProductDetails,\r\n ProductEnrichedDetails,\r\n ProductSearchResponse,\r\n ProductSearchResultItem,\r\n} from '../types/product.js';\r\n\r\n/** Primeiro valor preenchido (ignora undefined, null e texto vazio). */\r\nfunction primeiro<T>(...valores: Array<T | undefined | null | ''>): T | undefined {\r\n return valores.find((v) => v !== undefined && v !== null && v !== '') as T | undefined;\r\n}\r\n\r\nfunction numero(valor: any): number | undefined {\r\n const n = valor === undefined || valor === null || valor === '' ? NaN : Number(valor);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\n/** Converte o produto da API (layout NF-e + `infoAdicional`) para `ProductDetails`. */\r\nfunction produtoDaApi(data: any, gtinFallback = ''): ProductDetails {\r\n const prod = data?.produto || data || {};\r\n const info = prod.infoAdicional || {};\r\n return {\r\n gtin: String(primeiro(prod.GTIN, prod.gtin, gtinFallback) ?? ''),\r\n xProd: primeiro(prod.xProd, prod.descricao) || 'Descrição Indisponível',\r\n ncm: primeiro(prod.NCM, prod.ncm),\r\n cest: primeiro(prod.CEST, prod.cest),\r\n marca: primeiro(prod.marca, info.xMarca),\r\n fabricante: prod.fabricante,\r\n categoria: primeiro(prod.categoria, info.xCategoria),\r\n imagemUrl: primeiro(prod.imagem_url, prod.thumbnail, info.urlImagem),\r\n pesoBruto: numero(primeiro(prod.peso_bruto, info.pesoBruto)),\r\n pesoLiquido: numero(primeiro(prod.peso_liquido, info.pesoLiquido)),\r\n quantidadeEmbalagem: Number(prod.quantidade_embalagem || 1),\r\n tpGTIN: prod.tpGTIN ?? undefined,\r\n fonte: prod.fonte ?? undefined,\r\n infoAdicional: prod.infoAdicional ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte o produto enriquecido (`/v2/gtin`, scan ou item da busca) para `ProductEnrichedDetails`. */\r\nfunction produtoEnriquecidoDaApi(data: any, gtinFallback = ''): ProductEnrichedDetails {\r\n const prod = data?.produto || data || {};\r\n const base = produtoDaApi(prod, gtinFallback);\r\n const enriquecimento = prod.enriquecimentoIA || {};\r\n const atributos = enriquecimento.atributos || {};\r\n const temAtributos = Object.keys(atributos).length > 0;\r\n return {\r\n gtin: base.gtin,\r\n xProd: base.xProd,\r\n xProd_higienizado: enriquecimento.xProd_higienizado,\r\n descricao_completa: primeiro(prod.descricao_completa, enriquecimento.descricao_seo),\r\n ficha_tecnica: prod.ficha_tecnica ?? (temAtributos ? atributos : undefined),\r\n palavras_chave: prod.palavras_chave,\r\n ncm: base.ncm,\r\n cest: base.cest,\r\n marca: primeiro(prod.marca, atributos.marca, base.marca),\r\n categoria: primeiro(prod.categoria, enriquecimento.categoria_comercial, base.categoria),\r\n imagem_url: base.imagemUrl,\r\n peso_bruto: base.pesoBruto,\r\n peso_liquido: primeiro(numero(prod.peso_liquido), numero(atributos.peso_liquido), base.pesoLiquido),\r\n dados_tributarios_sugeridos: prod.dados_tributarios_sugeridos ?? prod.tributacaoIA ?? undefined,\r\n tpGTIN: base.tpGTIN,\r\n fonte: base.fonte,\r\n infoAdicional: base.infoAdicional,\r\n enriquecimentoIA: prod.enriquecimentoIA ?? undefined,\r\n tributacaoIA: prod.tributacaoIA ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte `/v2/gtin/search` (`resultados[].produto`; aceita o legado `produtos`). */\r\nfunction buscaDaApi(data: any, query: string): ProductSearchResponse {\r\n const itens: ProductSearchResultItem[] = (data?.resultados || data?.produtos || []).map((item: any) => {\r\n const prod = produtoEnriquecidoDaApi(item.produto || item);\r\n return {\r\n gtin: prod.gtin,\r\n xProd: prod.xProd,\r\n marca: prod.marca,\r\n categoria: prod.categoria,\r\n score: item.score !== undefined && item.score !== null ? Number(item.score) : undefined,\r\n justificativa: item.justificativa ?? undefined,\r\n ncm: prod.ncm,\r\n cest: prod.cest,\r\n imagem_url: prod.imagem_url,\r\n };\r\n });\r\n return {\r\n status: data?.status || 'success',\r\n provider: data?.provider || 'PAIRUS',\r\n total_encontrados: itens.length,\r\n termo_buscado: data?.query || query,\r\n motor_busca: data?.motor_busca,\r\n produtos: itens,\r\n };\r\n}\r\n\r\nexport class ProductsResource extends BaseResource {\r\n /**\r\n * Consulta dados oficiais de um produto por código de barras GTIN/EAN (V1).\r\n * @param gtin Código numérico de 8 a 14 dígitos.\r\n */\r\n public async get(gtin: string): Promise<ProductDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v1/gtin/${gtinLimpo}` });\r\n return produtoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Consulta dados enriquecidos por IA, com SEO e ficha técnica estruturada (V2).\r\n * @param gtin Código numérico do produto.\r\n */\r\n public async getEnriched(gtin: string): Promise<ProductEnrichedDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v2/gtin/${gtinLimpo}` });\r\n return produtoEnriquecidoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Executa busca semântica por intenção/linguagem natural (V2).\r\n * @param query Termo livre de busca (ex: 'refrigerante zero lata').\r\n */\r\n public async search(query: string): Promise<ProductSearchResponse> {\r\n const data = await this.request<any>({ method: 'GET', path: '/v2/gtin/search', params: { q: query } });\r\n return buscaDaApi(data, query);\r\n }\r\n\r\n /**\r\n * Reconhece código de barras por visão computacional a partir de foto JPEG (OCR V2).\r\n * @param file Blob, Buffer ou FormData com a imagem JPEG.\r\n */\r\n public async scan(file: Blob | Buffer | FormData): Promise<ProductEnrichedDetails> {\r\n let formData: FormData;\r\n\r\n if (typeof FormData !== 'undefined' && file instanceof FormData) {\r\n formData = file;\r\n } else {\r\n formData = new FormData();\r\n if (typeof Blob !== 'undefined' && file instanceof Blob) {\r\n formData.append('file', file, 'barcode.jpg');\r\n } else {\r\n // Node Buffer\r\n const blob = new Blob([file as any], { type: 'image/jpeg' });\r\n formData.append('file', blob, 'barcode.jpg');\r\n }\r\n }\r\n\r\n const data = await this.request<any>({ method: 'POST', path: '/v2/gtin/scan', body: formData });\r\n return produtoEnriquecidoDaApi(data);\r\n }\r\n}\r\n","import * as crypto from 'crypto';\r\nimport { InvalidSignatureError } from './errors.js';\r\nimport { WebhookEvent } from './types/webhook.js';\r\n\r\n/** Prefixo do formato legado dos eventos de emissão (aceito até 27/12/2026). */\r\nconst PREFIXO_ASSINATURA = 'sha256=';\r\n\r\n/**\r\n * Helper oficial de webhooks. Aceita os dois formatos enviados pela PAIRUS durante a transição:\r\n * oficial (`{event, timestamp, data}` e assinatura hex) e legado da emissão de NF-e/NFC-e/NFS-e\r\n * (`{evento, dados}` e assinatura `sha256=<hex>`).\r\n */\r\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada (hexadecimal, sem prefixo) para o payload informado.\r\n */\r\n public static computeSignature(payload: string | Buffer, secret: string): string {\r\n return crypto\r\n .createHmac('sha256', secret)\r\n .update(payload)\r\n .digest('hex');\r\n }\r\n\r\n /**\r\n * Verifica de forma segura (resistente a timing attacks) a assinatura de um webhook.\r\n * Prefira sempre o corpo bruto: um objeto é reserializado e pode não reproduzir os bytes enviados.\r\n */\r\n public static verifySignature(\r\n payload: string | Buffer | Record<string, any>,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): boolean {\r\n if (!signature || !secret) {\r\n return false;\r\n }\r\n\r\n let payloadBuffer: Buffer;\r\n if (Buffer.isBuffer(payload)) {\r\n payloadBuffer = payload;\r\n } else if (typeof payload === 'string') {\r\n payloadBuffer = Buffer.from(payload, 'utf-8');\r\n } else {\r\n payloadBuffer = Buffer.from(JSON.stringify(payload), 'utf-8');\r\n }\r\n\r\n let recebida = signature.trim();\r\n if (recebida.toLowerCase().startsWith(PREFIXO_ASSINATURA)) {\r\n recebida = recebida.slice(PREFIXO_ASSINATURA.length);\r\n }\r\n\r\n const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(recebida, 'hex');\r\n const expectedBuf = Buffer.from(expectedSignature, 'hex');\r\n\r\n if (sigBuf.length !== expectedBuf.length) {\r\n return false;\r\n }\r\n\r\n return crypto.timingSafeEqual(sigBuf, expectedBuf);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Converte o envelope legado `{evento, dados}` para `{event, timestamp, data}`.\r\n */\r\n public static normalizeEvent<T = Record<string, any>>(raw: Record<string, any>): WebhookEvent<T> {\r\n if (!('event' in raw) && 'evento' in raw) {\r\n return { event: raw.evento, timestamp: raw.timestamp ?? null, data: (raw.dados ?? {}) as T };\r\n }\r\n return raw as WebhookEvent<T>;\r\n }\r\n\r\n /**\r\n * Valida a assinatura e converte o payload em objeto tipado WebhookEvent.\r\n */\r\n public static constructEvent<T = Record<string, any>>(\r\n payload: string | Buffer,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): WebhookEvent<T> {\r\n if (!this.verifySignature(payload, signature, secret)) {\r\n throw new InvalidSignatureError(\"Assinatura do webhook ('X-Pairus-Signature') é inválida.\");\r\n }\r\n\r\n const rawStr = Buffer.isBuffer(payload) ? payload.toString('utf-8') : payload;\r\n return this.normalizeEvent<T>(JSON.parse(rawStr));\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/empresas.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.16.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;\r\n\r\n if (options.body && !isFormData && !reqHeaders['Content-Type']) {\r\n reqHeaders['Content-Type'] = 'application/json';\r\n }\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const bodyData = isFormData\r\n ? options.body\r\n : options.body\r\n ? JSON.stringify(options.body)\r\n : undefined;\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n body: bodyData,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return (await response.json()) as T;\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n // 502/503/504 e, com Idempotency-Key, o 409 de venda ainda em processamento: retry com a mesma chave\r\n const vendaEmProcessamento = response.status === 409 && 'Idempotency-Key' in reqHeaders;\r\n if (([502, 503, 504].includes(response.status) || vendaEmProcessamento) && attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestText(options: RequestOptions): Promise<string> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.16.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.text();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n\r\n protected async requestBinary(options: RequestOptions): Promise<ArrayBuffer> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': '*/*',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.16.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n EnviarCertificadoDFeInput,\r\n EnviarCertificadoDFeResponse,\r\n ListarDocumentosDFeParams,\r\n ListarDocumentosDFeResponse,\r\n ManifestarDFeInput,\r\n ManifestarDFeResponse,\r\n SincronizarDFeInput,\r\n SincronizarDFeResponse,\r\n StatusCertificadoDFeResponse,\r\n} from '../types/dfe.js';\r\n\r\nexport class DFeResource extends BaseResource {\r\n /**\r\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\r\n *\r\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\r\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\r\n */\r\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\r\n return this.request<SincronizarDFeResponse>({\r\n method: 'POST',\r\n path: '/v1/dfe/sincronizar',\r\n body: {\r\n cnpj: input.cnpj,\r\n ambiente: input.ambiente || 'producao',\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\r\n *\r\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\r\n * @returns Lista de documentos fiscais capturados e status de manifestação\r\n */\r\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\r\n const queryParams: Record<string, string> = {\r\n cnpj: params.cnpj,\r\n ambiente: params.ambiente || 'producao',\r\n };\r\n if (params.limite) {\r\n queryParams.limite = String(params.limite);\r\n }\r\n\r\n return this.request<ListarDocumentosDFeResponse>({\r\n method: 'GET',\r\n path: '/v1/dfe/documentos',\r\n params: queryParams,\r\n });\r\n }\r\n\r\n /**\r\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\r\n *\r\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\r\n * @returns Protocolo de homologação do evento na SEFAZ\r\n */\r\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\r\n return this.request<ManifestarDFeResponse>({\r\n method: 'POST',\r\n path: '/v1/dfe/manifestar',\r\n body: {\r\n cnpj: input.cnpj,\r\n chave_acesso: input.chave_acesso,\r\n tipo_evento: input.tipo_evento,\r\n justificativa: input.justificativa,\r\n ambiente: input.ambiente || 'producao',\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\r\n *\r\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\r\n * @returns Conteúdo do XML em formato string\r\n */\r\n public async baixarXml(chaveAcesso: string): Promise<string> {\r\n return this.requestText({\r\n method: 'GET',\r\n path: `/v1/dfe/xml/${chaveAcesso}`,\r\n });\r\n }\r\n\r\n /**\r\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\r\n *\r\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\r\n * @returns ArrayBuffer contendo o PDF binário\r\n */\r\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\r\n return this.requestBinary({\r\n method: 'GET',\r\n path: `/v1/dfe/danfe/${chaveAcesso}`,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta se há Certificado Digital A1 ativo para o CNPJ e quando ele vence.\r\n *\r\n * @param cnpj CNPJ do estabelecimento (com ou sem máscara)\r\n * @returns `status` 'ativo' (com vencimento e dias restantes) ou 'nao_configurado'\r\n */\r\n public async consultarCertificado(cnpj: string): Promise<StatusCertificadoDFeResponse> {\r\n return this.request<StatusCertificadoDFeResponse>({\r\n method: 'GET',\r\n path: '/v1/dfe/certificado',\r\n params: { cnpj },\r\n });\r\n }\r\n\r\n /**\r\n * Instala ou atualiza o Certificado Digital A1 da conta, usado na DF-e e na emissão de NF-e.\r\n *\r\n * @param input Apelido, arquivo .pfx em Base64 e senha\r\n * @returns Metadados do certificado validado e instalado\r\n */\r\n public async enviarCertificado(input: EnviarCertificadoDFeInput): Promise<EnviarCertificadoDFeResponse> {\r\n if (!input.alias || input.alias.trim().length < 2) {\r\n throw new Error('O apelido (alias) do certificado deve ter ao menos 2 caracteres.');\r\n }\r\n return this.request<EnviarCertificadoDFeResponse>({\r\n method: 'POST',\r\n path: '/v1/dfe/certificado',\r\n body: { alias: input.alias, pfx_base64: input.pfx_base64, senha: input.senha },\r\n });\r\n }\r\n}\r\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n NotaEmitidaResponse,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Consulta a situação atual de uma NF-e ou NFC-e emitida pela sua conta.\r\n *\r\n * @param chaveAcesso Chave de 44 dígitos da nota\r\n * @param options `incluirXml` traz o procNFe em Base64\r\n */\r\n public async consultar(chaveAcesso: string, options?: { incluirXml?: boolean }): Promise<NotaEmitidaResponse> {\r\n return this.request<NotaEmitidaResponse>({\r\n method: 'GET',\r\n path: `/v1/nfe/${chaveAcesso}`,\r\n params: { incluir_xml: String(options?.incluirXml ?? false) },\r\n });\r\n }\r\n\r\n /**\r\n * Localiza as notas emitidas para uma venda pela `referencia_externa` informada na emissão.\r\n * Lista vazia: nenhuma nota gravada para a venda, é seguro emitir.\r\n */\r\n public async buscarPorReferencia(cnpjEmitente: string, referenciaExterna: string): Promise<NotaEmitidaResponse[]> {\r\n return this.request<NotaEmitidaResponse[]>({\r\n method: 'GET',\r\n path: '/v1/nfe',\r\n params: { cnpj_emitente: cnpjEmitente, referencia_externa: referenciaExterna },\r\n });\r\n }\r\n\r\n /**\r\n * Baixa o DANFE em PDF de uma nota emitida (na contingência ainda não transmitida, com a tarja).\r\n */\r\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\r\n return this.requestBinary({ method: 'GET', path: `/v1/nfe/${chaveAcesso}/danfe` });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport { CscNFCeInput, CscNFCeStatus } from '../types/emissao.js';\r\n\r\n/** Cadastro de empresas emitentes (CSC da NFC-e). */\r\nexport class EmpresasResource extends BaseResource {\r\n /**\r\n * Grava o CSC da NFC-e do estabelecimento (gerado no portal da SEFAZ da UF).\r\n * O estabelecimento precisa de certificado próprio na conta; o código nunca é devolvido.\r\n */\r\n public async configurarCsc(cnpj: string, input: CscNFCeInput): Promise<CscNFCeStatus> {\r\n return this.request<CscNFCeStatus>({ method: 'PUT', path: `/v1/empresas/${cnpj}/csc`, body: input });\r\n }\r\n\r\n /** Indica, por ambiente, se o CSC da NFC-e está configurado (sem devolver o código). */\r\n public async consultarCsc(cnpj: string): Promise<CscNFCeStatus> {\r\n return this.request<CscNFCeStatus>({ method: 'GET', path: `/v1/empresas/${cnpj}/csc` });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoNFSeInput,\r\n CancelamentoNFSeResponse,\r\n NFSeEmissaoInput,\r\n NFSeEmissaoResponse,\r\n} from '../types/nfse.js';\r\n\r\nexport class NFSeResource extends BaseResource {\r\n /**\r\n * Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).\r\n * Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.\r\n */\r\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/emitir',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\r\n */\r\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.\r\n * Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.\r\n */\r\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\r\n return this.request<CancelamentoNFSeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/cancelar',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\r\n * Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.\r\n */\r\n async consultar(chaveOuNumero: string, opcoes: { sincronizar?: boolean } = {}): Promise<Record<string, any>> {\r\n return this.request<Record<string, any>>({\r\n method: 'GET',\r\n path: `/v1/nfse/${chaveOuNumero}`,\r\n params: opcoes.sincronizar ? { sincronizar: 'true' } : undefined,\r\n });\r\n }\r\n}\r\n\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n ProductDetails,\r\n ProductEnrichedDetails,\r\n ProductSearchResponse,\r\n ProductSearchResultItem,\r\n} from '../types/product.js';\r\n\r\n/** Primeiro valor preenchido (ignora undefined, null e texto vazio). */\r\nfunction primeiro<T>(...valores: Array<T | undefined | null | ''>): T | undefined {\r\n return valores.find((v) => v !== undefined && v !== null && v !== '') as T | undefined;\r\n}\r\n\r\nfunction numero(valor: any): number | undefined {\r\n const n = valor === undefined || valor === null || valor === '' ? NaN : Number(valor);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\n/** Converte o produto da API (layout NF-e + `infoAdicional`) para `ProductDetails`. */\r\nfunction produtoDaApi(data: any, gtinFallback = ''): ProductDetails {\r\n const prod = data?.produto || data || {};\r\n const info = prod.infoAdicional || {};\r\n return {\r\n gtin: String(primeiro(prod.GTIN, prod.gtin, gtinFallback) ?? ''),\r\n xProd: primeiro(prod.xProd, prod.descricao) || 'Descrição Indisponível',\r\n ncm: primeiro(prod.NCM, prod.ncm),\r\n cest: primeiro(prod.CEST, prod.cest),\r\n marca: primeiro(prod.marca, info.xMarca),\r\n fabricante: prod.fabricante,\r\n categoria: primeiro(prod.categoria, info.xCategoria),\r\n imagemUrl: primeiro(prod.imagem_url, prod.thumbnail, info.urlImagem),\r\n pesoBruto: numero(primeiro(prod.peso_bruto, info.pesoBruto)),\r\n pesoLiquido: numero(primeiro(prod.peso_liquido, info.pesoLiquido)),\r\n quantidadeEmbalagem: Number(prod.quantidade_embalagem || 1),\r\n tpGTIN: prod.tpGTIN ?? undefined,\r\n fonte: prod.fonte ?? undefined,\r\n infoAdicional: prod.infoAdicional ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte o produto enriquecido (`/v2/gtin`, scan ou item da busca) para `ProductEnrichedDetails`. */\r\nfunction produtoEnriquecidoDaApi(data: any, gtinFallback = ''): ProductEnrichedDetails {\r\n const prod = data?.produto || data || {};\r\n const base = produtoDaApi(prod, gtinFallback);\r\n const enriquecimento = prod.enriquecimentoIA || {};\r\n const atributos = enriquecimento.atributos || {};\r\n const temAtributos = Object.keys(atributos).length > 0;\r\n return {\r\n gtin: base.gtin,\r\n xProd: base.xProd,\r\n xProd_higienizado: enriquecimento.xProd_higienizado,\r\n descricao_completa: primeiro(prod.descricao_completa, enriquecimento.descricao_seo),\r\n ficha_tecnica: prod.ficha_tecnica ?? (temAtributos ? atributos : undefined),\r\n palavras_chave: prod.palavras_chave,\r\n ncm: base.ncm,\r\n cest: base.cest,\r\n marca: primeiro(prod.marca, atributos.marca, base.marca),\r\n categoria: primeiro(prod.categoria, enriquecimento.categoria_comercial, base.categoria),\r\n imagem_url: base.imagemUrl,\r\n peso_bruto: base.pesoBruto,\r\n peso_liquido: primeiro(numero(prod.peso_liquido), numero(atributos.peso_liquido), base.pesoLiquido),\r\n dados_tributarios_sugeridos: prod.dados_tributarios_sugeridos ?? prod.tributacaoIA ?? undefined,\r\n tpGTIN: base.tpGTIN,\r\n fonte: base.fonte,\r\n infoAdicional: base.infoAdicional,\r\n enriquecimentoIA: prod.enriquecimentoIA ?? undefined,\r\n tributacaoIA: prod.tributacaoIA ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte `/v2/gtin/search` (`resultados[].produto`; aceita o legado `produtos`). */\r\nfunction buscaDaApi(data: any, query: string): ProductSearchResponse {\r\n const itens: ProductSearchResultItem[] = (data?.resultados || data?.produtos || []).map((item: any) => {\r\n const prod = produtoEnriquecidoDaApi(item.produto || item);\r\n return {\r\n gtin: prod.gtin,\r\n xProd: prod.xProd,\r\n marca: prod.marca,\r\n categoria: prod.categoria,\r\n score: item.score !== undefined && item.score !== null ? Number(item.score) : undefined,\r\n justificativa: item.justificativa ?? undefined,\r\n ncm: prod.ncm,\r\n cest: prod.cest,\r\n imagem_url: prod.imagem_url,\r\n };\r\n });\r\n return {\r\n status: data?.status || 'success',\r\n provider: data?.provider || 'PAIRUS',\r\n total_encontrados: itens.length,\r\n termo_buscado: data?.query || query,\r\n motor_busca: data?.motor_busca,\r\n produtos: itens,\r\n };\r\n}\r\n\r\nexport class ProductsResource extends BaseResource {\r\n /**\r\n * Consulta dados oficiais de um produto por código de barras GTIN/EAN (V1).\r\n * @param gtin Código numérico de 8 a 14 dígitos.\r\n */\r\n public async get(gtin: string): Promise<ProductDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v1/gtin/${gtinLimpo}` });\r\n return produtoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Consulta dados enriquecidos por IA, com SEO e ficha técnica estruturada (V2).\r\n * @param gtin Código numérico do produto.\r\n */\r\n public async getEnriched(gtin: string): Promise<ProductEnrichedDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v2/gtin/${gtinLimpo}` });\r\n return produtoEnriquecidoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Executa busca semântica por intenção/linguagem natural (V2).\r\n * @param query Termo livre de busca (ex: 'refrigerante zero lata').\r\n */\r\n public async search(query: string): Promise<ProductSearchResponse> {\r\n const data = await this.request<any>({ method: 'GET', path: '/v2/gtin/search', params: { q: query } });\r\n return buscaDaApi(data, query);\r\n }\r\n\r\n /**\r\n * Reconhece código de barras por visão computacional a partir de foto JPEG (OCR V2).\r\n * @param file Blob, Buffer ou FormData com a imagem JPEG.\r\n */\r\n public async scan(file: Blob | Buffer | FormData): Promise<ProductEnrichedDetails> {\r\n let formData: FormData;\r\n\r\n if (typeof FormData !== 'undefined' && file instanceof FormData) {\r\n formData = file;\r\n } else {\r\n formData = new FormData();\r\n if (typeof Blob !== 'undefined' && file instanceof Blob) {\r\n formData.append('file', file, 'barcode.jpg');\r\n } else {\r\n // Node Buffer\r\n const blob = new Blob([file as any], { type: 'image/jpeg' });\r\n formData.append('file', blob, 'barcode.jpg');\r\n }\r\n }\r\n\r\n const data = await this.request<any>({ method: 'POST', path: '/v2/gtin/scan', body: formData });\r\n return produtoEnriquecidoDaApi(data);\r\n }\r\n}\r\n","import * as crypto from 'crypto';\r\nimport { InvalidSignatureError } from './errors.js';\r\nimport { WebhookEvent } from './types/webhook.js';\r\n\r\n/** Prefixo do formato legado dos eventos de emissão (aceito até 27/12/2026). */\r\nconst PREFIXO_ASSINATURA = 'sha256=';\r\n\r\n/**\r\n * Helper oficial de webhooks. Aceita os dois formatos enviados pela PAIRUS durante a transição:\r\n * oficial (`{event, timestamp, data}` e assinatura hex) e legado da emissão de NF-e/NFC-e/NFS-e\r\n * (`{evento, dados}` e assinatura `sha256=<hex>`).\r\n */\r\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada (hexadecimal, sem prefixo) para o payload informado.\r\n */\r\n public static computeSignature(payload: string | Buffer, secret: string): string {\r\n return crypto\r\n .createHmac('sha256', secret)\r\n .update(payload)\r\n .digest('hex');\r\n }\r\n\r\n /**\r\n * Verifica de forma segura (resistente a timing attacks) a assinatura de um webhook.\r\n * Prefira sempre o corpo bruto: um objeto é reserializado e pode não reproduzir os bytes enviados.\r\n */\r\n public static verifySignature(\r\n payload: string | Buffer | Record<string, any>,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): boolean {\r\n if (!signature || !secret) {\r\n return false;\r\n }\r\n\r\n let payloadBuffer: Buffer;\r\n if (Buffer.isBuffer(payload)) {\r\n payloadBuffer = payload;\r\n } else if (typeof payload === 'string') {\r\n payloadBuffer = Buffer.from(payload, 'utf-8');\r\n } else {\r\n payloadBuffer = Buffer.from(JSON.stringify(payload), 'utf-8');\r\n }\r\n\r\n let recebida = signature.trim();\r\n if (recebida.toLowerCase().startsWith(PREFIXO_ASSINATURA)) {\r\n recebida = recebida.slice(PREFIXO_ASSINATURA.length);\r\n }\r\n\r\n const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(recebida, 'hex');\r\n const expectedBuf = Buffer.from(expectedSignature, 'hex');\r\n\r\n if (sigBuf.length !== expectedBuf.length) {\r\n return false;\r\n }\r\n\r\n return crypto.timingSafeEqual(sigBuf, expectedBuf);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Converte o envelope legado `{evento, dados}` para `{event, timestamp, data}`.\r\n */\r\n public static normalizeEvent<T = Record<string, any>>(raw: Record<string, any>): WebhookEvent<T> {\r\n if (!('event' in raw) && 'evento' in raw) {\r\n return { event: raw.evento, timestamp: raw.timestamp ?? null, data: (raw.dados ?? {}) as T };\r\n }\r\n return raw as WebhookEvent<T>;\r\n }\r\n\r\n /**\r\n * Valida a assinatura e converte o payload em objeto tipado WebhookEvent.\r\n */\r\n public static constructEvent<T = Record<string, any>>(\r\n payload: string | Buffer,\r\n signature: string | undefined | null,\r\n secret: string\r\n ): WebhookEvent<T> {\r\n if (!this.verifySignature(payload, signature, secret)) {\r\n throw new InvalidSignatureError(\"Assinatura do webhook ('X-Pairus-Signature') é inválida.\");\r\n }\r\n\r\n const rawStr = Buffer.isBuffer(payload) ? payload.toString('utf-8') : payload;\r\n return this.normalizeEvent<T>(JSON.parse(rawStr));\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { EmpresasResource } from './resources/empresas.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n public readonly empresas: EmpresasResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.empresas = new EmpresasResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pairus/product-data",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "SDK oficial da PAIRUS para integração com catálogo GTIN/EAN, predição fiscal (IBS/CBS/IS) e emissão de NF-e/NFC-e com Autocura SEFAZ.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",