latinfo 0.3.0 → 0.4.1
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/dist/index.js +263 -90
- package/dist/sdk.d.ts +9 -22
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -9,10 +9,19 @@ const http_1 = __importDefault(require("http"));
|
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const os_1 = __importDefault(require("os"));
|
|
11
11
|
const child_process_1 = require("child_process");
|
|
12
|
+
const VERSION = '0.4.1';
|
|
12
13
|
const API_URL = process.env.LATINFO_API_URL || 'https://api.latinfo.dev';
|
|
13
|
-
const GITHUB_CLIENT_ID = 'Ov23li5fcQaiCsVtaMKK';
|
|
14
|
+
const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID || 'Ov23li5fcQaiCsVtaMKK';
|
|
14
15
|
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.latinfo');
|
|
15
16
|
const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
17
|
+
// --- JSON mode ---
|
|
18
|
+
const jsonFlag = process.argv.includes('--json');
|
|
19
|
+
const liveFlag = process.argv.includes('--live');
|
|
20
|
+
const rawArgs = process.argv.slice(2).filter(a => a !== '--json' && a !== '--live');
|
|
21
|
+
function jsonError(error, message) {
|
|
22
|
+
process.stderr.write(JSON.stringify({ error, message }) + '\n');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
16
25
|
function loadConfig() {
|
|
17
26
|
try {
|
|
18
27
|
return JSON.parse(fs_1.default.readFileSync(CONFIG_FILE, 'utf-8'));
|
|
@@ -58,6 +67,30 @@ async function waitForCallback(port) {
|
|
|
58
67
|
setTimeout(() => { server.close(); reject(new Error('Timeout waiting for authorization')); }, 120_000);
|
|
59
68
|
});
|
|
60
69
|
}
|
|
70
|
+
function requireAuth() {
|
|
71
|
+
const config = loadConfig();
|
|
72
|
+
if (!config) {
|
|
73
|
+
if (jsonFlag)
|
|
74
|
+
jsonError('auth_required', 'Not logged in. Run: latinfo login');
|
|
75
|
+
console.error('Not logged in. Run: latinfo login');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
return config;
|
|
79
|
+
}
|
|
80
|
+
async function apiRequest(config, path) {
|
|
81
|
+
const res = await fetch(`${API_URL}${path}`, {
|
|
82
|
+
headers: { Authorization: `Bearer ${config.api_key}` },
|
|
83
|
+
});
|
|
84
|
+
if (!res.ok) {
|
|
85
|
+
const err = await res.json();
|
|
86
|
+
if (jsonFlag)
|
|
87
|
+
jsonError(err.error, err.message || err.error);
|
|
88
|
+
console.error(err.message || err.error);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
return res;
|
|
92
|
+
}
|
|
93
|
+
// --- Commands ---
|
|
61
94
|
async function login() {
|
|
62
95
|
const port = 8400;
|
|
63
96
|
const redirectUri = `http://localhost:${port}/callback`;
|
|
@@ -65,9 +98,7 @@ async function login() {
|
|
|
65
98
|
const authUrl = `https://github.com/login/oauth/authorize?client_id=${GITHUB_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}`;
|
|
66
99
|
console.log('Opening GitHub...');
|
|
67
100
|
openBrowser(authUrl);
|
|
68
|
-
// 1. Wait for GitHub to redirect back with code
|
|
69
101
|
const code = await waitForCallback(port);
|
|
70
|
-
// 2. Exchange code for access token (server-side, needs client_secret)
|
|
71
102
|
const authRes = await fetch(`${API_URL}/auth/github`, {
|
|
72
103
|
method: 'POST',
|
|
73
104
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -81,136 +112,278 @@ async function login() {
|
|
|
81
112
|
saveConfig({ api_key: authData.api_key, github_username: authData.github_username });
|
|
82
113
|
console.log(`Logged in as ${authData.github_username}`);
|
|
83
114
|
}
|
|
84
|
-
// --- Commands ---
|
|
85
115
|
async function ruc(rucNumber) {
|
|
86
|
-
const config =
|
|
87
|
-
if (!
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
if (!/^\d{11}$/.test(rucNumber)) {
|
|
116
|
+
const config = requireAuth();
|
|
117
|
+
if (!rucNumber || !/^\d{11}$/.test(rucNumber)) {
|
|
118
|
+
if (jsonFlag)
|
|
119
|
+
jsonError('invalid_input', 'Invalid RUC. Must be 11 digits.');
|
|
92
120
|
console.error('Invalid RUC. Must be 11 digits.');
|
|
93
121
|
process.exit(1);
|
|
94
122
|
}
|
|
95
|
-
const res = await
|
|
96
|
-
headers: { Authorization: `Bearer ${config.api_key}` },
|
|
97
|
-
});
|
|
98
|
-
if (!res.ok) {
|
|
99
|
-
const err = await res.json();
|
|
100
|
-
console.error(err.message || err.error);
|
|
101
|
-
process.exit(1);
|
|
102
|
-
}
|
|
123
|
+
const res = await apiRequest(config, `/pe/ruc/${rucNumber}`);
|
|
103
124
|
const data = await res.json();
|
|
125
|
+
if (jsonFlag) {
|
|
126
|
+
console.log(JSON.stringify(data));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
104
129
|
console.log(`
|
|
105
130
|
RUC: ${data.ruc}
|
|
106
|
-
Razón Social: ${data.
|
|
131
|
+
Razón Social: ${data.razon_social}
|
|
107
132
|
Estado: ${data.estado}
|
|
108
133
|
Condición: ${data.condicion}
|
|
109
134
|
Ubigeo: ${data.ubigeo}
|
|
110
|
-
Dirección: ${[data.
|
|
111
|
-
Zona: ${[data.
|
|
135
|
+
Dirección: ${[data.tipo_via, data.nombre_via, data.numero].filter(v => v && v !== '-').join(' ')}
|
|
136
|
+
Zona: ${[data.codigo_zona, data.tipo_zona].filter(v => v && v !== '-').join(' ')}
|
|
112
137
|
`.trim());
|
|
113
138
|
}
|
|
114
139
|
async function dni(dniNumber) {
|
|
115
|
-
const config =
|
|
116
|
-
if (!
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
if (!/^\d{8}$/.test(dniNumber)) {
|
|
140
|
+
const config = requireAuth();
|
|
141
|
+
if (!dniNumber || !/^\d{8}$/.test(dniNumber)) {
|
|
142
|
+
if (jsonFlag)
|
|
143
|
+
jsonError('invalid_input', 'Invalid DNI. Must be 8 digits.');
|
|
121
144
|
console.error('Invalid DNI. Must be 8 digits.');
|
|
122
145
|
process.exit(1);
|
|
123
146
|
}
|
|
124
|
-
const res = await
|
|
125
|
-
headers: { Authorization: `Bearer ${config.api_key}` },
|
|
126
|
-
});
|
|
127
|
-
if (!res.ok) {
|
|
128
|
-
const err = await res.json();
|
|
129
|
-
console.error(err.message || err.error);
|
|
130
|
-
process.exit(1);
|
|
131
|
-
}
|
|
147
|
+
const res = await apiRequest(config, `/pe/dni/${dniNumber}`);
|
|
132
148
|
const data = await res.json();
|
|
149
|
+
if (jsonFlag) {
|
|
150
|
+
console.log(JSON.stringify(data));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
133
153
|
console.log(`
|
|
134
|
-
DNI: ${data.dni}
|
|
135
154
|
RUC: ${data.ruc}
|
|
136
|
-
Razón Social: ${data.
|
|
155
|
+
Razón Social: ${data.razon_social}
|
|
137
156
|
Estado: ${data.estado}
|
|
138
157
|
Condición: ${data.condicion}
|
|
139
158
|
Ubigeo: ${data.ubigeo}
|
|
140
|
-
Dirección: ${[data.
|
|
141
|
-
Zona: ${[data.
|
|
159
|
+
Dirección: ${[data.tipo_via, data.nombre_via, data.numero].filter(v => v && v !== '-').join(' ')}
|
|
160
|
+
Zona: ${[data.codigo_zona, data.tipo_zona].filter(v => v && v !== '-').join(' ')}
|
|
142
161
|
`.trim());
|
|
143
162
|
}
|
|
144
163
|
async function search(query) {
|
|
145
|
-
const config =
|
|
146
|
-
if (!
|
|
147
|
-
|
|
164
|
+
const config = requireAuth();
|
|
165
|
+
if (!query) {
|
|
166
|
+
if (jsonFlag)
|
|
167
|
+
jsonError('invalid_input', 'Search query is required.');
|
|
168
|
+
console.error('Search query is required.');
|
|
148
169
|
process.exit(1);
|
|
149
170
|
}
|
|
150
|
-
const res = await
|
|
151
|
-
|
|
171
|
+
const res = await apiRequest(config, `/pe/search?q=${encodeURIComponent(query)}`);
|
|
172
|
+
const results = await res.json();
|
|
173
|
+
if (jsonFlag) {
|
|
174
|
+
console.log(JSON.stringify(results));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (results.length === 0) {
|
|
178
|
+
console.log('No results found.');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
for (const r of results) {
|
|
182
|
+
console.log(` ${r.ruc} ${r.razon_social} [${r.estado}]`);
|
|
183
|
+
}
|
|
184
|
+
console.log(`\n${results.length} result(s)`);
|
|
185
|
+
}
|
|
186
|
+
function whoami() {
|
|
187
|
+
const config = requireAuth();
|
|
188
|
+
if (jsonFlag) {
|
|
189
|
+
console.log(JSON.stringify({ username: config.github_username, api_key: config.api_key }));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
console.log(config.github_username);
|
|
193
|
+
}
|
|
194
|
+
function plan() {
|
|
195
|
+
const config = requireAuth();
|
|
196
|
+
if (jsonFlag) {
|
|
197
|
+
console.log(JSON.stringify({ plan: 'free', limit: '1M requests/month' }));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
console.log(`
|
|
201
|
+
User: ${config.github_username}
|
|
202
|
+
Plan: free
|
|
203
|
+
Limit: 1M requests/month
|
|
204
|
+
`.trim());
|
|
205
|
+
}
|
|
206
|
+
function calcCf(requests) {
|
|
207
|
+
if (requests <= 3_000_000)
|
|
208
|
+
return { cost: 0, tier: 'free' };
|
|
209
|
+
if (requests <= 10_000_000)
|
|
210
|
+
return { cost: 5, tier: 'paid' };
|
|
211
|
+
return { cost: 5 + Math.ceil((requests - 10_000_000) / 1_000_000) * 0.50, tier: 'paid' };
|
|
212
|
+
}
|
|
213
|
+
function printCosts(data) {
|
|
214
|
+
if (jsonFlag) {
|
|
215
|
+
console.log(JSON.stringify(data));
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const fmt = (n) => n.toLocaleString();
|
|
219
|
+
const fmtMoney = (n) => `$${n.toFixed(2)}`;
|
|
220
|
+
console.log(`
|
|
221
|
+
${data.month ? `Month: ${data.month}\n ` : ''}Users: ${fmt(data.users)}
|
|
222
|
+
Pro users: ${fmt(data.pro_users)}
|
|
223
|
+
Requests: ${fmt(data.requests)}/month
|
|
224
|
+
|
|
225
|
+
CF tier: ${data.cf_tier}
|
|
226
|
+
CF cost: ${fmtMoney(data.cf_cost)}/month
|
|
227
|
+
Revenue: ${fmtMoney(data.revenue)}/month
|
|
228
|
+
Margin: ${data.margin >= 0 ? '+' : ''}${fmtMoney(data.margin)}/month
|
|
229
|
+
|
|
230
|
+
Status: ${data.safe ? 'SAFE' : 'DEFICIT'}
|
|
231
|
+
`.trim());
|
|
232
|
+
}
|
|
233
|
+
async function costsLive() {
|
|
234
|
+
const adminSecret = process.env.LATINFO_ADMIN_SECRET;
|
|
235
|
+
if (!adminSecret) {
|
|
236
|
+
if (jsonFlag)
|
|
237
|
+
jsonError('missing_secret', 'Set LATINFO_ADMIN_SECRET env var.');
|
|
238
|
+
console.error('Set LATINFO_ADMIN_SECRET env var.');
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
const res = await fetch(`${API_URL}/admin/stats`, {
|
|
242
|
+
headers: { Authorization: `Bearer ${adminSecret}` },
|
|
152
243
|
});
|
|
153
244
|
if (!res.ok) {
|
|
154
245
|
const err = await res.json();
|
|
246
|
+
if (jsonFlag)
|
|
247
|
+
jsonError(err.error, err.message || err.error);
|
|
155
248
|
console.error(err.message || err.error);
|
|
156
249
|
process.exit(1);
|
|
157
250
|
}
|
|
158
251
|
const data = await res.json();
|
|
159
|
-
|
|
160
|
-
console.log('No results found.');
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
for (const r of data.results) {
|
|
164
|
-
console.log(` ${r.ruc} ${r.razonSocial} [${r.estado}]`);
|
|
165
|
-
}
|
|
166
|
-
console.log(`\n${data.count} result(s)`);
|
|
252
|
+
printCosts(data);
|
|
167
253
|
}
|
|
168
|
-
function
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
254
|
+
function costsSimulate(usersStr, rpmStr, proPctStr) {
|
|
255
|
+
const users = parseInt(usersStr);
|
|
256
|
+
const avgRpm = parseInt(rpmStr || '1000');
|
|
257
|
+
const proPct = parseFloat(proPctStr || '1');
|
|
258
|
+
if (!users || users < 0) {
|
|
259
|
+
if (jsonFlag)
|
|
260
|
+
jsonError('invalid_input', 'Usage: latinfo costs <users> [avg_req/user/month] [pro_%]');
|
|
261
|
+
console.error('Usage: latinfo costs <users> [avg_req/user/month] [pro_%]');
|
|
172
262
|
process.exit(1);
|
|
173
263
|
}
|
|
174
|
-
|
|
264
|
+
const requests = users * avgRpm;
|
|
265
|
+
const proUsers = Math.floor(users * proPct / 100);
|
|
266
|
+
const revenue = proUsers * 1;
|
|
267
|
+
const { cost: cfCost, tier: cfTier } = calcCf(requests);
|
|
268
|
+
const margin = revenue - cfCost;
|
|
269
|
+
printCosts({ users, pro_users: proUsers, requests, cf_tier: cfTier, cf_cost: cfCost, revenue, margin, safe: margin >= 0 });
|
|
175
270
|
}
|
|
176
271
|
function logout() {
|
|
177
272
|
deleteConfig();
|
|
178
273
|
console.log('Logged out.');
|
|
179
274
|
}
|
|
180
275
|
function help() {
|
|
181
|
-
console.log(`
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
276
|
+
console.log(`latinfo v${VERSION} — Public data API for Latin America
|
|
277
|
+
|
|
278
|
+
API base: ${API_URL}
|
|
279
|
+
|
|
280
|
+
USAGE
|
|
281
|
+
latinfo <command> [args] [--json]
|
|
282
|
+
|
|
283
|
+
COMMANDS
|
|
284
|
+
login
|
|
285
|
+
Authenticate via GitHub OAuth. Opens a browser, waits for callback
|
|
286
|
+
on localhost:8400, and stores the API key in ~/.latinfo/config.json.
|
|
287
|
+
|
|
288
|
+
logout
|
|
289
|
+
Remove stored credentials from ~/.latinfo/config.json.
|
|
290
|
+
|
|
291
|
+
whoami
|
|
292
|
+
Show the authenticated GitHub username.
|
|
293
|
+
Output fields (--json): username, api_key
|
|
294
|
+
|
|
295
|
+
plan
|
|
296
|
+
Show current plan and limits.
|
|
297
|
+
Output fields (--json): plan, limit
|
|
298
|
+
|
|
299
|
+
ruc <ruc>
|
|
300
|
+
Lookup a Peruvian taxpayer by RUC (11 digits).
|
|
301
|
+
Output fields (--json): ruc, razon_social, estado, condicion,
|
|
302
|
+
ubigeo, tipo_via, nombre_via, numero, codigo_zona, tipo_zona,
|
|
303
|
+
departamento, provincia, distrito, direccion_completa, tipo_contribuyente
|
|
304
|
+
|
|
305
|
+
dni <dni>
|
|
306
|
+
Lookup a Peruvian taxpayer by DNI (8 digits). Finds the RUC
|
|
307
|
+
associated with the person and returns the same fields as 'ruc'.
|
|
308
|
+
Output fields (--json): same as ruc
|
|
309
|
+
|
|
310
|
+
search <query>
|
|
311
|
+
Search taxpayers by business name (razón social). Returns an array.
|
|
312
|
+
Output fields (--json): array of objects with same fields as ruc
|
|
313
|
+
|
|
314
|
+
costs <users> [avg_req] [pro_%]
|
|
315
|
+
Simulate Cloudflare cost vs revenue. Defaults: 1000 req/user, 1% Pro.
|
|
316
|
+
Output fields (--json): users, pro_users, requests, cf_tier,
|
|
317
|
+
cf_cost, revenue, margin, safe
|
|
318
|
+
|
|
319
|
+
costs --live
|
|
320
|
+
Real-time cost report from production data (admin only).
|
|
321
|
+
Requires LATINFO_ADMIN_SECRET env var.
|
|
322
|
+
Output fields (--json): month, users, pro_users, requests,
|
|
323
|
+
cf_tier, cf_cost, revenue, margin, safe
|
|
324
|
+
|
|
325
|
+
help
|
|
326
|
+
Show this help text.
|
|
327
|
+
|
|
328
|
+
FLAGS
|
|
329
|
+
--json Output raw JSON instead of human-formatted text.
|
|
330
|
+
Errors are written to stderr as {"error":"...","message":"..."}.
|
|
331
|
+
--live Use real-time production data (for 'costs' command).
|
|
332
|
+
--version, -v
|
|
333
|
+
Print version and exit.
|
|
334
|
+
|
|
335
|
+
COUNTRIES
|
|
336
|
+
pe Peru (SUNAT padrón). Active and available.
|
|
337
|
+
|
|
338
|
+
AUTH
|
|
339
|
+
Run 'latinfo login' to authenticate with GitHub. This opens your
|
|
340
|
+
browser for OAuth, then stores your API key locally. All data
|
|
341
|
+
commands (ruc, dni, search) require authentication.
|
|
342
|
+
|
|
343
|
+
Config file: ~/.latinfo/config.json
|
|
344
|
+
Environment: LATINFO_API_URL to override API base URL.
|
|
345
|
+
|
|
346
|
+
EXIT CODES
|
|
347
|
+
0 Success
|
|
348
|
+
1 Error (invalid input, auth failure, API error)`);
|
|
349
|
+
}
|
|
350
|
+
function version() {
|
|
351
|
+
console.log(`latinfo/${VERSION}`);
|
|
193
352
|
}
|
|
194
353
|
// --- Main ---
|
|
195
|
-
const [command, ...args] =
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
354
|
+
const [command, ...args] = rawArgs;
|
|
355
|
+
if (rawArgs.includes('--version') || rawArgs.includes('-v')) {
|
|
356
|
+
version();
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
switch (command) {
|
|
360
|
+
case 'login':
|
|
361
|
+
login().catch(e => { console.error(e); process.exit(1); });
|
|
362
|
+
break;
|
|
363
|
+
case 'logout':
|
|
364
|
+
logout();
|
|
365
|
+
break;
|
|
366
|
+
case 'whoami':
|
|
367
|
+
whoami();
|
|
368
|
+
break;
|
|
369
|
+
case 'plan':
|
|
370
|
+
plan();
|
|
371
|
+
break;
|
|
372
|
+
case 'costs':
|
|
373
|
+
(liveFlag ? costsLive() : Promise.resolve(costsSimulate(args[0], args[1], args[2]))).catch(e => { console.error(e); process.exit(1); });
|
|
374
|
+
break;
|
|
375
|
+
case 'ruc':
|
|
376
|
+
ruc(args[0]).catch(e => { console.error(e); process.exit(1); });
|
|
377
|
+
break;
|
|
378
|
+
case 'dni':
|
|
379
|
+
dni(args[0]).catch(e => { console.error(e); process.exit(1); });
|
|
380
|
+
break;
|
|
381
|
+
case 'search':
|
|
382
|
+
search(args.join(' ')).catch(e => { console.error(e); process.exit(1); });
|
|
383
|
+
break;
|
|
384
|
+
case 'help':
|
|
385
|
+
help();
|
|
386
|
+
break;
|
|
387
|
+
default: help();
|
|
388
|
+
}
|
|
216
389
|
}
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
interface
|
|
1
|
+
export interface PeRecord {
|
|
2
2
|
ruc: string;
|
|
3
|
-
|
|
3
|
+
razon_social: string;
|
|
4
4
|
estado: string;
|
|
5
5
|
condicion: string;
|
|
6
6
|
ubigeo: string;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
tipo_via: string;
|
|
8
|
+
nombre_via: string;
|
|
9
|
+
codigo_zona: string;
|
|
10
|
+
tipo_zona: string;
|
|
11
11
|
numero: string;
|
|
12
12
|
interior: string;
|
|
13
13
|
lote: string;
|
|
@@ -15,19 +15,6 @@ interface RucResult {
|
|
|
15
15
|
manzana: string;
|
|
16
16
|
kilometro: string;
|
|
17
17
|
}
|
|
18
|
-
interface DniResult extends RucResult {
|
|
19
|
-
dni: string;
|
|
20
|
-
}
|
|
21
|
-
interface SearchResult {
|
|
22
|
-
ruc: string;
|
|
23
|
-
razonSocial: string;
|
|
24
|
-
estado: string;
|
|
25
|
-
condicion: string;
|
|
26
|
-
}
|
|
27
|
-
interface SearchResponse {
|
|
28
|
-
count: number;
|
|
29
|
-
results: SearchResult[];
|
|
30
|
-
}
|
|
31
18
|
declare class Country {
|
|
32
19
|
private request;
|
|
33
20
|
private prefix;
|
|
@@ -36,9 +23,9 @@ declare class Country {
|
|
|
36
23
|
}
|
|
37
24
|
declare class Peru extends Country {
|
|
38
25
|
constructor(request: <T>(path: string) => Promise<T>);
|
|
39
|
-
ruc(ruc: string): Promise<
|
|
40
|
-
dni(dni: string): Promise<
|
|
41
|
-
search(query: string): Promise<
|
|
26
|
+
ruc(ruc: string): Promise<PeRecord>;
|
|
27
|
+
dni(dni: string): Promise<PeRecord>;
|
|
28
|
+
search(query: string): Promise<PeRecord[]>;
|
|
42
29
|
}
|
|
43
30
|
export declare class Latinfo {
|
|
44
31
|
private apiKey;
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "latinfo",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "CLI & SDK to query RUC, DNI, and business data from SUNAT Peru. JSON output, AI-friendly.",
|
|
5
|
+
"keywords": ["ruc", "sunat", "peru", "dni", "api", "cli", "tax", "taxpayer", "consulta", "padron", "latin-america", "latam", "json"],
|
|
5
6
|
"main": "dist/sdk.js",
|
|
6
7
|
"types": "dist/sdk.d.ts",
|
|
7
8
|
"bin": {
|