latinfo 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +62 -48
  2. package/dist/index.js +59 -55
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -1,40 +1,53 @@
1
- # Latinfo
1
+ # latinfo
2
2
 
3
- Tax registry API for Latin America. One request, one response, no infrastructure.
3
+ Tax registry API for Latin America. Query RUC, DNI, and company data from Peru's SUNAT. 18M+ records, updated daily, sub-100ms from anywhere.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```bash
8
8
  npm install -g latinfo
9
+ latinfo login
9
10
  ```
10
11
 
11
- ## Quick start
12
+ `latinfo login` opens GitHub OAuth in your browser and stores your API key in `~/.latinfo/config.json`. Takes 30 seconds.
12
13
 
13
- ```bash
14
- # Login with GitHub
15
- latinfo login
14
+ ## CLI
16
15
 
17
- # Lookup by RUC
18
- latinfo ruc 20100047218
16
+ ```bash
17
+ latinfo ruc 20100047218 # Lookup by RUC
18
+ latinfo dni 12345678 # Lookup by DNI (converts to RUC automatically)
19
+ latinfo search "banco de credito" # Search by company name
20
+ latinfo ruc 20100047218 --json # JSON output (for scripts and AI agents)
21
+ ```
19
22
 
20
- # Lookup by DNI (converts to RUC automatically)
21
- latinfo dni 12345678
23
+ No login needed for demo data (5 embedded records). Run `latinfo login` for 18M+ records.
22
24
 
23
- # Search by company name
24
- latinfo search "banco de credito"
25
+ ## SDK
25
26
 
26
- # JSON output (for scripts and AI agents)
27
- latinfo ruc 20100047218 --json
27
+ ```bash
28
+ npm install latinfo
28
29
  ```
29
30
 
30
- ## What you get
31
+ ```typescript
32
+ import { Latinfo } from 'latinfo';
33
+
34
+ const client = new Latinfo('YOUR_API_KEY');
35
+
36
+ // Lookup by RUC
37
+ const company = await client.pe.ruc('20100047218');
38
+ console.log(company.razon_social); // BANCO DE CREDITO DEL PERU
39
+
40
+ // Lookup by DNI
41
+ const person = await client.pe.dni('12345678');
31
42
 
32
- - RUC lookup in ~80ms from any location
33
- - DNI to RUC conversion with check digit validation
34
- - Company name search with ranked results, prefix autocomplete, and LATAM abbreviation handling (S.A.C., E.I.R.L., S.R.L.)
35
- - 18M+ records from Peru's SUNAT official registry, updated daily
36
- - All data sourced from official government registries. Public records, no scraping.
37
- - Free: 1M requests/month. No credit card. Self-hosting 18M records requires a database server with enough RAM for full-text search indexes, a daily import pipeline, and ongoing maintenance.
43
+ // Search by company name
44
+ const results = await client.pe.search('banco de credito');
45
+
46
+ // Rotate API key
47
+ const { api_key } = await client.rotate();
48
+ ```
49
+
50
+ Get your API key: `npm install -g latinfo && latinfo login`
38
51
 
39
52
  ## API
40
53
 
@@ -42,8 +55,9 @@ Base URL: `https://api.latinfo.dev`
42
55
 
43
56
  ```
44
57
  GET /pe/ruc/:ruc → Lookup by RUC (11 digits)
45
- GET /pe/dni/:dni → Lookup by DNI (8 digits, converts to RUC)
58
+ GET /pe/dni/:dni → Lookup by DNI (8 digits)
46
59
  GET /pe/search?q=... → Search by company name
60
+ POST /auth/rotate → Rotate API key
47
61
  ```
48
62
 
49
63
  ```bash
@@ -51,50 +65,50 @@ curl -H "Authorization: Bearer YOUR_API_KEY" \
51
65
  https://api.latinfo.dev/pe/ruc/20100047218
52
66
  ```
53
67
 
