@pairus/product-data 1.16.0 → 1.17.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
@@ -110,8 +110,8 @@ console.log(trib.avisos_fiscais);
110
110
  #### Saneamento Fiscal em Lote
111
111
  ```typescript
112
112
  const lote = await client.fiscal.sanitize([
113
- { NCM: '22021000', xProd: 'Refrigerante Cola', id: 'SKU-001' },
114
- { NCM: '22030000', CEST: '0302100', xProd: 'Cerveja Pilsen' },
113
+ { ncm: '22021000', xProd: 'Refrigerante Cola', id: 'SKU-001' },
114
+ { ncm: '22030000', cest: '0302100', xProd: 'Cerveja Pilsen' },
115
115
  ]);
116
116
 
117
117
  for (const item of lote.itens) {
package/dist/index.d.mts CHANGED
@@ -548,16 +548,22 @@ interface TaxPredictionData {
548
548
  beneficio_fiscal?: string;
549
549
  }
550
550
  interface TaxPredictionItemInput {
551
+ /** Identificador do item no ERP, devolvido no resultado. */
552
+ id?: string;
551
553
  xProd?: string;
552
554
  gtin?: string;
553
555
  ncm?: string;
554
556
  cest?: string;
557
+ /** Substitui a `finalidade` do topo neste item. */
558
+ finalidade?: 'revenda' | 'consumo_final' | 'industrializacao';
555
559
  }
556
560
  interface TaxPredictionParams {
557
561
  regimeTributario: 'simples_nacional' | 'lucro_presumido' | 'lucro_real' | string;
558
562
  ufOrigem: string;
559
563
  ufDestino?: string;
564
+ /** `revenda`: comprado para revender. `industrializacao`: fabricado pelo vendedor. `consumo_final`: o comprador usa e não revende. */
560
565
  finalidade?: 'revenda' | 'consumo_final' | 'industrializacao' | string;
566
+ /** Se o comprador é contribuinte do ICMS (`false` na venda a pessoa física). */
561
567
  destinatarioContribuinte?: boolean;
562
568
  /** Alíquota de crédito de ICMS do Simples Nacional (pCredSN). */
563
569
  aliquotaCreditoIcmsSn?: number;
@@ -571,6 +577,7 @@ interface TaxPredictionParams {
571
577
  }
572
578
  interface TaxPredictionItemResult {
573
579
  item_index: number;
580
+ id?: string | null;
574
581
  xProd?: string | null;
575
582
  dados_tributarios: TaxPredictionData;
576
583
  }
@@ -583,27 +590,28 @@ interface TaxPredictionResponse {
583
590
  dados_tributarios?: TaxPredictionData | null;
584
591
  resultados?: TaxPredictionItemResult[] | null;
585
592
  }
586
- /**
587
- * Item do saneamento. A API exige `NCM`/`CEST` em maiúsculas; os nomes `ncm`, `cest`,
588
- * `descricao` e `gtin` da 1.5 continuam aceitos e são convertidos pelo SDK.
589
- */
593
+ /** Item do saneamento, com os mesmos nomes do item da predição. `ncm` é obrigatório. */
590
594
  interface FiscalSanitizeItemInput {
591
- NCM?: string;
592
- CEST?: string;
593
- xProd?: string;
594
- id?: string;
595
- /** @deprecated Use `NCM`. */
596
595
  ncm?: string;
597
- /** @deprecated Use `CEST`. */
598
596
  cest?: string;
597
+ xProd?: string;
598
+ gtin?: string;
599
+ id?: string;
600
+ /** @deprecated Use `ncm`. */
601
+ NCM?: string;
602
+ /** @deprecated Use `cest`. */
603
+ CEST?: string;
599
604
  /** @deprecated Use `xProd`. */
600
605
  descricao?: string;
601
- /** @deprecated Use `id`. */
602
- gtin?: string;
606
+ }
607
+ interface FiscalSanitizeOptions {
608
+ /** UF de referência das alíquotas e da regra de ST. */
609
+ ufOrigem?: string;
603
610
  }
604
611
  interface FiscalSanitizeItemResult {
605
612
  id?: string;
606
613
  xProd?: string;
614
+ gtin?: string | null;
607
615
  NCM_informado?: string;
608
616
  CEST_informado?: string | null;
609
617
  auditoria_fiscal: Record<string, any>;
@@ -623,9 +631,9 @@ declare class FiscalResource extends BaseResource {
623
631
  predict(params: TaxPredictionParams): Promise<TaxPredictionResponse>;
624
632
  /**
625
633
  * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.
626
- * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.
634
+ * Cada item precisa de `ncm`; `cest`, `xProd`, `gtin` e `id` são opcionais.
627
635
  */
628
- sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse>;
636
+ sanitize(itens: FiscalSanitizeItemInput[], opcoes?: FiscalSanitizeOptions): Promise<FiscalSanitizeResponse>;
629
637
  }
630
638
 
631
639
  interface EnderecoNFSeInput {
@@ -973,4 +981,4 @@ declare class NetworkError extends PairusError {
973
981
  constructor(message: string);
974
982
  }
975
983
 
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 };
984
+ 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 FiscalSanitizeOptions, 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
@@ -548,16 +548,22 @@ interface TaxPredictionData {
548
548
  beneficio_fiscal?: string;
549
549
  }
550
550
  interface TaxPredictionItemInput {
551
+ /** Identificador do item no ERP, devolvido no resultado. */
552
+ id?: string;
551
553
  xProd?: string;
552
554
  gtin?: string;
553
555
  ncm?: string;
554
556
  cest?: string;
557
+ /** Substitui a `finalidade` do topo neste item. */
558
+ finalidade?: 'revenda' | 'consumo_final' | 'industrializacao';
555
559
  }
556
560
  interface TaxPredictionParams {
557
561
  regimeTributario: 'simples_nacional' | 'lucro_presumido' | 'lucro_real' | string;
558
562
  ufOrigem: string;
559
563
  ufDestino?: string;
564
+ /** `revenda`: comprado para revender. `industrializacao`: fabricado pelo vendedor. `consumo_final`: o comprador usa e não revende. */
560
565
  finalidade?: 'revenda' | 'consumo_final' | 'industrializacao' | string;
566
+ /** Se o comprador é contribuinte do ICMS (`false` na venda a pessoa física). */
561
567
  destinatarioContribuinte?: boolean;
562
568
  /** Alíquota de crédito de ICMS do Simples Nacional (pCredSN). */
563
569
  aliquotaCreditoIcmsSn?: number;
@@ -571,6 +577,7 @@ interface TaxPredictionParams {
571
577
  }
572
578
  interface TaxPredictionItemResult {
573
579
  item_index: number;
580
+ id?: string | null;
574
581
  xProd?: string | null;
575
582
  dados_tributarios: TaxPredictionData;
576
583
  }
@@ -583,27 +590,28 @@ interface TaxPredictionResponse {
583
590
  dados_tributarios?: TaxPredictionData | null;
584
591
  resultados?: TaxPredictionItemResult[] | null;
585
592
  }
586
- /**
587
- * Item do saneamento. A API exige `NCM`/`CEST` em maiúsculas; os nomes `ncm`, `cest`,
588
- * `descricao` e `gtin` da 1.5 continuam aceitos e são convertidos pelo SDK.
589
- */
593
+ /** Item do saneamento, com os mesmos nomes do item da predição. `ncm` é obrigatório. */
590
594
  interface FiscalSanitizeItemInput {
591
- NCM?: string;
592
- CEST?: string;
593
- xProd?: string;
594
- id?: string;
595
- /** @deprecated Use `NCM`. */
596
595
  ncm?: string;
597
- /** @deprecated Use `CEST`. */
598
596
  cest?: string;
597
+ xProd?: string;
598
+ gtin?: string;
599
+ id?: string;
600
+ /** @deprecated Use `ncm`. */
601
+ NCM?: string;
602
+ /** @deprecated Use `cest`. */
603
+ CEST?: string;
599
604
  /** @deprecated Use `xProd`. */
600
605
  descricao?: string;
601
- /** @deprecated Use `id`. */
602
- gtin?: string;
606
+ }
607
+ interface FiscalSanitizeOptions {
608
+ /** UF de referência das alíquotas e da regra de ST. */
609
+ ufOrigem?: string;
603
610
  }
604
611
  interface FiscalSanitizeItemResult {
605
612
  id?: string;
606
613
  xProd?: string;
614
+ gtin?: string | null;
607
615
  NCM_informado?: string;
608
616
  CEST_informado?: string | null;
609
617
  auditoria_fiscal: Record<string, any>;
@@ -623,9 +631,9 @@ declare class FiscalResource extends BaseResource {
623
631
  predict(params: TaxPredictionParams): Promise<TaxPredictionResponse>;
624
632
  /**
625
633
  * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.
626
- * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.
634
+ * Cada item precisa de `ncm`; `cest`, `xProd`, `gtin` e `id` são opcionais.
627
635
  */
628
- sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse>;
636
+ sanitize(itens: FiscalSanitizeItemInput[], opcoes?: FiscalSanitizeOptions): Promise<FiscalSanitizeResponse>;
629
637
  }
630
638
 
631
639
  interface EnderecoNFSeInput {
@@ -973,4 +981,4 @@ declare class NetworkError extends PairusError {
973
981
  constructor(message: string);
974
982
  }
975
983
 
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 };
984
+ 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 FiscalSanitizeOptions, 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
@@ -126,7 +126,7 @@ var BaseResource = class {
126
126
  const reqHeaders = {
127
127
  "Accept": "application/json",
128
128
  "X-API-Key": this.apiKey,
129
- "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
129
+ "User-Agent": "Pairus-NodeJS-SDK/1.17.0",
130
130
  ...options.headers || {}
131
131
  };
132
132
  const isFormData = typeof FormData !== "undefined" && options.body instanceof FormData;
@@ -197,7 +197,7 @@ var BaseResource = class {
197
197
  const reqHeaders = {
198
198
  "Accept": "*/*",
199
199
  "X-API-Key": this.apiKey,
200
- "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
200
+ "User-Agent": "Pairus-NodeJS-SDK/1.17.0",
201
201
  ...options.headers || {}
202
202
  };
203
203
  let lastError = null;
@@ -256,7 +256,7 @@ var BaseResource = class {
256
256
  const reqHeaders = {
257
257
  "Accept": "*/*",
258
258
  "X-API-Key": this.apiKey,
259
- "User-Agent": "Pairus-NodeJS-SDK/1.16.0",
259
+ "User-Agent": "Pairus-NodeJS-SDK/1.17.0",
260
260
  ...options.headers || {}
261
261
  };
262
262
  let lastError = null;
@@ -572,10 +572,11 @@ function itemDeSaneamento(item) {
572
572
  const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;
573
573
  const convertido = {
574
574
  ...extras,
575
- NCM: NCM ?? ncm,
576
- CEST: CEST ?? cest,
575
+ ncm: ncm ?? NCM,
576
+ cest: cest ?? CEST,
577
577
  xProd: xProd ?? descricao,
578
- id: id ?? gtin
578
+ gtin,
579
+ id
579
580
  };
580
581
  return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== void 0 && v !== null));
581
582
  }
@@ -612,13 +613,13 @@ var FiscalResource = class extends BaseResource {
612
613
  }
613
614
  /**
614
615
  * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.
615
- * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.
616
+ * Cada item precisa de `ncm`; `cest`, `xProd`, `gtin` e `id` são opcionais.
616
617
  */
617
- async sanitize(itens) {
618
+ async sanitize(itens, opcoes = {}) {
618
619
  return this.request({
619
620
  method: "POST",
620
621
  path: "/v2/fiscal/sanitize",
621
- body: { itens: itens.map(itemDeSaneamento) }
622
+ body: { ...opcoes.ufOrigem ? { uf_origem: opcoes.ufOrigem } : {}, itens: itens.map(itemDeSaneamento) }
622
623
  });
623
624
  }
624
625
  };
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/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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACWO,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB;;;ACT5B,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAN,cAA6B,YAAY;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YAAY,YAAoB,OAAgB,SAAkB,SAAe;AAC/E,UAAM,OAAO,SAAS,OAAO,UAAU;AACvC,UAAM,SAAS,WAAW,SAAS,UAAU,aAAa,UAAU;AACpE,UAAM,IAAI,IAAI,KAAK,MAAM,EAAE;AAC3B,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,UAAU;AAAA,EACjB;AACF;AAEO,IAAM,sBAAN,cAAkC,eAAe;AAAA,EACtD,YAAY,QAAQ,OAAO,UAAU,kDAA4C,SAAe;AAC9F,UAAM,KAAK,OAAO,SAAS,OAAO;AAClC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAN,cAA6B,eAAe;AAAA,EACjC;AAAA,EAEhB,YAAY,YAAqB,QAAQ,OAAO,UAAU,yCAAmC,SAAe;AAC1G,UAAM,KAAK,OAAO,SAAS,OAAO;AAClC,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAEO,IAAM,wBAAN,cAAoC,YAAY;AAAA,EACrD,YAAY,UAAU,qFAA4E;AAChG,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,eAAN,cAA2B,YAAY;AAAA,EAC5C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;AC3CO,IAAM,eAAN,MAAmB;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEV,YAAY,QAAgB,SAAiB,WAAmB,YAAoB;AAClF,SAAK,SAAS;AACd,SAAK,UAAU,QAAQ,QAAQ,QAAQ,EAAE;AACzC,SAAK,YAAY;AACjB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAgB,QAAW,SAAqC;AAC9D,QAAI,MAAM,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,QAAQ,EAAE,CAAC;AAC7D,QAAI,QAAQ,QAAQ;AAClB,YAAM,QAAQ,IAAI,gBAAgB,QAAQ,MAAM,EAAE,SAAS;AAC3D,YAAM,GAAG,GAAG,IAAI,KAAK;AAAA,IACvB;AAEA,UAAM,aAAqC;AAAA,MACzC,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,MAClB,cAAc;AAAA,MACd,GAAI,QAAQ,WAAW,CAAC;AAAA,IAC1B;AAEA,UAAM,aAAa,OAAO,aAAa,eAAe,QAAQ,gBAAgB;AAE9E,QAAI,QAAQ,QAAQ,CAAC,cAAc,CAAC,WAAW,cAAc,GAAG;AAC9D,iBAAW,cAAc,IAAI;AAAA,IAC/B;AAEA,QAAI,YAAiB;AAErB,aAAS,UAAU,GAAG,UAAU,KAAK,YAAY,WAAW;AAC1D,UAAI;AACF,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,SAAS;AAErE,cAAM,WAAW,aACb,QAAQ,OACR,QAAQ,OACR,KAAK,UAAU,QAAQ,IAAI,IAC3B;AAEJ,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC,QAAQ,QAAQ;AAAA,UAChB,SAAS;AAAA,UACT,MAAM;AAAA,UACN,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,qBAAa,SAAS;AAEtB,YAAI,SAAS,MAAO,SAAS,UAAU,OAAO,SAAS,SAAS,KAAM;AACpE,iBAAQ,MAAM,SAAS,KAAK;AAAA,QAC9B;AAEA,YAAI,UAAe,CAAC;AACpB,YAAI;AACF,oBAAU,MAAM,SAAS,KAAK;AAAA,QAChC,QAAQ;AACN,oBAAU,CAAC;AAAA,QACb;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,IAAI,oBAAoB,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,QACvE;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,gBAAgB,WAAW,SAAS,QAAQ,IAAI,aAAa,KAAK,GAAG;AAC3E,cAAI,UAAU,KAAK,aAAa,GAAG;AACjC,kBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,MAAM,gBAAgB,KAAK,OAAO,IAAI,OAAO,GAAI,CAAC;AACxF;AAAA,UACF;AACA,gBAAM,IAAI,eAAe,eAAe,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,QACjF;AAGA,cAAM,uBAAuB,SAAS,WAAW,OAAO,qBAAqB;AAC7E,aAAK,CAAC,KAAK,KAAK,GAAG,EAAE,SAAS,SAAS,MAAM,KAAK,yBAAyB,UAAU,KAAK,aAAa,GAAG;AACxG,gBAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,MAAO,KAAK,OAAO,IAAI;AAC5D,gBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,KAAK,KAAK,CAAC;AACjD;AAAA,QACF;AAEA,cAAM,IAAI,eAAe,SAAS,QAAQ,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,MACnF,SAAS,KAAU;AACjB,YAAI,eAAe,gBAAgB;AACjC,gBAAM;AAAA,QACR;AACA,oBAAY;AACZ,YAAI,UAAU,KAAK,aAAa,GAAG;AACjC,gBAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,MAAO,KAAK,OAAO,IAAI;AAC5D,gBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,KAAK,KAAK,CAAC;AACjD;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,IAAI,aAAa,gDAA0C,KAAK,UAAU,gBAAgB,WAAW,WAAW,SAAS,EAAE;AAAA,EACnI;AAAA,EAEA,MAAgB,YAAY,SAA0C;AACpE,QAAI,MAAM,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,QAAQ,EAAE,CAAC;AAC7D,QAAI,QAAQ,QAAQ;AAClB,YAAM,QAAQ,IAAI,gBAAgB,QAAQ,MAAM,EAAE,SAAS;AAC3D,YAAM,GAAG,GAAG,IAAI,KAAK;AAAA,IACvB;AAEA,UAAM,aAAqC;AAAA,MACzC,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,MAClB,cAAc;AAAA,MACd,GAAI,QAAQ,WAAW,CAAC;AAAA,IAC1B;AAEA,QAAI,YAAiB;AAErB,aAAS,UAAU,GAAG,UAAU,KAAK,YAAY,WAAW;AAC1D,UAAI;AACF,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,SAAS;AAErE,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC,QAAQ,QAAQ;AAAA,UAChB,SAAS;AAAA,UACT,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,qBAAa,SAAS;AAEtB,YAAI,SAAS,MAAO,SAAS,UAAU,OAAO,SAAS,SAAS,KAAM;AACpE,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B;AAEA,YAAI,UAAe,CAAC;AACpB,YAAI;AACF,oBAAU,MAAM,SAAS,KAAK;AAAA,QAChC,QAAQ;AACN,oBAAU,CAAC;AAAA,QACb;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,IAAI,oBAAoB,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,QACvE;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,gBAAgB,WAAW,SAAS,QAAQ,IAAI,aAAa,KAAK,GAAG;AAC3E,cAAI,UAAU,KAAK,aAAa,GAAG;AACjC,kBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,MAAM,gBAAgB,KAAK,OAAO,IAAI,OAAO,GAAI,CAAC;AACxF;AAAA,UACF;AACA,gBAAM,IAAI,eAAe,eAAe,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,QACjF;AAEA,cAAM,IAAI,eAAe,SAAS,QAAQ,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,MACnF,SAAS,KAAU;AACjB,YAAI,eAAe,gBAAgB;AACjC,gBAAM;AAAA,QACR;AACA,oBAAY;AACZ,YAAI,UAAU,KAAK,aAAa,GAAG;AACjC,gBAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,MAAO,KAAK,OAAO,IAAI;AAC5D,gBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,KAAK,KAAK,CAAC;AACjD;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,IAAI,aAAa,gDAA0C,KAAK,UAAU,gBAAgB,WAAW,WAAW,SAAS,EAAE;AAAA,EACnI;AAAA,EAEA,MAAgB,cAAc,SAA+C;AAC3E,QAAI,MAAM,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,QAAQ,EAAE,CAAC;AAC7D,QAAI,QAAQ,QAAQ;AAClB,YAAM,QAAQ,IAAI,gBAAgB,QAAQ,MAAM,EAAE,SAAS;AAC3D,YAAM,GAAG,GAAG,IAAI,KAAK;AAAA,IACvB;AAEA,UAAM,aAAqC;AAAA,MACzC,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,MAClB,cAAc;AAAA,MACd,GAAI,QAAQ,WAAW,CAAC;AAAA,IAC1B;AAEA,QAAI,YAAiB;AAErB,aAAS,UAAU,GAAG,UAAU,KAAK,YAAY,WAAW;AAC1D,UAAI;AACF,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,SAAS;AAErE,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC,QAAQ,QAAQ;AAAA,UAChB,SAAS;AAAA,UACT,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,qBAAa,SAAS;AAEtB,YAAI,SAAS,MAAO,SAAS,UAAU,OAAO,SAAS,SAAS,KAAM;AACpE,iBAAO,MAAM,SAAS,YAAY;AAAA,QACpC;AAEA,YAAI,UAAe,CAAC;AACpB,YAAI;AACF,oBAAU,MAAM,SAAS,KAAK;AAAA,QAChC,QAAQ;AACN,oBAAU,CAAC;AAAA,QACb;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,IAAI,oBAAoB,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,QACvE;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,gBAAgB,WAAW,SAAS,QAAQ,IAAI,aAAa,KAAK,GAAG;AAC3E,cAAI,UAAU,KAAK,aAAa,GAAG;AACjC,kBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,MAAM,gBAAgB,KAAK,OAAO,IAAI,OAAO,GAAI,CAAC;AACxF;AAAA,UACF;AACA,gBAAM,IAAI,eAAe,eAAe,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,QACjF;AAEA,cAAM,IAAI,eAAe,SAAS,QAAQ,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,MACnF,SAAS,KAAU;AACjB,YAAI,eAAe,gBAAgB;AACjC,gBAAM;AAAA,QACR;AACA,oBAAY;AACZ,YAAI,UAAU,KAAK,aAAa,GAAG;AACjC,gBAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,MAAO,KAAK,OAAO,IAAI;AAC5D,gBAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,KAAK,KAAK,CAAC;AACjD;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,IAAI,aAAa,gDAA0C,KAAK,UAAU,gBAAgB,WAAW,WAAW,SAAS,EAAE;AAAA,EACnI;AACF;;;ACxPO,IAAM,cAAN,cAA0B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5C,MAAa,YAAY,OAA6D;AACpF,WAAO,KAAK,QAAgC;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,MAAM,MAAM;AAAA,QACZ,UAAU,MAAM,YAAY;AAAA,MAC9B;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,iBAAiB,QAAyE;AACrG,UAAM,cAAsC;AAAA,MAC1C,MAAM,OAAO;AAAA,MACb,UAAU,OAAO,YAAY;AAAA,IAC/B;AACA,QAAI,OAAO,QAAQ;AACjB,kBAAY,SAAS,OAAO,OAAO,MAAM;AAAA,IAC3C;AAEA,WAAO,KAAK,QAAqC;AAAA,MAC/C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,WAAW,OAA2D;AACjF,WAAO,KAAK,QAA+B;AAAA,MACzC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,MAAM,MAAM;AAAA,QACZ,cAAc,MAAM;AAAA,QACpB,aAAa,MAAM;AAAA,QACnB,eAAe,MAAM;AAAA,QACrB,UAAU,MAAM,YAAY;AAAA,MAC9B;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,UAAU,aAAsC;AAC3D,WAAO,KAAK,YAAY;AAAA,MACtB,QAAQ;AAAA,MACR,MAAM,eAAe,WAAW;AAAA,IAClC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,YAAY,aAA2C;AAClE,WAAO,KAAK,cAAc;AAAA,MACxB,QAAQ;AAAA,MACR,MAAM,iBAAiB,WAAW;AAAA,IACpC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,qBAAqB,MAAqD;AACrF,WAAO,KAAK,QAAsC;AAAA,MAChD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,EAAE,KAAK;AAAA,IACjB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,kBAAkB,OAAyE;AACtG,QAAI,CAAC,MAAM,SAAS,MAAM,MAAM,KAAK,EAAE,SAAS,GAAG;AACjD,YAAM,IAAI,MAAM,kEAAkE;AAAA,IACpF;AACA,WAAO,KAAK,QAAsC;AAAA,MAChD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,EAAE,OAAO,MAAM,OAAO,YAAY,MAAM,YAAY,OAAO,MAAM,MAAM;AAAA,IAC/E,CAAC;AAAA,EACH;AACF;;;ACjIA,yBAA2B;AAkB3B,SAAS,sBAAsB,SAAkD;AAC/E,SAAO,EAAE,mBAAmB,SAAS,sBAAkB,+BAAW,EAAE;AACtE;AAEO,IAAM,kBAAN,cAA8B,aAAa;AAAA;AAAA;AAAA;AAAA,EAIhD,MAAa,UAAU,SAA0B,SAAuD;AACtG,WAAO,KAAK,QAA4B;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,sBAAsB,OAAO;AAAA,IACxC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,WAAW,SAA0B,SAAuD;AACvG,WAAO,KAAK,QAA4B;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,sBAAsB,OAAO;AAAA,IACxC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAQ,SAAuD;AAC1E,WAAO,KAAK,QAA4B;AAAA,MACtC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,SAAS,QAAuD;AAC3E,WAAO,KAAK,QAA2B;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO;AAAA,QACtB,uBAAuB,OAAO;AAAA,MAChC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,cAAc,QAAwD;AACjF,WAAO,KAAK,QAA2B;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,cAAc,OAAO;AAAA,QACrB,UAAU,OAAO;AAAA,QACjB,kBAAkB,OAAO,oBAAoB;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,WAAW,QAAuD;AAC7E,WAAO,KAAK,QAA2B;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,eAAe,OAAO;AAAA,QACtB,OAAO,OAAO;AAAA,QACd,gBAAgB,OAAO;AAAA,QACvB,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO;AAAA,QACtB,KAAK,OAAO;AAAA,QACZ,QAAQ,OAAO,OAAO,UAAU,IAAI;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,UAAU,aAAqB,SAAkE;AAC5G,WAAO,KAAK,QAA6B;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM,WAAW,WAAW;AAAA,MAC5B,QAAQ,EAAE,aAAa,OAAO,SAAS,cAAc,KAAK,EAAE;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,oBAAoB,cAAsB,mBAA2D;AAChH,WAAO,KAAK,QAA+B;AAAA,MACzC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,EAAE,eAAe,cAAc,oBAAoB,kBAAkB;AAAA,IAC/E,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,YAAY,aAA2C;AAClE,WAAO,KAAK,cAAc,EAAE,QAAQ,OAAO,MAAM,WAAW,WAAW,SAAS,CAAC;AAAA,EACnF;AACF;;;ACvIO,IAAM,mBAAN,cAA+B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjD,MAAa,cAAc,MAAc,OAA6C;AACpF,WAAO,KAAK,QAAuB,EAAE,QAAQ,OAAO,MAAM,gBAAgB,IAAI,QAAQ,MAAM,MAAM,CAAC;AAAA,EACrG;AAAA;AAAA,EAGA,MAAa,aAAa,MAAsC;AAC9D,WAAO,KAAK,QAAuB,EAAE,QAAQ,OAAO,MAAM,gBAAgB,IAAI,OAAO,CAAC;AAAA,EACxF;AACF;;;ACPA,SAAS,gBAAgB,OAA6C;AACpE,QAAM,KAAK,MAAM,MAAM,MAAM;AAC7B,QAAM,kBAAkB,KACpB,EAAE,GAAG,IAAI,OAAO,GAAG,SAAS,GAAG,KAAK,KAAK,GAAG,OAAO,GAAG,OAAO,KAAK,GAAG,OAAO,GAAG,UAAU,UAAU,GAAG,YAAY,GAAG,IAAI,IACzH;AACJ,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc,MAAM,gBAAgB,MAAM;AAAA,IAC1C,MAAM,MAAM,QAAQ,MAAM;AAAA,IAC1B,wBAAwB,MAAM,0BAA0B,MAAM;AAAA,IAC9D,gBAAgB,MAAM,kBAAkB,MAAM;AAAA,IAC9C,IAAI;AAAA,IACJ,kBAAkB;AAAA,IAClB,4BAA4B,MAAM,8BAA8B,MAAM,QAAQ,8BAA8B;AAAA,IAC5G,gBAAgB,MAAM,kBAAkB,MAAM,UAAU,CAAC;AAAA,IACzD,QAAQ,MAAM,UAAU,MAAM,kBAAkB,CAAC;AAAA,EACnD;AACF;AAGA,SAAS,iBAAiB,MAAoD;AAC5E,QAAM,EAAE,KAAK,MAAM,OAAO,IAAI,KAAK,MAAM,WAAW,MAAM,GAAG,OAAO,IAAI;AACxE,QAAM,aAAkC;AAAA,IACtC,GAAG;AAAA,IACH,KAAK,OAAO;AAAA,IACZ,MAAM,QAAQ;AAAA,IACd,OAAO,SAAS;AAAA,IAChB,IAAI,MAAM;AAAA,EACZ;AACA,SAAO,OAAO,YAAY,OAAO,QAAQ,UAAU,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,UAAa,MAAM,IAAI,CAAC;AACvG;AAEO,IAAM,iBAAN,cAA6B,aAAa;AAAA;AAAA;AAAA;AAAA,EAI/C,MAAa,QAAQ,QAA6D;AAChF,UAAM,UAA+B;AAAA,MACnC,mBAAmB,OAAO;AAAA,MAC1B,WAAW,OAAO;AAAA,MAClB,YAAY,OAAO,aAAa,OAAO;AAAA,MACvC,YAAY,OAAO,cAAc;AAAA,MACjC,2BAA2B,OAAO,4BAA4B;AAAA,IAChE;AAEA,QAAI,OAAO,0BAA0B,OAAW,SAAQ,2BAA2B,OAAO;AAC1F,QAAI,OAAO,wBAAwB,OAAW,SAAQ,uBAAuB,OAAO;AACpF,QAAI,OAAO,iBAAkB,SAAQ,oBAAoB,OAAO;AAChE,QAAI,OAAO,MAAO,SAAQ,QAAQ,OAAO;AACzC,QAAI,OAAO,KAAM,SAAQ,OAAO,OAAO;AACvC,QAAI,OAAO,IAAK,SAAQ,MAAM,OAAO;AACrC,QAAI,OAAO,KAAM,SAAQ,OAAO,OAAO;AACvC,QAAI,OAAO,MAAO,SAAQ,QAAQ,OAAO;AAEzC,UAAM,MAAM,MAAM,KAAK,QAA+B;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAED,WAAO;AAAA,MACL,GAAG;AAAA,MACH,mBAAmB,IAAI,oBAAoB,gBAAgB,IAAI,iBAAiB,IAAI,IAAI;AAAA,MACxF,YAAY,IAAI,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,mBAAmB,gBAAgB,EAAE,iBAAiB,EAAE,EAAE;AAAA,IAC5G;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,SAAS,OAAmE;AACvF,WAAO,KAAK,QAAgC;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,EAAE,OAAO,MAAM,IAAI,gBAAgB,EAAE;AAAA,IAC7C,CAAC;AAAA,EACH;AACF;;;AChFO,IAAM,eAAN,cAA2B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK7C,MAAM,OAAO,SAA+E;AAC1F,WAAO,KAAK,QAA6B;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,SAA+E;AAC3F,WAAO,KAAK,QAA6B;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,SAAmE;AAChF,WAAO,KAAK,QAAkC;AAAA,MAC5C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU,eAAuB,SAAoC,CAAC,GAAiC;AAC3G,WAAO,KAAK,QAA6B;AAAA,MACvC,QAAQ;AAAA,MACR,MAAM,YAAY,aAAa;AAAA,MAC/B,QAAQ,OAAO,cAAc,EAAE,aAAa,OAAO,IAAI;AAAA,IACzD,CAAC;AAAA,EACH;AACF;;;AC9CA,SAAS,YAAe,SAA0D;AAChF,SAAO,QAAQ,KAAK,CAAC,MAAM,MAAM,UAAa,MAAM,QAAQ,MAAM,EAAE;AACtE;AAEA,SAAS,OAAO,OAAgC;AAC9C,QAAM,IAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,KAAK,MAAM,OAAO,KAAK;AACpF,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAGA,SAAS,aAAa,MAAW,eAAe,IAAoB;AAClE,QAAM,OAAO,MAAM,WAAW,QAAQ,CAAC;AACvC,QAAM,OAAO,KAAK,iBAAiB,CAAC;AACpC,SAAO;AAAA,IACL,MAAM,OAAO,SAAS,KAAK,MAAM,KAAK,MAAM,YAAY,KAAK,EAAE;AAAA,IAC/D,OAAO,SAAS,KAAK,OAAO,KAAK,SAAS,KAAK;AAAA,IAC/C,KAAK,SAAS,KAAK,KAAK,KAAK,GAAG;AAAA,IAChC,MAAM,SAAS,KAAK,MAAM,KAAK,IAAI;AAAA,IACnC,OAAO,SAAS,KAAK,OAAO,KAAK,MAAM;AAAA,IACvC,YAAY,KAAK;AAAA,IACjB,WAAW,SAAS,KAAK,WAAW,KAAK,UAAU;AAAA,IACnD,WAAW,SAAS,KAAK,YAAY,KAAK,WAAW,KAAK,SAAS;AAAA,IACnE,WAAW,OAAO,SAAS,KAAK,YAAY,KAAK,SAAS,CAAC;AAAA,IAC3D,aAAa,OAAO,SAAS,KAAK,cAAc,KAAK,WAAW,CAAC;AAAA,IACjE,qBAAqB,OAAO,KAAK,wBAAwB,CAAC;AAAA,IAC1D,QAAQ,KAAK,UAAU;AAAA,IACvB,OAAO,KAAK,SAAS;AAAA,IACrB,eAAe,KAAK,iBAAiB;AAAA,EACvC;AACF;AAGA,SAAS,wBAAwB,MAAW,eAAe,IAA4B;AACrF,QAAM,OAAO,MAAM,WAAW,QAAQ,CAAC;AACvC,QAAM,OAAO,aAAa,MAAM,YAAY;AAC5C,QAAM,iBAAiB,KAAK,oBAAoB,CAAC;AACjD,QAAM,YAAY,eAAe,aAAa,CAAC;AAC/C,QAAM,eAAe,OAAO,KAAK,SAAS,EAAE,SAAS;AACrD,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,mBAAmB,eAAe;AAAA,IAClC,oBAAoB,SAAS,KAAK,oBAAoB,eAAe,aAAa;AAAA,IAClF,eAAe,KAAK,kBAAkB,eAAe,YAAY;AAAA,IACjE,gBAAgB,KAAK;AAAA,IACrB,KAAK,KAAK;AAAA,IACV,MAAM,KAAK;AAAA,IACX,OAAO,SAAS,KAAK,OAAO,UAAU,OAAO,KAAK,KAAK;AAAA,IACvD,WAAW,SAAS,KAAK,WAAW,eAAe,qBAAqB,KAAK,SAAS;AAAA,IACtF,YAAY,KAAK;AAAA,IACjB,YAAY,KAAK;AAAA,IACjB,cAAc,SAAS,OAAO,KAAK,YAAY,GAAG,OAAO,UAAU,YAAY,GAAG,KAAK,WAAW;AAAA,IAClG,6BAA6B,KAAK,+BAA+B,KAAK,gBAAgB;AAAA,IACtF,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,IACZ,eAAe,KAAK;AAAA,IACpB,kBAAkB,KAAK,oBAAoB;AAAA,IAC3C,cAAc,KAAK,gBAAgB;AAAA,EACrC;AACF;AAGA,SAAS,WAAW,MAAW,OAAsC;AACnE,QAAM,SAAoC,MAAM,cAAc,MAAM,YAAY,CAAC,GAAG,IAAI,CAAC,SAAc;AACrG,UAAM,OAAO,wBAAwB,KAAK,WAAW,IAAI;AACzD,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB,OAAO,KAAK,UAAU,UAAa,KAAK,UAAU,OAAO,OAAO,KAAK,KAAK,IAAI;AAAA,MAC9E,eAAe,KAAK,iBAAiB;AAAA,MACrC,KAAK,KAAK;AAAA,MACV,MAAM,KAAK;AAAA,MACX,YAAY,KAAK;AAAA,IACnB;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL,QAAQ,MAAM,UAAU;AAAA,IACxB,UAAU,MAAM,YAAY;AAAA,IAC5B,mBAAmB,MAAM;AAAA,IACzB,eAAe,MAAM,SAAS;AAAA,IAC9B,aAAa,MAAM;AAAA,IACnB,UAAU;AAAA,EACZ;AACF;AAEO,IAAM,mBAAN,cAA+B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjD,MAAa,IAAI,MAAuC;AACtD,UAAM,YAAY,KAAK,QAAQ,OAAO,EAAE;AACxC,UAAM,OAAO,MAAM,KAAK,QAAa,EAAE,QAAQ,OAAO,MAAM,YAAY,SAAS,GAAG,CAAC;AACrF,WAAO,aAAa,MAAM,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,YAAY,MAA+C;AACtE,UAAM,YAAY,KAAK,QAAQ,OAAO,EAAE;AACxC,UAAM,OAAO,MAAM,KAAK,QAAa,EAAE,QAAQ,OAAO,MAAM,YAAY,SAAS,GAAG,CAAC;AACrF,WAAO,wBAAwB,MAAM,SAAS;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,OAAO,OAA+C;AACjE,UAAM,OAAO,MAAM,KAAK,QAAa,EAAE,QAAQ,OAAO,MAAM,mBAAmB,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;AACrG,WAAO,WAAW,MAAM,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,KAAK,MAAiE;AACjF,QAAI;AAEJ,QAAI,OAAO,aAAa,eAAe,gBAAgB,UAAU;AAC/D,iBAAW;AAAA,IACb,OAAO;AACL,iBAAW,IAAI,SAAS;AACxB,UAAI,OAAO,SAAS,eAAe,gBAAgB,MAAM;AACvD,iBAAS,OAAO,QAAQ,MAAM,aAAa;AAAA,MAC7C,OAAO;AAEL,cAAM,OAAO,IAAI,KAAK,CAAC,IAAW,GAAG,EAAE,MAAM,aAAa,CAAC;AAC3D,iBAAS,OAAO,QAAQ,MAAM,aAAa;AAAA,MAC7C;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,KAAK,QAAa,EAAE,QAAQ,QAAQ,MAAM,iBAAiB,MAAM,SAAS,CAAC;AAC9F,WAAO,wBAAwB,IAAI;AAAA,EACrC;AACF;;;ACrJA,aAAwB;AAKxB,IAAM,qBAAqB;AAOpB,IAAM,WAAN,MAAe;AAAA;AAAA;AAAA;AAAA,EAIpB,OAAc,iBAAiB,SAA0B,QAAwB;AAC/E,WACG,kBAAW,UAAU,MAAM,EAC3B,OAAO,OAAO,EACd,OAAO,KAAK;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,gBACZ,SACA,WACA,QACS;AACT,QAAI,CAAC,aAAa,CAAC,QAAQ;AACzB,aAAO;AAAA,IACT;AAEA,QAAI;AACJ,QAAI,OAAO,SAAS,OAAO,GAAG;AAC5B,sBAAgB;AAAA,IAClB,WAAW,OAAO,YAAY,UAAU;AACtC,sBAAgB,OAAO,KAAK,SAAS,OAAO;AAAA,IAC9C,OAAO;AACL,sBAAgB,OAAO,KAAK,KAAK,UAAU,OAAO,GAAG,OAAO;AAAA,IAC9D;AAEA,QAAI,WAAW,UAAU,KAAK;AAC9B,QAAI,SAAS,YAAY,EAAE,WAAW,kBAAkB,GAAG;AACzD,iBAAW,SAAS,MAAM,mBAAmB,MAAM;AAAA,IACrD;AAEA,UAAM,oBAAoB,KAAK,iBAAiB,eAAe,MAAM;AAErE,QAAI;AACF,YAAM,SAAS,OAAO,KAAK,UAAU,KAAK;AAC1C,YAAM,cAAc,OAAO,KAAK,mBAAmB,KAAK;AAExD,UAAI,OAAO,WAAW,YAAY,QAAQ;AACxC,eAAO;AAAA,MACT;AAEA,aAAc,uBAAgB,QAAQ,WAAW;AAAA,IACnD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,eAAwC,KAA2C;AAC/F,QAAI,EAAE,WAAW,QAAQ,YAAY,KAAK;AACxC,aAAO,EAAE,OAAO,IAAI,QAAQ,WAAW,IAAI,aAAa,MAAM,MAAO,IAAI,SAAS,CAAC,EAAQ;AAAA,IAC7F;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,eACZ,SACA,WACA,QACiB;AACjB,QAAI,CAAC,KAAK,gBAAgB,SAAS,WAAW,MAAM,GAAG;AACrD,YAAM,IAAI,sBAAsB,gEAA0D;AAAA,IAC5F;AAEA,UAAM,SAAS,OAAO,SAAS,OAAO,IAAI,QAAQ,SAAS,OAAO,IAAI;AACtE,WAAO,KAAK,eAAkB,KAAK,MAAM,MAAM,CAAC;AAAA,EAClD;AACF;;;AC7EO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,OAAuB,WAAW;AAAA,EAClB,WAAW;AAAA,EAEX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YAAY,SAA+B;AACzC,UAAM,SAAS,SAAS,WAAW,OAAO,YAAY,cAAc,QAAQ,IAAI,iBAAiB;AACjG,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,SAAS,YAAY,OAAO,YAAY,cAAc,QAAQ,IAAI,kBAAkB,WAAc;AAClH,UAAM,YAAY,SAAS,aAAa;AACxC,UAAM,aAAa,SAAS,cAAc;AAE1C,SAAK,WAAW,IAAI,iBAAiB,QAAQ,SAAS,WAAW,UAAU;AAC3E,SAAK,SAAS,IAAI,eAAe,QAAQ,SAAS,WAAW,UAAU;AACvE,SAAK,UAAU,IAAI,gBAAgB,QAAQ,SAAS,WAAW,UAAU;AACzE,SAAK,OAAO,IAAI,aAAa,QAAQ,SAAS,WAAW,UAAU;AACnE,SAAK,MAAM,IAAI,YAAY,QAAQ,SAAS,WAAW,UAAU;AACjE,SAAK,WAAW,IAAI,iBAAiB,QAAQ,SAAS,WAAW,UAAU;AAAA,EAC7E;AACF;","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.17.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.17.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.17.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 FiscalSanitizeOptions,\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/** Envia o item com os nomes atuais da API, aceitando os antigos (`NCM`, `CEST`, `descricao`). */\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 gtin,\r\n id,\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`; `cest`, `xProd`, `gtin` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[], opcoes: FiscalSanitizeOptions = {}): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { ...(opcoes.ufOrigem ? { uf_origem: opcoes.ufOrigem } : {}), 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.16.0",
77
+ "User-Agent": "Pairus-NodeJS-SDK/1.17.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.16.0",
148
+ "User-Agent": "Pairus-NodeJS-SDK/1.17.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.16.0",
207
+ "User-Agent": "Pairus-NodeJS-SDK/1.17.0",
208
208
  ...options.headers || {}
209
209
  };
