@ntlinkmx/nt 0.0.0-stage → 0.2.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/README.md +460 -2
- package/dist/cli.js +271 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/http.js +123 -0
- package/dist/http.js.map +1 -0
- package/dist/native-routes.json +698 -0
- package/package.json +41 -6
- package/scripts/postinstall.mjs +7 -0
- package/scripts/sync-routes.mjs +17 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
3
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
4
|
+
import { basename } from 'node:path';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { pathToFileURL } from 'node:url';
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
import { emitKeypressEvents } from 'node:readline';
|
|
9
|
+
import { createInterface } from 'node:readline/promises';
|
|
10
|
+
import { effective, load, profileName, TEST_BASE_URL, updateProfile, useProfile } from './config.js';
|
|
11
|
+
import { API, ApiError, output, pairs, readJson, multipart } from './http.js';
|
|
12
|
+
import routes from './native-routes.json' with { type: 'json' };
|
|
13
|
+
const collect = (value, previous) => [...previous, value];
|
|
14
|
+
const opts = (command) => command.optsWithGlobals();
|
|
15
|
+
const api = (command) => new API(opts(command));
|
|
16
|
+
const id = encodeURIComponent;
|
|
17
|
+
async function prompt(label, secret = false) {
|
|
18
|
+
if (secret) {
|
|
19
|
+
if (!process.stdin.isTTY || !process.stdin.setRawMode)
|
|
20
|
+
throw new Error('Sin terminal interactiva: usa NTLINK_PASSWORD o --password-stdin.');
|
|
21
|
+
process.stderr.write(label);
|
|
22
|
+
emitKeypressEvents(process.stdin);
|
|
23
|
+
process.stdin.setRawMode(true);
|
|
24
|
+
process.stdin.resume();
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
let value = '';
|
|
27
|
+
const cleanup = () => { process.stdin.setRawMode(false); process.stdin.pause(); process.stdin.off('keypress', handler); process.stderr.write('\n'); };
|
|
28
|
+
const handler = (char, key) => {
|
|
29
|
+
if (key.ctrl && key.name === 'c') {
|
|
30
|
+
cleanup();
|
|
31
|
+
reject(new Error('Inicio de sesión cancelado.'));
|
|
32
|
+
}
|
|
33
|
+
else if (key.name === 'return' || key.name === 'enter') {
|
|
34
|
+
cleanup();
|
|
35
|
+
resolve(value);
|
|
36
|
+
}
|
|
37
|
+
else if (key.name === 'backspace')
|
|
38
|
+
value = [...value].slice(0, -1).join('');
|
|
39
|
+
else if (char && !key.ctrl)
|
|
40
|
+
value += char;
|
|
41
|
+
};
|
|
42
|
+
process.stdin.on('keypress', handler);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const reader = createInterface({ input: process.stdin, output: process.stderr });
|
|
46
|
+
try {
|
|
47
|
+
return (await reader.question(label)).trim();
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
reader.close();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function queryOptions(command) { return command.option('-q, --query <KEY=VALUE>', 'Parámetro de consulta repetible.', collect, []); }
|
|
54
|
+
function payloadOptions(command) {
|
|
55
|
+
return queryOptions(command).option('--data <file>', 'Archivo JSON.').option('--raw <file>', 'Archivo enviado como cuerpo binario/XML.')
|
|
56
|
+
.option('--header <KEY=VALUE>', 'Cabecera HTTP adicional repetible.', collect, [])
|
|
57
|
+
.option('--content-type <type>', 'Content-Type para --raw.', 'application/octet-stream')
|
|
58
|
+
.option('--field <KEY=VALUE>', 'Campo multipart repetible.', collect, [])
|
|
59
|
+
.option('--file <FIELD=PATH>', 'Archivo multipart repetible.', collect, [])
|
|
60
|
+
.option('--output <path>', 'Guardar respuesta en archivo.').option('--force', 'Sobrescribir archivo de salida.')
|
|
61
|
+
.option('--stream', 'Mostrar SSE sin transformar.');
|
|
62
|
+
}
|
|
63
|
+
function requestOptions(options) {
|
|
64
|
+
const modes = Number(!!options.data) + Number(!!options.raw) + Number(!!(options.file?.length || options.field?.length));
|
|
65
|
+
if (modes > 1)
|
|
66
|
+
throw new Error('Usa solo uno de --data, --raw o multipart (--file/--field).');
|
|
67
|
+
if (options.stream && options.output)
|
|
68
|
+
throw new Error('--stream y --output son excluyentes.');
|
|
69
|
+
return { query: options.query, json: options.data ? readJson(options.data) : undefined,
|
|
70
|
+
body: options.raw ? readFileSync(options.raw) : options.file?.length || options.field?.length ? multipart(options.field, options.file) : undefined,
|
|
71
|
+
headers: { ...Object.fromEntries(pairs(options.header)), ...(options.raw ? { 'Content-Type': options.contentType } : {}) },
|
|
72
|
+
output: options.output, force: options.force, stream: options.stream };
|
|
73
|
+
}
|
|
74
|
+
function paged(command) {
|
|
75
|
+
return queryOptions(command).option('--page <number>', 'Página base cero.').option('--size <number>', 'Tamaño, máximo 200.')
|
|
76
|
+
.option('--company <id>', 'Empresa.').option('--customer <id>', 'Cliente.').option('--search <text>', 'Búsqueda.')
|
|
77
|
+
.option('--from <date>', 'Fecha inicial.').option('--to <date>', 'Fecha final.')
|
|
78
|
+
.option('--filter <KEY=VALUE>', 'Filtro del backend repetible.', collect, []);
|
|
79
|
+
}
|
|
80
|
+
function listQuery(o) {
|
|
81
|
+
const q = [...o.query, ...o.filter];
|
|
82
|
+
for (const [flag, key] of Object.entries({ page: 'page', size: 'size', company: 'companyId', customer: 'customerId', search: 'search', from: 'from', to: 'to' }))
|
|
83
|
+
if (o[flag] !== undefined)
|
|
84
|
+
q.push(`${key}=${o[flag]}`);
|
|
85
|
+
return q;
|
|
86
|
+
}
|
|
87
|
+
function jsonCommand(parent, signature, method, path, anonymous = false) {
|
|
88
|
+
parent.command(signature).description(`${method} ${path(['{id}'])}; envía JSON sin modificar.`).action(async (...args) => {
|
|
89
|
+
const command = args.at(-1);
|
|
90
|
+
const positional = args.slice(0, -2);
|
|
91
|
+
output(await api(command).request(method, path(positional), { json: readJson(positional.at(-1)), anonymous }));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export function createProgram() {
|
|
95
|
+
const program = new Command().name('nt').version('0.2.1').description('Cliente para NTLink IA Invoice / backend Go.')
|
|
96
|
+
.option('--profile <name>', 'Perfil de entorno.').option('--base-url <url>', 'Origen HTTP(S) de Go, sin /api.')
|
|
97
|
+
.option('--token <token>', 'Bearer token; preferir NTLINK_TOKEN.').option('--timeout <seconds>', 'Timeout por solicitud.')
|
|
98
|
+
.option('--json', 'Salida JSON (también es el formato por defecto).').option('--verbose', 'Método/ruta/estado por stderr, sin cuerpos ni secretos.')
|
|
99
|
+
.option('--allow-insecure-http', 'Permitir explícitamente HTTP remoto sin cifrado.')
|
|
100
|
+
.option('--unsafe-api', 'Habilitar llamadas manuales y rutas nativas sin interfaz estable.');
|
|
101
|
+
const config = program.command('config').description('Perfiles independientes de entorno y sesión.');
|
|
102
|
+
config.command('show').action((_o, c) => { const current = effective(opts(c)); output({ mode: profileName(opts(c)), timeout: current.timeout }); });
|
|
103
|
+
config.command('list').action(() => { const store = load(); output({ mode: store.active, profiles: Object.keys(store.profiles) }); });
|
|
104
|
+
config.command('use <name>').action(name => { useProfile(name); output({ profile: name }); });
|
|
105
|
+
config.command('set').option('--url <url>', 'Alias local de --base-url.')
|
|
106
|
+
.option('--allow-insecure-http', 'Permitir HTTP remoto para este perfil; credenciales y datos viajan sin cifrar.')
|
|
107
|
+
.option('--https-only', 'Bloquear HTTP remoto para este perfil.').action((o, c) => {
|
|
108
|
+
if (o.allowInsecureHttp && o.httpsOnly)
|
|
109
|
+
throw new Error('Elige solo una opción: --allow-insecure-http o --https-only.');
|
|
110
|
+
const options = opts(c);
|
|
111
|
+
const current = effective({ ...options, baseUrl: o.url || options.baseUrl });
|
|
112
|
+
updateProfile(profileName(options), { ...current, ...(o.allowInsecureHttp ? { allowInsecureHttp: true } : {}), ...(o.httpsOnly ? { allowInsecureHttp: false } : {}) });
|
|
113
|
+
output({ mode: profileName(options), timeout: current.timeout, insecureHttpAllowed: o.allowInsecureHttp ? true : o.httpsOnly ? false : !!current.allowInsecureHttp });
|
|
114
|
+
});
|
|
115
|
+
program.command('mode [environment]').description('Ver el modo actual o cambiar de entorno.')
|
|
116
|
+
.action((environment) => {
|
|
117
|
+
if (!environment) {
|
|
118
|
+
output({ mode: load().active, production: 'próximamente' });
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const selected = environment.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
|
|
122
|
+
if (['production', 'produccion', 'prod'].includes(selected)) {
|
|
123
|
+
output({ mode: load().active, message: 'El modo producción estará disponible próximamente.' });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (['test', 'testing', 'prueba', 'pruebas'].includes(selected)) {
|
|
127
|
+
updateProfile('pruebas', { baseUrl: TEST_BASE_URL });
|
|
128
|
+
useProfile('pruebas');
|
|
129
|
+
output({ mode: 'pruebas', message: 'La cuenta pública de demostración iniciará sesión automáticamente al usar un comando protegido.' });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
throw new Error('Usa nt mode pruebas o nt mode production.');
|
|
133
|
+
});
|
|
134
|
+
const auth = program.command('auth').description('Autenticación Membership Go; no existe refresh token.');
|
|
135
|
+
auth.command('login').option('--email <email>', 'Correo.').option('--password-stdin', 'Leer contraseña desde stdin.').action(async (o, c) => {
|
|
136
|
+
const options = opts(c);
|
|
137
|
+
const current = effective(options);
|
|
138
|
+
const email = o.email || await prompt('Correo: ');
|
|
139
|
+
const password = o.passwordStdin ? readFileSync(0, 'utf8').replace(/\r?\n$/, '') : process.env.NTLINK_PASSWORD || await prompt('Contraseña: ', true);
|
|
140
|
+
const response = await api(c).request('POST', '/api/v2/auth/login', { anonymous: true, json: { email, password } });
|
|
141
|
+
if (typeof response.token !== 'string' || !response.token)
|
|
142
|
+
throw new Error('El backend no devolvió token.');
|
|
143
|
+
updateProfile(profileName(options), { baseUrl: current.baseUrl, timeout: current.timeout, token: response.token });
|
|
144
|
+
output({ authenticated: true, profile: profileName(options), email: response.email, roles: response.roles, termsAndConditions: response.termsAndConditions });
|
|
145
|
+
});
|
|
146
|
+
auth.command('logout').action((_o, c) => { updateProfile(profileName(opts(c)), { token: undefined }); output({ authenticated: false }); });
|
|
147
|
+
auth.command('status').action(async (_o, c) => output(await api(c).request('GET', '/api/v2/customer/profile')));
|
|
148
|
+
jsonCommand(auth, 'register <file>', 'POST', () => '/api/v2/auth/register', true);
|
|
149
|
+
jsonCommand(auth, 'verify-code <file>', 'POST', () => '/api/v2/auth/verify-code', true);
|
|
150
|
+
auth.command('accept-terms').action(async (_o, c) => output(await api(c).request('POST', '/api/v2/customer/terms-and-conditions')));
|
|
151
|
+
const client = program.command('client').description('Cuenta, saldos y reportes.');
|
|
152
|
+
for (const [name, path] of [['info', 'profile'], ['balance', 'balances'], ['companies', 'companies']])
|
|
153
|
+
client.command(name).action(async (_o, c) => output(await api(c).request('GET', `/api/v2/customer/${path}`)));
|
|
154
|
+
client.command('usage').option('--year <year>', 'Año.').action(async (o, c) => output(await api(c).request('GET', '/api/v2/customer/stamp-usage', { query: o.year ? [`year=${o.year}`] : [] })));
|
|
155
|
+
client.command('blacklist <rfc>').action(async (rfc, _o, c) => output(await api(c).request('GET', '/api/v2/customer/blacklist', { query: [`rfc=${rfc}`] })));
|
|
156
|
+
for (const [name, resource] of [['customers', 'clients'], ['companies', 'companies'], ['users', 'users']]) {
|
|
157
|
+
const group = program.command(name).description(`Directorio y escrituras: ${resource}.`);
|
|
158
|
+
queryOptions(group.command('list')).action(async (o, c) => output(await api(c).request('GET', `/api/v2/customer/${resource}`, { query: o.query })));
|
|
159
|
+
if (name !== 'users')
|
|
160
|
+
group.command('get <id>').action(async (key, _o, c) => output(await api(c).request('GET', `/api/v2/customer/${resource}/${id(key)}`)));
|
|
161
|
+
jsonCommand(group, 'create <file>', 'POST', () => `/api/v2/customer/${resource}`);
|
|
162
|
+
jsonCommand(group, 'update <id> <file>', 'PUT', args => `/api/v2/customer/${resource}/${id(args[0])}`);
|
|
163
|
+
if (name === 'customers')
|
|
164
|
+
group.command('delete <id>').action(async (key, _o, c) => output(await api(c).request('DELETE', `/api/v2/customer/clients/${id(key)}`)));
|
|
165
|
+
}
|
|
166
|
+
const dashboard = program.command('dashboard');
|
|
167
|
+
for (const [name, resource] of Object.entries({ daily: 'daily-counts', types: 'cfdi-types-counts', status: 'status-counts', 'top-receivers': 'top-ten-receivers', 'top-transmitters': 'top-ten-transmitters' }))
|
|
168
|
+
dashboard.command(name).addOption(new Option('--range <range>').choices(['LAST_WEEK', 'LAST_MONTH', 'LAST_3_MONTHS', 'LAST_YEAR']).default('LAST_MONTH')).action(async (o, c) => output(await api(c).request('GET', `/api/v2/dashboard/${resource}`, { query: [`range=${o.range}`] })));
|
|
169
|
+
const reports = program.command('reports');
|
|
170
|
+
for (const [name, resource] of [['pending-ppd', 'pending-ppd-invoices'], ['retentions', 'retentions']])
|
|
171
|
+
paged(reports.command(name)).action(async (o, c) => output(await api(c).request('GET', `/api/v2/customer/${resource}`, { query: listQuery(o) })));
|
|
172
|
+
const catalogs = program.command('catalogs');
|
|
173
|
+
const catalogNames = ['ClaveProdServ', 'ClaveUnidad', 'RegimenFiscal', 'UsoCFDI', 'FormaPago', 'MetodoPago', 'TipoDeComprobante', 'Exportacion', 'Moneda', 'ObjetoImp', 'Impuesto', 'TipoFactor', 'Periodicidad', 'Meses', 'TipoRelacion'];
|
|
174
|
+
catalogs.command('list').action(() => output(catalogNames));
|
|
175
|
+
queryOptions(catalogs.command('get <name>')).option('--id <id>').option('--description <text>').action(async (name, o, c) => {
|
|
176
|
+
const canonical = catalogNames.find(n => n.toLowerCase() === name.toLowerCase());
|
|
177
|
+
if (!canonical)
|
|
178
|
+
throw new Error('Catálogo desconocido; consulta catalogs list o native catalogo.');
|
|
179
|
+
output(await api(c).request('GET', `/api/v1/catalogs/${canonical}`, { query: [...o.query, ...(o.id ? [`id=${o.id}`] : []), ...(o.description ? [`q=${o.description}`] : [])] }));
|
|
180
|
+
});
|
|
181
|
+
const cfdi = program.command('cfdi');
|
|
182
|
+
paged(cfdi.command('list')).action(async (o, c) => output(await api(c).request('GET', '/api/v2/cfdis', { query: listQuery(o) })));
|
|
183
|
+
for (const action of ['get', 'status'])
|
|
184
|
+
cfdi.command(`${action} <uuid>`).action(async (uuid, _o, c) => output(await api(c).request('GET', `/api/v2/cfdis/${id(uuid)}${action === 'status' ? '/status' : ''}`)));
|
|
185
|
+
for (const action of ['prepare', 'stamp'])
|
|
186
|
+
jsonCommand(cfdi, `${action} <file>`, 'POST', () => `/api/v2/cfdis/${action}`);
|
|
187
|
+
cfdi.command('validate <file>').action(async (file, _o, c) => output(await api(c).request('POST', '/api/v2/cfdis/validate', { body: readFileSync(file), headers: { 'Content-Type': 'application/xml' } })));
|
|
188
|
+
cfdi.command('cancel <uuid>').addOption(new Option('--reason <reason>').choices(['01', '02', '03', '04']).makeOptionMandatory()).option('--replacement <uuid>').action(async (uuid, o, c) => output(await api(c).request('POST', '/api/v2/cfdis/cancel', { json: { uuid, motivo: o.reason, folioSustituto: o.replacement } })));
|
|
189
|
+
cfdi.command('email <uuid>').requiredOption('--to <email>', 'Destinatario repetible.', collect, []).action(async (uuid, o, c) => output(await api(c).request('POST', `/api/v2/cfdis/${id(uuid)}/send-email`, { json: o.to })));
|
|
190
|
+
cfdi.command('download <uuid>').addOption(new Option('--format <format>').choices(['xml', 'pdf']).default('xml')).option('--output <path>').option('--force').action(async (uuid, o, c) => output(await api(c).request('GET', `/api/v2/cfdis/${id(uuid)}/${o.format}`, { output: o.output || `${uuid}.${o.format}`, force: o.force })));
|
|
191
|
+
const drafts = program.command('drafts');
|
|
192
|
+
paged(drafts.command('list')).action(async (o, c) => output(await api(c).request('GET', '/api/v2/pre-cfdis', { query: listQuery(o) })));
|
|
193
|
+
drafts.command('get <id>').action(async (key, _o, c) => output(await api(c).request('GET', `/api/v2/pre-cfdis/${id(key)}`)));
|
|
194
|
+
jsonCommand(drafts, 'create <file>', 'POST', () => '/api/v2/pre-cfdis');
|
|
195
|
+
jsonCommand(drafts, 'update <id> <file>', 'PUT', args => `/api/v2/pre-cfdis/${id(args[0])}`);
|
|
196
|
+
jsonCommand(drafts, 'stamp <id> <file>', 'POST', args => `/api/v2/pre-cfdis/${id(args[0])}/stamp`);
|
|
197
|
+
drafts.command('reserve-folio').action(async (_o, c) => output(await api(c).request('POST', '/api/v2/pre-cfdis/folios/reserve')));
|
|
198
|
+
drafts.command('next-folio').description('Consultar el siguiente folio fiscal de la empresa; no lo reserva.').action(async (_o, c) => output(await api(c).request('GET', '/api/v2/pre-cfdis/folios/next')));
|
|
199
|
+
registerChat(program);
|
|
200
|
+
const health = program.command('health');
|
|
201
|
+
for (const name of ['live', 'ready'])
|
|
202
|
+
health.command(name).action(async (_o, c) => output(await api(c).request('GET', `/health/${name}`, { anonymous: true })));
|
|
203
|
+
program.command('parity').description('Diagnóstico de rutas, solo entorno dev Go.').action(async (_o, c) => output(await api(c).request('GET', '/api/dev/parity', { anonymous: true })));
|
|
204
|
+
payloadOptions(program.command('api <method> <path>').description('Solicitud manual al backend configurado.')).option('--anonymous', 'Omitir Bearer.').action(async (method, path, o, c) => {
|
|
205
|
+
if (!opts(c).unsafeApi)
|
|
206
|
+
throw new Error('La API manual está deshabilitada por defecto. Confirma con --unsafe-api antes de usarla.');
|
|
207
|
+
if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'].includes(method.toUpperCase()))
|
|
208
|
+
throw new Error('Método HTTP inválido.');
|
|
209
|
+
const result = await api(c).request(method.toUpperCase(), path, { ...requestOptions(o), anonymous: o.anonymous });
|
|
210
|
+
if (!o.stream)
|
|
211
|
+
output(result);
|
|
212
|
+
});
|
|
213
|
+
const native = program.command('native').description('Rutas nativas Go; consulta ayuda y contratos antes de escribir.');
|
|
214
|
+
native.command('routes').option('--controller <name>').action(o => output(routes.filter(r => !o.controller || r.controller.toLowerCase() === o.controller.toLowerCase())));
|
|
215
|
+
const groups = new Map();
|
|
216
|
+
for (const route of routes) {
|
|
217
|
+
const name = route.controller.toLowerCase();
|
|
218
|
+
let group = groups.get(name);
|
|
219
|
+
if (!group) {
|
|
220
|
+
group = native.command(name);
|
|
221
|
+
groups.set(name, group);
|
|
222
|
+
}
|
|
223
|
+
const commandName = route.action.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
224
|
+
const command = payloadOptions(group.command(commandName).description(`${route.method} ${route.path}${route.registered ? '' : ' (registro pendiente)'}`)).option('--param <KEY=VALUE>', 'Parámetro de ruta repetible.', collect, []);
|
|
225
|
+
command.action(async (o, c) => {
|
|
226
|
+
if (!opts(c).unsafeApi)
|
|
227
|
+
throw new Error('Las rutas nativas están deshabilitadas por defecto. Confirma con --unsafe-api antes de usarlas.');
|
|
228
|
+
const params = Object.fromEntries(pairs(o.param));
|
|
229
|
+
const path = route.path.replace(/\{(\w+)(?::\w+)?\}/g, (_match, key) => {
|
|
230
|
+
if (!params[key])
|
|
231
|
+
throw new Error(`Falta --param ${key}=VALUE`);
|
|
232
|
+
return id(params[key]);
|
|
233
|
+
});
|
|
234
|
+
const result = await api(c).request(route.method, path, { ...requestOptions(o), anonymous: route.anonymous });
|
|
235
|
+
if (!o.stream)
|
|
236
|
+
output(result);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return program;
|
|
240
|
+
}
|
|
241
|
+
function registerChat(program) {
|
|
242
|
+
const chat = program.command('chat').description('Chat persistente, adjuntos y eventos SSE.');
|
|
243
|
+
chat.command('models').action(async (_o, c) => output(await api(c).request('GET', '/api/v2/chat/models')));
|
|
244
|
+
const sessions = chat.command('sessions');
|
|
245
|
+
for (const action of ['list', 'create'])
|
|
246
|
+
sessions.command(action).action(async (_o, c) => output(await api(c).request(action === 'list' ? 'GET' : 'POST', '/api/v2/chat/sessions')));
|
|
247
|
+
for (const action of ['get', 'delete'])
|
|
248
|
+
sessions.command(`${action} <id>`).action(async (key, _o, c) => output(await api(c).request(action === 'get' ? 'GET' : 'DELETE', `/api/v2/chat/sessions/${id(key)}`)));
|
|
249
|
+
chat.command('attach <file>').action(async (file, _o, c) => output(await api(c).request('POST', '/api/v2/chat/attachments', { body: readFileSync(file), headers: { 'Content-Type': 'application/octet-stream', 'X-File-Name': encodeURIComponent(basename(file)) } })));
|
|
250
|
+
chat.command('send <session> <message>').option('--provider <id>').option('--model <id>').option('--request-id <uuid>', 'UUID idempotente; se genera si falta.')
|
|
251
|
+
.option('--attach <file>', 'Adjunto local repetible.', collect, []).action(async (session, message, o, c) => {
|
|
252
|
+
const attachments = [];
|
|
253
|
+
for (const file of o.attach)
|
|
254
|
+
attachments.push(await api(c).request('POST', '/api/v2/chat/attachments', { body: readFileSync(file), headers: { 'Content-Type': 'application/octet-stream', 'X-File-Name': encodeURIComponent(basename(file)) } }));
|
|
255
|
+
const requestId = o.requestId || randomUUID();
|
|
256
|
+
const result = await api(c).request('POST', `/api/v2/chat/sessions/${id(session)}/messages`, { json: { message, provider: o.provider, model: o.model, requestId, attachments } });
|
|
257
|
+
output({ sessionId: session, requestId, ...result });
|
|
258
|
+
});
|
|
259
|
+
chat.command('events <run>').option('--last-event-id <id>', 'Reanudar SSE desde un evento.').action(async (run, o, c) => {
|
|
260
|
+
await api(c).request('GET', `/api/v2/chat/runs/${id(run)}/events`, { stream: true, headers: o.lastEventId ? { 'Last-Event-ID': o.lastEventId } : {} });
|
|
261
|
+
});
|
|
262
|
+
chat.command('cancel <run>').action(async (run, _o, c) => output(await api(c).request('POST', `/api/v2/chat/runs/${id(run)}/cancel`)));
|
|
263
|
+
jsonCommand(chat, 'complete <file>', 'POST', () => '/api/v2/chat');
|
|
264
|
+
}
|
|
265
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(resolve(process.argv[1]))).href) {
|
|
266
|
+
createProgram().parseAsync().catch(error => {
|
|
267
|
+
process.stderr.write(JSON.stringify({ error: error instanceof Error ? error.message : String(error), ...(error instanceof ApiError ? { status: error.status } : {}) }) + '\n');
|
|
268
|
+
process.exitCode = 1;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync, renameSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
export const TEST_BASE_URL = 'http://pruebas.ntlink.com.mx:8092';
|
|
6
|
+
export const TEST_ACCOUNT = { email: 'URE180429TM6@ntlink.com.mx', password: 'NTPruebas.2021*?' };
|
|
7
|
+
const defaults = { baseUrl: TEST_BASE_URL, timeout: 120 };
|
|
8
|
+
export function configFile() { return join(process.env.NTLINK_INVOICE_CONFIG_DIR || join(homedir(), '.ntlink-invoice'), 'config.json'); }
|
|
9
|
+
export function load() {
|
|
10
|
+
try {
|
|
11
|
+
const value = JSON.parse(readFileSync(configFile(), 'utf8'));
|
|
12
|
+
if (!value.profiles || !value.active)
|
|
13
|
+
throw new Error('Configuración inválida.');
|
|
14
|
+
if (value.active === 'local' && value.profiles.local?.baseUrl === 'http://localhost:8092') {
|
|
15
|
+
value.profiles.pruebas ??= { ...defaults };
|
|
16
|
+
value.active = 'pruebas';
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
if (error.code !== 'ENOENT')
|
|
22
|
+
throw error;
|
|
23
|
+
return { active: 'pruebas', profiles: { pruebas: { ...defaults } } };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function save(value) {
|
|
27
|
+
const dir = join(configFile(), '..');
|
|
28
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
29
|
+
const temp = `${configFile()}.${randomUUID()}.tmp`;
|
|
30
|
+
writeFileSync(temp, JSON.stringify(value, null, 2) + '\n', { mode: 0o600, flag: 'wx' });
|
|
31
|
+
renameSync(temp, configFile());
|
|
32
|
+
}
|
|
33
|
+
export function profileName(options) { return options.profile || process.env.NTLINK_PROFILE || load().active; }
|
|
34
|
+
export function validateBaseUrl(value) {
|
|
35
|
+
const url = new URL(value);
|
|
36
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash || url.pathname !== '/') {
|
|
37
|
+
throw new Error('--base-url debe ser el origen HTTP(S), sin /api, credenciales ni parámetros.');
|
|
38
|
+
}
|
|
39
|
+
return url.origin;
|
|
40
|
+
}
|
|
41
|
+
export function effective(options) {
|
|
42
|
+
const profiles = load().profiles;
|
|
43
|
+
const name = profileName(options);
|
|
44
|
+
const saved = Object.hasOwn(profiles, name) ? profiles[name] : undefined;
|
|
45
|
+
if (!saved && !options.baseUrl && !process.env.NTLINK_BASE_URL)
|
|
46
|
+
throw new Error('Perfil desconocido. Créalo con config set --base-url.');
|
|
47
|
+
const baseUrl = validateBaseUrl(options.baseUrl || process.env.NTLINK_BASE_URL || saved?.baseUrl || defaults.baseUrl);
|
|
48
|
+
const timeout = Number(options.timeout || process.env.NTLINK_TIMEOUT || saved?.timeout || defaults.timeout);
|
|
49
|
+
if (!Number.isFinite(timeout) || timeout <= 0)
|
|
50
|
+
throw new Error('Timeout debe ser un número positivo de segundos.');
|
|
51
|
+
// A stored token must never follow an override to a different backend.
|
|
52
|
+
const token = options.token || process.env.NTLINK_TOKEN || (saved && validateBaseUrl(saved.baseUrl) === baseUrl ? saved.token : undefined);
|
|
53
|
+
const insecurePermission = saved && validateBaseUrl(saved.baseUrl) === baseUrl && saved.allowInsecureHttp;
|
|
54
|
+
return { baseUrl, timeout, token, allowInsecureHttp: options.allowInsecureHttp || insecurePermission };
|
|
55
|
+
}
|
|
56
|
+
export function updateProfile(name, changes) {
|
|
57
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(name) || ['__proto__', 'constructor', 'prototype'].includes(name))
|
|
58
|
+
throw new Error('Nombre de perfil inválido.');
|
|
59
|
+
const store = load();
|
|
60
|
+
const previous = store.profiles[name];
|
|
61
|
+
const baseUrl = changes.baseUrl ? validateBaseUrl(changes.baseUrl) : previous?.baseUrl || defaults.baseUrl;
|
|
62
|
+
store.profiles[name] = { ...defaults, ...previous, ...(previous?.baseUrl !== baseUrl ? { token: undefined, allowInsecureHttp: undefined } : {}), ...changes, baseUrl };
|
|
63
|
+
save(store);
|
|
64
|
+
}
|
|
65
|
+
export function useProfile(name) {
|
|
66
|
+
const store = load();
|
|
67
|
+
if (!Object.hasOwn(store.profiles, name))
|
|
68
|
+
throw new Error('Perfil desconocido.');
|
|
69
|
+
store.active = name;
|
|
70
|
+
save(store);
|
|
71
|
+
}
|
|
72
|
+
export function masked(value) {
|
|
73
|
+
if (Array.isArray(value))
|
|
74
|
+
return value.map(masked);
|
|
75
|
+
if (value && typeof value === 'object')
|
|
76
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, /token|password|secret|clave|authorization|cookie/i.test(key) ? (item ? '[oculto]' : item) : masked(item)]));
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { effective, profileName, TEST_ACCOUNT, TEST_BASE_URL, updateProfile } from './config.js';
|
|
4
|
+
export class ApiError extends Error {
|
|
5
|
+
status;
|
|
6
|
+
constructor(status, message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = status;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function pairs(values = []) {
|
|
12
|
+
return values.map(value => {
|
|
13
|
+
const index = value.indexOf('=');
|
|
14
|
+
if (index < 1)
|
|
15
|
+
throw new Error(`Se esperaba KEY=VALUE: ${value}`);
|
|
16
|
+
return [value.slice(0, index), value.slice(index + 1)];
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function readJson(file) { return JSON.parse(readFileSync(file, 'utf8').replace(/^\uFEFF/, '')); }
|
|
20
|
+
export function output(value) { process.stdout.write(JSON.stringify(value ?? null, null, 2) + '\n'); }
|
|
21
|
+
export function download(file, bytes, force = false) { writeFileSync(file, bytes, { flag: force ? 'w' : 'wx', mode: 0o600 }); }
|
|
22
|
+
export function multipart(fields = [], files = []) {
|
|
23
|
+
const form = new FormData();
|
|
24
|
+
for (const [key, value] of pairs(fields))
|
|
25
|
+
form.append(key, value);
|
|
26
|
+
for (const [key, file] of pairs(files))
|
|
27
|
+
form.append(key, new Blob([readFileSync(file)]), basename(file));
|
|
28
|
+
return form;
|
|
29
|
+
}
|
|
30
|
+
export class API {
|
|
31
|
+
options;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.options = options;
|
|
34
|
+
}
|
|
35
|
+
async request(method, path, opts = {}) {
|
|
36
|
+
const config = effective(this.options);
|
|
37
|
+
const hostname = new URL(config.baseUrl).hostname;
|
|
38
|
+
const trustedDemoHttp = config.baseUrl === TEST_BASE_URL;
|
|
39
|
+
if (config.baseUrl.startsWith('http://') && !['localhost', '127.0.0.1', '[::1]', '::1'].includes(hostname) && !trustedDemoHttp && !config.allowInsecureHttp) {
|
|
40
|
+
throw new Error('Conexión HTTP sin cifrar bloqueada. Usa HTTPS o confirma explícitamente con nt config set --allow-insecure-http.');
|
|
41
|
+
}
|
|
42
|
+
if (config.baseUrl.startsWith('http://') && !['localhost', '127.0.0.1', '[::1]', '::1'].includes(hostname) && !trustedDemoHttp && config.allowInsecureHttp) {
|
|
43
|
+
process.stderr.write('ADVERTENCIA: HTTP remoto no cifra credenciales ni tokens.\n');
|
|
44
|
+
}
|
|
45
|
+
if (!path.startsWith('/') || path.startsWith('//') || path.includes('\\'))
|
|
46
|
+
throw new Error('Usa una ruta relativa al backend, como /api/v2/customer/profile.');
|
|
47
|
+
const url = new URL(path, config.baseUrl);
|
|
48
|
+
if (url.origin !== config.baseUrl)
|
|
49
|
+
throw new Error('La ruta debe pertenecer al backend configurado.');
|
|
50
|
+
for (const [key, value] of pairs(opts.query))
|
|
51
|
+
url.searchParams.append(key, value);
|
|
52
|
+
const headers = { ...opts.headers };
|
|
53
|
+
if (!opts.anonymous) {
|
|
54
|
+
if (!config.token && config.baseUrl === TEST_BASE_URL && profileName(this.options) === 'pruebas') {
|
|
55
|
+
const login = await fetch(new URL('/api/v2/auth/login', config.baseUrl), {
|
|
56
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
57
|
+
body: JSON.stringify(TEST_ACCOUNT), redirect: 'error', signal: AbortSignal.timeout(config.timeout * 1000),
|
|
58
|
+
});
|
|
59
|
+
if (!login.ok)
|
|
60
|
+
throw new ApiError(login.status, 'No se pudo iniciar la sesión automática en el entorno de pruebas.');
|
|
61
|
+
const session = await login.json();
|
|
62
|
+
if (typeof session.token !== 'string' || !session.token)
|
|
63
|
+
throw new Error('El backend de pruebas no devolvió token.');
|
|
64
|
+
config.token = session.token;
|
|
65
|
+
updateProfile('pruebas', { baseUrl: config.baseUrl, timeout: config.timeout, token: session.token });
|
|
66
|
+
}
|
|
67
|
+
if (!config.token)
|
|
68
|
+
throw new Error('Inicia sesión con nt auth login o proporciona NTLINK_TOKEN.');
|
|
69
|
+
headers.Authorization = `Bearer ${config.token}`;
|
|
70
|
+
}
|
|
71
|
+
let body = opts.body;
|
|
72
|
+
if (opts.json !== undefined) {
|
|
73
|
+
body = JSON.stringify(opts.json);
|
|
74
|
+
headers['Content-Type'] = 'application/json';
|
|
75
|
+
}
|
|
76
|
+
if (this.options.verbose)
|
|
77
|
+
process.stderr.write(`${method} ${url.origin}${url.pathname}\n`);
|
|
78
|
+
const response = await fetch(url, { method, headers, body, redirect: 'error', signal: AbortSignal.timeout(config.timeout * 1000) });
|
|
79
|
+
if (this.options.verbose)
|
|
80
|
+
process.stderr.write(`HTTP ${response.status}\n`);
|
|
81
|
+
if (!response.ok) {
|
|
82
|
+
const text = await response.text();
|
|
83
|
+
let message = `HTTP ${response.status}`;
|
|
84
|
+
try {
|
|
85
|
+
const data = JSON.parse(text);
|
|
86
|
+
message = typeof data === 'string' ? data : String(data.message || data.error || message);
|
|
87
|
+
}
|
|
88
|
+
catch { /* Do not print a possibly sensitive HTML/body. */ }
|
|
89
|
+
if (response.status === 401)
|
|
90
|
+
message += ' Ejecuta nt auth login para renovar la sesión.';
|
|
91
|
+
throw new ApiError(response.status, message);
|
|
92
|
+
}
|
|
93
|
+
if (opts.stream) {
|
|
94
|
+
if (!response.body)
|
|
95
|
+
throw new Error('El backend no devolvió eventos.');
|
|
96
|
+
const decoder = new TextDecoder();
|
|
97
|
+
for await (const chunk of response.body)
|
|
98
|
+
process.stdout.write(decoder.decode(chunk, { stream: true }));
|
|
99
|
+
process.stdout.write(decoder.decode());
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
103
|
+
if (opts.output) {
|
|
104
|
+
download(opts.output, bytes, opts.force);
|
|
105
|
+
return { path: opts.output, bytes: bytes.length };
|
|
106
|
+
}
|
|
107
|
+
if (!bytes.length)
|
|
108
|
+
return null;
|
|
109
|
+
const text = new TextDecoder().decode(bytes);
|
|
110
|
+
let result;
|
|
111
|
+
try {
|
|
112
|
+
result = JSON.parse(text);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return text;
|
|
116
|
+
}
|
|
117
|
+
if (result && typeof result === 'object' && 'exito' in result && result.exito === false) {
|
|
118
|
+
throw new ApiError(response.status, 'La operación nativa devolvió exito:false. Consulta el contrato y los datos de entrada.');
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|