54
- Your API key is stored in `~/.latinfo/config.json` after `latinfo login`.
55
-
56
- ## SDK
57
-
58
- ```typescript
59
- import { latinfo } from 'latinfo';
60
-
61
- const client = latinfo('YOUR_API_KEY');
62
-
63
- const company = await client.ruc('20100047218');
64
- console.log(company.razon_social); // BANCO DE CREDITO DEL PERU
65
- ```
68
+ Full API reference: [latinfo.dev/docs](https://latinfo.dev/docs)
66
69
 
67
70
  ## Response fields
68
71
 
69
72
  | Field | Description | Example |
70
- |-------|------------|---------|
71
- | `ruc` | RUC number (11 digits) | 20100047218 |
72
- | `razon_social` | Business name | BANCO DE CREDITO DEL PERU |
73
- | `estado` | Tax status | ACTIVO |
74
- | `condicion` | Condition | HABIDO |
75
- | `ubigeo` | Location code | 150114 |
76
- | `tipo_via` | Street type | JR. |
77
- | `nombre_via` | Street name | CENTENARIO |
78
- | `numero` | Street number | 156 |
73
+ |-------|-------------|---------|
74
+ | `ruc` | RUC number (11 digits) | `20100047218` |
75
+ | `razon_social` | Business name | `BANCO DE CREDITO DEL PERU` |
76
+ | `estado` | Tax status | `ACTIVO` |
77
+ | `condicion` | Condition | `HABIDO` |
78
+ | `ubigeo` | Location code | `150114` |
79
+ | `tipo_via` | Street type | `JR.` |
80
+ | `nombre_via` | Street name | `CENTENARIO` |
81
+ | `numero` | Street number | `156` |
82
+ | `interior` | Interior / apt | `-` |
83
+ | `lote` | Lot | `-` |
84
+ | `codigo_zona` | Zone code | `URB.` |
85
+ | `tipo_zona` | Zone name | `BALCONCILLO` |
86
+ | `departamento` | Department | `-` |
87
+ | `manzana` | Block | `-` |
88
+ | `kilometro` | Kilometer | `-` |
79
89
 
80
90
  ## What you don't have to do
81
91
 
82
92
  You don't download 364MB from SUNAT. You don't parse Latin1 with escaped pipe delimiters. You don't write a check digit algorithm. You don't build a search index that handles S.A.C. and E.I.R.L. You don't set up a daily import pipeline. You don't manage servers.
83
93
 
84
- We do all of that. Daily. For free.
94
+ We do all of that. Daily.
85
95
 
86
96
  ## Pricing
87
97
 
88
- - **Free**: 1M requests/month
98
+ - **Free**: 100,000 requests/day — no credit card
89
99
  - **Pro**: 10M requests/month — $1/month
90
100
 
91
101
  ## Countries
92
102
 
93
- - **Peru** (SUNAT) RUC, DNI, company name search. 18M+ records, updated daily.
94
- - Brazil, Mexico, Colombia, Argentina, Chile — in development.
103
+ | Country | Data | Status |
104
+ |---------|------|--------|
105
+ | Peru | SUNAT padrón — RUC, DNI, company search | Active |
106
+ | Brazil, Mexico, Colombia, Argentina, Chile | — | In development |
95
107
 
96
108
  ## Links
97
109
 
98
110
  - Website: [latinfo.dev](https://latinfo.dev)
99
- - API docs: [api.latinfo.dev/openapi.json](https://api.latinfo.dev/openapi.json)
111
+ - Docs: [latinfo.dev/docs](https://latinfo.dev/docs)
112
+ - Changelog: [latinfo.dev/changelog](https://latinfo.dev/changelog)
113
+ - Status: [carrera.instatus.com](https://carrera.instatus.com)
100
114
  - Email: [hola@latinfo.dev](mailto:hola@latinfo.dev)
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ const path_1 = __importDefault(require("path"));
10
10
  const os_1 = __importDefault(require("os"));
11
11
  const child_process_1 = require("child_process");
12
12
  const demo_data_1 = require("./demo-data");
13
- const VERSION = '0.5.3';
13
+ const VERSION = '0.5.7';
14
14
  const API_URL = process.env.LATINFO_API_URL || 'https://api.latinfo.dev';
15
15
  const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID || 'Ov23li5fcQaiCsVtaMKK';
16
16
  const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.latinfo');
@@ -32,8 +32,8 @@ function loadConfig() {
32
32
  }
33
33
  }
34
34
  function saveConfig(config) {
35
- fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
36
- fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
35
+ fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
36
+ fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
37
37
  }
38
38
  function deleteConfig() {
39
39
  try {
@@ -46,12 +46,13 @@ function openBrowser(url) {
46
46
  const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
47
47
  (0, child_process_1.exec)(`${cmd} "${url}"`);
48
48
  }
49
- async function waitForCallback(port) {
49
+ async function waitForCallback(port, expectedState) {
50
50
  return new Promise((resolve, reject) => {
51
51
  const server = http_1.default.createServer((req, res) => {
52
52
  const url = new URL(req.url || '', `http://localhost:${port}`);
53
53
  const code = url.searchParams.get('code');
54
- if (code) {
54
+ const state = url.searchParams.get('state');
55
+ if (code && state === expectedState) {
55
56
  res.writeHead(200, { 'Content-Type': 'text/html' });
56
57
  res.end('<h2>Done. You can close this window.</h2>');
57
58
  server.close();
@@ -59,9 +60,9 @@ async function waitForCallback(port) {
59
60
  }
60
61
  else {
61
62
  res.writeHead(400);
62
- res.end('Missing code');
63
+ res.end('Authorization failed');
63
64
  server.close();
64
- reject(new Error('No code received from GitHub'));
65
+ reject(new Error('Invalid state or missing code'));
65
66
  }
66
67
  });
67
68
  server.listen(port, () => { });
@@ -104,10 +105,11 @@ async function login() {
104
105
  const port = 8400;
105
106
  const redirectUri = `http://localhost:${port}/callback`;
106
107
  const scope = 'read:user,user:email';
107
- const authUrl = `https://github.com/login/oauth/authorize?client_id=${GITHUB_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}`;
108
+ const state = crypto.randomUUID();
109
+ const authUrl = `https://github.com/login/oauth/authorize?client_id=${GITHUB_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&state=${state}`;
108
110
  console.log('Opening GitHub...');
109
111
  openBrowser(authUrl);
110
- const code = await waitForCallback(port);
112
+ const code = await waitForCallback(port, state);
111
113
  const authRes = await fetch(`${API_URL}/auth/github`, {
112
114
  method: 'POST',
113
115
  headers: { 'Content-Type': 'application/json' },
@@ -342,83 +344,85 @@ function logout() {
342
344
  console.log('Logged out.');
343
345
  }
344
346
  function help() {
345
- console.log(`latinfo v${VERSION} — Public data API for Latin America
346
-
347
- API base: ${API_URL}
347
+ console.log(`latinfo v${VERSION} — Tax registry API for Latin America
348
348
 
349
349
  USAGE
350
350
  latinfo <command> [args] [--json]
351
351
 
352
+ QUICK START
353
+ npm install -g latinfo
354
+ latinfo login # GitHub OAuth, 30 seconds
355
+ latinfo ruc 20100047218 # Banco de Crédito del Perú
356
+ latinfo search "banco de credito" # search by company name
357
+ latinfo ruc 20100047218 --json # JSON output
358
+
359
+ Works instantly with ${Object.keys(demo_data_1.DEMO_DATA).length} embedded records (no login needed).
360
+ Run 'latinfo login' for 18M+ records and DNI lookup.
361
+
352
362
  COMMANDS
353
363
  login
354
- Authenticate via GitHub OAuth. Opens a browser, waits for callback
355
- on localhost:8400, and stores the API key in ~/.latinfo/config.json.
364
+ GitHub OAuth. Opens browser, waits for callback on localhost:8400,
365
+ stores API key in ~/.latinfo/config.json.
356
366
 
357
367
  logout
358
- Remove stored credentials from ~/.latinfo/config.json.
368
+ Remove stored credentials.
359
369
 
360
370
  whoami
361
- Show the authenticated GitHub username.
362
- Output fields (--json): username, api_key
363
-
364
- plan
365
- Show current plan and limits.
366
- Output fields (--json): plan, limit
371
+ Show authenticated GitHub username.
372
+ --json: { username, api_key }
367
373
 
368
374
  ruc <ruc>
369
- Lookup a Peruvian taxpayer by RUC (11 digits).
370
- Output fields (--json): ruc, razon_social, estado, condicion,
371
- ubigeo, tipo_via, nombre_via, numero, codigo_zona, tipo_zona,
372
- departamento, provincia, distrito, direccion_completa, tipo_contribuyente
375
+ Lookup by RUC (11 digits).
376
+ --json fields: ruc, razon_social, estado, condicion, ubigeo,
377
+ tipo_via, nombre_via, numero, interior, lote, codigo_zona,
378
+ tipo_zona, departamento, manzana, kilometro
373
379
 
374
380
  dni <dni>
375
- Lookup a Peruvian taxpayer by DNI (8 digits). Finds the RUC
376
- associated with the person and returns the same fields as 'ruc'.
377
- Output fields (--json): same as ruc
381
+ Lookup by DNI (8 digits). Converts to RUC automatically.
382
+ --json fields: same as ruc
378
383
 
379
384
  search <query>
380
- Search taxpayers by business name (razón social). Returns an array.
381
- Output fields (--json): array of objects with same fields as ruc
385
+ Search by company name (razón social). Returns ranked results
386
+ with prefix autocomplete and abbreviation handling (S.A.C., E.I.R.L.).
387
+ --json fields: array of ruc objects
382
388
 
383
- costs <users> [avg_req] [pro_%]
384
- Simulate Cloudflare cost vs revenue. Defaults: 1000 req/user, 1% Pro.
385
- Output fields (--json): users, pro_users, requests, cf_tier,
386
- cf_cost, revenue, margin, safe
389
+ costs <users> [avg_req/user/month] [pro_%]
390
+ Simulate Cloudflare cost vs revenue.
391
+ Defaults: 1000 req/user, 1% Pro.
392
+ --json fields: users, pro_users, requests, cf_tier, cf_cost,
393
+ revenue, margin, safe
387
394
 
388
395
  costs --live
389
- Real-time cost report from production data (admin only).
396
+ Real-time cost report from production (admin only).
390
397
  Requires LATINFO_ADMIN_SECRET env var.
391
- Output fields (--json): month, users, pro_users, requests,
392
- cf_tier, cf_cost, revenue, margin, safe
393
398
 
394
- help
395
- Show this help text.
399
+ help Show this help text.
396
400
 
397
401
  FLAGS
398
- --json Output raw JSON instead of human-formatted text.
399
- Errors are written to stderr as {"error":"...","message":"..."}.
400
- --live Use real-time production data (for 'costs' command).
401
- --version, -v
402
- Print version and exit.
402
+ --json Output raw JSON. Errors stderr as { error, message }.
403
+ --live Use production data (costs command).
404
+ --version Print version and exit.
403
405
 
404
406
  COUNTRIES
405
- pe Peru (SUNAT padrón). Active and available.
407
+ pe Peru (SUNAT padrón) 18M+ records, updated daily. Active.
408
+ br, mx, co, ar, cl — in development.
406
409
 
407
- QUICK START (no login needed)
408
- latinfo ruc 20100047218 # Banco de Crédito del Perú
409
- latinfo search "GLORIA" # search by business name
410
- latinfo ruc 20131312955 --json # SUNAT, JSON output
410
+ PRICING
411
+ Free 100,000 requests/day no credit card
412
+ Pro 10M requests/month — $1/month
411
413
 
412
- Works instantly with ${Object.keys(demo_data_1.DEMO_DATA).length} embedded records. Run 'latinfo login'
413
- for 18M+ records and DNI lookup.
414
+ LINKS
415
+ latinfo.dev/docs API reference
416
+ latinfo.dev/changelog Changelog
417
+ carrera.instatus.com Status page
414
418
 
415
- AUTH
416
- Config file: ~/.latinfo/config.json
417
- Environment: LATINFO_API_URL to override API base URL.
419
+ CONFIG
420
+ ~/.latinfo/config.json API key (written by 'latinfo login')
421
+ LATINFO_API_URL Override API base URL
418
422
 
419
423
  EXIT CODES
420
424
  0 Success
421
- 1 Error (invalid input, auth failure, API error)`);
425
+ 1 Error`);
422
426
  }
423
427
  function version() {
424
428
  console.log(`latinfo/${VERSION}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "latinfo",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "description": "Tax registry API for Latin America. Query RUC, DNI, and company data from SUNAT Peru. 18M+ records, updated daily, sub-100ms from anywhere.",
5
5
  "homepage": "https://latinfo.dev",
6
6
  "repository": {
@@ -23,6 +23,7 @@
23
23
  "build": "tsc",
24
24
  "dev": "tsx src/index.ts"
25
25
  },
26
+ "license": "MIT",
26
27
  "files": ["dist"],
27
28
  "devDependencies": {
28
29
  "tsx": "^4.19.0",