210
210
  let lastError = null;
@@ -520,10 +520,11 @@ function itemDeSaneamento(item) {
520
520
  const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;
521
521
  const convertido = {
522
522
  ...extras,
523
- NCM: NCM ?? ncm,
524
- CEST: CEST ?? cest,
523
+ ncm: ncm ?? NCM,
524
+ cest: cest ?? CEST,
525
525
  xProd: xProd ?? descricao,
526
- id: id ?? gtin
526
+ gtin,
527
+ id
527
528
  };
528
529
  return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== void 0 && v !== null));
529
530
  }
@@ -560,13 +561,13 @@ var FiscalResource = class extends BaseResource {
560
561
  }
561
562
  /**
562
563
  * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.
563
- * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.
564
+ * Cada item precisa de `ncm`; `cest`, `xProd`, `gtin` e `id` são opcionais.
564
565
  */
565
- async sanitize(itens) {
566
+ async sanitize(itens, opcoes = {}) {
566
567
  return this.request({
567
568
  method: "POST",
568
569
  path: "/v2/fiscal/sanitize",
569
- body: { itens: itens.map(itemDeSaneamento) }
570
+ body: { ...opcoes.ufOrigem ? { uf_origem: opcoes.ufOrigem } : {}, itens: itens.map(itemDeSaneamento) }
570
571
  });
571
572
  }
572
573
  };
@@ -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/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":[]}
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.17.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.17.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.17.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 FiscalSanitizeOptions,\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/** Envia o item com os nomes atuais da API, aceitando os antigos (`NCM`, `CEST`, `descricao`). */\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 gtin,\r\n id,\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`; `cest`, `xProd`, `gtin` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[], opcoes: FiscalSanitizeOptions = {}): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { ...(opcoes.ufOrigem ? { uf_origem: opcoes.ufOrigem } : {}), 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.16.0",
3
+ "version": "1.17.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",