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