@tostudy-ai/cli 0.1.1 → 0.1.3
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/bin/tostudy.ts +4 -0
- package/dist/cli.js +1264 -867
- package/dist/cli.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5,9 +5,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __commonJS = (cb, mod) => function __require() {
|
|
9
12
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
13
|
};
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
11
18
|
var __copyProps = (to, from, except, desc) => {
|
|
12
19
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
20
|
for (let key of __getOwnPropNames(from))
|
|
@@ -25,85 +32,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
32
|
mod
|
|
26
33
|
));
|
|
27
34
|
|
|
28
|
-
// ../../node_modules/picocolors/picocolors.js
|
|
29
|
-
var require_picocolors = __commonJS({
|
|
30
|
-
"../../node_modules/picocolors/picocolors.js"(exports, module) {
|
|
31
|
-
var p = process || {};
|
|
32
|
-
var argv = p.argv || [];
|
|
33
|
-
var env = p.env || {};
|
|
34
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
35
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
36
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
37
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
38
|
-
};
|
|
39
|
-
var replaceClose = (string, close, replace, index) => {
|
|
40
|
-
let result = "", cursor = 0;
|
|
41
|
-
do {
|
|
42
|
-
result += string.substring(cursor, index) + replace;
|
|
43
|
-
cursor = index + close.length;
|
|
44
|
-
index = string.indexOf(close, cursor);
|
|
45
|
-
} while (~index);
|
|
46
|
-
return result + string.substring(cursor);
|
|
47
|
-
};
|
|
48
|
-
var createColors = (enabled = isColorSupported) => {
|
|
49
|
-
let f = enabled ? formatter : () => String;
|
|
50
|
-
return {
|
|
51
|
-
isColorSupported: enabled,
|
|
52
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
53
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
54
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
55
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
56
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
57
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
58
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
59
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
60
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
61
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
62
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
63
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
64
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
65
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
66
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
67
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
68
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
69
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
70
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
71
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
72
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
73
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
74
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
75
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
76
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
77
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
78
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
79
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
80
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
81
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
82
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
83
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
84
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
85
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
86
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
87
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
88
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
89
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
90
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
91
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
92
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
module.exports = createColors();
|
|
96
|
-
module.exports.createColors = createColors;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// src/cli.ts
|
|
101
|
-
import { Command as Command15 } from "commander";
|
|
102
|
-
|
|
103
|
-
// src/commands/login.ts
|
|
104
|
-
import { Command } from "commander";
|
|
105
|
-
import { execFile } from "node:child_process";
|
|
106
|
-
|
|
107
35
|
// src/auth/oauth-server.ts
|
|
108
36
|
import http from "node:http";
|
|
109
37
|
function startCallbackServer(port) {
|
|
@@ -114,7 +42,9 @@ function startCallbackServer(port) {
|
|
|
114
42
|
const code = url.searchParams.get("code");
|
|
115
43
|
if (code) {
|
|
116
44
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
117
|
-
res.end(
|
|
45
|
+
res.end(
|
|
46
|
+
`<!DOCTYPE html><html lang="pt-BR"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>ToStudy</title><style>*{margin:0;padding:0;box-sizing:border-box}body{background:#0a0a0a;color:#fafafa;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh}.c{text-align:center;padding:2rem}.ck{width:80px;height:80px;border-radius:50%;border:3px solid #22d3ee;display:flex;align-items:center;justify-content:center;margin:0 auto 1.5rem;animation:s .4s ease-out}.cm{width:40px;height:40px;stroke:#22d3ee;stroke-width:3;fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50;stroke-dashoffset:50;animation:d .5s ease-out .3s forwards}h1{font-size:1.5rem;font-weight:600;margin-bottom:.5rem}.s{color:#a1a1aa;font-size:.95rem;margin-bottom:.25rem}.b{color:#22d3ee;font-size:.85rem;margin-top:2rem;letter-spacing:.05em}@keyframes s{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}@keyframes d{to{stroke-dashoffset:0}}</style></head><body><div class="c"><div class="ck"><svg class="cm" viewBox="0 0 40 40"><polyline points="12,20 18,26 28,14"/></svg></div><h1>Autenticado com sucesso!</h1><p class="s">Pode voltar ao terminal.</p><p class="s" id="m">Esta aba ser\xE1 fechada automaticamente.</p><p class="b">ToStudy</p></div><script>setTimeout(function(){window.close();document.getElementById('m').textContent='Pode fechar esta aba manualmente.'},3000)</script></body></html>`
|
|
47
|
+
);
|
|
118
48
|
server.close();
|
|
119
49
|
resolve({ code });
|
|
120
50
|
} else {
|
|
@@ -135,12 +65,18 @@ function startCallbackServer(port) {
|
|
|
135
65
|
reject(err);
|
|
136
66
|
}
|
|
137
67
|
});
|
|
138
|
-
setTimeout(() => {
|
|
68
|
+
const timeoutId = setTimeout(() => {
|
|
139
69
|
server.close();
|
|
140
70
|
reject(new Error("Login timeout \u2014 nenhuma resposta em 2 minutos"));
|
|
141
71
|
}, 12e4);
|
|
72
|
+
timeoutId.unref();
|
|
142
73
|
});
|
|
143
74
|
}
|
|
75
|
+
var init_oauth_server = __esm({
|
|
76
|
+
"src/auth/oauth-server.ts"() {
|
|
77
|
+
"use strict";
|
|
78
|
+
}
|
|
79
|
+
});
|
|
144
80
|
|
|
145
81
|
// src/auth/session.ts
|
|
146
82
|
import fs from "node:fs";
|
|
@@ -207,6 +143,11 @@ async function requireActiveCourse(configDir) {
|
|
|
207
143
|
}
|
|
208
144
|
return course;
|
|
209
145
|
}
|
|
146
|
+
var init_session = __esm({
|
|
147
|
+
"src/auth/session.ts"() {
|
|
148
|
+
"use strict";
|
|
149
|
+
}
|
|
150
|
+
});
|
|
210
151
|
|
|
211
152
|
// src/output/formatter.ts
|
|
212
153
|
function output(data, opts) {
|
|
@@ -367,64 +308,84 @@ function formatModuleStart(data) {
|
|
|
367
308
|
);
|
|
368
309
|
return lines.join("\n");
|
|
369
310
|
}
|
|
311
|
+
var init_formatter = __esm({
|
|
312
|
+
"src/output/formatter.ts"() {
|
|
313
|
+
"use strict";
|
|
314
|
+
}
|
|
315
|
+
});
|
|
370
316
|
|
|
371
317
|
// src/commands/login.ts
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
var
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
318
|
+
import { Command } from "commander";
|
|
319
|
+
import { execFile } from "node:child_process";
|
|
320
|
+
var DEFAULT_API_URL, PORT, loginCommand;
|
|
321
|
+
var init_login = __esm({
|
|
322
|
+
"src/commands/login.ts"() {
|
|
323
|
+
"use strict";
|
|
324
|
+
init_oauth_server();
|
|
325
|
+
init_session();
|
|
326
|
+
init_formatter();
|
|
327
|
+
DEFAULT_API_URL = "https://tostudy.ai";
|
|
328
|
+
PORT = 9876;
|
|
329
|
+
loginCommand = new Command("login").description("Autentica no ToStudy via browser").option("--manual", "Login manual (sem browser)").option("--api-url <url>", "API URL override", DEFAULT_API_URL).action(async (opts) => {
|
|
330
|
+
const apiUrl = opts.apiUrl;
|
|
331
|
+
if (opts.manual) {
|
|
332
|
+
console.log(`
|
|
378
333
|
Acesse este endere\xE7o no seu browser:`);
|
|
379
|
-
|
|
334
|
+
console.log(` ${apiUrl}/api/cli/auth/authorize?port=${PORT}
|
|
380
335
|
`);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
336
|
+
console.log(" Ap\xF3s autorizar, o browser ser\xE1 redirecionado e o login ser\xE1 conclu\xEDdo.");
|
|
337
|
+
console.log(" Certifique-se de rodar este comando sem --manual para o fluxo autom\xE1tico.\n");
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
console.log("\n Abrindo browser para autentica\xE7\xE3o...\n");
|
|
341
|
+
const serverPromise = startCallbackServer(PORT);
|
|
342
|
+
const authUrl = `${apiUrl}/api/cli/auth/authorize?port=${PORT}`;
|
|
343
|
+
const openCmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
344
|
+
execFile(openCmd, [authUrl], (err) => {
|
|
345
|
+
if (err) {
|
|
346
|
+
console.log(` N\xE3o foi poss\xEDvel abrir o browser automaticamente.`);
|
|
347
|
+
console.log(` Abra manualmente: ${authUrl}
|
|
393
348
|
`);
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
try {
|
|
352
|
+
const { code } = await serverPromise;
|
|
353
|
+
const res = await fetch(`${apiUrl}/api/cli/auth/exchange`, {
|
|
354
|
+
method: "POST",
|
|
355
|
+
headers: { "Content-Type": "application/json" },
|
|
356
|
+
body: JSON.stringify({ code })
|
|
357
|
+
});
|
|
358
|
+
if (!res.ok) {
|
|
359
|
+
const body = await res.json();
|
|
360
|
+
error(body.error ?? "Falha na autentica\xE7\xE3o");
|
|
361
|
+
}
|
|
362
|
+
const { token: token2, userId, userName, expiresAt } = await res.json();
|
|
363
|
+
await saveSession({ token: token2, userId, userName, expiresAt, apiUrl });
|
|
364
|
+
console.log(`
|
|
410
365
|
Logado como ${userName}
|
|
411
366
|
`);
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
367
|
+
} catch (err) {
|
|
368
|
+
const msg = err instanceof Error ? err.message : "Login falhou";
|
|
369
|
+
error(msg);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
415
372
|
}
|
|
416
373
|
});
|
|
417
374
|
|
|
418
375
|
// src/commands/logout.ts
|
|
419
376
|
import { Command as Command2 } from "commander";
|
|
420
|
-
var logoutCommand
|
|
421
|
-
|
|
422
|
-
|
|
377
|
+
var logoutCommand;
|
|
378
|
+
var init_logout = __esm({
|
|
379
|
+
"src/commands/logout.ts"() {
|
|
380
|
+
"use strict";
|
|
381
|
+
init_session();
|
|
382
|
+
logoutCommand = new Command2("logout").description("Remove token local").action(async () => {
|
|
383
|
+
await clearSession();
|
|
384
|
+
console.log("\n Deslogado com sucesso.\n");
|
|
385
|
+
});
|
|
386
|
+
}
|
|
423
387
|
});
|
|
424
388
|
|
|
425
|
-
// src/commands/setup.ts
|
|
426
|
-
import { Command as Command3 } from "commander";
|
|
427
|
-
|
|
428
389
|
// src/installer/node-detector.ts
|
|
429
390
|
import { execFileSync } from "node:child_process";
|
|
430
391
|
function detectNode() {
|
|
@@ -444,6 +405,11 @@ function detectNode() {
|
|
|
444
405
|
return { installed: false, version: null, meetsMinimum: false, path: null };
|
|
445
406
|
}
|
|
446
407
|
}
|
|
408
|
+
var init_node_detector = __esm({
|
|
409
|
+
"src/installer/node-detector.ts"() {
|
|
410
|
+
"use strict";
|
|
411
|
+
}
|
|
412
|
+
});
|
|
447
413
|
|
|
448
414
|
// src/installer/ide-detector.ts
|
|
449
415
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
@@ -524,164 +490,230 @@ function detectIDEs() {
|
|
|
524
490
|
}
|
|
525
491
|
return ides;
|
|
526
492
|
}
|
|
493
|
+
var init_ide_detector = __esm({
|
|
494
|
+
"src/installer/ide-detector.ts"() {
|
|
495
|
+
"use strict";
|
|
496
|
+
}
|
|
497
|
+
});
|
|
527
498
|
|
|
528
499
|
// src/commands/setup.ts
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
500
|
+
import { Command as Command3 } from "commander";
|
|
501
|
+
var setupCommand;
|
|
502
|
+
var init_setup = __esm({
|
|
503
|
+
"src/commands/setup.ts"() {
|
|
504
|
+
"use strict";
|
|
505
|
+
init_node_detector();
|
|
506
|
+
init_ide_detector();
|
|
507
|
+
init_session();
|
|
508
|
+
setupCommand = new Command3("setup").description("Configura ambiente para estudar").option("--quick", "Setup r\xE1pido (sem wizard)").option("--ide <ide>", "Configura IDE espec\xEDfica").action(async (_opts) => {
|
|
509
|
+
console.log("\n ToStudy Setup\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
|
|
510
|
+
console.log(" 1. Verificando Node.js...");
|
|
511
|
+
const node = detectNode();
|
|
512
|
+
if (!node.installed) {
|
|
513
|
+
console.log(" \u2717 Node.js n\xE3o encontrado");
|
|
514
|
+
console.log(" \u2192 Instale via: https://nodejs.org/ ou `nvm install --lts`\n");
|
|
515
|
+
process.exit(1);
|
|
516
|
+
}
|
|
517
|
+
if (!node.meetsMinimum) {
|
|
518
|
+
console.log(` \u2717 Node.js ${node.version} \xE9 muito antigo (m\xEDnimo: v18)`);
|
|
519
|
+
console.log(" \u2192 Atualize via: `nvm install --lts`\n");
|
|
520
|
+
process.exit(1);
|
|
521
|
+
}
|
|
522
|
+
console.log(` \u2713 Node.js ${node.version}
|
|
544
523
|
`);
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
524
|
+
console.log(" 2. Verificando autentica\xE7\xE3o...");
|
|
525
|
+
let session = null;
|
|
526
|
+
try {
|
|
527
|
+
session = await getSession();
|
|
528
|
+
} catch {
|
|
529
|
+
}
|
|
530
|
+
if (!session) {
|
|
531
|
+
console.log(" \u2717 N\xE3o autenticado");
|
|
532
|
+
console.log(" \u2192 Rode: tostudy login\n");
|
|
533
|
+
process.exit(1);
|
|
534
|
+
}
|
|
535
|
+
console.log(` \u2713 Logado como ${session.userName}
|
|
557
536
|
`);
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
537
|
+
console.log(" 3. Detectando IDEs...");
|
|
538
|
+
let ides = [];
|
|
539
|
+
try {
|
|
540
|
+
ides = detectIDEs();
|
|
541
|
+
} catch {
|
|
542
|
+
}
|
|
543
|
+
const detected = ides.filter((ide) => ide.detected);
|
|
544
|
+
if (detected.length === 0) {
|
|
545
|
+
console.log(" \u25CB Nenhum IDE detectado");
|
|
546
|
+
console.log(" \u2192 Use tostudy diretamente no terminal\n");
|
|
547
|
+
} else {
|
|
548
|
+
for (const ide of detected) {
|
|
549
|
+
console.log(` \u2713 ${ide.name} detectado`);
|
|
550
|
+
}
|
|
551
|
+
console.log("");
|
|
552
|
+
}
|
|
553
|
+
console.log(" Setup completo!");
|
|
554
|
+
console.log(" \u2192 tostudy courses (ver cursos matriculados)");
|
|
555
|
+
console.log(" \u2192 tostudy doctor (diagn\xF3stico completo)\n");
|
|
556
|
+
});
|
|
573
557
|
}
|
|
574
|
-
console.log(" Setup completo!");
|
|
575
|
-
console.log(" \u2192 tostudy courses (ver cursos matriculados)");
|
|
576
|
-
console.log(" \u2192 tostudy doctor (diagn\xF3stico completo)\n");
|
|
577
558
|
});
|
|
578
559
|
|
|
579
560
|
// src/commands/doctor.ts
|
|
580
561
|
import { Command as Command4 } from "commander";
|
|
581
|
-
var doctorCommand
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
562
|
+
var doctorCommand;
|
|
563
|
+
var init_doctor = __esm({
|
|
564
|
+
"src/commands/doctor.ts"() {
|
|
565
|
+
"use strict";
|
|
566
|
+
init_node_detector();
|
|
567
|
+
init_ide_detector();
|
|
568
|
+
init_session();
|
|
569
|
+
init_formatter();
|
|
570
|
+
doctorCommand = new Command4("doctor").description("Diagn\xF3stico do ambiente").option("--json", "Output JSON").option("--fix", "Auto-corrigir problemas (reservado para vers\xF5es futuras)").action(async (opts) => {
|
|
571
|
+
const checks = {};
|
|
572
|
+
const node = detectNode();
|
|
573
|
+
const envChecks = {
|
|
574
|
+
os: { platform: process.platform, arch: process.arch },
|
|
575
|
+
node: { ...node },
|
|
576
|
+
pnpm: null,
|
|
577
|
+
git: null
|
|
578
|
+
};
|
|
579
|
+
try {
|
|
580
|
+
const { execFileSync: execFileSync3 } = await import("node:child_process");
|
|
581
|
+
envChecks["pnpm"] = execFileSync3("pnpm", ["--version"], { encoding: "utf-8" }).trim();
|
|
582
|
+
} catch {
|
|
583
|
+
envChecks["pnpm"] = null;
|
|
584
|
+
}
|
|
585
|
+
try {
|
|
586
|
+
const { execFileSync: execFileSync3 } = await import("node:child_process");
|
|
587
|
+
envChecks["git"] = execFileSync3("git", ["--version"], { encoding: "utf-8" }).trim().replace("git version ", "");
|
|
588
|
+
} catch {
|
|
589
|
+
envChecks["git"] = null;
|
|
590
|
+
}
|
|
591
|
+
checks["environment"] = envChecks;
|
|
592
|
+
let session = null;
|
|
593
|
+
try {
|
|
594
|
+
session = await getSession();
|
|
595
|
+
} catch {
|
|
596
|
+
}
|
|
597
|
+
checks["auth"] = {
|
|
598
|
+
loggedIn: !!session,
|
|
599
|
+
userName: session?.userName ?? null,
|
|
600
|
+
expiresAt: session?.expiresAt ?? null
|
|
601
|
+
};
|
|
602
|
+
try {
|
|
603
|
+
const apiUrl = session?.apiUrl ?? "https://tostudy.ai";
|
|
604
|
+
const start = Date.now();
|
|
605
|
+
const res = await fetch(`${apiUrl}/api/health`, {
|
|
606
|
+
signal: AbortSignal.timeout(5e3)
|
|
607
|
+
});
|
|
608
|
+
checks["connectivity"] = { ok: res.ok, latencyMs: Date.now() - start };
|
|
609
|
+
} catch {
|
|
610
|
+
checks["connectivity"] = { ok: false, latencyMs: null };
|
|
611
|
+
}
|
|
612
|
+
let ides = [];
|
|
613
|
+
try {
|
|
614
|
+
ides = detectIDEs();
|
|
615
|
+
} catch {
|
|
616
|
+
}
|
|
617
|
+
checks["ides"] = ides.filter((ide) => ide.detected);
|
|
618
|
+
if (opts.json) {
|
|
619
|
+
output(checks, { json: true });
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const pnpmVersion = envChecks["pnpm"];
|
|
623
|
+
const gitVersion = envChecks["git"];
|
|
624
|
+
const connectivity = checks["connectivity"];
|
|
625
|
+
console.log("\n Ambiente");
|
|
626
|
+
console.log(
|
|
627
|
+
` ${node.installed ? "\u2713" : "\u2717"} Node ${node.version ?? "n\xE3o encontrado"}`
|
|
628
|
+
);
|
|
629
|
+
console.log(
|
|
630
|
+
` ${node.meetsMinimum ? "\u2713" : "\u2717"} Vers\xE3o ${node.meetsMinimum ? "OK (>= 18)" : "Desatualizado"}`
|
|
631
|
+
);
|
|
632
|
+
console.log(` \u2713 OS ${process.platform} (${process.arch})`);
|
|
633
|
+
console.log(` ${pnpmVersion ? "\u2713" : "\u25CB"} pnpm ${pnpmVersion ?? "n\xE3o encontrado"}`);
|
|
634
|
+
console.log(` ${gitVersion ? "\u2713" : "\u25CB"} git ${gitVersion ?? "n\xE3o encontrado"}`);
|
|
635
|
+
console.log("\n Autentica\xE7\xE3o");
|
|
636
|
+
console.log(` ${session ? "\u2713" : "\u2717"} Token ${session ? "v\xE1lido" : "n\xE3o logado"}`);
|
|
637
|
+
if (session) {
|
|
638
|
+
console.log(` \u2713 Usu\xE1rio ${session.userName}`);
|
|
639
|
+
}
|
|
640
|
+
console.log("\n Conectividade");
|
|
641
|
+
console.log(
|
|
642
|
+
` ${connectivity.ok ? "\u2713" : "\u2717"} API ${connectivity.ok ? `OK (${connectivity.latencyMs}ms)` : "indispon\xEDvel"}`
|
|
643
|
+
);
|
|
644
|
+
console.log("\n LLM Clients");
|
|
645
|
+
for (const ide of ides) {
|
|
646
|
+
console.log(
|
|
647
|
+
` ${ide.detected ? "\u2713" : "\u25CB"} ${ide.name.padEnd(14)} ${ide.detected ? "detectado" : "n\xE3o detectado"}`
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
console.log("");
|
|
620
651
|
});
|
|
621
|
-
checks["connectivity"] = { ok: res.ok, latencyMs: Date.now() - start };
|
|
622
|
-
} catch {
|
|
623
|
-
checks["connectivity"] = { ok: false, latencyMs: null };
|
|
624
|
-
}
|
|
625
|
-
let ides = [];
|
|
626
|
-
try {
|
|
627
|
-
ides = detectIDEs();
|
|
628
|
-
} catch {
|
|
629
652
|
}
|
|
630
|
-
checks["ides"] = ides.filter((ide) => ide.detected);
|
|
631
|
-
if (opts.json) {
|
|
632
|
-
output(checks, { json: true });
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
const pnpmVersion = envChecks["pnpm"];
|
|
636
|
-
const gitVersion = envChecks["git"];
|
|
637
|
-
const connectivity = checks["connectivity"];
|
|
638
|
-
console.log("\n Ambiente");
|
|
639
|
-
console.log(
|
|
640
|
-
` ${node.installed ? "\u2713" : "\u2717"} Node ${node.version ?? "n\xE3o encontrado"}`
|
|
641
|
-
);
|
|
642
|
-
console.log(
|
|
643
|
-
` ${node.meetsMinimum ? "\u2713" : "\u2717"} Vers\xE3o ${node.meetsMinimum ? "OK (>= 18)" : "Desatualizado"}`
|
|
644
|
-
);
|
|
645
|
-
console.log(` \u2713 OS ${process.platform} (${process.arch})`);
|
|
646
|
-
console.log(` ${pnpmVersion ? "\u2713" : "\u25CB"} pnpm ${pnpmVersion ?? "n\xE3o encontrado"}`);
|
|
647
|
-
console.log(` ${gitVersion ? "\u2713" : "\u25CB"} git ${gitVersion ?? "n\xE3o encontrado"}`);
|
|
648
|
-
console.log("\n Autentica\xE7\xE3o");
|
|
649
|
-
console.log(` ${session ? "\u2713" : "\u2717"} Token ${session ? "v\xE1lido" : "n\xE3o logado"}`);
|
|
650
|
-
if (session) {
|
|
651
|
-
console.log(` \u2713 Usu\xE1rio ${session.userName}`);
|
|
652
|
-
}
|
|
653
|
-
console.log("\n Conectividade");
|
|
654
|
-
console.log(
|
|
655
|
-
` ${connectivity.ok ? "\u2713" : "\u2717"} API ${connectivity.ok ? `OK (${connectivity.latencyMs}ms)` : "indispon\xEDvel"}`
|
|
656
|
-
);
|
|
657
|
-
console.log("\n LLM Clients");
|
|
658
|
-
for (const ide of ides) {
|
|
659
|
-
console.log(
|
|
660
|
-
` ${ide.detected ? "\u2713" : "\u25CB"} ${ide.name.padEnd(14)} ${ide.detected ? "detectado" : "n\xE3o detectado"}`
|
|
661
|
-
);
|
|
662
|
-
}
|
|
663
|
-
console.log("");
|
|
664
653
|
});
|
|
665
654
|
|
|
666
|
-
// src/commands/courses.ts
|
|
667
|
-
import { Command as Command5 } from "commander";
|
|
668
|
-
|
|
669
655
|
// ../../packages/logger/src/types.ts
|
|
670
|
-
var LOG_LEVELS
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
656
|
+
var LOG_LEVELS;
|
|
657
|
+
var init_types = __esm({
|
|
658
|
+
"../../packages/logger/src/types.ts"() {
|
|
659
|
+
"use strict";
|
|
660
|
+
LOG_LEVELS = {
|
|
661
|
+
trace: 0,
|
|
662
|
+
debug: 1,
|
|
663
|
+
info: 2,
|
|
664
|
+
warn: 3,
|
|
665
|
+
error: 4,
|
|
666
|
+
fatal: 5
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
});
|
|
678
670
|
|
|
679
671
|
// ../../packages/logger/src/context/async-context.ts
|
|
680
672
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
681
|
-
var asyncLocalStorage = new AsyncLocalStorage();
|
|
682
673
|
function getLogContext() {
|
|
683
674
|
return asyncLocalStorage.getStore();
|
|
684
675
|
}
|
|
676
|
+
var asyncLocalStorage;
|
|
677
|
+
var init_async_context = __esm({
|
|
678
|
+
"../../packages/logger/src/context/async-context.ts"() {
|
|
679
|
+
"use strict";
|
|
680
|
+
asyncLocalStorage = new AsyncLocalStorage();
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
// ../../packages/logger/src/context/span.shared.ts
|
|
685
|
+
var init_span_shared = __esm({
|
|
686
|
+
"../../packages/logger/src/context/span.shared.ts"() {
|
|
687
|
+
"use strict";
|
|
688
|
+
}
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
// ../../packages/logger/src/context/span.ts
|
|
692
|
+
var init_span = __esm({
|
|
693
|
+
"../../packages/logger/src/context/span.ts"() {
|
|
694
|
+
"use strict";
|
|
695
|
+
init_async_context();
|
|
696
|
+
init_span_shared();
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
// ../../packages/logger/src/context/w3c-trace.ts
|
|
701
|
+
var init_w3c_trace = __esm({
|
|
702
|
+
"../../packages/logger/src/context/w3c-trace.ts"() {
|
|
703
|
+
"use strict";
|
|
704
|
+
init_async_context();
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
// ../../packages/logger/src/context/index.ts
|
|
709
|
+
var init_context = __esm({
|
|
710
|
+
"../../packages/logger/src/context/index.ts"() {
|
|
711
|
+
"use strict";
|
|
712
|
+
init_async_context();
|
|
713
|
+
init_span();
|
|
714
|
+
init_w3c_trace();
|
|
715
|
+
}
|
|
716
|
+
});
|
|
685
717
|
|
|
686
718
|
// ../../packages/logger/src/formatters/json.ts
|
|
687
719
|
function formatJson(entry) {
|
|
@@ -700,18 +732,85 @@ function formatJson(entry) {
|
|
|
700
732
|
}
|
|
701
733
|
return JSON.stringify(output2);
|
|
702
734
|
}
|
|
735
|
+
var init_json = __esm({
|
|
736
|
+
"../../packages/logger/src/formatters/json.ts"() {
|
|
737
|
+
"use strict";
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
// ../../node_modules/picocolors/picocolors.js
|
|
742
|
+
var require_picocolors = __commonJS({
|
|
743
|
+
"../../node_modules/picocolors/picocolors.js"(exports, module) {
|
|
744
|
+
var p = process || {};
|
|
745
|
+
var argv = p.argv || [];
|
|
746
|
+
var env = p.env || {};
|
|
747
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
748
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
749
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
750
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
751
|
+
};
|
|
752
|
+
var replaceClose = (string, close, replace, index) => {
|
|
753
|
+
let result = "", cursor = 0;
|
|
754
|
+
do {
|
|
755
|
+
result += string.substring(cursor, index) + replace;
|
|
756
|
+
cursor = index + close.length;
|
|
757
|
+
index = string.indexOf(close, cursor);
|
|
758
|
+
} while (~index);
|
|
759
|
+
return result + string.substring(cursor);
|
|
760
|
+
};
|
|
761
|
+
var createColors = (enabled = isColorSupported) => {
|
|
762
|
+
let f = enabled ? formatter : () => String;
|
|
763
|
+
return {
|
|
764
|
+
isColorSupported: enabled,
|
|
765
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
766
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
767
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
768
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
769
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
770
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
771
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
772
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
773
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
774
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
775
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
776
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
777
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
778
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
779
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
780
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
781
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
782
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
783
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
784
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
785
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
786
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
787
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
788
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
789
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
790
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
791
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
792
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
793
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
794
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
795
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
796
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
797
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
798
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
799
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
800
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
801
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
802
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
803
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
804
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
805
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
806
|
+
};
|
|
807
|
+
};
|
|
808
|
+
module.exports = createColors();
|
|
809
|
+
module.exports.createColors = createColors;
|
|
810
|
+
}
|
|
811
|
+
});
|
|
703
812
|
|
|
704
813
|
// ../../packages/logger/src/formatters/pretty.ts
|
|
705
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
706
|
-
var LEVEL_COLORS = {
|
|
707
|
-
trace: import_picocolors.default.gray,
|
|
708
|
-
debug: import_picocolors.default.cyan,
|
|
709
|
-
info: import_picocolors.default.green,
|
|
710
|
-
warn: import_picocolors.default.yellow,
|
|
711
|
-
error: import_picocolors.default.red,
|
|
712
|
-
fatal: (s) => import_picocolors.default.bgRed(import_picocolors.default.white(s))
|
|
713
|
-
};
|
|
714
|
-
var LEVEL_WIDTH = 5;
|
|
715
814
|
function formatTime(timestamp) {
|
|
716
815
|
const date = new Date(timestamp);
|
|
717
816
|
const hours = String(date.getUTCHours()).padStart(2, "0");
|
|
@@ -765,56 +864,24 @@ function formatPretty(entry) {
|
|
|
765
864
|
}
|
|
766
865
|
return output2;
|
|
767
866
|
}
|
|
867
|
+
var import_picocolors, LEVEL_COLORS, LEVEL_WIDTH;
|
|
868
|
+
var init_pretty = __esm({
|
|
869
|
+
"../../packages/logger/src/formatters/pretty.ts"() {
|
|
870
|
+
"use strict";
|
|
871
|
+
import_picocolors = __toESM(require_picocolors(), 1);
|
|
872
|
+
LEVEL_COLORS = {
|
|
873
|
+
trace: import_picocolors.default.gray,
|
|
874
|
+
debug: import_picocolors.default.cyan,
|
|
875
|
+
info: import_picocolors.default.green,
|
|
876
|
+
warn: import_picocolors.default.yellow,
|
|
877
|
+
error: import_picocolors.default.red,
|
|
878
|
+
fatal: (s) => import_picocolors.default.bgRed(import_picocolors.default.white(s))
|
|
879
|
+
};
|
|
880
|
+
LEVEL_WIDTH = 5;
|
|
881
|
+
}
|
|
882
|
+
});
|
|
768
883
|
|
|
769
884
|
// ../../packages/logger/src/sanitize.ts
|
|
770
|
-
var SENSITIVE_FIELDS = [
|
|
771
|
-
// Authentication
|
|
772
|
-
"password",
|
|
773
|
-
"senha",
|
|
774
|
-
"pwd",
|
|
775
|
-
"pass",
|
|
776
|
-
"token",
|
|
777
|
-
"accessToken",
|
|
778
|
-
"access_token",
|
|
779
|
-
"refreshToken",
|
|
780
|
-
"refresh_token",
|
|
781
|
-
"apiKey",
|
|
782
|
-
"api_key",
|
|
783
|
-
"apikey",
|
|
784
|
-
"secret",
|
|
785
|
-
"secretKey",
|
|
786
|
-
"secret_key",
|
|
787
|
-
"authorization",
|
|
788
|
-
"auth",
|
|
789
|
-
"bearer",
|
|
790
|
-
// Payment
|
|
791
|
-
"creditCard",
|
|
792
|
-
"credit_card",
|
|
793
|
-
"cardNumber",
|
|
794
|
-
"card_number",
|
|
795
|
-
"cvv",
|
|
796
|
-
"cvc",
|
|
797
|
-
"securityCode",
|
|
798
|
-
"security_code",
|
|
799
|
-
"accountNumber",
|
|
800
|
-
"account_number",
|
|
801
|
-
// Personal identification
|
|
802
|
-
"cpf",
|
|
803
|
-
"rg",
|
|
804
|
-
"ssn",
|
|
805
|
-
"cnh",
|
|
806
|
-
"passport",
|
|
807
|
-
"email",
|
|
808
|
-
"phone",
|
|
809
|
-
// Crypto
|
|
810
|
-
"privateKey",
|
|
811
|
-
"private_key",
|
|
812
|
-
"privatekey",
|
|
813
|
-
"mnemonic",
|
|
814
|
-
"seed",
|
|
815
|
-
"seedPhrase",
|
|
816
|
-
"seed_phrase"
|
|
817
|
-
];
|
|
818
885
|
function email(value) {
|
|
819
886
|
if (!value || typeof value !== "string") return "[INVALID_EMAIL]";
|
|
820
887
|
const atIndex = value.indexOf("@");
|
|
@@ -928,17 +995,71 @@ function headers(hdrs) {
|
|
|
928
995
|
}
|
|
929
996
|
return sanitized;
|
|
930
997
|
}
|
|
931
|
-
var sanitize
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
998
|
+
var SENSITIVE_FIELDS, sanitize;
|
|
999
|
+
var init_sanitize = __esm({
|
|
1000
|
+
"../../packages/logger/src/sanitize.ts"() {
|
|
1001
|
+
"use strict";
|
|
1002
|
+
SENSITIVE_FIELDS = [
|
|
1003
|
+
// Authentication
|
|
1004
|
+
"password",
|
|
1005
|
+
"senha",
|
|
1006
|
+
"pwd",
|
|
1007
|
+
"pass",
|
|
1008
|
+
"token",
|
|
1009
|
+
"accessToken",
|
|
1010
|
+
"access_token",
|
|
1011
|
+
"refreshToken",
|
|
1012
|
+
"refresh_token",
|
|
1013
|
+
"apiKey",
|
|
1014
|
+
"api_key",
|
|
1015
|
+
"apikey",
|
|
1016
|
+
"secret",
|
|
1017
|
+
"secretKey",
|
|
1018
|
+
"secret_key",
|
|
1019
|
+
"authorization",
|
|
1020
|
+
"auth",
|
|
1021
|
+
"bearer",
|
|
1022
|
+
// Payment
|
|
1023
|
+
"creditCard",
|
|
1024
|
+
"credit_card",
|
|
1025
|
+
"cardNumber",
|
|
1026
|
+
"card_number",
|
|
1027
|
+
"cvv",
|
|
1028
|
+
"cvc",
|
|
1029
|
+
"securityCode",
|
|
1030
|
+
"security_code",
|
|
1031
|
+
"accountNumber",
|
|
1032
|
+
"account_number",
|
|
1033
|
+
// Personal identification
|
|
1034
|
+
"cpf",
|
|
1035
|
+
"rg",
|
|
1036
|
+
"ssn",
|
|
1037
|
+
"cnh",
|
|
1038
|
+
"passport",
|
|
1039
|
+
"email",
|
|
1040
|
+
"phone",
|
|
1041
|
+
// Crypto
|
|
1042
|
+
"privateKey",
|
|
1043
|
+
"private_key",
|
|
1044
|
+
"privatekey",
|
|
1045
|
+
"mnemonic",
|
|
1046
|
+
"seed",
|
|
1047
|
+
"seedPhrase",
|
|
1048
|
+
"seed_phrase"
|
|
1049
|
+
];
|
|
1050
|
+
sanitize = {
|
|
1051
|
+
email,
|
|
1052
|
+
phone,
|
|
1053
|
+
cpf,
|
|
1054
|
+
creditCard,
|
|
1055
|
+
ip,
|
|
1056
|
+
token,
|
|
1057
|
+
object,
|
|
1058
|
+
headers,
|
|
1059
|
+
isSensitiveKey
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
942
1063
|
|
|
943
1064
|
// ../../packages/logger/src/logger.base.ts
|
|
944
1065
|
function extractErrorInfo(error2, includeStack) {
|
|
@@ -957,230 +1078,252 @@ function extractErrorInfo(error2, includeStack) {
|
|
|
957
1078
|
}
|
|
958
1079
|
return info;
|
|
959
1080
|
}
|
|
960
|
-
var BaseLogger
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1081
|
+
var BaseLogger;
|
|
1082
|
+
var init_logger_base = __esm({
|
|
1083
|
+
"../../packages/logger/src/logger.base.ts"() {
|
|
1084
|
+
"use strict";
|
|
1085
|
+
init_types();
|
|
1086
|
+
init_json();
|
|
1087
|
+
init_pretty();
|
|
1088
|
+
init_sanitize();
|
|
1089
|
+
BaseLogger = class {
|
|
1090
|
+
level;
|
|
1091
|
+
format;
|
|
1092
|
+
module;
|
|
1093
|
+
service;
|
|
1094
|
+
environment;
|
|
1095
|
+
additionalContext;
|
|
1096
|
+
transports;
|
|
1097
|
+
shouldSanitize;
|
|
1098
|
+
sensitiveFields;
|
|
1099
|
+
includeCaller;
|
|
1100
|
+
constructor(options, defaults) {
|
|
1101
|
+
this.level = options.level ?? defaults.level;
|
|
1102
|
+
this.format = options.format ?? defaults.format;
|
|
1103
|
+
this.module = options.module;
|
|
1104
|
+
this.service = options.service ?? defaults.service;
|
|
1105
|
+
this.environment = options.environment ?? defaults.env;
|
|
1106
|
+
this.additionalContext = {};
|
|
1107
|
+
this.transports = [];
|
|
1108
|
+
this.shouldSanitize = options.sanitize ?? true;
|
|
1109
|
+
this.sensitiveFields = options.sensitiveFields;
|
|
1110
|
+
this.includeCaller = options.includeCaller ?? "errors";
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Get caller information for error logging (Node.js only).
|
|
1114
|
+
*/
|
|
1115
|
+
getCaller() {
|
|
1116
|
+
return void 0;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Flush any buffered logs (e.g., file transport).
|
|
1120
|
+
*/
|
|
1121
|
+
flush() {
|
|
1122
|
+
}
|
|
1123
|
+
shouldLog(level) {
|
|
1124
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
1125
|
+
}
|
|
1126
|
+
buildEntry(level, message, data, error2) {
|
|
1127
|
+
const asyncContext = this.getLogContext() ?? {};
|
|
1128
|
+
const context = {
|
|
1129
|
+
...asyncContext,
|
|
1130
|
+
...this.additionalContext
|
|
1131
|
+
};
|
|
1132
|
+
if (this.module) {
|
|
1133
|
+
context.module = this.module;
|
|
1134
|
+
}
|
|
1135
|
+
const shouldIncludeCaller = this.includeCaller === true || this.includeCaller === "errors" && (level === "error" || level === "fatal");
|
|
1136
|
+
if (shouldIncludeCaller) {
|
|
1137
|
+
const caller = this.getCaller();
|
|
1138
|
+
if (caller) context.caller = caller;
|
|
1139
|
+
}
|
|
1140
|
+
return {
|
|
1141
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1142
|
+
level,
|
|
1143
|
+
message,
|
|
1144
|
+
service: this.service,
|
|
1145
|
+
environment: this.environment,
|
|
1146
|
+
context,
|
|
1147
|
+
data,
|
|
1148
|
+
error: error2
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Normalizes any data type to Record<string, unknown> for structured logging.
|
|
1153
|
+
*/
|
|
1154
|
+
normalizeData(data) {
|
|
1155
|
+
if (data === null || data === void 0) {
|
|
1156
|
+
return void 0;
|
|
1157
|
+
}
|
|
1158
|
+
if (data instanceof Error) {
|
|
1159
|
+
return {
|
|
1160
|
+
error: data.message,
|
|
1161
|
+
errorName: data.name,
|
|
1162
|
+
stack: data.stack
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
if (typeof data === "string" || typeof data === "number" || typeof data === "boolean") {
|
|
1166
|
+
return { value: data };
|
|
1167
|
+
}
|
|
1168
|
+
if (Array.isArray(data)) {
|
|
1169
|
+
return { items: data };
|
|
1170
|
+
}
|
|
1171
|
+
if (typeof data === "object") {
|
|
1172
|
+
const obj = data;
|
|
1173
|
+
return this.shouldSanitize ? sanitize.object(obj, this.sensitiveFields) : obj;
|
|
1174
|
+
}
|
|
1175
|
+
return { value: String(data) };
|
|
1176
|
+
}
|
|
1177
|
+
log(level, message, data, errorObj) {
|
|
1178
|
+
if (!this.shouldLog(level)) return;
|
|
1179
|
+
const normalizedData = this.normalizeData(data);
|
|
1180
|
+
const errorInfo = errorObj ? extractErrorInfo(errorObj, !this.isProd()) : void 0;
|
|
1181
|
+
const entry = this.buildEntry(level, message, normalizedData, errorInfo);
|
|
1182
|
+
const formatted = this.format === "json" ? formatJson(entry) : formatPretty(entry);
|
|
1183
|
+
for (const transport of this.transports) {
|
|
1184
|
+
transport.log(entry, formatted);
|
|
1185
|
+
}
|
|
1186
|
+
this.flush();
|
|
1187
|
+
}
|
|
1188
|
+
trace(message, ...args) {
|
|
1189
|
+
this.log("trace", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1190
|
+
}
|
|
1191
|
+
debug(message, ...args) {
|
|
1192
|
+
this.log("debug", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1193
|
+
}
|
|
1194
|
+
info(message, ...args) {
|
|
1195
|
+
this.log("info", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1196
|
+
}
|
|
1197
|
+
warn(message, ...args) {
|
|
1198
|
+
this.log("warn", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1199
|
+
}
|
|
1200
|
+
error(message, errorOrData, data) {
|
|
1201
|
+
if (errorOrData instanceof Error) {
|
|
1202
|
+
this.log("error", message, data, errorOrData);
|
|
1203
|
+
} else {
|
|
1204
|
+
this.log("error", message, errorOrData);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Log a fatal error (system-critical).
|
|
1209
|
+
*/
|
|
1210
|
+
fatal(message, errorOrData, data) {
|
|
1211
|
+
if (errorOrData instanceof Error) {
|
|
1212
|
+
this.log("fatal", message, data, errorOrData);
|
|
1213
|
+
} else {
|
|
1214
|
+
this.log("fatal", message, errorOrData);
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Get the current trace ID from context.
|
|
1219
|
+
*/
|
|
1220
|
+
getTraceId() {
|
|
1221
|
+
const ctx = this.getLogContext();
|
|
1222
|
+
return ctx?.traceId ?? this.additionalContext.traceId;
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Get the current span ID from context.
|
|
1226
|
+
*/
|
|
1227
|
+
getSpanId() {
|
|
1228
|
+
const ctx = this.getLogContext();
|
|
1229
|
+
return ctx?.spanId ?? this.additionalContext.spanId;
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* Time an async operation and log its duration.
|
|
1233
|
+
*/
|
|
1234
|
+
async time(operation, fn, data) {
|
|
1235
|
+
const start = Date.now();
|
|
1236
|
+
try {
|
|
1237
|
+
const result = await fn();
|
|
1238
|
+
const duration = Date.now() - start;
|
|
1239
|
+
this.info(`${operation} completed`, { ...data, duration, operation });
|
|
1240
|
+
return result;
|
|
1241
|
+
} catch (error2) {
|
|
1242
|
+
const duration = Date.now() - start;
|
|
1243
|
+
this.error(`${operation} failed`, error2, { ...data, duration, operation });
|
|
1244
|
+
throw error2;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Time a sync operation and log its duration.
|
|
1249
|
+
*/
|
|
1250
|
+
timeSync(operation, fn, data) {
|
|
1251
|
+
const start = Date.now();
|
|
1252
|
+
try {
|
|
1253
|
+
const result = fn();
|
|
1254
|
+
const duration = Date.now() - start;
|
|
1255
|
+
this.info(`${operation} completed`, { ...data, duration, operation });
|
|
1256
|
+
return result;
|
|
1257
|
+
} catch (error2) {
|
|
1258
|
+
const duration = Date.now() - start;
|
|
1259
|
+
this.error(`${operation} failed`, error2, { ...data, duration, operation });
|
|
1260
|
+
throw error2;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1020
1263
|
};
|
|
1021
1264
|
}
|
|
1022
|
-
|
|
1023
|
-
* Normalizes any data type to Record<string, unknown> for structured logging.
|
|
1024
|
-
*/
|
|
1025
|
-
normalizeData(data) {
|
|
1026
|
-
if (data === null || data === void 0) {
|
|
1027
|
-
return void 0;
|
|
1028
|
-
}
|
|
1029
|
-
if (data instanceof Error) {
|
|
1030
|
-
return {
|
|
1031
|
-
error: data.message,
|
|
1032
|
-
errorName: data.name,
|
|
1033
|
-
stack: data.stack
|
|
1034
|
-
};
|
|
1035
|
-
}
|
|
1036
|
-
if (typeof data === "string" || typeof data === "number" || typeof data === "boolean") {
|
|
1037
|
-
return { value: data };
|
|
1038
|
-
}
|
|
1039
|
-
if (Array.isArray(data)) {
|
|
1040
|
-
return { items: data };
|
|
1041
|
-
}
|
|
1042
|
-
if (typeof data === "object") {
|
|
1043
|
-
const obj = data;
|
|
1044
|
-
return this.shouldSanitize ? sanitize.object(obj, this.sensitiveFields) : obj;
|
|
1045
|
-
}
|
|
1046
|
-
return { value: String(data) };
|
|
1047
|
-
}
|
|
1048
|
-
log(level, message, data, errorObj) {
|
|
1049
|
-
if (!this.shouldLog(level)) return;
|
|
1050
|
-
const normalizedData = this.normalizeData(data);
|
|
1051
|
-
const errorInfo = errorObj ? extractErrorInfo(errorObj, !this.isProd()) : void 0;
|
|
1052
|
-
const entry = this.buildEntry(level, message, normalizedData, errorInfo);
|
|
1053
|
-
const formatted = this.format === "json" ? formatJson(entry) : formatPretty(entry);
|
|
1054
|
-
for (const transport of this.transports) {
|
|
1055
|
-
transport.log(entry, formatted);
|
|
1056
|
-
}
|
|
1057
|
-
this.flush();
|
|
1058
|
-
}
|
|
1059
|
-
trace(message, ...args) {
|
|
1060
|
-
this.log("trace", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1061
|
-
}
|
|
1062
|
-
debug(message, ...args) {
|
|
1063
|
-
this.log("debug", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1064
|
-
}
|
|
1065
|
-
info(message, ...args) {
|
|
1066
|
-
this.log("info", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1067
|
-
}
|
|
1068
|
-
warn(message, ...args) {
|
|
1069
|
-
this.log("warn", message, args.length === 1 ? args[0] : args.length > 1 ? args : void 0);
|
|
1070
|
-
}
|
|
1071
|
-
error(message, errorOrData, data) {
|
|
1072
|
-
if (errorOrData instanceof Error) {
|
|
1073
|
-
this.log("error", message, data, errorOrData);
|
|
1074
|
-
} else {
|
|
1075
|
-
this.log("error", message, errorOrData);
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
/**
|
|
1079
|
-
* Log a fatal error (system-critical).
|
|
1080
|
-
*/
|
|
1081
|
-
fatal(message, errorOrData, data) {
|
|
1082
|
-
if (errorOrData instanceof Error) {
|
|
1083
|
-
this.log("fatal", message, data, errorOrData);
|
|
1084
|
-
} else {
|
|
1085
|
-
this.log("fatal", message, errorOrData);
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
/**
|
|
1089
|
-
* Get the current trace ID from context.
|
|
1090
|
-
*/
|
|
1091
|
-
getTraceId() {
|
|
1092
|
-
const ctx = this.getLogContext();
|
|
1093
|
-
return ctx?.traceId ?? this.additionalContext.traceId;
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Get the current span ID from context.
|
|
1097
|
-
*/
|
|
1098
|
-
getSpanId() {
|
|
1099
|
-
const ctx = this.getLogContext();
|
|
1100
|
-
return ctx?.spanId ?? this.additionalContext.spanId;
|
|
1101
|
-
}
|
|
1102
|
-
/**
|
|
1103
|
-
* Time an async operation and log its duration.
|
|
1104
|
-
*/
|
|
1105
|
-
async time(operation, fn, data) {
|
|
1106
|
-
const start = Date.now();
|
|
1107
|
-
try {
|
|
1108
|
-
const result = await fn();
|
|
1109
|
-
const duration = Date.now() - start;
|
|
1110
|
-
this.info(`${operation} completed`, { ...data, duration, operation });
|
|
1111
|
-
return result;
|
|
1112
|
-
} catch (error2) {
|
|
1113
|
-
const duration = Date.now() - start;
|
|
1114
|
-
this.error(`${operation} failed`, error2, { ...data, duration, operation });
|
|
1115
|
-
throw error2;
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
/**
|
|
1119
|
-
* Time a sync operation and log its duration.
|
|
1120
|
-
*/
|
|
1121
|
-
timeSync(operation, fn, data) {
|
|
1122
|
-
const start = Date.now();
|
|
1123
|
-
try {
|
|
1124
|
-
const result = fn();
|
|
1125
|
-
const duration = Date.now() - start;
|
|
1126
|
-
this.info(`${operation} completed`, { ...data, duration, operation });
|
|
1127
|
-
return result;
|
|
1128
|
-
} catch (error2) {
|
|
1129
|
-
const duration = Date.now() - start;
|
|
1130
|
-
this.error(`${operation} failed`, error2, { ...data, duration, operation });
|
|
1131
|
-
throw error2;
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
};
|
|
1265
|
+
});
|
|
1135
1266
|
|
|
1136
1267
|
// ../../packages/logger/src/transports/console.ts
|
|
1137
|
-
var ConsoleTransport
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1268
|
+
var ConsoleTransport;
|
|
1269
|
+
var init_console = __esm({
|
|
1270
|
+
"../../packages/logger/src/transports/console.ts"() {
|
|
1271
|
+
"use strict";
|
|
1272
|
+
ConsoleTransport = class {
|
|
1273
|
+
log(entry, formatted) {
|
|
1274
|
+
if (entry.level === "error" || entry.level === "fatal") {
|
|
1275
|
+
process.stderr.write(formatted + "\n");
|
|
1276
|
+
} else {
|
|
1277
|
+
process.stdout.write(formatted + "\n");
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1144
1281
|
}
|
|
1145
|
-
};
|
|
1282
|
+
});
|
|
1146
1283
|
|
|
1147
1284
|
// ../../packages/logger/src/transports/file.ts
|
|
1148
1285
|
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
1149
1286
|
import { join } from "node:path";
|
|
1150
|
-
var FileTransport
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1287
|
+
var FileTransport;
|
|
1288
|
+
var init_file = __esm({
|
|
1289
|
+
"../../packages/logger/src/transports/file.ts"() {
|
|
1290
|
+
"use strict";
|
|
1291
|
+
FileTransport = class {
|
|
1292
|
+
dir;
|
|
1293
|
+
initialized = false;
|
|
1294
|
+
buffer = [];
|
|
1295
|
+
constructor(options) {
|
|
1296
|
+
this.dir = options.dir;
|
|
1297
|
+
}
|
|
1298
|
+
init() {
|
|
1299
|
+
if (this.initialized) return;
|
|
1300
|
+
if (!existsSync(this.dir)) {
|
|
1301
|
+
mkdirSync(this.dir, { recursive: true });
|
|
1302
|
+
}
|
|
1303
|
+
const gitignore = join(this.dir, ".gitignore");
|
|
1304
|
+
if (!existsSync(gitignore)) {
|
|
1305
|
+
writeFileSync(gitignore, "*.log\n");
|
|
1306
|
+
}
|
|
1307
|
+
this.initialized = true;
|
|
1308
|
+
}
|
|
1309
|
+
log(entry, formatted) {
|
|
1310
|
+
this.init();
|
|
1311
|
+
const line = formatted + "\n";
|
|
1312
|
+
this.buffer.push({ file: "combined.log", content: line });
|
|
1313
|
+
if (entry.level === "error") {
|
|
1314
|
+
this.buffer.push({ file: "error.log", content: line });
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
flush() {
|
|
1318
|
+
for (const { file, content } of this.buffer) {
|
|
1319
|
+
const filepath = join(this.dir, file);
|
|
1320
|
+
appendFileSync(filepath, content);
|
|
1321
|
+
}
|
|
1322
|
+
this.buffer = [];
|
|
1323
|
+
}
|
|
1324
|
+
};
|
|
1182
1325
|
}
|
|
1183
|
-
};
|
|
1326
|
+
});
|
|
1184
1327
|
|
|
1185
1328
|
// ../../packages/logger/src/logger.ts
|
|
1186
1329
|
function detectEnvironment() {
|
|
@@ -1223,90 +1366,149 @@ function getCaller() {
|
|
|
1223
1366
|
}
|
|
1224
1367
|
return void 0;
|
|
1225
1368
|
}
|
|
1226
|
-
var Logger
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1369
|
+
var Logger;
|
|
1370
|
+
var init_logger = __esm({
|
|
1371
|
+
"../../packages/logger/src/logger.ts"() {
|
|
1372
|
+
"use strict";
|
|
1373
|
+
init_types();
|
|
1374
|
+
init_context();
|
|
1375
|
+
init_logger_base();
|
|
1376
|
+
init_console();
|
|
1377
|
+
init_file();
|
|
1378
|
+
Logger = class _Logger extends BaseLogger {
|
|
1379
|
+
fileTransport;
|
|
1380
|
+
_isProd;
|
|
1381
|
+
constructor(options = {}) {
|
|
1382
|
+
const { isProd, env } = detectEnvironment();
|
|
1383
|
+
super(options, {
|
|
1384
|
+
level: getDefaultLevel(),
|
|
1385
|
+
format: getDefaultFormat(),
|
|
1386
|
+
service: getDefaultService(),
|
|
1387
|
+
env
|
|
1388
|
+
});
|
|
1389
|
+
this._isProd = isProd;
|
|
1390
|
+
this.transports = [new ConsoleTransport()];
|
|
1391
|
+
if (!isProd && !process.env.VERCEL && !process.env.RAILWAY_ENVIRONMENT) {
|
|
1392
|
+
this.fileTransport = new FileTransport({ dir: "logs" });
|
|
1393
|
+
this.transports.push(this.fileTransport);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
getLogContext() {
|
|
1397
|
+
return getLogContext();
|
|
1398
|
+
}
|
|
1399
|
+
isProd() {
|
|
1400
|
+
return this._isProd;
|
|
1401
|
+
}
|
|
1402
|
+
getCaller() {
|
|
1403
|
+
return getCaller();
|
|
1404
|
+
}
|
|
1405
|
+
flush() {
|
|
1406
|
+
this.fileTransport?.flush();
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* Create a child logger with additional context.
|
|
1410
|
+
* Child shares transports with parent.
|
|
1411
|
+
*/
|
|
1412
|
+
child(context) {
|
|
1413
|
+
const child = new _Logger({
|
|
1414
|
+
level: this.level,
|
|
1415
|
+
format: this.format,
|
|
1416
|
+
module: this.module,
|
|
1417
|
+
service: this.service,
|
|
1418
|
+
environment: this.environment,
|
|
1419
|
+
sanitize: this.shouldSanitize,
|
|
1420
|
+
sensitiveFields: this.sensitiveFields,
|
|
1421
|
+
includeCaller: this.includeCaller
|
|
1422
|
+
});
|
|
1423
|
+
child.additionalContext = { ...this.additionalContext, ...context };
|
|
1424
|
+
child.transports = this.transports;
|
|
1425
|
+
child.fileTransport = this.fileTransport;
|
|
1426
|
+
return child;
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1243
1429
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
}
|
|
1253
|
-
flush() {
|
|
1254
|
-
this.fileTransport?.flush();
|
|
1255
|
-
}
|
|
1256
|
-
/**
|
|
1257
|
-
* Create a child logger with additional context.
|
|
1258
|
-
* Child shares transports with parent.
|
|
1259
|
-
*/
|
|
1260
|
-
child(context) {
|
|
1261
|
-
const child = new _Logger({
|
|
1262
|
-
level: this.level,
|
|
1263
|
-
format: this.format,
|
|
1264
|
-
module: this.module,
|
|
1265
|
-
service: this.service,
|
|
1266
|
-
environment: this.environment,
|
|
1267
|
-
sanitize: this.shouldSanitize,
|
|
1268
|
-
sensitiveFields: this.sensitiveFields,
|
|
1269
|
-
includeCaller: this.includeCaller
|
|
1270
|
-
});
|
|
1271
|
-
child.additionalContext = { ...this.additionalContext, ...context };
|
|
1272
|
-
child.transports = this.transports;
|
|
1273
|
-
child.fileTransport = this.fileTransport;
|
|
1274
|
-
return child;
|
|
1430
|
+
});
|
|
1431
|
+
|
|
1432
|
+
// ../../packages/logger/src/middleware/trpc.ts
|
|
1433
|
+
var init_trpc = __esm({
|
|
1434
|
+
"../../packages/logger/src/middleware/trpc.ts"() {
|
|
1435
|
+
"use strict";
|
|
1436
|
+
init_context();
|
|
1437
|
+
init_logger();
|
|
1275
1438
|
}
|
|
1276
|
-
};
|
|
1439
|
+
});
|
|
1440
|
+
|
|
1441
|
+
// ../../packages/logger/src/middleware/index.ts
|
|
1442
|
+
var init_middleware = __esm({
|
|
1443
|
+
"../../packages/logger/src/middleware/index.ts"() {
|
|
1444
|
+
"use strict";
|
|
1445
|
+
init_trpc();
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1277
1448
|
|
|
1278
1449
|
// ../../packages/logger/src/index.ts
|
|
1279
|
-
var logger = new Logger();
|
|
1280
1450
|
function createLogger(module, options) {
|
|
1281
1451
|
return new Logger({ ...options, module });
|
|
1282
1452
|
}
|
|
1453
|
+
var logger;
|
|
1454
|
+
var init_src = __esm({
|
|
1455
|
+
"../../packages/logger/src/index.ts"() {
|
|
1456
|
+
"use strict";
|
|
1457
|
+
init_logger();
|
|
1458
|
+
init_types();
|
|
1459
|
+
init_context();
|
|
1460
|
+
init_context();
|
|
1461
|
+
init_context();
|
|
1462
|
+
init_sanitize();
|
|
1463
|
+
init_middleware();
|
|
1464
|
+
logger = new Logger();
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1283
1467
|
|
|
1284
1468
|
// ../../packages/tostudy-core/src/courses/list-courses.ts
|
|
1285
1469
|
async function listCourses(input, deps) {
|
|
1286
1470
|
deps.logger.info("tostudy-core: listCourses", { userId: input.userId });
|
|
1287
1471
|
return deps.data.courses.list(input.userId);
|
|
1288
1472
|
}
|
|
1473
|
+
var init_list_courses = __esm({
|
|
1474
|
+
"../../packages/tostudy-core/src/courses/list-courses.ts"() {
|
|
1475
|
+
"use strict";
|
|
1476
|
+
}
|
|
1477
|
+
});
|
|
1289
1478
|
|
|
1290
1479
|
// ../../packages/tostudy-core/src/courses/select-course.ts
|
|
1291
1480
|
async function selectCourse(input, deps) {
|
|
1292
1481
|
deps.logger.info("tostudy-core: selectCourse", input);
|
|
1293
1482
|
return deps.data.courses.select(input.userId, input.courseId);
|
|
1294
1483
|
}
|
|
1484
|
+
var init_select_course = __esm({
|
|
1485
|
+
"../../packages/tostudy-core/src/courses/select-course.ts"() {
|
|
1486
|
+
"use strict";
|
|
1487
|
+
}
|
|
1488
|
+
});
|
|
1295
1489
|
|
|
1296
1490
|
// ../../packages/tostudy-core/src/courses/get-progress.ts
|
|
1297
1491
|
async function getProgress(input, deps) {
|
|
1298
1492
|
deps.logger.info("tostudy-core: getProgress", input);
|
|
1299
1493
|
return deps.data.courses.getProgress(input.enrollmentId);
|
|
1300
1494
|
}
|
|
1495
|
+
var init_get_progress = __esm({
|
|
1496
|
+
"../../packages/tostudy-core/src/courses/get-progress.ts"() {
|
|
1497
|
+
"use strict";
|
|
1498
|
+
}
|
|
1499
|
+
});
|
|
1301
1500
|
|
|
1302
|
-
// ../../packages/tostudy-core/src/
|
|
1303
|
-
var
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1501
|
+
// ../../packages/tostudy-core/src/courses/index.ts
|
|
1502
|
+
var init_courses = __esm({
|
|
1503
|
+
"../../packages/tostudy-core/src/courses/index.ts"() {
|
|
1504
|
+
"use strict";
|
|
1505
|
+
init_list_courses();
|
|
1506
|
+
init_select_course();
|
|
1507
|
+
init_get_progress();
|
|
1308
1508
|
}
|
|
1309
|
-
};
|
|
1509
|
+
});
|
|
1510
|
+
|
|
1511
|
+
// ../../packages/tostudy-core/src/adapters/http.ts
|
|
1310
1512
|
async function apiFetch(url, token2, init) {
|
|
1311
1513
|
const response = await fetch(url, {
|
|
1312
1514
|
...init,
|
|
@@ -1382,200 +1584,314 @@ function createHttpProvider(apiUrl, token2) {
|
|
|
1382
1584
|
}
|
|
1383
1585
|
};
|
|
1384
1586
|
}
|
|
1587
|
+
var CliApiError;
|
|
1588
|
+
var init_http = __esm({
|
|
1589
|
+
"../../packages/tostudy-core/src/adapters/http.ts"() {
|
|
1590
|
+
"use strict";
|
|
1591
|
+
CliApiError = class extends Error {
|
|
1592
|
+
constructor(message, status) {
|
|
1593
|
+
super(message);
|
|
1594
|
+
this.status = status;
|
|
1595
|
+
this.name = "CliApiError";
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
});
|
|
1385
1600
|
|
|
1386
1601
|
// src/commands/courses.ts
|
|
1387
|
-
|
|
1388
|
-
var
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1602
|
+
import { Command as Command5 } from "commander";
|
|
1603
|
+
var logger2, coursesCommand;
|
|
1604
|
+
var init_courses2 = __esm({
|
|
1605
|
+
"src/commands/courses.ts"() {
|
|
1606
|
+
"use strict";
|
|
1607
|
+
init_src();
|
|
1608
|
+
init_courses();
|
|
1609
|
+
init_http();
|
|
1610
|
+
init_session();
|
|
1611
|
+
init_formatter();
|
|
1612
|
+
logger2 = createLogger("cli:courses");
|
|
1613
|
+
coursesCommand = new Command5("courses").description("List your enrolled courses with progress").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1614
|
+
try {
|
|
1615
|
+
const session = await requireSession();
|
|
1616
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1617
|
+
const deps = { data, logger: logger2 };
|
|
1618
|
+
const courses = await listCourses({ userId: session.userId }, deps);
|
|
1619
|
+
if (opts.json) {
|
|
1620
|
+
output(courses, { json: true });
|
|
1621
|
+
} else {
|
|
1622
|
+
output(formatCourseList(courses), { json: false });
|
|
1623
|
+
}
|
|
1624
|
+
} catch (err) {
|
|
1625
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1626
|
+
error(msg);
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1402
1629
|
}
|
|
1403
1630
|
});
|
|
1404
1631
|
|
|
1405
1632
|
// src/commands/select.ts
|
|
1406
1633
|
import { Command as Command6 } from "commander";
|
|
1407
|
-
var logger3
|
|
1408
|
-
var
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1634
|
+
var logger3, selectCommand;
|
|
1635
|
+
var init_select = __esm({
|
|
1636
|
+
"src/commands/select.ts"() {
|
|
1637
|
+
"use strict";
|
|
1638
|
+
init_src();
|
|
1639
|
+
init_courses();
|
|
1640
|
+
init_http();
|
|
1641
|
+
init_session();
|
|
1642
|
+
init_formatter();
|
|
1643
|
+
logger3 = createLogger("cli:select");
|
|
1644
|
+
selectCommand = new Command6("select").description("Activate a course by ID or list index number").argument("<course>", "Course ID (UUID) or index number from `tostudy courses`").option("--json", "Output structured JSON").action(async (course, opts) => {
|
|
1645
|
+
try {
|
|
1646
|
+
const session = await requireSession();
|
|
1647
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1648
|
+
const deps = { data, logger: logger3 };
|
|
1649
|
+
const courses = await listCourses({ userId: session.userId }, deps);
|
|
1650
|
+
let courseId = course;
|
|
1651
|
+
let enrollmentId = "";
|
|
1652
|
+
if (/^\d+$/.test(course)) {
|
|
1653
|
+
const idx = parseInt(course, 10) - 1;
|
|
1654
|
+
if (idx < 0 || idx >= courses.length) {
|
|
1655
|
+
error(`\xCDndice ${course} inv\xE1lido. Voc\xEA tem ${courses.length} curso(s).`);
|
|
1656
|
+
}
|
|
1657
|
+
const found = courses[idx];
|
|
1658
|
+
courseId = found.courseId;
|
|
1659
|
+
enrollmentId = found.enrollmentId;
|
|
1660
|
+
} else {
|
|
1661
|
+
const found = courses.find((c) => c.courseId === course);
|
|
1662
|
+
if (found) {
|
|
1663
|
+
enrollmentId = found.enrollmentId;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
const detail = await selectCourse({ userId: session.userId, courseId }, deps);
|
|
1667
|
+
await setActiveCourse({
|
|
1668
|
+
courseId: detail.courseId,
|
|
1669
|
+
courseTitle: detail.courseTitle,
|
|
1670
|
+
enrollmentId
|
|
1671
|
+
});
|
|
1672
|
+
if (opts.json) {
|
|
1673
|
+
output({ ...detail, enrollmentId }, { json: true });
|
|
1674
|
+
} else {
|
|
1675
|
+
output(
|
|
1676
|
+
[
|
|
1677
|
+
`\u2713 Curso ativado: ${detail.courseTitle}`,
|
|
1678
|
+
` Progresso: ${detail.progress}% | ${detail.moduleCount} m\xF3dulos | ${detail.lessonCount} li\xE7\xF5es`,
|
|
1679
|
+
"",
|
|
1680
|
+
"\u2192 tostudy progress para ver seu progresso detalhado",
|
|
1681
|
+
"\u2192 tostudy start para come\xE7ar o m\xF3dulo atual",
|
|
1682
|
+
"\u2192 tostudy next para avan\xE7ar para a pr\xF3xima li\xE7\xE3o"
|
|
1683
|
+
].join("\n"),
|
|
1684
|
+
{ json: false }
|
|
1685
|
+
);
|
|
1686
|
+
}
|
|
1687
|
+
} catch (err) {
|
|
1688
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1689
|
+
error(msg);
|
|
1428
1690
|
}
|
|
1429
|
-
}
|
|
1430
|
-
const detail = await selectCourse({ userId: session.userId, courseId }, deps);
|
|
1431
|
-
await setActiveCourse({
|
|
1432
|
-
courseId: detail.courseId,
|
|
1433
|
-
courseTitle: detail.courseTitle,
|
|
1434
|
-
enrollmentId
|
|
1435
1691
|
});
|
|
1436
|
-
if (opts.json) {
|
|
1437
|
-
output({ ...detail, enrollmentId }, { json: true });
|
|
1438
|
-
} else {
|
|
1439
|
-
output(
|
|
1440
|
-
[
|
|
1441
|
-
`\u2713 Curso ativado: ${detail.courseTitle}`,
|
|
1442
|
-
` Progresso: ${detail.progress}% | ${detail.moduleCount} m\xF3dulos | ${detail.lessonCount} li\xE7\xF5es`,
|
|
1443
|
-
"",
|
|
1444
|
-
"\u2192 tostudy progress para ver seu progresso detalhado",
|
|
1445
|
-
"\u2192 tostudy start para come\xE7ar o m\xF3dulo atual",
|
|
1446
|
-
"\u2192 tostudy next para avan\xE7ar para a pr\xF3xima li\xE7\xE3o"
|
|
1447
|
-
].join("\n"),
|
|
1448
|
-
{ json: false }
|
|
1449
|
-
);
|
|
1450
|
-
}
|
|
1451
|
-
} catch (err) {
|
|
1452
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1453
|
-
error(msg);
|
|
1454
1692
|
}
|
|
1455
1693
|
});
|
|
1456
1694
|
|
|
1457
1695
|
// src/commands/progress.ts
|
|
1458
1696
|
import { Command as Command7 } from "commander";
|
|
1459
|
-
var logger4
|
|
1460
|
-
var
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1697
|
+
var logger4, progressCommand;
|
|
1698
|
+
var init_progress = __esm({
|
|
1699
|
+
"src/commands/progress.ts"() {
|
|
1700
|
+
"use strict";
|
|
1701
|
+
init_src();
|
|
1702
|
+
init_courses();
|
|
1703
|
+
init_http();
|
|
1704
|
+
init_session();
|
|
1705
|
+
init_formatter();
|
|
1706
|
+
logger4 = createLogger("cli:progress");
|
|
1707
|
+
progressCommand = new Command7("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1708
|
+
try {
|
|
1709
|
+
const session = await requireSession();
|
|
1710
|
+
const activeCourse = await requireActiveCourse();
|
|
1711
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1712
|
+
const deps = { data, logger: logger4 };
|
|
1713
|
+
const progress = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
1714
|
+
if (opts.json) {
|
|
1715
|
+
output(progress, { json: true });
|
|
1716
|
+
} else {
|
|
1717
|
+
output(formatProgress(progress), { json: false });
|
|
1718
|
+
}
|
|
1719
|
+
} catch (err) {
|
|
1720
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1721
|
+
error(msg);
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1475
1724
|
}
|
|
1476
1725
|
});
|
|
1477
1726
|
|
|
1478
|
-
// src/commands/start.ts
|
|
1479
|
-
import { Command as Command8 } from "commander";
|
|
1480
|
-
|
|
1481
1727
|
// ../../packages/tostudy-core/src/lessons/next-lesson.ts
|
|
1482
1728
|
async function nextLesson(input, deps) {
|
|
1483
1729
|
deps.logger.info("tostudy-core: nextLesson", { enrollmentId: input.enrollmentId });
|
|
1484
1730
|
return deps.data.lessons.next(input.enrollmentId, input.userConfirmation);
|
|
1485
1731
|
}
|
|
1732
|
+
var init_next_lesson = __esm({
|
|
1733
|
+
"../../packages/tostudy-core/src/lessons/next-lesson.ts"() {
|
|
1734
|
+
"use strict";
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1486
1737
|
|
|
1487
1738
|
// ../../packages/tostudy-core/src/lessons/get-content.ts
|
|
1488
1739
|
async function getContent(input, deps) {
|
|
1489
1740
|
deps.logger.info("tostudy-core: getContent", { lessonId: input.lessonId });
|
|
1490
1741
|
return deps.data.lessons.getContent(input.lessonId, input.enrollmentId);
|
|
1491
1742
|
}
|
|
1743
|
+
var init_get_content = __esm({
|
|
1744
|
+
"../../packages/tostudy-core/src/lessons/get-content.ts"() {
|
|
1745
|
+
"use strict";
|
|
1746
|
+
}
|
|
1747
|
+
});
|
|
1492
1748
|
|
|
1493
1749
|
// ../../packages/tostudy-core/src/lessons/get-hint.ts
|
|
1494
1750
|
async function getHint(input, deps) {
|
|
1495
1751
|
deps.logger.info("tostudy-core: getHint", { userId: input.userId });
|
|
1496
1752
|
return deps.data.lessons.getHint(input.userId, input.enrollmentId);
|
|
1497
1753
|
}
|
|
1754
|
+
var init_get_hint = __esm({
|
|
1755
|
+
"../../packages/tostudy-core/src/lessons/get-hint.ts"() {
|
|
1756
|
+
"use strict";
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1498
1759
|
|
|
1499
1760
|
// ../../packages/tostudy-core/src/lessons/start-module.ts
|
|
1500
1761
|
async function startModule(input, deps) {
|
|
1501
1762
|
deps.logger.info("tostudy-core: startModule", { enrollmentId: input.enrollmentId });
|
|
1502
1763
|
return deps.data.lessons.startModule(input.enrollmentId);
|
|
1503
1764
|
}
|
|
1765
|
+
var init_start_module = __esm({
|
|
1766
|
+
"../../packages/tostudy-core/src/lessons/start-module.ts"() {
|
|
1767
|
+
"use strict";
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1504
1770
|
|
|
1505
1771
|
// ../../packages/tostudy-core/src/lessons/start-next-module.ts
|
|
1506
1772
|
async function startNextModule(input, deps) {
|
|
1507
1773
|
deps.logger.info("tostudy-core: startNextModule", { enrollmentId: input.enrollmentId });
|
|
1508
1774
|
return deps.data.lessons.startNextModule(input.enrollmentId);
|
|
1509
1775
|
}
|
|
1776
|
+
var init_start_next_module = __esm({
|
|
1777
|
+
"../../packages/tostudy-core/src/lessons/start-next-module.ts"() {
|
|
1778
|
+
"use strict";
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1781
|
+
|
|
1782
|
+
// ../../packages/tostudy-core/src/lessons/index.ts
|
|
1783
|
+
var init_lessons = __esm({
|
|
1784
|
+
"../../packages/tostudy-core/src/lessons/index.ts"() {
|
|
1785
|
+
"use strict";
|
|
1786
|
+
init_next_lesson();
|
|
1787
|
+
init_get_content();
|
|
1788
|
+
init_get_hint();
|
|
1789
|
+
init_start_module();
|
|
1790
|
+
init_start_next_module();
|
|
1791
|
+
}
|
|
1792
|
+
});
|
|
1510
1793
|
|
|
1511
1794
|
// src/commands/start.ts
|
|
1512
|
-
|
|
1513
|
-
var
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1795
|
+
import { Command as Command8 } from "commander";
|
|
1796
|
+
var logger5, startCommand;
|
|
1797
|
+
var init_start = __esm({
|
|
1798
|
+
"src/commands/start.ts"() {
|
|
1799
|
+
"use strict";
|
|
1800
|
+
init_src();
|
|
1801
|
+
init_lessons();
|
|
1802
|
+
init_http();
|
|
1803
|
+
init_session();
|
|
1804
|
+
init_formatter();
|
|
1805
|
+
logger5 = createLogger("cli:start");
|
|
1806
|
+
startCommand = new Command8("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1807
|
+
try {
|
|
1808
|
+
const session = await requireSession();
|
|
1809
|
+
const activeCourse = await requireActiveCourse();
|
|
1810
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1811
|
+
const deps = { data, logger: logger5 };
|
|
1812
|
+
const moduleData = await startModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
1813
|
+
if (opts.json) {
|
|
1814
|
+
output(moduleData, { json: true });
|
|
1815
|
+
} else {
|
|
1816
|
+
output(formatModuleStart(moduleData), { json: false });
|
|
1817
|
+
}
|
|
1818
|
+
} catch (err) {
|
|
1819
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1820
|
+
error(msg);
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1528
1823
|
}
|
|
1529
1824
|
});
|
|
1530
1825
|
|
|
1531
1826
|
// src/commands/start-next.ts
|
|
1532
1827
|
import { Command as Command9 } from "commander";
|
|
1533
|
-
var logger6
|
|
1534
|
-
var
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1828
|
+
var logger6, startNextCommand;
|
|
1829
|
+
var init_start_next = __esm({
|
|
1830
|
+
"src/commands/start-next.ts"() {
|
|
1831
|
+
"use strict";
|
|
1832
|
+
init_src();
|
|
1833
|
+
init_lessons();
|
|
1834
|
+
init_http();
|
|
1835
|
+
init_session();
|
|
1836
|
+
init_formatter();
|
|
1837
|
+
logger6 = createLogger("cli:start-next");
|
|
1838
|
+
startNextCommand = new Command9("start-next").description("Transition to the next module after completing the current one").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1839
|
+
try {
|
|
1840
|
+
const session = await requireSession();
|
|
1841
|
+
const activeCourse = await requireActiveCourse();
|
|
1842
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1843
|
+
const deps = { data, logger: logger6 };
|
|
1844
|
+
const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
1845
|
+
if (opts.json) {
|
|
1846
|
+
output(moduleData, { json: true });
|
|
1847
|
+
} else {
|
|
1848
|
+
output(formatModuleStart(moduleData), { json: false });
|
|
1849
|
+
}
|
|
1850
|
+
} catch (err) {
|
|
1851
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1852
|
+
error(msg);
|
|
1853
|
+
}
|
|
1854
|
+
});
|
|
1549
1855
|
}
|
|
1550
1856
|
});
|
|
1551
1857
|
|
|
1552
1858
|
// src/commands/next.ts
|
|
1553
1859
|
import { Command as Command10 } from "commander";
|
|
1554
|
-
var logger7
|
|
1555
|
-
var
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
)
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1860
|
+
var logger7, nextCommand;
|
|
1861
|
+
var init_next = __esm({
|
|
1862
|
+
"src/commands/next.ts"() {
|
|
1863
|
+
"use strict";
|
|
1864
|
+
init_src();
|
|
1865
|
+
init_lessons();
|
|
1866
|
+
init_http();
|
|
1867
|
+
init_session();
|
|
1868
|
+
init_formatter();
|
|
1869
|
+
logger7 = createLogger("cli:next");
|
|
1870
|
+
nextCommand = new Command10("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1871
|
+
try {
|
|
1872
|
+
const session = await requireSession();
|
|
1873
|
+
const activeCourse = await requireActiveCourse();
|
|
1874
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1875
|
+
const deps = { data, logger: logger7 };
|
|
1876
|
+
const lessonData = await nextLesson(
|
|
1877
|
+
{ enrollmentId: activeCourse.enrollmentId, userConfirmation: "cli-next" },
|
|
1878
|
+
deps
|
|
1879
|
+
);
|
|
1880
|
+
if (opts.json) {
|
|
1881
|
+
output(lessonData, { json: true });
|
|
1882
|
+
} else {
|
|
1883
|
+
output(formatLesson(lessonData), { json: false });
|
|
1884
|
+
}
|
|
1885
|
+
} catch (err) {
|
|
1886
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1887
|
+
error(msg);
|
|
1888
|
+
}
|
|
1889
|
+
});
|
|
1573
1890
|
}
|
|
1574
1891
|
});
|
|
1575
1892
|
|
|
1576
1893
|
// src/commands/lesson.ts
|
|
1577
1894
|
import { Command as Command11 } from "commander";
|
|
1578
|
-
var logger8 = createLogger("cli:lesson");
|
|
1579
1895
|
function formatLessonContent(data) {
|
|
1580
1896
|
const lines = [
|
|
1581
1897
|
`\u2501\u2501\u2501 Li\xE7\xE3o: ${data.title} \u2501\u2501\u2501`,
|
|
@@ -1598,56 +1914,75 @@ function formatLessonContent(data) {
|
|
|
1598
1914
|
);
|
|
1599
1915
|
return lines.join("\n");
|
|
1600
1916
|
}
|
|
1601
|
-
var
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1917
|
+
var logger8, lessonCommand;
|
|
1918
|
+
var init_lesson = __esm({
|
|
1919
|
+
"src/commands/lesson.ts"() {
|
|
1920
|
+
"use strict";
|
|
1921
|
+
init_src();
|
|
1922
|
+
init_lessons();
|
|
1923
|
+
init_http();
|
|
1924
|
+
init_session();
|
|
1925
|
+
init_formatter();
|
|
1926
|
+
logger8 = createLogger("cli:lesson");
|
|
1927
|
+
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1928
|
+
try {
|
|
1929
|
+
const session = await requireSession();
|
|
1930
|
+
const activeCourse = await requireActiveCourse();
|
|
1931
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1932
|
+
const deps = { data, logger: logger8 };
|
|
1933
|
+
const lessonId = activeCourse.currentLessonId;
|
|
1934
|
+
if (!lessonId) {
|
|
1935
|
+
error("Nenhuma li\xE7\xE3o ativa encontrada. Rode: tostudy start ou tostudy next");
|
|
1936
|
+
}
|
|
1937
|
+
const content = await getContent({ lessonId, enrollmentId: activeCourse.enrollmentId }, deps);
|
|
1938
|
+
if (opts.json) {
|
|
1939
|
+
output(content, { json: true });
|
|
1940
|
+
} else {
|
|
1941
|
+
output(formatLessonContent(content), { json: false });
|
|
1942
|
+
}
|
|
1943
|
+
} catch (err) {
|
|
1944
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1945
|
+
error(msg);
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1620
1948
|
}
|
|
1621
1949
|
});
|
|
1622
1950
|
|
|
1623
1951
|
// src/commands/hint.ts
|
|
1624
1952
|
import { Command as Command12 } from "commander";
|
|
1625
|
-
var logger9
|
|
1626
|
-
var
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
)
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1953
|
+
var logger9, hintCommand;
|
|
1954
|
+
var init_hint = __esm({
|
|
1955
|
+
"src/commands/hint.ts"() {
|
|
1956
|
+
"use strict";
|
|
1957
|
+
init_src();
|
|
1958
|
+
init_lessons();
|
|
1959
|
+
init_http();
|
|
1960
|
+
init_session();
|
|
1961
|
+
init_formatter();
|
|
1962
|
+
logger9 = createLogger("cli:hint");
|
|
1963
|
+
hintCommand = new Command12("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
|
|
1964
|
+
try {
|
|
1965
|
+
const session = await requireSession();
|
|
1966
|
+
const activeCourse = await requireActiveCourse();
|
|
1967
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1968
|
+
const deps = { data, logger: logger9 };
|
|
1969
|
+
const hint = await getHint(
|
|
1970
|
+
{ userId: session.userId, enrollmentId: activeCourse.enrollmentId },
|
|
1971
|
+
deps
|
|
1972
|
+
);
|
|
1973
|
+
if (opts.json) {
|
|
1974
|
+
output(hint, { json: true });
|
|
1975
|
+
} else {
|
|
1976
|
+
output(formatHint(hint), { json: false });
|
|
1977
|
+
}
|
|
1978
|
+
} catch (err) {
|
|
1979
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1980
|
+
error(msg);
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1644
1983
|
}
|
|
1645
1984
|
});
|
|
1646
1985
|
|
|
1647
|
-
// src/commands/validate.ts
|
|
1648
|
-
import fs3 from "node:fs";
|
|
1649
|
-
import { Command as Command13 } from "commander";
|
|
1650
|
-
|
|
1651
1986
|
// ../../packages/tostudy-core/src/exercises/validate-solution.ts
|
|
1652
1987
|
async function validateSolution(input, deps) {
|
|
1653
1988
|
deps.logger.info("tostudy-core: validateSolution", { lessonId: input.lessonId });
|
|
@@ -1658,111 +1993,150 @@ async function validateSolution(input, deps) {
|
|
|
1658
1993
|
input.enrollmentId
|
|
1659
1994
|
);
|
|
1660
1995
|
}
|
|
1996
|
+
var init_validate_solution = __esm({
|
|
1997
|
+
"../../packages/tostudy-core/src/exercises/validate-solution.ts"() {
|
|
1998
|
+
"use strict";
|
|
1999
|
+
}
|
|
2000
|
+
});
|
|
2001
|
+
|
|
2002
|
+
// ../../packages/tostudy-core/src/exercises/index.ts
|
|
2003
|
+
var init_exercises = __esm({
|
|
2004
|
+
"../../packages/tostudy-core/src/exercises/index.ts"() {
|
|
2005
|
+
"use strict";
|
|
2006
|
+
init_validate_solution();
|
|
2007
|
+
}
|
|
2008
|
+
});
|
|
1661
2009
|
|
|
1662
2010
|
// src/commands/validate.ts
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
2011
|
+
import fs3 from "node:fs";
|
|
2012
|
+
import { Command as Command13 } from "commander";
|
|
2013
|
+
var logger10, validateCommand;
|
|
2014
|
+
var init_validate = __esm({
|
|
2015
|
+
"src/commands/validate.ts"() {
|
|
2016
|
+
"use strict";
|
|
2017
|
+
init_src();
|
|
2018
|
+
init_exercises();
|
|
2019
|
+
init_http();
|
|
2020
|
+
init_session();
|
|
2021
|
+
init_formatter();
|
|
2022
|
+
logger10 = createLogger("cli:validate");
|
|
2023
|
+
validateCommand = new Command13("validate").description("Validate your solution for the current exercise").argument("[file]", "Path to the solution file to read").option("--stdin", "Read solution from stdin instead of a file").option("--json", "Output structured JSON").action(async (file, opts) => {
|
|
2024
|
+
try {
|
|
2025
|
+
const session = await requireSession();
|
|
2026
|
+
const activeCourse = await requireActiveCourse();
|
|
2027
|
+
const lessonId = activeCourse.currentLessonId;
|
|
2028
|
+
if (!lessonId) {
|
|
2029
|
+
error("Nenhuma li\xE7\xE3o ativa encontrada. Rode: tostudy start ou tostudy next");
|
|
2030
|
+
}
|
|
2031
|
+
let solution;
|
|
2032
|
+
if (opts.stdin) {
|
|
2033
|
+
solution = fs3.readFileSync("/dev/stdin", "utf-8");
|
|
2034
|
+
} else if (file) {
|
|
2035
|
+
if (!fs3.existsSync(file)) {
|
|
2036
|
+
error(`Arquivo n\xE3o encontrado: ${file}`);
|
|
2037
|
+
}
|
|
2038
|
+
solution = fs3.readFileSync(file, "utf-8");
|
|
2039
|
+
} else {
|
|
2040
|
+
error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
|
|
2041
|
+
}
|
|
2042
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
2043
|
+
const deps = { data, logger: logger10 };
|
|
2044
|
+
const result = await validateSolution(
|
|
2045
|
+
{
|
|
2046
|
+
lessonId,
|
|
2047
|
+
solution,
|
|
2048
|
+
userId: session.userId,
|
|
2049
|
+
enrollmentId: activeCourse.enrollmentId
|
|
2050
|
+
},
|
|
2051
|
+
deps
|
|
2052
|
+
);
|
|
2053
|
+
if (opts.json) {
|
|
2054
|
+
output(result, { json: true });
|
|
2055
|
+
} else {
|
|
2056
|
+
output(formatValidation(result), { json: false });
|
|
2057
|
+
}
|
|
2058
|
+
process.exit(result.passed ? 0 : 1);
|
|
2059
|
+
} catch (err) {
|
|
2060
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2061
|
+
error(msg);
|
|
1678
2062
|
}
|
|
1679
|
-
|
|
1680
|
-
} else {
|
|
1681
|
-
error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
|
|
1682
|
-
}
|
|
1683
|
-
const data = createHttpProvider(session.apiUrl, session.token);
|
|
1684
|
-
const deps = { data, logger: logger10 };
|
|
1685
|
-
const result = await validateSolution(
|
|
1686
|
-
{
|
|
1687
|
-
lessonId,
|
|
1688
|
-
solution,
|
|
1689
|
-
userId: session.userId,
|
|
1690
|
-
enrollmentId: activeCourse.enrollmentId
|
|
1691
|
-
},
|
|
1692
|
-
deps
|
|
1693
|
-
);
|
|
1694
|
-
if (opts.json) {
|
|
1695
|
-
output(result, { json: true });
|
|
1696
|
-
} else {
|
|
1697
|
-
output(formatValidation(result), { json: false });
|
|
1698
|
-
}
|
|
1699
|
-
process.exit(result.passed ? 0 : 1);
|
|
1700
|
-
} catch (err) {
|
|
1701
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1702
|
-
error(msg);
|
|
2063
|
+
});
|
|
1703
2064
|
}
|
|
1704
2065
|
});
|
|
1705
2066
|
|
|
1706
2067
|
// src/commands/menu.ts
|
|
1707
2068
|
import { Command as Command14 } from "commander";
|
|
1708
|
-
var menuCommand
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
"
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
" Para come\xE7ar:",
|
|
1722
|
-
" tostudy login Autenticar com sua conta ToStudy",
|
|
1723
|
-
""
|
|
1724
|
-
);
|
|
1725
|
-
} else {
|
|
1726
|
-
lines.push(` Usu\xE1rio: ${session.userName}`);
|
|
1727
|
-
if (activeCourse) {
|
|
1728
|
-
lines.push(` Curso ativo: ${activeCourse.courseTitle}`, "");
|
|
1729
|
-
} else {
|
|
1730
|
-
lines.push(
|
|
1731
|
-
" Curso ativo: (nenhum)",
|
|
1732
|
-
" \u2192 tostudy courses para ver seus cursos",
|
|
1733
|
-
" \u2192 tostudy select <n\xFAmero> para ativar um curso",
|
|
2069
|
+
var menuCommand;
|
|
2070
|
+
var init_menu = __esm({
|
|
2071
|
+
"src/commands/menu.ts"() {
|
|
2072
|
+
"use strict";
|
|
2073
|
+
init_session();
|
|
2074
|
+
init_formatter();
|
|
2075
|
+
menuCommand = new Command14("menu").description("Show available commands and current study context").action(async () => {
|
|
2076
|
+
const session = await getSession();
|
|
2077
|
+
const activeCourse = session ? await getActiveCourse() : null;
|
|
2078
|
+
const lines = [
|
|
2079
|
+
"\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
|
|
2080
|
+
"\u2502 ToStudy CLI \u2014 Menu \u2502",
|
|
2081
|
+
"\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
|
|
1734
2082
|
""
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
2083
|
+
];
|
|
2084
|
+
if (!session) {
|
|
2085
|
+
lines.push(
|
|
2086
|
+
" Status: N\xE3o autenticado",
|
|
2087
|
+
"",
|
|
2088
|
+
" Para come\xE7ar:",
|
|
2089
|
+
" tostudy login Autenticar com sua conta ToStudy",
|
|
2090
|
+
""
|
|
2091
|
+
);
|
|
2092
|
+
} else {
|
|
2093
|
+
lines.push(` Usu\xE1rio: ${session.userName}`);
|
|
2094
|
+
if (activeCourse) {
|
|
2095
|
+
lines.push(` Curso ativo: ${activeCourse.courseTitle}`, "");
|
|
2096
|
+
} else {
|
|
2097
|
+
lines.push(
|
|
2098
|
+
" Curso ativo: (nenhum)",
|
|
2099
|
+
" \u2192 tostudy courses para ver seus cursos",
|
|
2100
|
+
" \u2192 tostudy select <n\xFAmero> para ativar um curso",
|
|
2101
|
+
""
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
lines.push(
|
|
2105
|
+
" \u2500\u2500\u2500 Navega\xE7\xE3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
2106
|
+
" tostudy courses Listar seus cursos",
|
|
2107
|
+
" tostudy select <id> Ativar um curso",
|
|
2108
|
+
" tostudy progress Ver progresso do curso ativo",
|
|
2109
|
+
"",
|
|
2110
|
+
" \u2500\u2500\u2500 Estudo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
2111
|
+
" tostudy start Iniciar/retomar o m\xF3dulo atual",
|
|
2112
|
+
" tostudy start-next Avan\xE7ar para o pr\xF3ximo m\xF3dulo",
|
|
2113
|
+
" tostudy next Avan\xE7ar para a pr\xF3xima li\xE7\xE3o",
|
|
2114
|
+
" tostudy lesson Ver conte\xFAdo da li\xE7\xE3o atual",
|
|
2115
|
+
"",
|
|
2116
|
+
" \u2500\u2500\u2500 Exerc\xEDcios \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
2117
|
+
" tostudy validate <arquivo> Validar sua solu\xE7\xE3o",
|
|
2118
|
+
" tostudy hint Obter uma dica progressiva",
|
|
2119
|
+
"",
|
|
2120
|
+
" \u2500\u2500\u2500 Dicas r\xE1pidas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
2121
|
+
" Adicione --json a qualquer comando para sa\xEDda em JSON",
|
|
2122
|
+
" Adicione --help a qualquer comando para ver op\xE7\xF5es",
|
|
2123
|
+
""
|
|
2124
|
+
);
|
|
2125
|
+
}
|
|
2126
|
+
output(lines.join("\n"), { json: false });
|
|
2127
|
+
});
|
|
1758
2128
|
}
|
|
1759
|
-
output(lines.join("\n"), { json: false });
|
|
1760
2129
|
});
|
|
1761
2130
|
|
|
1762
2131
|
// src/cli.ts
|
|
2132
|
+
var cli_exports = {};
|
|
2133
|
+
__export(cli_exports, {
|
|
2134
|
+
createProgram: () => createProgram
|
|
2135
|
+
});
|
|
2136
|
+
import { Command as Command15 } from "commander";
|
|
1763
2137
|
function createProgram() {
|
|
1764
2138
|
const program2 = new Command15();
|
|
1765
|
-
program2.name("tostudy").description("ToStudy CLI \u2014 study courses from the terminal").version("0.1.
|
|
2139
|
+
program2.name("tostudy").description("ToStudy CLI \u2014 study courses from the terminal").version("0.1.3").option("--json", "Output structured JSON (for LLM agents)").option("--verbose", "Enable debug output").option("--course <id>", "Override active course ID");
|
|
1766
2140
|
program2.addCommand(setupCommand);
|
|
1767
2141
|
program2.addCommand(doctorCommand);
|
|
1768
2142
|
program2.addCommand(loginCommand);
|
|
@@ -1779,8 +2153,31 @@ function createProgram() {
|
|
|
1779
2153
|
program2.addCommand(menuCommand);
|
|
1780
2154
|
return program2;
|
|
1781
2155
|
}
|
|
2156
|
+
var init_cli = __esm({
|
|
2157
|
+
"src/cli.ts"() {
|
|
2158
|
+
"use strict";
|
|
2159
|
+
init_login();
|
|
2160
|
+
init_logout();
|
|
2161
|
+
init_setup();
|
|
2162
|
+
init_doctor();
|
|
2163
|
+
init_courses2();
|
|
2164
|
+
init_select();
|
|
2165
|
+
init_progress();
|
|
2166
|
+
init_start();
|
|
2167
|
+
init_start_next();
|
|
2168
|
+
init_next();
|
|
2169
|
+
init_lesson();
|
|
2170
|
+
init_hint();
|
|
2171
|
+
init_validate();
|
|
2172
|
+
init_menu();
|
|
2173
|
+
}
|
|
2174
|
+
});
|
|
1782
2175
|
|
|
1783
2176
|
// src/cli-entry.ts
|
|
1784
|
-
|
|
2177
|
+
if (!process.env.LOG_LEVEL) {
|
|
2178
|
+
process.env.LOG_LEVEL = "fatal";
|
|
2179
|
+
}
|
|
2180
|
+
var { createProgram: createProgram2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
2181
|
+
var program = createProgram2();
|
|
1785
2182
|
program.parse();
|
|
1786
2183
|
//# sourceMappingURL=cli.js.map
|