Skip to content

Commit 0f5cd51

Browse files
feat(consulta-cpf): implementa recurso Natural Person Lookup (Consulta CPF)
Adiciona suporte completo para consulta de situação cadastral de CPF na Receita Federal via a API naturalperson.api.nfe.io. ## Novos arquivos - src/core/resources/natural-person-lookup.ts Resource com validação de CPF (11 dígitos, aceita pontuação), validação de data de nascimento (string YYYY-MM-DD ou Date object), e método getStatus() que consulta a API. - openapi/spec/consulta-cpf.yaml Spec OpenAPI (Swagger 2.0) da API de Consulta CPF, renomeado de cpf-api.yaml para seguir o padrão de nomenclatura do projeto. - tests/unit/natural-person-lookup.test.ts 22 testes unitários cobrindo: validação de CPF (vazio, curto, longo, formatado), validação de data (formato inválido, mês/dia fora de range, Date object inválido), chamadas getStatus() com normalização de entrada, e propagação de erros HTTP (404, 401, 400). - examples/cpf-lookup.js Exemplo de uso com string date, Date object e tratamento de erros. ## Tipos adicionados (src/core/types.ts) - NaturalPersonStatus: union type com valores conhecidos da Receita ('Regular', 'Suspensa', 'Cancelada', 'Titular Falecido', 'Pendente de Regularização', 'Nula') + fallback string. - NaturalPersonStatusResponse: interface com campos name?, federalTaxNumber, birthOn?, status?, createdOn?. ## Integração no NfeClient (src/core/client.ts) - Lazy getter naturalPersonLookup com HttpClient dedicado - Método privado getNaturalPersonHttpClient() usando resolveDataApiKey() - Re-export de NATURAL_PERSON_API_BASE_URL ## Exports públicos (src/index.ts) - Tipos: NaturalPersonStatus, NaturalPersonStatusResponse - Constante: NATURAL_PERSON_API_BASE_URL ## Documentação - README.md: seção Consulta CPF com exemplos de código - docs/API.md: referência completa (método, parâmetros, tipos, throws) ## Arquivos gerados (src/generated/) - Apenas atualização de timestamps pela re-execução do gerador.
1 parent eac4982 commit 0f5cd51

18 files changed

Lines changed: 822 additions & 10 deletions

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,23 @@ console.log('IE recomendada:', melhorIE?.taxNumber);
617617

618618
> **Nota:** A API de Consulta CNPJ usa um host separado (`legalentity.api.nfe.io`). Você pode configurar uma chave API específica com `dataApiKey`, ou o SDK usará `apiKey` como fallback.
619619
620+
#### 👤 Consulta CPF / Pessoa Física (`nfe.naturalPersonLookup`)
621+
622+
Consultar a situação cadastral de CPF (pessoa física) na Receita Federal:
623+
624+
```typescript
625+
// Consulta com CPF e data de nascimento
626+
const result = await nfe.naturalPersonLookup.getStatus('123.456.789-01', '1990-01-15');
627+
console.log('Nome:', result.name); // 'JOÃO DA SILVA'
628+
console.log('Status:', result.status); // 'Regular'
629+
630+
// Também aceita Date object
631+
const result = await nfe.naturalPersonLookup.getStatus('12345678901', new Date(1990, 0, 15));
632+
console.log('Situação Cadastral:', result.status);
633+
```
634+
635+
> **Nota:** A API de Consulta CPF usa um host separado (`naturalperson.api.nfe.io`). Você pode configurar uma chave API específica com `dataApiKey`, ou o SDK usará `apiKey` como fallback.
636+
620637
---
621638

622639
### Opções de Configuração

