@pairus/product-data 1.10.0 → 1.12.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 +34 -15
- package/dist/index.d.mts +33 -4
- package/dist/index.d.ts +33 -4
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -194,14 +194,22 @@ console.log('Simulação realizada:', simulacao.sucesso);
|
|
|
194
194
|
|
|
195
195
|
---
|
|
196
196
|
|
|
197
|
-
### 4. 🏛️ Emissão de NFS-e (
|
|
197
|
+
### 4. 🏛️ Emissão de NFS-e (Sistema Nacional da NFS-e)
|
|
198
|
+
|
|
199
|
+
A DPS (leiaute nacional v1.01) é assinada com o certificado A1 do prestador, cadastrado na Área do Cliente, e transmitida à Sefin Nacional. Hoje a emissão real está disponível em **homologação** (produção restrita); a produção está em implantação.
|
|
198
200
|
|
|
199
201
|
```typescript
|
|
200
202
|
const nfse = await client.nfse.emitir({
|
|
203
|
+
ambiente: 'homologacao',
|
|
201
204
|
prestador: {
|
|
202
205
|
cnpj: '12345678000195',
|
|
203
206
|
inscricao_municipal: '123456',
|
|
204
207
|
razao_social: 'Minha Empresa Tech LTDA',
|
|
208
|
+
percentual_tributos_simples: 6.0, // alíquota efetiva do Simples (ME/EPP)
|
|
209
|
+
endereco: { // o município do prestador é o emissor da DPS
|
|
210
|
+
logradouro: 'Av. Paulista', numero: '1578', bairro: 'Bela Vista',
|
|
211
|
+
codigo_municipio_ibge: '3550308', uf: 'SP', cep: '01310200',
|
|
212
|
+
},
|
|
205
213
|
},
|
|
206
214
|
tomador: {
|
|
207
215
|
cpf_cnpj: '98765432000198',
|
|
@@ -209,27 +217,30 @@ const nfse = await client.nfse.emitir({
|
|
|
209
217
|
email: 'contas@tomador.com.br',
|
|
210
218
|
},
|
|
211
219
|
servico: {
|
|
212
|
-
item_lista_servico: '1.07', //
|
|
220
|
+
item_lista_servico: '1.07', // LC 116/2003; o cTribNac é derivado pela lista nacional
|
|
213
221
|
discriminacao: 'Desenvolvimento e manutenção de software sob medida',
|
|
214
|
-
municipio_prestacao_ibge: '3550308',
|
|
222
|
+
municipio_prestacao_ibge: '3550308',
|
|
215
223
|
valor_servicos: 4500.0,
|
|
216
224
|
aliquota_iss: 2.0,
|
|
217
|
-
iss_retido: false,
|
|
218
|
-
retencoes_federais: {
|
|
219
|
-
pis_retido: true, aliquota_pis: 0.65, valor_pis: 29.25,
|
|
220
|
-
cofins_retido: true, aliquota_cofins: 3.0, valor_cofins: 135.0,
|
|
221
|
-
csll_retida: true, aliquota_csll: 1.0, valor_csll: 45.0,
|
|
222
|
-
irrf_retido: true, aliquota_irrf: 1.5, valor_irrf: 67.50,
|
|
223
|
-
},
|
|
224
225
|
},
|
|
225
226
|
});
|
|
226
227
|
|
|
227
228
|
if (nfse.sucesso) {
|
|
228
|
-
console.log(`✅ NFS-e
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
console.log(
|
|
229
|
+
console.log(`✅ NFS-e ${nfse.numero_nfse} | chave ${nfse.chave_acesso_nacional}`);
|
|
230
|
+
} else if (nfse.numero_dps) {
|
|
231
|
+
// Sem resposta do Sistema Nacional: reenvie com o mesmo número para recuperar a nota sem duplicidade
|
|
232
|
+
console.log(`Reenvie com numero_dps=${nfse.numero_dps}`, nfse.erros);
|
|
232
233
|
}
|
|
234
|
+
|
|
235
|
+
// Cancelamento (evento e101101 no Sistema Nacional)
|
|
236
|
+
const cancelamento = await client.nfse.cancelar({
|
|
237
|
+
numero_nfse: nfse.numero_nfse!, cnpj_prestador: '12345678000195', inscricao_municipal: '123456',
|
|
238
|
+
codigo_municipio_ibge: '3550308', chave_acesso_nacional: nfse.chave_acesso_nacional,
|
|
239
|
+
motivo_codigo: '1', justificativa: 'Erro nos dados do tomador informados na emissão',
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Consulta; sincronizar confere no Sistema Nacional se a nota foi cancelada fora da plataforma
|
|
243
|
+
const nota = await client.nfse.consultar(nfse.chave_acesso_nacional!, { sincronizar: true });
|
|
233
244
|
```
|
|
234
245
|
|
|
235
246
|
---
|
|
@@ -389,6 +400,10 @@ try {
|
|
|
389
400
|
| `prestador.cnpj` | `string` | **Obrigatório** | - | CNPJ da empresa prestadora (14 dígitos). |
|
|
390
401
|
| `prestador.inscricao_municipal` | `string` | **Obrigatório** | - | Inscrição Municipal do prestador. |
|
|
391
402
|
| `prestador.razao_social` | `string` | **Obrigatório** | - | Razão Social do prestador emitente. |
|
|
403
|
+
| `prestador.endereco` | `object` | **Obrigatório** | - | Endereço do prestador; o município dele é o emissor da DPS (Rejeição E0037). |
|
|
404
|
+
| `prestador.percentual_tributos_simples` | `number` | Condicional | - | Alíquota efetiva do Simples (pTotTribSN), exigida do ME/EPP (Rejeição E0712). |
|
|
405
|
+
| `prestador.situacao_simples_nacional` | `string` | Opcional | Derivado | `'1'` não optante, `'2'` MEI, `'3'` ME/EPP. |
|
|
406
|
+
| `prestador.regime_apuracao_simples` | `string` | Opcional | `'1'` | Só ME/EPP: `'1'` tudo pelo SN, `'2'` ISSQN fora, `'3'` federais e ISSQN fora. |
|
|
392
407
|
| `tomador.cpf_cnpj` | `string` | **Obrigatório** | - | CPF (11) ou CNPJ (14) do cliente tomador. |
|
|
393
408
|
| `tomador.razao_social` | `string` | **Obrigatório** | - | Nome completo ou Razão Social do tomador. |
|
|
394
409
|
| `servico.item_lista_servico` | `string` | **Obrigatório** | - | Subitem da LC 116/2003 (ex: `"1.07"`). |
|
|
@@ -397,8 +412,12 @@ try {
|
|
|
397
412
|
| `servico.valor_servicos` | `number` | **Obrigatório** | - | Valor bruto cobrado pelo serviço (R$). |
|
|
398
413
|
| `servico.aliquota_iss` | `number` | Opcional | `2.0` | Alíquota de ISS de 0.0% a 5.0%. |
|
|
399
414
|
| `servico.iss_retido` | `boolean`| Opcional | `false` | Se o ISS deve ser retido pelo tomador. |
|
|
415
|
+
| `servico.codigo_tributacao_nacional` | `string` | Opcional | Derivado | cTribNac de 6 dígitos; se omitido, vem do item pela lista nacional. |
|
|
416
|
+
| `servico.codigo_nbs` | `string` | Opcional | - | Código NBS de 9 dígitos. |
|
|
417
|
+
| `servico.tipo_imunidade` | `string` | Condicional | - | `'0'` a `'5'`, obrigatório com `exigibilidade_iss: '5'` (imunidade). |
|
|
400
418
|
| `modo` | `string` | Opcional | `'direto'` | `'direto'` (pass-through) ou `'assistido'` (IA). |
|
|
401
|
-
| `ambiente` | `string` | Opcional | `'producao'` | `'
|
|
419
|
+
| `ambiente` | `string` | Opcional | `'producao'` | `'homologacao'` (emissão real na produção restrita) ou `'producao'` (em implantação). |
|
|
420
|
+
| `numero_dps` | `number` | Opcional | Automático | Omitido, a API reserva o próximo; informe o devolvido na resposta para reenviar após falta de resposta. |
|
|
402
421
|
|
|
403
422
|
### 📌 Manifestação do Destinatário (`client.dfe.manifestar`)
|
|
404
423
|
|
package/dist/index.d.mts
CHANGED
|
@@ -152,6 +152,8 @@ interface EmissaoItemInput {
|
|
|
152
152
|
gtin?: string;
|
|
153
153
|
ncm?: string;
|
|
154
154
|
cest?: string;
|
|
155
|
+
/** cBenef da UF do emitente (ex: SP010360); exigido em DF, ES, GO, PR, RJ, RS, SC e SP (Rejeição 930). */
|
|
156
|
+
codigo_beneficio_fiscal?: string;
|
|
155
157
|
cfop?: string;
|
|
156
158
|
/** '0' Nacional, '1' Importada, etc. */
|
|
157
159
|
origem_mercadoria?: string;
|
|
@@ -378,6 +380,8 @@ interface TaxPredictionData {
|
|
|
378
380
|
cfop_devolucao_interno?: string | null;
|
|
379
381
|
cfop_devolucao_externo?: string | null;
|
|
380
382
|
icms_cst_csosn: string;
|
|
383
|
+
/** cBenef sugerido pela tabela da UF de origem, quando a CST/CSOSN o exige. */
|
|
384
|
+
codigo_beneficio_fiscal?: string | null;
|
|
381
385
|
icms_aliquota: number;
|
|
382
386
|
icms_reducao_bc: number;
|
|
383
387
|
icms_sujeito_st?: boolean;
|
|
@@ -517,6 +521,13 @@ interface PrestadorNFSeInput {
|
|
|
517
521
|
nome_fantasia?: string;
|
|
518
522
|
optante_simples_nacional?: boolean;
|
|
519
523
|
regime_especial_tributacao?: string;
|
|
524
|
+
/** opSimpNac da DPS: '1' não optante, '2' MEI, '3' ME/EPP. Se omitido, é derivado do regime e do optante. */
|
|
525
|
+
situacao_simples_nacional?: '1' | '2' | '3';
|
|
526
|
+
/** regApTribSN (só ME/EPP): '1' tudo pelo SN, '2' ISSQN fora do SN, '3' federais e ISSQN fora do SN. */
|
|
527
|
+
regime_apuracao_simples?: '1' | '2' | '3';
|
|
528
|
+
/** Alíquota efetiva do Simples Nacional (pTotTribSN, %), exigida do ME/EPP (Rejeição E0712). */
|
|
529
|
+
percentual_tributos_simples?: number;
|
|
530
|
+
/** Endereço do prestador: o município dele é o emissor da DPS (obrigatório na emissão). */
|
|
520
531
|
endereco?: EnderecoNFSeInput;
|
|
521
532
|
}
|
|
522
533
|
interface TomadorNFSeInput {
|
|
@@ -558,7 +569,14 @@ interface ServicoNFSeInput {
|
|
|
558
569
|
municipio_prestacao_ibge: string;
|
|
559
570
|
valor_servicos: number;
|
|
560
571
|
codigo_cnae?: string;
|
|
572
|
+
/** Código de tributação municipal (cTribMun, 3 dígitos). */
|
|
561
573
|
codigo_tributacao_municipio?: string;
|
|
574
|
+
/** cTribNac de 6 dígitos; se omitido, é derivado do item pela lista nacional de serviços. */
|
|
575
|
+
codigo_tributacao_nacional?: string;
|
|
576
|
+
/** Código NBS de 9 dígitos (cNBS). */
|
|
577
|
+
codigo_nbs?: string;
|
|
578
|
+
/** tpImunidade ('0' a '5'), obrigatório com exigibilidade '5' (imunidade). */
|
|
579
|
+
tipo_imunidade?: string;
|
|
562
580
|
valor_deducoes?: number;
|
|
563
581
|
valor_desconto_incondicionado?: number;
|
|
564
582
|
valor_desconto_condicionado?: number;
|
|
@@ -589,6 +607,10 @@ interface NFSeEmissaoResponse {
|
|
|
589
607
|
chave_acesso_nacional?: string;
|
|
590
608
|
data_emissao?: string;
|
|
591
609
|
link_visualizacao?: string;
|
|
610
|
+
/** Número da DPS transmitida: sem resposta do Sistema Nacional, reenvie com ele e a mesma série. */
|
|
611
|
+
numero_dps?: number;
|
|
612
|
+
/** Identificador nacional da DPS (45 posições). */
|
|
613
|
+
id_dps?: string;
|
|
592
614
|
danfse_pdf_base64?: string;
|
|
593
615
|
/** Alias de danfse_pdf_base64 devolvido pela API. */
|
|
594
616
|
danfse_base64?: string;
|
|
@@ -616,7 +638,7 @@ interface CancelamentoNFSeInput {
|
|
|
616
638
|
inscricao_municipal: string;
|
|
617
639
|
codigo_municipio_ibge: string;
|
|
618
640
|
justificativa: string;
|
|
619
|
-
/** '1' Erro de emissão, '2' Serviço não prestado, '3' Duplicidade, '9' Outros. */
|
|
641
|
+
/** '1' Erro de emissão, '2' Serviço não prestado, '3' Duplicidade (enviada como erro de emissão), '9' Outros. */
|
|
620
642
|
motivo_codigo?: string;
|
|
621
643
|
codigo_verificacao?: string;
|
|
622
644
|
chave_acesso_nacional?: string;
|
|
@@ -625,13 +647,16 @@ interface CancelamentoNFSeResponse {
|
|
|
625
647
|
sucesso: boolean;
|
|
626
648
|
numero_nfse: string;
|
|
627
649
|
data_cancelamento?: string;
|
|
650
|
+
/** XML do evento de cancelamento (e101101) registrado no Sistema Nacional. */
|
|
651
|
+
xml_evento?: string;
|
|
628
652
|
mensagem: string;
|
|
629
653
|
erros?: string[];
|
|
630
654
|
}
|
|
631
655
|
|
|
632
656
|
declare class NFSeResource extends BaseResource {
|
|
633
657
|
/**
|
|
634
|
-
* Emite uma
|
|
658
|
+
* Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).
|
|
659
|
+
* Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.
|
|
635
660
|
*/
|
|
636
661
|
emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse>;
|
|
637
662
|
/**
|
|
@@ -639,13 +664,17 @@ declare class NFSeResource extends BaseResource {
|
|
|
639
664
|
*/
|
|
640
665
|
simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse>;
|
|
641
666
|
/**
|
|
642
|
-
*
|
|
667
|
+
* Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.
|
|
668
|
+
* Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.
|
|
643
669
|
*/
|
|
644
670
|
cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse>;
|
|
645
671
|
/**
|
|
646
672
|
* Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.
|
|
673
|
+
* Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.
|
|
647
674
|
*/
|
|
648
|
-
consultar(chaveOuNumero: string
|
|
675
|
+
consultar(chaveOuNumero: string, opcoes?: {
|
|
676
|
+
sincronizar?: boolean;
|
|
677
|
+
}): Promise<Record<string, any>>;
|
|
649
678
|
}
|
|
650
679
|
|
|
651
680
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -152,6 +152,8 @@ interface EmissaoItemInput {
|
|
|
152
152
|
gtin?: string;
|
|
153
153
|
ncm?: string;
|
|
154
154
|
cest?: string;
|
|
155
|
+
/** cBenef da UF do emitente (ex: SP010360); exigido em DF, ES, GO, PR, RJ, RS, SC e SP (Rejeição 930). */
|
|
156
|
+
codigo_beneficio_fiscal?: string;
|
|
155
157
|
cfop?: string;
|
|
156
158
|
/** '0' Nacional, '1' Importada, etc. */
|
|
157
159
|
origem_mercadoria?: string;
|
|
@@ -378,6 +380,8 @@ interface TaxPredictionData {
|
|
|
378
380
|
cfop_devolucao_interno?: string | null;
|
|
379
381
|
cfop_devolucao_externo?: string | null;
|
|
380
382
|
icms_cst_csosn: string;
|
|
383
|
+
/** cBenef sugerido pela tabela da UF de origem, quando a CST/CSOSN o exige. */
|
|
384
|
+
codigo_beneficio_fiscal?: string | null;
|
|
381
385
|
icms_aliquota: number;
|
|
382
386
|
icms_reducao_bc: number;
|
|
383
387
|
icms_sujeito_st?: boolean;
|
|
@@ -517,6 +521,13 @@ interface PrestadorNFSeInput {
|
|
|
517
521
|
nome_fantasia?: string;
|
|
518
522
|
optante_simples_nacional?: boolean;
|
|
519
523
|
regime_especial_tributacao?: string;
|
|
524
|
+
/** opSimpNac da DPS: '1' não optante, '2' MEI, '3' ME/EPP. Se omitido, é derivado do regime e do optante. */
|
|
525
|
+
situacao_simples_nacional?: '1' | '2' | '3';
|
|
526
|
+
/** regApTribSN (só ME/EPP): '1' tudo pelo SN, '2' ISSQN fora do SN, '3' federais e ISSQN fora do SN. */
|
|
527
|
+
regime_apuracao_simples?: '1' | '2' | '3';
|
|
528
|
+
/** Alíquota efetiva do Simples Nacional (pTotTribSN, %), exigida do ME/EPP (Rejeição E0712). */
|
|
529
|
+
percentual_tributos_simples?: number;
|
|
530
|
+
/** Endereço do prestador: o município dele é o emissor da DPS (obrigatório na emissão). */
|
|
520
531
|
endereco?: EnderecoNFSeInput;
|
|
521
532
|
}
|
|
522
533
|
interface TomadorNFSeInput {
|
|
@@ -558,7 +569,14 @@ interface ServicoNFSeInput {
|
|
|
558
569
|
municipio_prestacao_ibge: string;
|
|
559
570
|
valor_servicos: number;
|
|
560
571
|
codigo_cnae?: string;
|
|
572
|
+
/** Código de tributação municipal (cTribMun, 3 dígitos). */
|
|
561
573
|
codigo_tributacao_municipio?: string;
|
|
574
|
+
/** cTribNac de 6 dígitos; se omitido, é derivado do item pela lista nacional de serviços. */
|
|
575
|
+
codigo_tributacao_nacional?: string;
|
|
576
|
+
/** Código NBS de 9 dígitos (cNBS). */
|
|
577
|
+
codigo_nbs?: string;
|
|
578
|
+
/** tpImunidade ('0' a '5'), obrigatório com exigibilidade '5' (imunidade). */
|
|
579
|
+
tipo_imunidade?: string;
|
|
562
580
|
valor_deducoes?: number;
|
|
563
581
|
valor_desconto_incondicionado?: number;
|
|
564
582
|
valor_desconto_condicionado?: number;
|
|
@@ -589,6 +607,10 @@ interface NFSeEmissaoResponse {
|
|
|
589
607
|
chave_acesso_nacional?: string;
|
|
590
608
|
data_emissao?: string;
|
|
591
609
|
link_visualizacao?: string;
|
|
610
|
+
/** Número da DPS transmitida: sem resposta do Sistema Nacional, reenvie com ele e a mesma série. */
|
|
611
|
+
numero_dps?: number;
|
|
612
|
+
/** Identificador nacional da DPS (45 posições). */
|
|
613
|
+
id_dps?: string;
|
|
592
614
|
danfse_pdf_base64?: string;
|
|
593
615
|
/** Alias de danfse_pdf_base64 devolvido pela API. */
|
|
594
616
|
danfse_base64?: string;
|
|
@@ -616,7 +638,7 @@ interface CancelamentoNFSeInput {
|
|
|
616
638
|
inscricao_municipal: string;
|
|
617
639
|
codigo_municipio_ibge: string;
|
|
618
640
|
justificativa: string;
|
|
619
|
-
/** '1' Erro de emissão, '2' Serviço não prestado, '3' Duplicidade, '9' Outros. */
|
|
641
|
+
/** '1' Erro de emissão, '2' Serviço não prestado, '3' Duplicidade (enviada como erro de emissão), '9' Outros. */
|
|
620
642
|
motivo_codigo?: string;
|
|
621
643
|
codigo_verificacao?: string;
|
|
622
644
|
chave_acesso_nacional?: string;
|
|
@@ -625,13 +647,16 @@ interface CancelamentoNFSeResponse {
|
|
|
625
647
|
sucesso: boolean;
|
|
626
648
|
numero_nfse: string;
|
|
627
649
|
data_cancelamento?: string;
|
|
650
|
+
/** XML do evento de cancelamento (e101101) registrado no Sistema Nacional. */
|
|
651
|
+
xml_evento?: string;
|
|
628
652
|
mensagem: string;
|
|
629
653
|
erros?: string[];
|
|
630
654
|
}
|
|
631
655
|
|
|
632
656
|
declare class NFSeResource extends BaseResource {
|
|
633
657
|
/**
|
|
634
|
-
* Emite uma
|
|
658
|
+
* Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).
|
|
659
|
+
* Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.
|
|
635
660
|
*/
|
|
636
661
|
emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse>;
|
|
637
662
|
/**
|
|
@@ -639,13 +664,17 @@ declare class NFSeResource extends BaseResource {
|
|
|
639
664
|
*/
|
|
640
665
|
simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse>;
|
|
641
666
|
/**
|
|
642
|
-
*
|
|
667
|
+
* Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.
|
|
668
|
+
* Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.
|
|
643
669
|
*/
|
|
644
670
|
cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse>;
|
|
645
671
|
/**
|
|
646
672
|
* Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.
|
|
673
|
+
* Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.
|
|
647
674
|
*/
|
|
648
|
-
consultar(chaveOuNumero: string
|
|
675
|
+
consultar(chaveOuNumero: string, opcoes?: {
|
|
676
|
+
sincronizar?: boolean;
|
|
677
|
+
}): Promise<Record<string, any>>;
|
|
649
678
|
}
|
|
650
679
|
|
|
651
680
|
/**
|
package/dist/index.js
CHANGED
|
@@ -125,7 +125,7 @@ var BaseResource = class {
|
|
|
125
125
|
const reqHeaders = {
|
|
126
126
|
"Accept": "application/json",
|
|
127
127
|
"X-API-Key": this.apiKey,
|
|
128
|
-
"User-Agent": "Pairus-NodeJS-SDK/1.
|
|
128
|
+
"User-Agent": "Pairus-NodeJS-SDK/1.12.0",
|
|
129
129
|
...options.headers || {}
|
|
130
130
|
};
|
|
131
131
|
const isFormData = typeof FormData !== "undefined" && options.body instanceof FormData;
|
|
@@ -196,7 +196,7 @@ var BaseResource = class {
|
|
|
196
196
|
const reqHeaders = {
|
|
197
197
|
"Accept": "*/*",
|
|
198
198
|
"X-API-Key": this.apiKey,
|
|
199
|
-
"User-Agent": "Pairus-NodeJS-SDK/1.
|
|
199
|
+
"User-Agent": "Pairus-NodeJS-SDK/1.12.0",
|
|
200
200
|
...options.headers || {}
|
|
201
201
|
};
|
|
202
202
|
let lastError = null;
|
|
@@ -255,7 +255,7 @@ var BaseResource = class {
|
|
|
255
255
|
const reqHeaders = {
|
|
256
256
|
"Accept": "*/*",
|
|
257
257
|
"X-API-Key": this.apiKey,
|
|
258
|
-
"User-Agent": "Pairus-NodeJS-SDK/1.
|
|
258
|
+
"User-Agent": "Pairus-NodeJS-SDK/1.12.0",
|
|
259
259
|
...options.headers || {}
|
|
260
260
|
};
|
|
261
261
|
let lastError = null;
|
|
@@ -551,7 +551,8 @@ var FiscalResource = class extends BaseResource {
|
|
|
551
551
|
// src/resources/nfse.ts
|
|
552
552
|
var NFSeResource = class extends BaseResource {
|
|
553
553
|
/**
|
|
554
|
-
* Emite uma
|
|
554
|
+
* Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).
|
|
555
|
+
* Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.
|
|
555
556
|
*/
|
|
556
557
|
async emitir(payload) {
|
|
557
558
|
return this.request({
|
|
@@ -571,7 +572,8 @@ var NFSeResource = class extends BaseResource {
|
|
|
571
572
|
});
|
|
572
573
|
}
|
|
573
574
|
/**
|
|
574
|
-
*
|
|
575
|
+
* Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.
|
|
576
|
+
* Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.
|
|
575
577
|
*/
|
|
576
578
|
async cancelar(payload) {
|
|
577
579
|
return this.request({
|
|
@@ -582,11 +584,13 @@ var NFSeResource = class extends BaseResource {
|
|
|
582
584
|
}
|
|
583
585
|
/**
|
|
584
586
|
* Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.
|
|
587
|
+
* Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.
|
|
585
588
|
*/
|
|
586
|
-
async consultar(chaveOuNumero) {
|
|
589
|
+
async consultar(chaveOuNumero, opcoes = {}) {
|
|
587
590
|
return this.request({
|
|
588
591
|
method: "GET",
|
|
589
|
-
path: `/v1/nfse/${chaveOuNumero}
|
|
592
|
+
path: `/v1/nfse/${chaveOuNumero}`,
|
|
593
|
+
params: opcoes.sincronizar ? { sincronizar: "true" } : void 0
|
|
590
594
|
});
|
|
591
595
|
}
|
|
592
596
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["export { PairusProductData } from './client.js';\r\nexport { Webhooks } from './webhooks.js';\r\nexport { ProductsResource } from './resources/products.js';\r\nexport { FiscalResource } from './resources/fiscal.js';\r\nexport { EmissaoResource } from './resources/emissao.js';\r\nexport { NFSeResource } from './resources/nfse.js';\r\nexport { DFeResource } from './resources/dfe.js';\r\nexport * from './errors.js';\r\nexport * from './config.js';\r\nexport * from './types/index.js';\r\n\r\n","/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.10.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.10.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.10.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n ListarDocumentosDFeParams,\n ListarDocumentosDFeResponse,\n ManifestarDFeInput,\n ManifestarDFeResponse,\n SincronizarDFeInput,\n SincronizarDFeResponse,\n} from '../types/dfe.js';\n\nexport class DFeResource extends BaseResource {\n /**\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\n *\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\n */\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\n return this.request<SincronizarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/sincronizar',\n body: {\n cnpj: input.cnpj,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\n *\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\n * @returns Lista de documentos fiscais capturados e status de manifestação\n */\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\n const queryParams: Record<string, string> = {\n cnpj: params.cnpj,\n ambiente: params.ambiente || 'producao',\n };\n if (params.limite) {\n queryParams.limite = String(params.limite);\n }\n\n return this.request<ListarDocumentosDFeResponse>({\n method: 'GET',\n path: '/v1/dfe/documentos',\n params: queryParams,\n });\n }\n\n /**\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\n *\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\n * @returns Protocolo de homologação do evento na SEFAZ\n */\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\n return this.request<ManifestarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/manifestar',\n body: {\n cnpj: input.cnpj,\n chave_acesso: input.chave_acesso,\n tipo_evento: input.tipo_evento,\n justificativa: input.justificativa,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns Conteúdo do XML em formato string\n */\n public async baixarXml(chaveAcesso: string): Promise<string> {\n return this.requestText({\n method: 'GET',\n path: `/v1/dfe/xml/${chaveAcesso}`,\n });\n }\n\n /**\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns ArrayBuffer contendo o PDF binário\n */\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\n return this.requestBinary({\n method: 'GET',\n path: `/v1/dfe/danfe/${chaveAcesso}`,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n CancelamentoNFSeInput,\n CancelamentoNFSeResponse,\n NFSeEmissaoInput,\n NFSeEmissaoResponse,\n} from '../types/nfse.js';\n\nexport class NFSeResource extends BaseResource {\n /**\n * Emite uma Nota Fiscal de Serviços Eletrônica (NFS-e) perante o SND ou prefeitura.\n */\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\n return this.request<NFSeEmissaoResponse>({\n method: 'POST',\n path: '/v1/nfse/emitir',\n body: payload,\n });\n }\n\n /**\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\n */\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\n return this.request<NFSeEmissaoResponse>({\n method: 'POST',\n path: '/v1/nfse/simular',\n body: payload,\n });\n }\n\n /**\n * Homologa o cancelamento oficial de uma NFS-e perante o SND ou prefeitura.\n */\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\n return this.request<CancelamentoNFSeResponse>({\n method: 'POST',\n path: '/v1/nfse/cancelar',\n body: payload,\n });\n }\n\n /**\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\n */\n async consultar(chaveOuNumero: string): Promise<Record<string, any>> {\n return this.request<Record<string, any>>({\n method: 'GET',\n path: `/v1/nfse/${chaveOuNumero}`,\n });\n }\n}\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\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada 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 */\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 const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(signature.trim(), '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 * 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 JSON.parse(rawStr) as WebhookEvent<T>;\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["export { PairusProductData } from './client.js';\r\nexport { Webhooks } from './webhooks.js';\r\nexport { ProductsResource } from './resources/products.js';\r\nexport { FiscalResource } from './resources/fiscal.js';\r\nexport { EmissaoResource } from './resources/emissao.js';\r\nexport { NFSeResource } from './resources/nfse.js';\r\nexport { DFeResource } from './resources/dfe.js';\r\nexport * from './errors.js';\r\nexport * from './config.js';\r\nexport * from './types/index.js';\r\n\r\n","/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.12.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.12.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.12.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n ListarDocumentosDFeParams,\n ListarDocumentosDFeResponse,\n ManifestarDFeInput,\n ManifestarDFeResponse,\n SincronizarDFeInput,\n SincronizarDFeResponse,\n} from '../types/dfe.js';\n\nexport class DFeResource extends BaseResource {\n /**\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\n *\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\n */\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\n return this.request<SincronizarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/sincronizar',\n body: {\n cnpj: input.cnpj,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\n *\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\n * @returns Lista de documentos fiscais capturados e status de manifestação\n */\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\n const queryParams: Record<string, string> = {\n cnpj: params.cnpj,\n ambiente: params.ambiente || 'producao',\n };\n if (params.limite) {\n queryParams.limite = String(params.limite);\n }\n\n return this.request<ListarDocumentosDFeResponse>({\n method: 'GET',\n path: '/v1/dfe/documentos',\n params: queryParams,\n });\n }\n\n /**\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\n *\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\n * @returns Protocolo de homologação do evento na SEFAZ\n */\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\n return this.request<ManifestarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/manifestar',\n body: {\n cnpj: input.cnpj,\n chave_acesso: input.chave_acesso,\n tipo_evento: input.tipo_evento,\n justificativa: input.justificativa,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns Conteúdo do XML em formato string\n */\n public async baixarXml(chaveAcesso: string): Promise<string> {\n return this.requestText({\n method: 'GET',\n path: `/v1/dfe/xml/${chaveAcesso}`,\n });\n }\n\n /**\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns ArrayBuffer contendo o PDF binário\n */\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\n return this.requestBinary({\n method: 'GET',\n path: `/v1/dfe/danfe/${chaveAcesso}`,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoNFSeInput,\r\n CancelamentoNFSeResponse,\r\n NFSeEmissaoInput,\r\n NFSeEmissaoResponse,\r\n} from '../types/nfse.js';\r\n\r\nexport class NFSeResource extends BaseResource {\r\n /**\r\n * Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).\r\n * Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.\r\n */\r\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/emitir',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\r\n */\r\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.\r\n * Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.\r\n */\r\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\r\n return this.request<CancelamentoNFSeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/cancelar',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\r\n * Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.\r\n */\r\n async consultar(chaveOuNumero: string, opcoes: { sincronizar?: boolean } = {}): Promise<Record<string, any>> {\r\n return this.request<Record<string, any>>({\r\n method: 'GET',\r\n path: `/v1/nfse/${chaveOuNumero}`,\r\n params: opcoes.sincronizar ? { sincronizar: 'true' } : undefined,\r\n });\r\n }\r\n}\r\n\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n ProductDetails,\r\n ProductEnrichedDetails,\r\n ProductSearchResponse,\r\n ProductSearchResultItem,\r\n} from '../types/product.js';\r\n\r\n/** Primeiro valor preenchido (ignora undefined, null e texto vazio). */\r\nfunction primeiro<T>(...valores: Array<T | undefined | null | ''>): T | undefined {\r\n return valores.find((v) => v !== undefined && v !== null && v !== '') as T | undefined;\r\n}\r\n\r\nfunction numero(valor: any): number | undefined {\r\n const n = valor === undefined || valor === null || valor === '' ? NaN : Number(valor);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\n/** Converte o produto da API (layout NF-e + `infoAdicional`) para `ProductDetails`. */\r\nfunction produtoDaApi(data: any, gtinFallback = ''): ProductDetails {\r\n const prod = data?.produto || data || {};\r\n const info = prod.infoAdicional || {};\r\n return {\r\n gtin: String(primeiro(prod.GTIN, prod.gtin, gtinFallback) ?? ''),\r\n xProd: primeiro(prod.xProd, prod.descricao) || 'Descrição Indisponível',\r\n ncm: primeiro(prod.NCM, prod.ncm),\r\n cest: primeiro(prod.CEST, prod.cest),\r\n marca: primeiro(prod.marca, info.xMarca),\r\n fabricante: prod.fabricante,\r\n categoria: primeiro(prod.categoria, info.xCategoria),\r\n imagemUrl: primeiro(prod.imagem_url, prod.thumbnail, info.urlImagem),\r\n pesoBruto: numero(primeiro(prod.peso_bruto, info.pesoBruto)),\r\n pesoLiquido: numero(primeiro(prod.peso_liquido, info.pesoLiquido)),\r\n quantidadeEmbalagem: Number(prod.quantidade_embalagem || 1),\r\n tpGTIN: prod.tpGTIN ?? undefined,\r\n fonte: prod.fonte ?? undefined,\r\n infoAdicional: prod.infoAdicional ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte o produto enriquecido (`/v2/gtin`, scan ou item da busca) para `ProductEnrichedDetails`. */\r\nfunction produtoEnriquecidoDaApi(data: any, gtinFallback = ''): ProductEnrichedDetails {\r\n const prod = data?.produto || data || {};\r\n const base = produtoDaApi(prod, gtinFallback);\r\n const enriquecimento = prod.enriquecimentoIA || {};\r\n const atributos = enriquecimento.atributos || {};\r\n const temAtributos = Object.keys(atributos).length > 0;\r\n return {\r\n gtin: base.gtin,\r\n xProd: base.xProd,\r\n xProd_higienizado: enriquecimento.xProd_higienizado,\r\n descricao_completa: primeiro(prod.descricao_completa, enriquecimento.descricao_seo),\r\n ficha_tecnica: prod.ficha_tecnica ?? (temAtributos ? atributos : undefined),\r\n palavras_chave: prod.palavras_chave,\r\n ncm: base.ncm,\r\n cest: base.cest,\r\n marca: primeiro(prod.marca, atributos.marca, base.marca),\r\n categoria: primeiro(prod.categoria, enriquecimento.categoria_comercial, base.categoria),\r\n imagem_url: base.imagemUrl,\r\n peso_bruto: base.pesoBruto,\r\n peso_liquido: primeiro(numero(prod.peso_liquido), numero(atributos.peso_liquido), base.pesoLiquido),\r\n dados_tributarios_sugeridos: prod.dados_tributarios_sugeridos ?? prod.tributacaoIA ?? undefined,\r\n tpGTIN: base.tpGTIN,\r\n fonte: base.fonte,\r\n infoAdicional: base.infoAdicional,\r\n enriquecimentoIA: prod.enriquecimentoIA ?? undefined,\r\n tributacaoIA: prod.tributacaoIA ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte `/v2/gtin/search` (`resultados[].produto`; aceita o legado `produtos`). */\r\nfunction buscaDaApi(data: any, query: string): ProductSearchResponse {\r\n const itens: ProductSearchResultItem[] = (data?.resultados || data?.produtos || []).map((item: any) => {\r\n const prod = produtoEnriquecidoDaApi(item.produto || item);\r\n return {\r\n gtin: prod.gtin,\r\n xProd: prod.xProd,\r\n marca: prod.marca,\r\n categoria: prod.categoria,\r\n score: item.score !== undefined && item.score !== null ? Number(item.score) : undefined,\r\n justificativa: item.justificativa ?? undefined,\r\n ncm: prod.ncm,\r\n cest: prod.cest,\r\n imagem_url: prod.imagem_url,\r\n };\r\n });\r\n return {\r\n status: data?.status || 'success',\r\n provider: data?.provider || 'PAIRUS',\r\n total_encontrados: itens.length,\r\n termo_buscado: data?.query || query,\r\n motor_busca: data?.motor_busca,\r\n produtos: itens,\r\n };\r\n}\r\n\r\nexport class ProductsResource extends BaseResource {\r\n /**\r\n * Consulta dados oficiais de um produto por código de barras GTIN/EAN (V1).\r\n * @param gtin Código numérico de 8 a 14 dígitos.\r\n */\r\n public async get(gtin: string): Promise<ProductDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v1/gtin/${gtinLimpo}` });\r\n return produtoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Consulta dados enriquecidos por IA, com SEO e ficha técnica estruturada (V2).\r\n * @param gtin Código numérico do produto.\r\n */\r\n public async getEnriched(gtin: string): Promise<ProductEnrichedDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v2/gtin/${gtinLimpo}` });\r\n return produtoEnriquecidoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Executa busca semântica por intenção/linguagem natural (V2).\r\n * @param query Termo livre de busca (ex: 'refrigerante zero lata').\r\n */\r\n public async search(query: string): Promise<ProductSearchResponse> {\r\n const data = await this.request<any>({ method: 'GET', path: '/v2/gtin/search', params: { q: query } });\r\n return buscaDaApi(data, query);\r\n }\r\n\r\n /**\r\n * Reconhece código de barras por visão computacional a partir de foto JPEG (OCR V2).\r\n * @param file Blob, Buffer ou FormData com a imagem JPEG.\r\n */\r\n public async scan(file: Blob | Buffer | FormData): Promise<ProductEnrichedDetails> {\r\n let formData: FormData;\r\n\r\n if (typeof FormData !== 'undefined' && file instanceof FormData) {\r\n formData = file;\r\n } else {\r\n formData = new FormData();\r\n if (typeof Blob !== 'undefined' && file instanceof Blob) {\r\n formData.append('file', file, 'barcode.jpg');\r\n } else {\r\n // Node Buffer\r\n const blob = new Blob([file as any], { type: 'image/jpeg' });\r\n formData.append('file', blob, 'barcode.jpg');\r\n }\r\n }\r\n\r\n const data = await this.request<any>({ method: 'POST', path: '/v2/gtin/scan', body: formData });\r\n return produtoEnriquecidoDaApi(data);\r\n }\r\n}\r\n","import * as crypto from 'crypto';\r\nimport { InvalidSignatureError } from './errors.js';\r\nimport { WebhookEvent } from './types/webhook.js';\r\n\r\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada 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 */\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 const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(signature.trim(), '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 * 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 JSON.parse(rawStr) as WebhookEvent<T>;\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
|
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.
|
|
77
|
+
"User-Agent": "Pairus-NodeJS-SDK/1.12.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.
|
|
148
|
+
"User-Agent": "Pairus-NodeJS-SDK/1.12.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.
|
|
207
|
+
"User-Agent": "Pairus-NodeJS-SDK/1.12.0",
|
|
208
208
|
...options.headers || {}
|
|
209
209
|
};
|
|
210
210
|
let lastError = null;
|
|
@@ -500,7 +500,8 @@ var FiscalResource = class extends BaseResource {
|
|
|
500
500
|
// src/resources/nfse.ts
|
|
501
501
|
var NFSeResource = class extends BaseResource {
|
|
502
502
|
/**
|
|
503
|
-
* Emite uma
|
|
503
|
+
* Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).
|
|
504
|
+
* Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.
|
|
504
505
|
*/
|
|
505
506
|
async emitir(payload) {
|
|
506
507
|
return this.request({
|
|
@@ -520,7 +521,8 @@ var NFSeResource = class extends BaseResource {
|
|
|
520
521
|
});
|
|
521
522
|
}
|
|
522
523
|
/**
|
|
523
|
-
*
|
|
524
|
+
* Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.
|
|
525
|
+
* Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.
|
|
524
526
|
*/
|
|
525
527
|
async cancelar(payload) {
|
|
526
528
|
return this.request({
|
|
@@ -531,11 +533,13 @@ var NFSeResource = class extends BaseResource {
|
|
|
531
533
|
}
|
|
532
534
|
/**
|
|
533
535
|
* Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.
|
|
536
|
+
* Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.
|
|
534
537
|
*/
|
|
535
|
-
async consultar(chaveOuNumero) {
|
|
538
|
+
async consultar(chaveOuNumero, opcoes = {}) {
|
|
536
539
|
return this.request({
|
|
537
540
|
method: "GET",
|
|
538
|
-
path: `/v1/nfse/${chaveOuNumero}
|
|
541
|
+
path: `/v1/nfse/${chaveOuNumero}`,
|
|
542
|
+
params: opcoes.sincronizar ? { sincronizar: "true" } : void 0
|
|
539
543
|
});
|
|
540
544
|
}
|
|
541
545
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/fiscal.ts","../src/resources/nfse.ts","../src/resources/products.ts","../src/webhooks.ts","../src/client.ts"],"sourcesContent":["/**\r\n * Opções de configuração para o cliente PairusProductData.\r\n */\r\n\r\nexport interface PairusClientOptions {\r\n apiKey?: string;\r\n baseUrl?: string;\r\n timeoutMs?: number;\r\n maxRetries?: number;\r\n}\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api.pairus.com.br';\r\nexport const DEFAULT_TIMEOUT_MS = 15000;\r\nexport const DEFAULT_MAX_RETRIES = 3;\r\n","/**\r\n * Classes de erro oficiais do SDK @pairus/product-data.\r\n */\r\n\r\nexport class PairusError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'PairusError';\r\n }\r\n}\r\n\r\nexport class PairusAPIError extends PairusError {\r\n public readonly statusCode: number;\r\n public readonly cStat: string;\r\n public readonly xMotivo: string;\r\n public readonly details?: any;\r\n\r\n constructor(statusCode: number, cStat?: string, xMotivo?: string, details?: any) {\r\n const code = cStat || String(statusCode);\r\n const reason = xMotivo || details?.detail || `Erro HTTP ${statusCode}`;\r\n super(`[${code}] ${reason}`);\r\n this.name = 'PairusAPIError';\r\n this.statusCode = statusCode;\r\n this.cStat = code;\r\n this.xMotivo = reason;\r\n this.details = details;\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends PairusAPIError {\r\n constructor(cStat = '401', xMotivo = 'Chave de API inválida ou não autorizada.', details?: any) {\r\n super(401, cStat, xMotivo, details);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\nexport class RateLimitError extends PairusAPIError {\r\n public readonly retryAfter?: number;\r\n\r\n constructor(retryAfter?: number, cStat = '429', xMotivo = 'Limite de requisições excedido.', details?: any) {\r\n super(429, cStat, xMotivo, details);\r\n this.name = 'RateLimitError';\r\n this.retryAfter = retryAfter;\r\n }\r\n}\r\n\r\nexport class InvalidSignatureError extends PairusError {\r\n constructor(message = \"A assinatura criptográfica do webhook ('X-Pairus-Signature') é inválida.\") {\r\n super(message);\r\n this.name = 'InvalidSignatureError';\r\n }\r\n}\r\n\r\nexport class NetworkError extends PairusError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NetworkError';\r\n }\r\n}\r\n","import {\r\n AuthenticationError,\r\n NetworkError,\r\n PairusAPIError,\r\n RateLimitError,\r\n} from '../errors.js';\r\n\r\nexport interface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string>;\r\n body?: any;\r\n headers?: Record<string, string>;\r\n}\r\n\r\nexport class BaseResource {\r\n protected apiKey: string;\r\n protected baseUrl: string;\r\n protected timeoutMs: number;\r\n protected maxRetries: number;\r\n\r\n constructor(apiKey: string, baseUrl: string, timeoutMs: number, maxRetries: number) {\r\n this.apiKey = apiKey;\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '');\r\n this.timeoutMs = timeoutMs;\r\n this.maxRetries = maxRetries;\r\n }\r\n\r\n protected async request<T>(options: RequestOptions): Promise<T> {\r\n let url = `${this.baseUrl}/${options.path.replace(/^\\/+/, '')}`;\r\n if (options.params) {\r\n const query = new URLSearchParams(options.params).toString();\r\n url = `${url}?${query}`;\r\n }\r\n\r\n const reqHeaders: Record<string, string> = {\r\n 'Accept': 'application/json',\r\n 'X-API-Key': this.apiKey,\r\n 'User-Agent': 'Pairus-NodeJS-SDK/1.10.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.10.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.10.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n ListarDocumentosDFeParams,\n ListarDocumentosDFeResponse,\n ManifestarDFeInput,\n ManifestarDFeResponse,\n SincronizarDFeInput,\n SincronizarDFeResponse,\n} from '../types/dfe.js';\n\nexport class DFeResource extends BaseResource {\n /**\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\n *\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\n */\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\n return this.request<SincronizarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/sincronizar',\n body: {\n cnpj: input.cnpj,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\n *\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\n * @returns Lista de documentos fiscais capturados e status de manifestação\n */\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\n const queryParams: Record<string, string> = {\n cnpj: params.cnpj,\n ambiente: params.ambiente || 'producao',\n };\n if (params.limite) {\n queryParams.limite = String(params.limite);\n }\n\n return this.request<ListarDocumentosDFeResponse>({\n method: 'GET',\n path: '/v1/dfe/documentos',\n params: queryParams,\n });\n }\n\n /**\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\n *\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\n * @returns Protocolo de homologação do evento na SEFAZ\n */\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\n return this.request<ManifestarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/manifestar',\n body: {\n cnpj: input.cnpj,\n chave_acesso: input.chave_acesso,\n tipo_evento: input.tipo_evento,\n justificativa: input.justificativa,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns Conteúdo do XML em formato string\n */\n public async baixarXml(chaveAcesso: string): Promise<string> {\n return this.requestText({\n method: 'GET',\n path: `/v1/dfe/xml/${chaveAcesso}`,\n });\n }\n\n /**\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns ArrayBuffer contendo o PDF binário\n */\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\n return this.requestBinary({\n method: 'GET',\n path: `/v1/dfe/danfe/${chaveAcesso}`,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n CancelamentoNFSeInput,\n CancelamentoNFSeResponse,\n NFSeEmissaoInput,\n NFSeEmissaoResponse,\n} from '../types/nfse.js';\n\nexport class NFSeResource extends BaseResource {\n /**\n * Emite uma Nota Fiscal de Serviços Eletrônica (NFS-e) perante o SND ou prefeitura.\n */\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\n return this.request<NFSeEmissaoResponse>({\n method: 'POST',\n path: '/v1/nfse/emitir',\n body: payload,\n });\n }\n\n /**\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\n */\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\n return this.request<NFSeEmissaoResponse>({\n method: 'POST',\n path: '/v1/nfse/simular',\n body: payload,\n });\n }\n\n /**\n * Homologa o cancelamento oficial de uma NFS-e perante o SND ou prefeitura.\n */\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\n return this.request<CancelamentoNFSeResponse>({\n method: 'POST',\n path: '/v1/nfse/cancelar',\n body: payload,\n });\n }\n\n /**\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\n */\n async consultar(chaveOuNumero: string): Promise<Record<string, any>> {\n return this.request<Record<string, any>>({\n method: 'GET',\n path: `/v1/nfse/${chaveOuNumero}`,\n });\n }\n}\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\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada 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 */\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 const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(signature.trim(), '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 * 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 JSON.parse(rawStr) as WebhookEvent<T>;\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/resources/base.ts","../src/resources/dfe.ts","../src/resources/emissao.ts","../src/resources/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.12.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.12.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.12.0',\r\n ...(options.headers || {}),\r\n };\r\n\r\n let lastError: any = null;\r\n\r\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\r\n\r\n const response = await fetch(url, {\r\n method: options.method,\r\n headers: reqHeaders,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (response.ok || (response.status >= 200 && response.status < 300)) {\r\n return await response.arrayBuffer();\r\n }\r\n\r\n let errData: any = {};\r\n try {\r\n errData = await response.json();\r\n } catch {\r\n errData = {};\r\n }\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n if (response.status === 429) {\r\n const retryAfterSec = parseFloat(response.headers.get('Retry-After') || '2');\r\n if (attempt < this.maxRetries - 1) {\r\n await new Promise((res) => setTimeout(res, (retryAfterSec + Math.random() * 0.5) * 1000));\r\n continue;\r\n }\r\n throw new RateLimitError(retryAfterSec, errData.cStat, errData.xMotivo, errData);\r\n }\r\n\r\n throw new PairusAPIError(response.status, errData.cStat, errData.xMotivo, errData);\r\n } catch (err: any) {\r\n if (err instanceof PairusAPIError) {\r\n throw err;\r\n }\r\n lastError = err;\r\n if (attempt < this.maxRetries - 1) {\r\n const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;\r\n await new Promise((res) => setTimeout(res, delay));\r\n continue;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n throw new NetworkError(`Falha de conexão com a API PAIRUS após ${this.maxRetries} tentativas: ${lastError?.message || lastError}`);\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\nimport {\n ListarDocumentosDFeParams,\n ListarDocumentosDFeResponse,\n ManifestarDFeInput,\n ManifestarDFeResponse,\n SincronizarDFeInput,\n SincronizarDFeResponse,\n} from '../types/dfe.js';\n\nexport class DFeResource extends BaseResource {\n /**\n * Dispara busca ativa de notas fiscais emitidas contra o CNPJ na SEFAZ Nacional.\n *\n * @param input Parâmetros de sincronização (CNPJ e ambiente opcional)\n * @returns Resultado da consulta SEFAZ com novos documentos e controle de NSU\n */\n public async sincronizar(input: SincronizarDFeInput): Promise<SincronizarDFeResponse> {\n return this.request<SincronizarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/sincronizar',\n body: {\n cnpj: input.cnpj,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Lista notas fiscais de compras emitidas por fornecedores contra a sua empresa.\n *\n * @param params Filtros de busca (CNPJ, ambiente e limite de registros)\n * @returns Lista de documentos fiscais capturados e status de manifestação\n */\n public async listarDocumentos(params: ListarDocumentosDFeParams): Promise<ListarDocumentosDFeResponse> {\n const queryParams: Record<string, string> = {\n cnpj: params.cnpj,\n ambiente: params.ambiente || 'producao',\n };\n if (params.limite) {\n queryParams.limite = String(params.limite);\n }\n\n return this.request<ListarDocumentosDFeResponse>({\n method: 'GET',\n path: '/v1/dfe/documentos',\n params: queryParams,\n });\n }\n\n /**\n * Registra evento oficial de Manifestação do Destinatário perante o Ambiente Nacional da SEFAZ.\n *\n * @param input Dados do evento ('210210' Ciência, '210200' Confirmação, '210220' Desconhecimento, '210240' Não Realizada)\n * @returns Protocolo de homologação do evento na SEFAZ\n */\n public async manifestar(input: ManifestarDFeInput): Promise<ManifestarDFeResponse> {\n return this.request<ManifestarDFeResponse>({\n method: 'POST',\n path: '/v1/dfe/manifestar',\n body: {\n cnpj: input.cnpj,\n chave_acesso: input.chave_acesso,\n tipo_evento: input.tipo_evento,\n justificativa: input.justificativa,\n ambiente: input.ambiente || 'producao',\n },\n });\n }\n\n /**\n * Baixa o arquivo XML autorizado (procNFe) da nota fiscal capturada.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns Conteúdo do XML em formato string\n */\n public async baixarXml(chaveAcesso: string): Promise<string> {\n return this.requestText({\n method: 'GET',\n path: `/v1/dfe/xml/${chaveAcesso}`,\n });\n }\n\n /**\n * Baixa o DANFE em PDF da nota fiscal de fornecedor.\n *\n * @param chaveAcesso Chave de acesso de 44 dígitos da NF-e\n * @returns ArrayBuffer contendo o PDF binário\n */\n public async baixarDanfe(chaveAcesso: string): Promise<ArrayBuffer> {\n return this.requestBinary({\n method: 'GET',\n path: `/v1/dfe/danfe/${chaveAcesso}`,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\r\nimport { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoInput,\r\n CartaCorrecaoInput,\r\n EmissaoNFeInput,\r\n EmissaoOptions,\r\n EmissaoNFeResponse,\r\n EventoNFeResponse,\r\n InutilizacaoInput,\r\n} from '../types/emissao.js';\r\n\r\n/**\r\n * Cabeçalho Idempotency-Key da emissão. Sem chave informada, gera um UUID por chamada; a mesma chave\r\n * acompanha todas as retentativas automáticas (timeout, rede, 5xx), então a API devolve a nota já\r\n * emitida em vez de emitir outra.\r\n */\r\nfunction cabecalhoIdempotencia(options?: EmissaoOptions): Record<string, string> {\r\n return { 'Idempotency-Key': options?.idempotencyKey || randomUUID() };\r\n}\r\n\r\nexport class EmissaoResource extends BaseResource {\r\n /**\r\n * Emite uma Nota Fiscal Eletrônica (NF-e Modelo 55) perante a SEFAZ.\r\n */\r\n public async emitirNFe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Nota Fiscal de Consumidor Eletrônica (NFC-e Modelo 65) perante a SEFAZ.\r\n */\r\n public async emitirNFCe(payload: EmissaoNFeInput, options?: EmissaoOptions): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfce/emitir',\r\n body: payload,\r\n headers: cabecalhoIdempotencia(options),\r\n });\r\n }\r\n\r\n /**\r\n * Simula uma emissão fiscal sem transmitir à SEFAZ (custo ZERO de créditos).\r\n */\r\n public async simular(payload: EmissaoNFeInput): Promise<EmissaoNFeResponse> {\r\n return this.request<EmissaoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Homologa o cancelamento oficial de uma NF-e ou NFC-e perante a SEFAZ.\r\n */\r\n public async cancelar(params: CancelamentoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/cancelar',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n justificativa: params.justificativa,\r\n protocolo_autorizacao: params.protocolo_autorizacao,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Emite uma Carta de Correção Eletrônica (CC-e) perante a SEFAZ.\r\n */\r\n public async cartaCorrecao(params: CartaCorrecaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/carta-correcao',\r\n body: {\r\n chave_acesso: params.chave_acesso,\r\n correcao: params.correcao,\r\n sequencia_evento: params.sequencia_evento ?? 1,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Inutiliza uma faixa de numeração quebrada na SEFAZ (Ajuste SINIEF 07/05).\r\n */\r\n public async inutilizar(params: InutilizacaoInput): Promise<EventoNFeResponse> {\r\n return this.request<EventoNFeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfe/inutilizar',\r\n body: {\r\n cnpj_emitente: params.cnpj_emitente,\r\n serie: params.serie,\r\n numero_inicial: params.numero_inicial,\r\n numero_final: params.numero_final,\r\n justificativa: params.justificativa,\r\n ano: params.ano,\r\n modelo: String(params.modelo ?? '55'),\r\n },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n FiscalSanitizeItemInput,\r\n FiscalSanitizeResponse,\r\n TaxPredictionData,\r\n TaxPredictionParams,\r\n TaxPredictionResponse,\r\n} from '../types/fiscal.js';\r\n\r\n/** Preenche os nomes da 1.5 (`cfop`, `avisos`, `imposto_seletivo`...) a partir dos oficiais da API. */\r\nfunction comNomesLegados(dados: TaxPredictionData): TaxPredictionData {\r\n const is = dados.is ?? dados.imposto_seletivo;\r\n const impostoSeletivo = is\r\n ? { ...is, CSTIS: is.CSTIS ?? is.cst, cst: is.cst ?? is.CSTIS, pIS: is.pIS ?? is.aliquota, aliquota: is.aliquota ?? is.pIS }\r\n : undefined;\r\n return {\r\n ...dados,\r\n cfop_interno: dados.cfop_interno ?? dados.cfop,\r\n cfop: dados.cfop ?? dados.cfop_interno,\r\n cfop_devolucao_interno: dados.cfop_devolucao_interno ?? dados.cfop_devolucao,\r\n cfop_devolucao: dados.cfop_devolucao ?? dados.cfop_devolucao_interno,\r\n is: impostoSeletivo,\r\n imposto_seletivo: impostoSeletivo,\r\n aliquota_efetiva_unificada: dados.aliquota_efetiva_unificada ?? dados.ibscbs?.aliquota_efetiva_unificada ?? 0,\r\n avisos_fiscais: dados.avisos_fiscais ?? dados.avisos ?? [],\r\n avisos: dados.avisos ?? dados.avisos_fiscais ?? [],\r\n };\r\n}\r\n\r\n/** Converte o item para os nomes exigidos pela API (a 1.5 enviava `ncm` minúsculo e recebia 422). */\r\nfunction itemDeSaneamento(item: FiscalSanitizeItemInput): Record<string, any> {\r\n const { NCM, CEST, xProd, id, ncm, cest, descricao, gtin, ...extras } = item;\r\n const convertido: Record<string, any> = {\r\n ...extras,\r\n NCM: NCM ?? ncm,\r\n CEST: CEST ?? cest,\r\n xProd: xProd ?? descricao,\r\n id: id ?? gtin,\r\n };\r\n return Object.fromEntries(Object.entries(convertido).filter(([, v]) => v !== undefined && v !== null));\r\n}\r\n\r\nexport class FiscalResource extends BaseResource {\r\n /**\r\n * Executa a predição fiscal completa da Reforma Tributária (IBS/CBS/IS) e NF-e.\r\n */\r\n public async predict(params: TaxPredictionParams): Promise<TaxPredictionResponse> {\r\n const payload: Record<string, any> = {\r\n regime_tributario: params.regimeTributario,\r\n uf_origem: params.ufOrigem,\r\n uf_destino: params.ufDestino || params.ufOrigem,\r\n finalidade: params.finalidade || 'revenda',\r\n destinatario_contribuinte: params.destinatarioContribuinte ?? true,\r\n };\r\n\r\n if (params.aliquotaCreditoIcmsSn !== undefined) payload.aliquota_credito_icms_sn = params.aliquotaCreditoIcmsSn;\r\n if (params.destinatarioSuframa !== undefined) payload.destinatario_suframa = params.destinatarioSuframa;\r\n if (params.inscricaoSuframa) payload.inscricao_suframa = params.inscricaoSuframa;\r\n if (params.xProd) payload.xProd = params.xProd;\r\n if (params.gtin) payload.gtin = params.gtin;\r\n if (params.ncm) payload.ncm = params.ncm;\r\n if (params.cest) payload.cest = params.cest;\r\n if (params.itens) payload.itens = params.itens;\r\n\r\n const res = await this.request<TaxPredictionResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/predict',\r\n body: payload,\r\n });\r\n\r\n return {\r\n ...res,\r\n dados_tributarios: res.dados_tributarios ? comNomesLegados(res.dados_tributarios) : res.dados_tributarios,\r\n resultados: res.resultados?.map((r) => ({ ...r, dados_tributarios: comNomesLegados(r.dados_tributarios) })),\r\n };\r\n }\r\n\r\n /**\r\n * Audita e higieniza uma lista de produtos em lote perante as tabelas fiscais vigentes.\r\n * Cada item precisa de `NCM` (aceita também `ncm`); `CEST`, `xProd` e `id` são opcionais.\r\n */\r\n public async sanitize(itens: FiscalSanitizeItemInput[]): Promise<FiscalSanitizeResponse> {\r\n return this.request<FiscalSanitizeResponse>({\r\n method: 'POST',\r\n path: '/v2/fiscal/sanitize',\r\n body: { itens: itens.map(itemDeSaneamento) },\r\n });\r\n }\r\n}\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n CancelamentoNFSeInput,\r\n CancelamentoNFSeResponse,\r\n NFSeEmissaoInput,\r\n NFSeEmissaoResponse,\r\n} from '../types/nfse.js';\r\n\r\nexport class NFSeResource extends BaseResource {\r\n /**\r\n * Emite uma NFS-e pelo Sistema Nacional (DPS assinada com o certificado A1 do prestador).\r\n * Sem resposta do Sistema Nacional, reenvie com o `numero_dps` devolvido para recuperar a nota sem duplicidade.\r\n */\r\n async emitir(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/emitir',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Simula o cálculo de NFS-e com retenções e apuração tributária (custo ZERO de créditos).\r\n */\r\n async simular(payload: NFSeEmissaoInput | Record<string, any>): Promise<NFSeEmissaoResponse> {\r\n return this.request<NFSeEmissaoResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/simular',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Cancela a NFS-e registrando o evento e101101 no Sistema Nacional.\r\n * Sem resposta, repita o pedido: um cancelamento já registrado é confirmado, sem duplicar.\r\n */\r\n async cancelar(payload: CancelamentoNFSeInput): Promise<CancelamentoNFSeResponse> {\r\n return this.request<CancelamentoNFSeResponse>({\r\n method: 'POST',\r\n path: '/v1/nfse/cancelar',\r\n body: payload,\r\n });\r\n }\r\n\r\n /**\r\n * Consulta os dados, status e DANFSE de uma NFS-e pelo número ou chave de 50 dígitos.\r\n * Com `sincronizar`, confere no Sistema Nacional se a nota foi cancelada fora da plataforma.\r\n */\r\n async consultar(chaveOuNumero: string, opcoes: { sincronizar?: boolean } = {}): Promise<Record<string, any>> {\r\n return this.request<Record<string, any>>({\r\n method: 'GET',\r\n path: `/v1/nfse/${chaveOuNumero}`,\r\n params: opcoes.sincronizar ? { sincronizar: 'true' } : undefined,\r\n });\r\n }\r\n}\r\n\r\n","import { BaseResource } from './base.js';\r\nimport {\r\n ProductDetails,\r\n ProductEnrichedDetails,\r\n ProductSearchResponse,\r\n ProductSearchResultItem,\r\n} from '../types/product.js';\r\n\r\n/** Primeiro valor preenchido (ignora undefined, null e texto vazio). */\r\nfunction primeiro<T>(...valores: Array<T | undefined | null | ''>): T | undefined {\r\n return valores.find((v) => v !== undefined && v !== null && v !== '') as T | undefined;\r\n}\r\n\r\nfunction numero(valor: any): number | undefined {\r\n const n = valor === undefined || valor === null || valor === '' ? NaN : Number(valor);\r\n return Number.isFinite(n) ? n : undefined;\r\n}\r\n\r\n/** Converte o produto da API (layout NF-e + `infoAdicional`) para `ProductDetails`. */\r\nfunction produtoDaApi(data: any, gtinFallback = ''): ProductDetails {\r\n const prod = data?.produto || data || {};\r\n const info = prod.infoAdicional || {};\r\n return {\r\n gtin: String(primeiro(prod.GTIN, prod.gtin, gtinFallback) ?? ''),\r\n xProd: primeiro(prod.xProd, prod.descricao) || 'Descrição Indisponível',\r\n ncm: primeiro(prod.NCM, prod.ncm),\r\n cest: primeiro(prod.CEST, prod.cest),\r\n marca: primeiro(prod.marca, info.xMarca),\r\n fabricante: prod.fabricante,\r\n categoria: primeiro(prod.categoria, info.xCategoria),\r\n imagemUrl: primeiro(prod.imagem_url, prod.thumbnail, info.urlImagem),\r\n pesoBruto: numero(primeiro(prod.peso_bruto, info.pesoBruto)),\r\n pesoLiquido: numero(primeiro(prod.peso_liquido, info.pesoLiquido)),\r\n quantidadeEmbalagem: Number(prod.quantidade_embalagem || 1),\r\n tpGTIN: prod.tpGTIN ?? undefined,\r\n fonte: prod.fonte ?? undefined,\r\n infoAdicional: prod.infoAdicional ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte o produto enriquecido (`/v2/gtin`, scan ou item da busca) para `ProductEnrichedDetails`. */\r\nfunction produtoEnriquecidoDaApi(data: any, gtinFallback = ''): ProductEnrichedDetails {\r\n const prod = data?.produto || data || {};\r\n const base = produtoDaApi(prod, gtinFallback);\r\n const enriquecimento = prod.enriquecimentoIA || {};\r\n const atributos = enriquecimento.atributos || {};\r\n const temAtributos = Object.keys(atributos).length > 0;\r\n return {\r\n gtin: base.gtin,\r\n xProd: base.xProd,\r\n xProd_higienizado: enriquecimento.xProd_higienizado,\r\n descricao_completa: primeiro(prod.descricao_completa, enriquecimento.descricao_seo),\r\n ficha_tecnica: prod.ficha_tecnica ?? (temAtributos ? atributos : undefined),\r\n palavras_chave: prod.palavras_chave,\r\n ncm: base.ncm,\r\n cest: base.cest,\r\n marca: primeiro(prod.marca, atributos.marca, base.marca),\r\n categoria: primeiro(prod.categoria, enriquecimento.categoria_comercial, base.categoria),\r\n imagem_url: base.imagemUrl,\r\n peso_bruto: base.pesoBruto,\r\n peso_liquido: primeiro(numero(prod.peso_liquido), numero(atributos.peso_liquido), base.pesoLiquido),\r\n dados_tributarios_sugeridos: prod.dados_tributarios_sugeridos ?? prod.tributacaoIA ?? undefined,\r\n tpGTIN: base.tpGTIN,\r\n fonte: base.fonte,\r\n infoAdicional: base.infoAdicional,\r\n enriquecimentoIA: prod.enriquecimentoIA ?? undefined,\r\n tributacaoIA: prod.tributacaoIA ?? undefined,\r\n };\r\n}\r\n\r\n/** Converte `/v2/gtin/search` (`resultados[].produto`; aceita o legado `produtos`). */\r\nfunction buscaDaApi(data: any, query: string): ProductSearchResponse {\r\n const itens: ProductSearchResultItem[] = (data?.resultados || data?.produtos || []).map((item: any) => {\r\n const prod = produtoEnriquecidoDaApi(item.produto || item);\r\n return {\r\n gtin: prod.gtin,\r\n xProd: prod.xProd,\r\n marca: prod.marca,\r\n categoria: prod.categoria,\r\n score: item.score !== undefined && item.score !== null ? Number(item.score) : undefined,\r\n justificativa: item.justificativa ?? undefined,\r\n ncm: prod.ncm,\r\n cest: prod.cest,\r\n imagem_url: prod.imagem_url,\r\n };\r\n });\r\n return {\r\n status: data?.status || 'success',\r\n provider: data?.provider || 'PAIRUS',\r\n total_encontrados: itens.length,\r\n termo_buscado: data?.query || query,\r\n motor_busca: data?.motor_busca,\r\n produtos: itens,\r\n };\r\n}\r\n\r\nexport class ProductsResource extends BaseResource {\r\n /**\r\n * Consulta dados oficiais de um produto por código de barras GTIN/EAN (V1).\r\n * @param gtin Código numérico de 8 a 14 dígitos.\r\n */\r\n public async get(gtin: string): Promise<ProductDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v1/gtin/${gtinLimpo}` });\r\n return produtoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Consulta dados enriquecidos por IA, com SEO e ficha técnica estruturada (V2).\r\n * @param gtin Código numérico do produto.\r\n */\r\n public async getEnriched(gtin: string): Promise<ProductEnrichedDetails> {\r\n const gtinLimpo = gtin.replace(/\\D/g, '');\r\n const data = await this.request<any>({ method: 'GET', path: `/v2/gtin/${gtinLimpo}` });\r\n return produtoEnriquecidoDaApi(data, gtinLimpo);\r\n }\r\n\r\n /**\r\n * Executa busca semântica por intenção/linguagem natural (V2).\r\n * @param query Termo livre de busca (ex: 'refrigerante zero lata').\r\n */\r\n public async search(query: string): Promise<ProductSearchResponse> {\r\n const data = await this.request<any>({ method: 'GET', path: '/v2/gtin/search', params: { q: query } });\r\n return buscaDaApi(data, query);\r\n }\r\n\r\n /**\r\n * Reconhece código de barras por visão computacional a partir de foto JPEG (OCR V2).\r\n * @param file Blob, Buffer ou FormData com a imagem JPEG.\r\n */\r\n public async scan(file: Blob | Buffer | FormData): Promise<ProductEnrichedDetails> {\r\n let formData: FormData;\r\n\r\n if (typeof FormData !== 'undefined' && file instanceof FormData) {\r\n formData = file;\r\n } else {\r\n formData = new FormData();\r\n if (typeof Blob !== 'undefined' && file instanceof Blob) {\r\n formData.append('file', file, 'barcode.jpg');\r\n } else {\r\n // Node Buffer\r\n const blob = new Blob([file as any], { type: 'image/jpeg' });\r\n formData.append('file', blob, 'barcode.jpg');\r\n }\r\n }\r\n\r\n const data = await this.request<any>({ method: 'POST', path: '/v2/gtin/scan', body: formData });\r\n return produtoEnriquecidoDaApi(data);\r\n }\r\n}\r\n","import * as crypto from 'crypto';\r\nimport { InvalidSignatureError } from './errors.js';\r\nimport { WebhookEvent } from './types/webhook.js';\r\n\r\nexport class Webhooks {\r\n /**\r\n * Calcula a assinatura HMAC-SHA256 esperada 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 */\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 const expectedSignature = this.computeSignature(payloadBuffer, secret);\r\n\r\n try {\r\n const sigBuf = Buffer.from(signature.trim(), '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 * 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 JSON.parse(rawStr) as WebhookEvent<T>;\r\n }\r\n}\r\n","import {\r\n DEFAULT_BASE_URL,\r\n DEFAULT_MAX_RETRIES,\r\n DEFAULT_TIMEOUT_MS,\r\n PairusClientOptions,\r\n} from './config.js';\r\nimport { DFeResource } from './resources/dfe.js';\r\nimport { EmissaoResource } from './resources/emissao.js';\r\nimport { FiscalResource } from './resources/fiscal.js';\r\nimport { NFSeResource } from './resources/nfse.js';\r\nimport { ProductsResource } from './resources/products.js';\r\nimport { Webhooks } from './webhooks.js';\r\n\r\nexport class PairusProductData {\r\n public static readonly webhooks = Webhooks;\r\n public readonly webhooks = Webhooks;\r\n\r\n public readonly products: ProductsResource;\r\n public readonly fiscal: FiscalResource;\r\n public readonly emissao: EmissaoResource;\r\n public readonly nfse: NFSeResource;\r\n public readonly dfe: DFeResource;\r\n\r\n constructor(options?: PairusClientOptions) {\r\n const apiKey = options?.apiKey || (typeof process !== 'undefined' ? process.env.PAIRUS_API_KEY : undefined);\r\n if (!apiKey) {\r\n throw new Error(\r\n \"A chave de API da PAIRUS é obrigatória. Passe 'apiKey' no construtor ou defina a variável 'PAIRUS_API_KEY'.\"\r\n );\r\n }\r\n\r\n const baseUrl = options?.baseUrl || (typeof process !== 'undefined' ? process.env.PAIRUS_BASE_URL : undefined) || DEFAULT_BASE_URL;\r\n const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;\r\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\r\n\r\n this.products = new ProductsResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.fiscal = new FiscalResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.emissao = new EmissaoResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.nfse = new NFSeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n this.dfe = new DFeResource(apiKey, baseUrl, timeoutMs, maxRetries);\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pairus/product-data",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.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",
|