docs/API.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Complete API reference for the NFE.io Node.js SDK v3.
2020
- [Product Invoice Query (Consulta NF-e)](#product-invoice-query-consulta-nf-e)
2121
- [Consumer Invoice Query (Consulta CFe-SAT)](#consumer-invoice-query-consulta-cfe-sat)
2222
- [Legal Entity Lookup (Consulta CNPJ)](#legal-entity-lookup-consulta-cnpj)
23+
- [Natural Person Lookup (Consulta CPF)](#natural-person-lookup-consulta-cpf)
2324
- [Types](#types)
2425
- [Error Handling](#error-handling)
2526
- [Advanced Usage](#advanced-usage)
@@ -2239,6 +2240,67 @@ interface LegalEntityStateTaxForInvoice {
22392240
22402241
---
22412242

2243+
### Natural Person Lookup (Consulta CPF)
2244+
2245+
**Resource:** `nfe.naturalPersonLookup`
2246+
**API Host:** `naturalperson.api.nfe.io`
2247+
**Authentication:** Uses `dataApiKey` (falls back to `apiKey`)
2248+
2249+
Lookup CPF cadastral status (situação cadastral) at the Brazilian Federal Revenue Service (Receita Federal).
2250+
2251+
#### `getStatus(federalTaxNumber: string, birthDate: string | Date): Promise<NaturalPersonStatusResponse>`
2252+
2253+
Query the cadastral status of a CPF, returning the person's name, CPF, birth date, status, and query timestamp.
2254+
2255+
```typescript
2256+
// With string date
2257+
const result = await nfe.naturalPersonLookup.getStatus('123.456.789-01', '1990-01-15');
2258+
console.log(result.name); // 'JOÃO DA SILVA'
2259+
console.log(result.status); // 'Regular'
2260+
2261+
// With Date object
2262+
const result = await nfe.naturalPersonLookup.getStatus('12345678901', new Date(1990, 0, 15));
2263+
```
2264+
2265+
**Parameters:**
2266+
2267+
| Parameter | Type | Required | Description |
2268+
|-----------|------|----------|-------------|
2269+
| `federalTaxNumber` | `string` | Yes | CPF number, with or without punctuation (e.g., `"12345678901"` or `"123.456.789-01"`) |
2270+
| `birthDate` | `string \| Date` | Yes | Date of birth in `YYYY-MM-DD` format or a `Date` object |
2271+
2272+
**Returns:** `NaturalPersonStatusResponse` — CPF cadastral status data.
2273+
2274+
**Throws:**
2275+
- `ValidationError` if CPF format is invalid (not 11 digits) or birth date format is invalid
2276+
- `NotFoundError` if CPF is not found or birth date does not match (HTTP 404)
2277+
- `AuthenticationError` if API key is invalid (HTTP 401)
2278+
2279+
#### Types
2280+
2281+
```typescript
2282+
type NaturalPersonStatus =
2283+
| 'Regular'
2284+
| 'Suspensa'
2285+
| 'Cancelada'
2286+
| 'Titular Falecido'
2287+
| 'Pendente de Regularização'
2288+
| 'Nula'
2289+
| (string & {});
2290+
2291+
interface NaturalPersonStatusResponse {
2292+
name?: string;
2293+
federalTaxNumber: string;
2294+
birthOn?: string;
2295+
status?: NaturalPersonStatus;
2296+
createdOn?: string;
2297+
}
2298+
```
2299+
2300+
> See [src/core/types.ts](../src/core/types.ts) for the complete type definitions.
2301+
2302+
---
2303+
22422304
## Types
22432305

22442306
### Core Types

examples/cpf-lookup.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* NFE.io SDK v3 - CPF / Natural Person Lookup Example
3+
*
4+
* This example demonstrates how to use the Natural Person Lookup API for querying
5+
* Brazilian CPF cadastral status (situação cadastral) at Receita Federal.
6+
*
7+
* Prerequisites:
8+
* - Set NFE_DATA_API_KEY or NFE_API_KEY environment variable
9+
* - Or pass the API key directly in the configuration
10+
*
11+
* Run this example:
12+
* node examples/cpf-lookup.js
13+
*/
14+
15+
import { NfeClient } from '../dist/index.js';
16+
17+
// Configuration
18+
const client = new NfeClient({
19+
// The Natural Person API uses dataApiKey (falls back to apiKey)
20+
// dataApiKey: process.env.NFE_DATA_API_KEY,
21+
apiKey: process.env.NFE_API_KEY,
22+
environment: 'production',
23+
});
24+
25+
// Example CPF and birth date — replace with real values for testing
26+
const EXAMPLE_CPF = process.env.TEST_CPF || '12345678901';
27+
const EXAMPLE_BIRTH_DATE = process.env.TEST_BIRTH_DATE || '1990-01-15';
28+
29+
/**
30+
* Example 1: CPF lookup with string date
31+
*/
32+
async function cpfLookupWithString() {
33+
console.log('\n👤 Example 1: CPF Lookup with String Date');
34+
console.log('='.repeat(50));
35+
36+
try {
37+
const result = await client.naturalPersonLookup.getStatus(EXAMPLE_CPF, EXAMPLE_BIRTH_DATE);
38+
39+
console.log('Name: ', result.name ?? 'N/A');
40+
console.log('CPF: ', result.federalTaxNumber);
41+
console.log('Birth Date: ', result.birthOn ?? 'N/A');
42+
console.log('Cadastral Status: ', result.status ?? 'N/A');
43+
console.log('Query Timestamp: ', result.createdOn ?? 'N/A');
44+
} catch (error) {
45+
console.error('Error:', error.message);
46+
}
47+
}
48+
49+
/**
50+
* Example 2: CPF lookup with formatted CPF and Date object
51+
*/
52+
async function cpfLookupWithDate() {
53+
console.log('\n👤 Example 2: CPF Lookup with Date Object');
54+
console.log('='.repeat(50));
55+
56+
try {
57+
// The SDK accepts formatted CPF (punctuation is stripped automatically)
58+
const formattedCpf = '123.456.789-01';
59+
60+
// The SDK also accepts Date objects for birth date
61+
const birthDate = new Date(1990, 0, 15); // January 15, 1990
62+
63+
const result = await client.naturalPersonLookup.getStatus(formattedCpf, birthDate);
64+
65+
console.log('Name: ', result.name ?? 'N/A');
66+
console.log('Cadastral Status: ', result.status ?? 'N/A');
67+
} catch (error) {
68+
console.error('Error:', error.message);
69+
}
70+
}
71+
72+
/**
73+
* Example 3: Error handling
74+
*/
75+
async function errorHandling() {
76+
console.log('\n⚠️ Example 3: Error Handling');
77+
console.log('='.repeat(50));
78+
79+
// Invalid CPF (too short)
80+
try {
81+
await client.naturalPersonLookup.getStatus('123', '1990-01-15');
82+
} catch (error) {
83+
console.log('Validation error (short CPF):', error.message);
84+
}
85+
86+
// Invalid birth date format
87+
try {
88+
await client.naturalPersonLookup.getStatus('12345678901', '15/01/1990');
89+
} catch (error) {
90+
console.log('Validation error (bad date):', error.message);
91+
}
92+
93+
// CPF not found (404)
94+
try {
95+
await client.naturalPersonLookup.getStatus('00000000000', '2000-01-01');
96+
} catch (error) {
97+
console.log('API error (not found): ', error.message);
98+
}
99+
}
100+
101+
/**
102+
* Run all examples
103+
*/
104+
async function main() {
105+
console.log('🇧🇷 NFE.io SDK v3 - CPF Lookup Examples');
106+
console.log('━'.repeat(50));
107+
console.log(`Using CPF: ${EXAMPLE_CPF}`);
108+
console.log(`Using birth date: ${EXAMPLE_BIRTH_DATE}`);
109+
110+
await cpfLookupWithString();
111+
await cpfLookupWithDate();
112+
await errorHandling();
113+
114+
console.log('\n✅ All examples completed');
115+
}
116+
117+
main().catch(console.error);

src/core/client.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ import {
3232
ProductInvoiceQueryResource,
3333
ConsumerInvoiceQueryResource,
3434
LegalEntityLookupResource,
35+
NaturalPersonLookupResource,
3536
ADDRESS_API_BASE_URL,
3637
NFE_QUERY_API_BASE_URL,
37-
LEGAL_ENTITY_API_BASE_URL
38+
LEGAL_ENTITY_API_BASE_URL,
39+
NATURAL_PERSON_API_BASE_URL
3840
} from './resources/index.js';
3941

4042
// ============================================================================
@@ -47,6 +49,9 @@ export const CTE_API_BASE_URL = 'https://api.nfse.io';
4749
/** Base URL for Legal Entity API (CNPJ Lookup) */
4850
export { LEGAL_ENTITY_API_BASE_URL } from './resources/index.js';
4951

52+
/** Base URL for Natural Person API (CPF Lookup) */
53+
export { NATURAL_PERSON_API_BASE_URL } from './resources/index.js';
54+
5055
// ============================================================================
5156
// Main NFE.io Client
5257
// ============================================================================
@@ -139,6 +144,9 @@ export class NfeClient {
139144
/** @internal HTTP client for Legal Entity API requests (created lazily) */
140145
private _legalEntityHttp: HttpClient | undefined;
141146

147+
/** @internal HTTP client for Natural Person API requests (created lazily) */
148+
private _naturalPersonHttp: HttpClient | undefined;
149+
142150
/** @internal Normalized client configuration */
143151
private readonly config: RequiredNfeConfig;
144152

@@ -154,6 +162,7 @@ export class NfeClient {
154162
private _productInvoiceQuery: ProductInvoiceQueryResource | undefined;
155163
private _consumerInvoiceQuery: ConsumerInvoiceQueryResource | undefined;
156164
private _legalEntityLookup: LegalEntityLookupResource | undefined;
165+
private _naturalPersonLookup: NaturalPersonLookupResource | undefined;
157166

158167
/**
159168
* Service Invoices API resource
@@ -522,6 +531,34 @@ export class NfeClient {
522531
return this._legalEntityLookup;
523532
}
524533

534+
/**
535+
* Natural Person Lookup API resource (CPF)
536+
*
537+
* @description
538+
* Provides a read-only operation for querying CPF cadastral status (situação cadastral)
539+
* at the Brazilian Federal Revenue Service (Receita Federal).
540+
*
541+
* **Note:** This resource uses a different API host (naturalperson.api.nfe.io).
542+
* Configure `dataApiKey` for a separate key, or it will fallback to `apiKey`.
543+
*
544+
* @see {@link NaturalPersonLookupResource}
545+
* @throws {ConfigurationError} If no API key is configured (dataApiKey or apiKey)
546+
*
547+
* @example
548+
* ```typescript
549+
* // CPF cadastral status lookup
550+
* const result = await nfe.naturalPersonLookup.getStatus('123.456.789-01', '1990-01-15');
551+
* console.log(result.name); // 'JOÃO DA SILVA'
552+
* console.log(result.status); // 'Regular'
553+
* ```
554+
*/
555+
get naturalPersonLookup(): NaturalPersonLookupResource {
556+
if (!this._naturalPersonLookup) {
557+
this._naturalPersonLookup = new NaturalPersonLookupResource(this.getNaturalPersonHttpClient());
558+
}
559+
return this._naturalPersonLookup;
560+
}
561+
525562
/**
526563
* Create a new NFE.io API client
527564
*
@@ -720,6 +757,29 @@ export class NfeClient {
720757
return this._legalEntityHttp;
721758
}
722759

760+
/**
761+
* Get or create the Natural Person API HTTP client (naturalperson.api.nfe.io)
762+
* @throws {ConfigurationError} If no API key is configured
763+
*/
764+
private getNaturalPersonHttpClient(): HttpClient {
765+
if (!this._naturalPersonHttp) {
766+
const apiKey = this.resolveDataApiKey();
767+
if (!apiKey) {
768+
throw new ConfigurationError(
769+
'API key required for data services. Set "dataApiKey" or "apiKey" in config, or NFE_DATA_API_KEY/NFE_API_KEY environment variable.'
770+
);
771+
}
772+
const httpConfig = buildHttpConfig(
773+
apiKey,
774+
NATURAL_PERSON_API_BASE_URL,
775+
this.config.timeout,
776+
this.config.retryConfig
777+
);
778+
this._naturalPersonHttp = new HttpClient(httpConfig);
779+
}
780+
return this._naturalPersonHttp;
781+
}
782+
723783
// --------------------------------------------------------------------------
724784
// Configuration Management
725785
// --------------------------------------------------------------------------

src/core/resources/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export { InboundProductInvoicesResource, createInboundProductInvoicesResource }
1616
export { ProductInvoiceQueryResource, createProductInvoiceQueryResource, NFE_QUERY_API_BASE_URL } from './product-invoice-query.js';
1717
export { ConsumerInvoiceQueryResource, createConsumerInvoiceQueryResource } from './consumer-invoice-query.js';
1818
export { LegalEntityLookupResource, createLegalEntityLookupResource, LEGAL_ENTITY_API_BASE_URL } from './legal-entity-lookup.js';
19+
export { NaturalPersonLookupResource, createNaturalPersonLookupResource, NATURAL_PERSON_API_BASE_URL } from './natural-person-lookup.js';

0 commit comments

Comments
 (0)