@tostudy-ai/cli 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1390 -620
- package/dist/cli.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -219,6 +219,47 @@ function getConfigDir(override) {
|
|
|
219
219
|
}
|
|
220
220
|
return path2.join(os2.homedir(), ".tostudy");
|
|
221
221
|
}
|
|
222
|
+
function getCourseOnboardingPath(configDir) {
|
|
223
|
+
return path2.join(getConfigDir(configDir), "course-onboarding.json");
|
|
224
|
+
}
|
|
225
|
+
function readCourseOnboardingState(configDir) {
|
|
226
|
+
const onboardingPath = getCourseOnboardingPath(configDir);
|
|
227
|
+
if (!fs2.existsSync(onboardingPath)) return {};
|
|
228
|
+
return JSON.parse(fs2.readFileSync(onboardingPath, "utf-8"));
|
|
229
|
+
}
|
|
230
|
+
function writeCourseOnboardingState(state, configDir) {
|
|
231
|
+
const dir = getConfigDir(configDir);
|
|
232
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
233
|
+
fs2.writeFileSync(getCourseOnboardingPath(configDir), JSON.stringify(state, null, 2), {
|
|
234
|
+
mode: 384
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
async function getCourseOnboardingState(courseId, configDir) {
|
|
238
|
+
const state = readCourseOnboardingState(configDir);
|
|
239
|
+
return state[courseId] ?? null;
|
|
240
|
+
}
|
|
241
|
+
async function updateCourseOnboardingState(courseId, patch, configDir) {
|
|
242
|
+
const state = readCourseOnboardingState(configDir);
|
|
243
|
+
state[courseId] = {
|
|
244
|
+
...state[courseId] ?? {},
|
|
245
|
+
...patch
|
|
246
|
+
};
|
|
247
|
+
writeCourseOnboardingState(state, configDir);
|
|
248
|
+
}
|
|
249
|
+
async function setCourseWorkspacePath(courseId, workspacePath, configDir) {
|
|
250
|
+
await updateCourseOnboardingState(courseId, { workspacePath }, configDir);
|
|
251
|
+
}
|
|
252
|
+
async function saveCourseLearnerProfile(course, learnerProfile, artifacts, configDir) {
|
|
253
|
+
await updateCourseOnboardingState(
|
|
254
|
+
course.courseId,
|
|
255
|
+
{
|
|
256
|
+
enrollmentId: course.enrollmentId,
|
|
257
|
+
learnerProfile,
|
|
258
|
+
artifacts
|
|
259
|
+
},
|
|
260
|
+
configDir
|
|
261
|
+
);
|
|
262
|
+
}
|
|
222
263
|
async function saveSession(session, configDir) {
|
|
223
264
|
const dir = getConfigDir(configDir);
|
|
224
265
|
fs2.mkdirSync(dir, { recursive: true });
|
|
@@ -263,6 +304,8 @@ async function clearSession(configDir) {
|
|
|
263
304
|
if (fs2.existsSync(p)) fs2.unlinkSync(p);
|
|
264
305
|
const ap = path2.join(dir, "active-course.json");
|
|
265
306
|
if (fs2.existsSync(ap)) fs2.unlinkSync(ap);
|
|
307
|
+
const onboardingPath = getCourseOnboardingPath(configDir);
|
|
308
|
+
if (fs2.existsSync(onboardingPath)) fs2.unlinkSync(onboardingPath);
|
|
266
309
|
await deleteStoredSessionSecrets(dir);
|
|
267
310
|
}
|
|
268
311
|
async function getActiveCourse(configDir) {
|
|
@@ -274,7 +317,9 @@ async function getActiveCourse(configDir) {
|
|
|
274
317
|
async function setActiveCourse(course, configDir) {
|
|
275
318
|
const dir = getConfigDir(configDir);
|
|
276
319
|
fs2.mkdirSync(dir, { recursive: true });
|
|
277
|
-
|
|
320
|
+
const onboardingState = await getCourseOnboardingState(course.courseId, configDir);
|
|
321
|
+
const persistedCourse = onboardingState?.initCompletedAt && !course.lastInitCourseId ? { ...course, lastInitCourseId: course.courseId } : course;
|
|
322
|
+
fs2.writeFileSync(path2.join(dir, "active-course.json"), JSON.stringify(persistedCourse, null, 2), {
|
|
278
323
|
mode: 384
|
|
279
324
|
});
|
|
280
325
|
}
|
|
@@ -332,6 +377,13 @@ async function setLastInitCourseId(courseId, configDir) {
|
|
|
332
377
|
const existing = await getActiveCourse(configDir);
|
|
333
378
|
if (!existing) return;
|
|
334
379
|
await setActiveCourse({ ...existing, lastInitCourseId: courseId }, configDir);
|
|
380
|
+
await updateCourseOnboardingState(
|
|
381
|
+
courseId,
|
|
382
|
+
{
|
|
383
|
+
initCompletedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
384
|
+
},
|
|
385
|
+
configDir
|
|
386
|
+
);
|
|
335
387
|
}
|
|
336
388
|
async function checkCourseDrift(configDir) {
|
|
337
389
|
const course = await getActiveCourse(configDir);
|
|
@@ -372,6 +424,23 @@ function progressBar(percent, width = 20) {
|
|
|
372
424
|
const empty = width - filled;
|
|
373
425
|
return "\u2588".repeat(filled) + "\u2591".repeat(empty) + ` ${clamped}%`;
|
|
374
426
|
}
|
|
427
|
+
function filterExerciseContent(content, tierIndex) {
|
|
428
|
+
const positions = [];
|
|
429
|
+
for (const pattern of TIER_HEADERS) {
|
|
430
|
+
const match = content.match(pattern);
|
|
431
|
+
if (match?.index != null) {
|
|
432
|
+
positions.push({ index: match.index, match: match[0] });
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
positions.sort((a, b2) => a.index - b2.index);
|
|
436
|
+
if (positions.length === 0) return content;
|
|
437
|
+
const intro = content.slice(0, positions[0].index).trimEnd();
|
|
438
|
+
const tierPos = positions[tierIndex];
|
|
439
|
+
if (!tierPos) return content;
|
|
440
|
+
const nextPos = positions[tierIndex + 1];
|
|
441
|
+
const tierContent = nextPos ? content.slice(tierPos.index, nextPos.index).trimEnd() : content.slice(tierPos.index).trimEnd();
|
|
442
|
+
return intro + "\n\n" + tierContent;
|
|
443
|
+
}
|
|
375
444
|
function formatCourseList(courses3) {
|
|
376
445
|
if (courses3.length === 0) {
|
|
377
446
|
return [
|
|
@@ -383,9 +452,17 @@ function formatCourseList(courses3) {
|
|
|
383
452
|
const lines = ["Seus cursos:", ""];
|
|
384
453
|
courses3.forEach((course, idx) => {
|
|
385
454
|
const bar = progressBar(course.progress);
|
|
455
|
+
const enrolledDate = course.enrolledAt ? new Date(course.enrolledAt).toLocaleDateString("pt-BR", {
|
|
456
|
+
year: "numeric",
|
|
457
|
+
month: "short",
|
|
458
|
+
day: "numeric"
|
|
459
|
+
}) : null;
|
|
386
460
|
lines.push(` ${idx + 1}. ${course.title}`);
|
|
387
461
|
lines.push(` ${bar}`);
|
|
388
462
|
lines.push(` Professor: ${course.creatorName}`);
|
|
463
|
+
if (enrolledDate) {
|
|
464
|
+
lines.push(` Inscrito em: ${enrolledDate}`);
|
|
465
|
+
}
|
|
389
466
|
lines.push("");
|
|
390
467
|
});
|
|
391
468
|
lines.push("\u2192 tostudy select <n\xFAmero> para ativar um curso");
|
|
@@ -413,16 +490,17 @@ function formatProgress(data) {
|
|
|
413
490
|
return lines.join("\n");
|
|
414
491
|
}
|
|
415
492
|
function formatLesson(data) {
|
|
416
|
-
const { lesson, wayfinding, progress: progress3 } = data;
|
|
493
|
+
const { lesson, wayfinding, progress: progress3, exercise } = data;
|
|
417
494
|
const courseBar = progressBar(progress3.coursePercent);
|
|
418
495
|
const moduleBar = progressBar(progress3.modulePercent);
|
|
496
|
+
const tierSuffix = exercise ? ` \xB7 ${exercise.tierLabel} (${exercise.index + 1}/${exercise.total})` : "";
|
|
419
497
|
const lines = [
|
|
420
|
-
`\u2501\u2501\u2501 M\xF3dulo ${wayfinding.moduleOrder}/${wayfinding.totalModules} \xB7 Li\xE7\xE3o ${wayfinding.lessonOrder}/${wayfinding.totalLessons} \u2501\u2501\u2501`,
|
|
498
|
+
`\u2501\u2501\u2501 M\xF3dulo ${wayfinding.moduleOrder}/${wayfinding.totalModules} \xB7 Li\xE7\xE3o ${wayfinding.lessonOrder}/${wayfinding.totalLessons}${tierSuffix} \u2501\u2501\u2501`,
|
|
421
499
|
"",
|
|
422
500
|
`\u{1F4D6} ${lesson.title}`,
|
|
423
501
|
` M\xF3dulo: ${lesson.moduleTitle} | Tipo: ${lesson.type}`,
|
|
424
502
|
"",
|
|
425
|
-
lesson.content,
|
|
503
|
+
exercise ? filterExerciseContent(lesson.content, exercise.index) : lesson.content,
|
|
426
504
|
"",
|
|
427
505
|
` Curso: ${courseBar}`,
|
|
428
506
|
` M\xF3dulo: ${moduleBar}`
|
|
@@ -433,12 +511,21 @@ function formatLesson(data) {
|
|
|
433
511
|
if (lesson.exerciseContent) {
|
|
434
512
|
lines.push("", "\u2500\u2500\u2500 Exerc\xEDcio \u2500\u2500\u2500", lesson.exerciseContent);
|
|
435
513
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
514
|
+
if (/^checkpoint/i.test(lesson.title.trim())) {
|
|
515
|
+
lines.push(
|
|
516
|
+
"",
|
|
517
|
+
"\u{1F4A1} Escreva suas respostas num arquivo (ex: checkpoint.md) e valide:",
|
|
518
|
+
" tostudy validate checkpoint.md",
|
|
519
|
+
"\u2192 tostudy next para avan\xE7ar"
|
|
520
|
+
);
|
|
521
|
+
} else {
|
|
522
|
+
lines.push(
|
|
523
|
+
"",
|
|
524
|
+
"\u2192 tostudy validate <resposta> para validar sua solu\xE7\xE3o",
|
|
525
|
+
"\u2192 tostudy hint para obter uma dica",
|
|
526
|
+
"\u2192 tostudy next para avan\xE7ar (ap\xF3s completar)"
|
|
527
|
+
);
|
|
528
|
+
}
|
|
442
529
|
return lines.join("\n");
|
|
443
530
|
}
|
|
444
531
|
function formatValidation(data) {
|
|
@@ -510,9 +597,11 @@ function formatModuleStart(data) {
|
|
|
510
597
|
);
|
|
511
598
|
return lines.join("\n");
|
|
512
599
|
}
|
|
600
|
+
var TIER_HEADERS;
|
|
513
601
|
var init_formatter = __esm({
|
|
514
602
|
"src/output/formatter.ts"() {
|
|
515
603
|
"use strict";
|
|
604
|
+
TIER_HEADERS = [/^## Prática Guiada/im, /^## Prática Semi-?[Gg]uiada/im, /^## Desafio/im];
|
|
516
605
|
}
|
|
517
606
|
});
|
|
518
607
|
|
|
@@ -739,6 +828,65 @@ var init_mcp_setup = __esm({
|
|
|
739
828
|
}
|
|
740
829
|
});
|
|
741
830
|
|
|
831
|
+
// src/workspace/resolve.ts
|
|
832
|
+
import fs4 from "node:fs/promises";
|
|
833
|
+
import path4 from "node:path";
|
|
834
|
+
import os4 from "node:os";
|
|
835
|
+
function courseSlug(title) {
|
|
836
|
+
return title.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
837
|
+
}
|
|
838
|
+
async function resolveWorkspace(courseTitle, basePath = DEFAULT_BASE) {
|
|
839
|
+
const slug = courseSlug(courseTitle);
|
|
840
|
+
const candidate = path4.join(basePath, slug);
|
|
841
|
+
try {
|
|
842
|
+
await fs4.access(path4.join(candidate, ".ana-config.json"));
|
|
843
|
+
return { found: true, workspacePath: candidate };
|
|
844
|
+
} catch {
|
|
845
|
+
return { found: false, workspacePath: null };
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
var DEFAULT_BASE;
|
|
849
|
+
var init_resolve = __esm({
|
|
850
|
+
"src/workspace/resolve.ts"() {
|
|
851
|
+
"use strict";
|
|
852
|
+
DEFAULT_BASE = path4.join(os4.homedir(), "study");
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
// src/onboarding/status.ts
|
|
857
|
+
import fs5 from "node:fs/promises";
|
|
858
|
+
import path5 from "node:path";
|
|
859
|
+
async function resolveStoredWorkspace(workspacePath) {
|
|
860
|
+
if (!workspacePath) return null;
|
|
861
|
+
try {
|
|
862
|
+
await fs5.access(path5.join(workspacePath, ".ana-config.json"));
|
|
863
|
+
return workspacePath;
|
|
864
|
+
} catch {
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
async function getCourseOnboardingStatus(activeCourse, configDir) {
|
|
869
|
+
const onboardingState = await getCourseOnboardingState(activeCourse.courseId, configDir);
|
|
870
|
+
const initReady = Boolean(onboardingState?.initCompletedAt);
|
|
871
|
+
let workspacePath = await resolveStoredWorkspace(onboardingState?.workspacePath);
|
|
872
|
+
if (!workspacePath) {
|
|
873
|
+
const resolvedWorkspace = await resolveWorkspace(activeCourse.courseTitle);
|
|
874
|
+
workspacePath = resolvedWorkspace.workspacePath;
|
|
875
|
+
}
|
|
876
|
+
return {
|
|
877
|
+
initReady,
|
|
878
|
+
workspaceReady: Boolean(workspacePath),
|
|
879
|
+
workspacePath
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
var init_status = __esm({
|
|
883
|
+
"src/onboarding/status.ts"() {
|
|
884
|
+
"use strict";
|
|
885
|
+
init_session();
|
|
886
|
+
init_resolve();
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
|
|
742
890
|
// src/commands/setup.ts
|
|
743
891
|
import { Command as Command3 } from "commander";
|
|
744
892
|
async function runSetup(opts, deps = defaultDeps) {
|
|
@@ -792,8 +940,34 @@ async function runSetup(opts, deps = defaultDeps) {
|
|
|
792
940
|
await deps.runMcpSetup(session, token2);
|
|
793
941
|
deps.log(" \u2713 MCP configurado\n");
|
|
794
942
|
}
|
|
943
|
+
const activeCourse = await deps.getActiveCourse();
|
|
944
|
+
if (!activeCourse) {
|
|
945
|
+
deps.log(" Ambiente validado, mas ainda falta selecionar um curso.");
|
|
946
|
+
deps.log(" Pr\xF3ximos passos obrigat\xF3rios:");
|
|
947
|
+
deps.log(" \u2192 tostudy courses");
|
|
948
|
+
deps.log(" \u2192 tostudy select <n\xFAmero>");
|
|
949
|
+
deps.log(" \u2192 tostudy init");
|
|
950
|
+
deps.log(" \u2192 tostudy workspace setup\n");
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
const onboarding = await deps.getCourseOnboardingStatus(activeCourse);
|
|
954
|
+
if (!onboarding.initReady || !onboarding.workspaceReady) {
|
|
955
|
+
deps.log(
|
|
956
|
+
` Ambiente validado para ${activeCourse.courseTitle}, mas o onboarding ainda n\xE3o terminou.`
|
|
957
|
+
);
|
|
958
|
+
deps.log(" Checklist obrigat\xF3rio antes do primeiro start:");
|
|
959
|
+
if (!onboarding.initReady) {
|
|
960
|
+
deps.log(" \u2192 tostudy init");
|
|
961
|
+
}
|
|
962
|
+
if (!onboarding.workspaceReady) {
|
|
963
|
+
deps.log(" \u2192 tostudy workspace setup");
|
|
964
|
+
}
|
|
965
|
+
deps.log(" \u2192 tostudy start ficar\xE1 dispon\xEDvel depois desses passos\n");
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
795
968
|
deps.log(" Setup completo!");
|
|
796
|
-
deps.log(" \u2192 tostudy
|
|
969
|
+
deps.log(" \u2192 tostudy start (iniciar ou retomar o m\xF3dulo atual)");
|
|
970
|
+
deps.log(" \u2192 tostudy courses (ver cursos matriculados)");
|
|
797
971
|
deps.log(" \u2192 tostudy doctor (diagn\xF3stico completo)\n");
|
|
798
972
|
}
|
|
799
973
|
async function runSetupMcpSubcommand() {
|
|
@@ -815,10 +989,13 @@ var init_setup = __esm({
|
|
|
815
989
|
init_ide_detector();
|
|
816
990
|
init_session();
|
|
817
991
|
init_mcp_setup();
|
|
992
|
+
init_status();
|
|
818
993
|
defaultDeps = {
|
|
819
994
|
detectNode,
|
|
820
995
|
detectIDEs,
|
|
821
996
|
getSession,
|
|
997
|
+
getActiveCourse,
|
|
998
|
+
getCourseOnboardingStatus,
|
|
822
999
|
exchangeCliSessionForMcpToken,
|
|
823
1000
|
runMcpSetup,
|
|
824
1001
|
log: (message = "") => {
|
|
@@ -843,20 +1020,20 @@ __export(update_checker_exports, {
|
|
|
843
1020
|
fetchLatestVersion: () => fetchLatestVersion,
|
|
844
1021
|
isNewerVersion: () => isNewerVersion
|
|
845
1022
|
});
|
|
846
|
-
import
|
|
847
|
-
import
|
|
848
|
-
import
|
|
1023
|
+
import fs6 from "node:fs";
|
|
1024
|
+
import path6 from "node:path";
|
|
1025
|
+
import os5 from "node:os";
|
|
849
1026
|
function getConfigDir2() {
|
|
850
1027
|
if (process.platform === "linux" && process.env["XDG_CONFIG_HOME"]) {
|
|
851
|
-
return
|
|
1028
|
+
return path6.join(process.env["XDG_CONFIG_HOME"], "tostudy");
|
|
852
1029
|
}
|
|
853
|
-
return
|
|
1030
|
+
return path6.join(os5.homedir(), ".tostudy");
|
|
854
1031
|
}
|
|
855
1032
|
function readCache() {
|
|
856
1033
|
try {
|
|
857
|
-
const p =
|
|
858
|
-
if (!
|
|
859
|
-
return JSON.parse(
|
|
1034
|
+
const p = path6.join(getConfigDir2(), CACHE_FILE);
|
|
1035
|
+
if (!fs6.existsSync(p)) return null;
|
|
1036
|
+
return JSON.parse(fs6.readFileSync(p, "utf-8"));
|
|
860
1037
|
} catch {
|
|
861
1038
|
return null;
|
|
862
1039
|
}
|
|
@@ -864,8 +1041,8 @@ function readCache() {
|
|
|
864
1041
|
function writeCache(cache) {
|
|
865
1042
|
try {
|
|
866
1043
|
const dir = getConfigDir2();
|
|
867
|
-
|
|
868
|
-
|
|
1044
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
1045
|
+
fs6.writeFileSync(path6.join(dir, CACHE_FILE), JSON.stringify(cache));
|
|
869
1046
|
} catch {
|
|
870
1047
|
}
|
|
871
1048
|
}
|
|
@@ -1111,7 +1288,7 @@ var init_context = __esm({
|
|
|
1111
1288
|
// ../../packages/logger/src/formatters/json.ts
|
|
1112
1289
|
function formatJson(entry) {
|
|
1113
1290
|
const { timestamp: timestamp2, level, message, service, environment, context, data, error: error49 } = entry;
|
|
1114
|
-
const
|
|
1291
|
+
const output3 = {
|
|
1115
1292
|
timestamp: timestamp2,
|
|
1116
1293
|
level,
|
|
1117
1294
|
message,
|
|
@@ -1121,9 +1298,9 @@ function formatJson(entry) {
|
|
|
1121
1298
|
...data
|
|
1122
1299
|
};
|
|
1123
1300
|
if (error49) {
|
|
1124
|
-
|
|
1301
|
+
output3.error = error49;
|
|
1125
1302
|
}
|
|
1126
|
-
return JSON.stringify(
|
|
1303
|
+
return JSON.stringify(output3);
|
|
1127
1304
|
}
|
|
1128
1305
|
var init_json = __esm({
|
|
1129
1306
|
"../../packages/logger/src/formatters/json.ts"() {
|
|
@@ -1138,8 +1315,8 @@ var require_picocolors = __commonJS({
|
|
|
1138
1315
|
var argv = p.argv || [];
|
|
1139
1316
|
var env = p.env || {};
|
|
1140
1317
|
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);
|
|
1141
|
-
var formatter = (open, close, replace = open) => (
|
|
1142
|
-
let string4 = "" +
|
|
1318
|
+
var formatter = (open, close, replace = open) => (input2) => {
|
|
1319
|
+
let string4 = "" + input2, index2 = string4.indexOf(close, open.length);
|
|
1143
1320
|
return ~index2 ? open + replaceClose(string4, close, replace, index2) + close : open + string4 + close;
|
|
1144
1321
|
};
|
|
1145
1322
|
var replaceClose = (string4, close, replace, index2) => {
|
|
@@ -1230,7 +1407,7 @@ function formatPretty(entry) {
|
|
|
1230
1407
|
const lvl = formatLevel(level);
|
|
1231
1408
|
const mod = context.module ? import_picocolors.default.dim(`[${context.module}]`) + " " : "";
|
|
1232
1409
|
const svc = import_picocolors.default.dim(`[${service}]`) + " ";
|
|
1233
|
-
let
|
|
1410
|
+
let output3 = `${import_picocolors.default.dim(time4)} ${lvl} ${svc}${mod}${message}`;
|
|
1234
1411
|
const traceInfo = {};
|
|
1235
1412
|
if (context.traceId) traceInfo.traceId = context.traceId;
|
|
1236
1413
|
if (context.requestId && context.requestId !== context.traceId) {
|
|
@@ -1240,22 +1417,22 @@ function formatPretty(entry) {
|
|
|
1240
1417
|
if (context.duration !== void 0) traceInfo.duration = `${context.duration}ms`;
|
|
1241
1418
|
const allData = { ...traceInfo, ...data };
|
|
1242
1419
|
if (Object.keys(allData).length > 0) {
|
|
1243
|
-
|
|
1420
|
+
output3 += formatData(allData);
|
|
1244
1421
|
}
|
|
1245
1422
|
if (error49) {
|
|
1246
|
-
|
|
1423
|
+
output3 += "\n" + import_picocolors.default.red(` ${error49.name}: ${error49.message}`);
|
|
1247
1424
|
if (error49.code) {
|
|
1248
|
-
|
|
1425
|
+
output3 += import_picocolors.default.dim(` (${error49.code})`);
|
|
1249
1426
|
}
|
|
1250
1427
|
if (error49.stack) {
|
|
1251
1428
|
const stackLines = error49.stack.split("\n").slice(1, 4);
|
|
1252
|
-
|
|
1429
|
+
output3 += "\n" + stackLines.map((l) => import_picocolors.default.dim(` ${l.trim()}`)).join("\n");
|
|
1253
1430
|
}
|
|
1254
1431
|
if (error49.cause) {
|
|
1255
|
-
|
|
1432
|
+
output3 += "\n" + import_picocolors.default.dim(` Caused by: ${error49.cause.name}: ${error49.cause.message}`);
|
|
1256
1433
|
}
|
|
1257
1434
|
}
|
|
1258
|
-
return
|
|
1435
|
+
return output3;
|
|
1259
1436
|
}
|
|
1260
1437
|
var import_picocolors, LEVEL_COLORS, LEVEL_WIDTH;
|
|
1261
1438
|
var init_pretty = __esm({
|
|
@@ -1343,6 +1520,22 @@ function isSensitiveKey(key) {
|
|
|
1343
1520
|
return patterns.some((p) => lowerKey.includes(p));
|
|
1344
1521
|
});
|
|
1345
1522
|
}
|
|
1523
|
+
function serializeError(error49) {
|
|
1524
|
+
const serialized = {
|
|
1525
|
+
name: error49.name,
|
|
1526
|
+
message: error49.message
|
|
1527
|
+
};
|
|
1528
|
+
if (error49.stack) {
|
|
1529
|
+
serialized.stack = error49.stack;
|
|
1530
|
+
}
|
|
1531
|
+
if ("code" in error49 && typeof error49.code === "string") {
|
|
1532
|
+
serialized.code = error49.code;
|
|
1533
|
+
}
|
|
1534
|
+
if (error49.cause instanceof Error) {
|
|
1535
|
+
serialized.cause = serializeError(error49.cause);
|
|
1536
|
+
}
|
|
1537
|
+
return serialized;
|
|
1538
|
+
}
|
|
1346
1539
|
function object(obj, additionalSensitiveKeys) {
|
|
1347
1540
|
if (!obj || typeof obj !== "object") return obj;
|
|
1348
1541
|
const sanitized = { ...obj };
|
|
@@ -1354,6 +1547,10 @@ function object(obj, additionalSensitiveKeys) {
|
|
|
1354
1547
|
sanitized[key] = "[REDACTED]";
|
|
1355
1548
|
continue;
|
|
1356
1549
|
}
|
|
1550
|
+
if (value instanceof Error) {
|
|
1551
|
+
sanitized[key] = serializeError(value);
|
|
1552
|
+
continue;
|
|
1553
|
+
}
|
|
1357
1554
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1358
1555
|
sanitized[key] = object(
|
|
1359
1556
|
value,
|
|
@@ -1363,6 +1560,7 @@ function object(obj, additionalSensitiveKeys) {
|
|
|
1363
1560
|
}
|
|
1364
1561
|
if (Array.isArray(value)) {
|
|
1365
1562
|
sanitized[key] = value.map((item) => {
|
|
1563
|
+
if (item instanceof Error) return serializeError(item);
|
|
1366
1564
|
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
1367
1565
|
return object(item, additionalSensitiveKeys);
|
|
1368
1566
|
}
|
|
@@ -1373,13 +1571,7 @@ function object(obj, additionalSensitiveKeys) {
|
|
|
1373
1571
|
return sanitized;
|
|
1374
1572
|
}
|
|
1375
1573
|
function headers(hdrs) {
|
|
1376
|
-
const sensitiveHeaders = [
|
|
1377
|
-
"authorization",
|
|
1378
|
-
"x-api-key",
|
|
1379
|
-
"x-auth-token",
|
|
1380
|
-
"cookie",
|
|
1381
|
-
"set-cookie"
|
|
1382
|
-
];
|
|
1574
|
+
const sensitiveHeaders = ["authorization", "x-api-key", "x-auth-token", "cookie", "set-cookie"];
|
|
1383
1575
|
const sanitized = { ...hdrs };
|
|
1384
1576
|
for (const key of Object.keys(sanitized)) {
|
|
1385
1577
|
if (sensitiveHeaders.some((h) => key.toLowerCase() === h)) {
|
|
@@ -1957,9 +2149,9 @@ var init_src = __esm({
|
|
|
1957
2149
|
});
|
|
1958
2150
|
|
|
1959
2151
|
// ../../packages/tostudy-core/src/courses/list-courses.ts
|
|
1960
|
-
async function listCourses(
|
|
1961
|
-
deps.logger.info("tostudy-core: listCourses", { userId:
|
|
1962
|
-
return deps.data.courses.list(
|
|
2152
|
+
async function listCourses(input2, deps) {
|
|
2153
|
+
deps.logger.info("tostudy-core: listCourses", { userId: input2.userId });
|
|
2154
|
+
return deps.data.courses.list(input2.userId);
|
|
1963
2155
|
}
|
|
1964
2156
|
var init_list_courses = __esm({
|
|
1965
2157
|
"../../packages/tostudy-core/src/courses/list-courses.ts"() {
|
|
@@ -1968,9 +2160,9 @@ var init_list_courses = __esm({
|
|
|
1968
2160
|
});
|
|
1969
2161
|
|
|
1970
2162
|
// ../../packages/tostudy-core/src/courses/select-course.ts
|
|
1971
|
-
async function selectCourse(
|
|
1972
|
-
deps.logger.info("tostudy-core: selectCourse",
|
|
1973
|
-
return deps.data.courses.select(
|
|
2163
|
+
async function selectCourse(input2, deps) {
|
|
2164
|
+
deps.logger.info("tostudy-core: selectCourse", input2);
|
|
2165
|
+
return deps.data.courses.select(input2.userId, input2.courseId);
|
|
1974
2166
|
}
|
|
1975
2167
|
var init_select_course = __esm({
|
|
1976
2168
|
"../../packages/tostudy-core/src/courses/select-course.ts"() {
|
|
@@ -1979,9 +2171,9 @@ var init_select_course = __esm({
|
|
|
1979
2171
|
});
|
|
1980
2172
|
|
|
1981
2173
|
// ../../packages/tostudy-core/src/courses/get-progress.ts
|
|
1982
|
-
async function getProgress(
|
|
1983
|
-
deps.logger.info("tostudy-core: getProgress",
|
|
1984
|
-
return deps.data.courses.getProgress(
|
|
2174
|
+
async function getProgress(input2, deps) {
|
|
2175
|
+
deps.logger.info("tostudy-core: getProgress", input2);
|
|
2176
|
+
return deps.data.courses.getProgress(input2.enrollmentId);
|
|
1985
2177
|
}
|
|
1986
2178
|
var init_get_progress = __esm({
|
|
1987
2179
|
"../../packages/tostudy-core/src/courses/get-progress.ts"() {
|
|
@@ -2176,11 +2368,14 @@ var init_select = __esm({
|
|
|
2176
2368
|
enrollmentId = found.enrollmentId;
|
|
2177
2369
|
}
|
|
2178
2370
|
}
|
|
2371
|
+
const matched = courses3.find((c) => c.courseId === courseId);
|
|
2179
2372
|
const detail = await selectCourse({ userId: session.userId, courseId }, deps);
|
|
2180
2373
|
await setActiveCourse({
|
|
2181
2374
|
courseId: detail.courseId,
|
|
2182
2375
|
courseTitle: detail.courseTitle,
|
|
2183
|
-
enrollmentId
|
|
2376
|
+
enrollmentId,
|
|
2377
|
+
courseTags: matched?.tags,
|
|
2378
|
+
courseLevel: matched?.level
|
|
2184
2379
|
});
|
|
2185
2380
|
if (opts.json) {
|
|
2186
2381
|
output({ ...detail, enrollmentId }, { json: true });
|
|
@@ -2240,9 +2435,9 @@ var init_progress = __esm({
|
|
|
2240
2435
|
});
|
|
2241
2436
|
|
|
2242
2437
|
// ../../packages/tostudy-core/src/lessons/next-lesson.ts
|
|
2243
|
-
async function nextLesson(
|
|
2244
|
-
deps.logger.info("tostudy-core: nextLesson", { enrollmentId:
|
|
2245
|
-
return deps.data.lessons.next(
|
|
2438
|
+
async function nextLesson(input2, deps) {
|
|
2439
|
+
deps.logger.info("tostudy-core: nextLesson", { enrollmentId: input2.enrollmentId });
|
|
2440
|
+
return deps.data.lessons.next(input2.enrollmentId, input2.userConfirmation);
|
|
2246
2441
|
}
|
|
2247
2442
|
var init_next_lesson = __esm({
|
|
2248
2443
|
"../../packages/tostudy-core/src/lessons/next-lesson.ts"() {
|
|
@@ -2251,9 +2446,9 @@ var init_next_lesson = __esm({
|
|
|
2251
2446
|
});
|
|
2252
2447
|
|
|
2253
2448
|
// ../../packages/tostudy-core/src/lessons/get-content.ts
|
|
2254
|
-
async function getContent(
|
|
2255
|
-
deps.logger.info("tostudy-core: getContent", { lessonId:
|
|
2256
|
-
return deps.data.lessons.getContent(
|
|
2449
|
+
async function getContent(input2, deps) {
|
|
2450
|
+
deps.logger.info("tostudy-core: getContent", { lessonId: input2.lessonId });
|
|
2451
|
+
return deps.data.lessons.getContent(input2.lessonId, input2.enrollmentId);
|
|
2257
2452
|
}
|
|
2258
2453
|
var init_get_content = __esm({
|
|
2259
2454
|
"../../packages/tostudy-core/src/lessons/get-content.ts"() {
|
|
@@ -2262,9 +2457,9 @@ var init_get_content = __esm({
|
|
|
2262
2457
|
});
|
|
2263
2458
|
|
|
2264
2459
|
// ../../packages/tostudy-core/src/lessons/get-hint.ts
|
|
2265
|
-
async function getHint(
|
|
2266
|
-
deps.logger.info("tostudy-core: getHint", { userId:
|
|
2267
|
-
return deps.data.lessons.getHint(
|
|
2460
|
+
async function getHint(input2, deps) {
|
|
2461
|
+
deps.logger.info("tostudy-core: getHint", { userId: input2.userId });
|
|
2462
|
+
return deps.data.lessons.getHint(input2.userId, input2.enrollmentId);
|
|
2268
2463
|
}
|
|
2269
2464
|
var init_get_hint = __esm({
|
|
2270
2465
|
"../../packages/tostudy-core/src/lessons/get-hint.ts"() {
|
|
@@ -2273,9 +2468,9 @@ var init_get_hint = __esm({
|
|
|
2273
2468
|
});
|
|
2274
2469
|
|
|
2275
2470
|
// ../../packages/tostudy-core/src/lessons/start-module.ts
|
|
2276
|
-
async function startModule(
|
|
2277
|
-
deps.logger.info("tostudy-core: startModule", { enrollmentId:
|
|
2278
|
-
return deps.data.lessons.startModule(
|
|
2471
|
+
async function startModule(input2, deps) {
|
|
2472
|
+
deps.logger.info("tostudy-core: startModule", { enrollmentId: input2.enrollmentId });
|
|
2473
|
+
return deps.data.lessons.startModule(input2.enrollmentId);
|
|
2279
2474
|
}
|
|
2280
2475
|
var init_start_module = __esm({
|
|
2281
2476
|
"../../packages/tostudy-core/src/lessons/start-module.ts"() {
|
|
@@ -2284,9 +2479,9 @@ var init_start_module = __esm({
|
|
|
2284
2479
|
});
|
|
2285
2480
|
|
|
2286
2481
|
// ../../packages/tostudy-core/src/lessons/start-next-module.ts
|
|
2287
|
-
async function startNextModule(
|
|
2288
|
-
deps.logger.info("tostudy-core: startNextModule", { enrollmentId:
|
|
2289
|
-
return deps.data.lessons.startNextModule(
|
|
2482
|
+
async function startNextModule(input2, deps) {
|
|
2483
|
+
deps.logger.info("tostudy-core: startNextModule", { enrollmentId: input2.enrollmentId });
|
|
2484
|
+
return deps.data.lessons.startNextModule(input2.enrollmentId);
|
|
2290
2485
|
}
|
|
2291
2486
|
var init_start_next_module = __esm({
|
|
2292
2487
|
"../../packages/tostudy-core/src/lessons/start-next-module.ts"() {
|
|
@@ -2923,8 +3118,8 @@ var init_common = __esm({
|
|
|
2923
3118
|
function isPgEnum(obj) {
|
|
2924
3119
|
return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
|
|
2925
3120
|
}
|
|
2926
|
-
function pgEnum(enumName,
|
|
2927
|
-
return Array.isArray(
|
|
3121
|
+
function pgEnum(enumName, input2) {
|
|
3122
|
+
return Array.isArray(input2) ? pgEnumWithSchema(enumName, [...input2], void 0) : pgEnumObjectWithSchema(enumName, input2, void 0);
|
|
2928
3123
|
}
|
|
2929
3124
|
function pgEnumWithSchema(enumName, values2, schema) {
|
|
2930
3125
|
const enumInstance = Object.assign(
|
|
@@ -3785,7 +3980,7 @@ var init_query_promise = __esm({
|
|
|
3785
3980
|
function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
3786
3981
|
const nullifyMap = {};
|
|
3787
3982
|
const result = columns.reduce(
|
|
3788
|
-
(result2, { path:
|
|
3983
|
+
(result2, { path: path15, field }, columnIndex) => {
|
|
3789
3984
|
let decoder;
|
|
3790
3985
|
if (is(field, Column)) {
|
|
3791
3986
|
decoder = field;
|
|
@@ -3797,8 +3992,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
|
3797
3992
|
decoder = field.sql.decoder;
|
|
3798
3993
|
}
|
|
3799
3994
|
let node = result2;
|
|
3800
|
-
for (const [pathChunkIndex, pathChunk] of
|
|
3801
|
-
if (pathChunkIndex <
|
|
3995
|
+
for (const [pathChunkIndex, pathChunk] of path15.entries()) {
|
|
3996
|
+
if (pathChunkIndex < path15.length - 1) {
|
|
3802
3997
|
if (!(pathChunk in node)) {
|
|
3803
3998
|
node[pathChunk] = {};
|
|
3804
3999
|
}
|
|
@@ -3806,8 +4001,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
|
3806
4001
|
} else {
|
|
3807
4002
|
const rawValue = row[columnIndex];
|
|
3808
4003
|
const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
|
|
3809
|
-
if (joinsNotNullableMap && is(field, Column) &&
|
|
3810
|
-
const objectName =
|
|
4004
|
+
if (joinsNotNullableMap && is(field, Column) && path15.length === 2) {
|
|
4005
|
+
const objectName = path15[0];
|
|
3811
4006
|
if (!(objectName in nullifyMap)) {
|
|
3812
4007
|
nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
|
|
3813
4008
|
} else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
|
|
@@ -7754,13 +7949,13 @@ function Subscribe(postgres2, options) {
|
|
|
7754
7949
|
}
|
|
7755
7950
|
}
|
|
7756
7951
|
function handle(a, b2) {
|
|
7757
|
-
const
|
|
7952
|
+
const path15 = b2.relation.schema + "." + b2.relation.table;
|
|
7758
7953
|
call("*", a, b2);
|
|
7759
|
-
call("*:" +
|
|
7760
|
-
b2.relation.keys.length && call("*:" +
|
|
7954
|
+
call("*:" + path15, a, b2);
|
|
7955
|
+
b2.relation.keys.length && call("*:" + path15 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
|
|
7761
7956
|
call(b2.command, a, b2);
|
|
7762
|
-
call(b2.command + ":" +
|
|
7763
|
-
b2.relation.keys.length && call(b2.command + ":" +
|
|
7957
|
+
call(b2.command + ":" + path15, a, b2);
|
|
7958
|
+
b2.relation.keys.length && call(b2.command + ":" + path15 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
|
|
7764
7959
|
}
|
|
7765
7960
|
function pong() {
|
|
7766
7961
|
const x2 = Buffer.alloc(34);
|
|
@@ -7873,8 +8068,8 @@ function parseEvent(x) {
|
|
|
7873
8068
|
const xs = x.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i) || [];
|
|
7874
8069
|
if (!xs)
|
|
7875
8070
|
throw new Error("Malformed subscribe pattern: " + x);
|
|
7876
|
-
const [, command,
|
|
7877
|
-
return (command || "*") + (
|
|
8071
|
+
const [, command, path15, key] = xs;
|
|
8072
|
+
return (command || "*") + (path15 ? ":" + (path15.indexOf(".") === -1 ? "public." + path15 : path15) : "") + (key ? "=" + key : "");
|
|
7878
8073
|
}
|
|
7879
8074
|
var noop2;
|
|
7880
8075
|
var init_subscribe = __esm({
|
|
@@ -7955,8 +8150,8 @@ var init_large = __esm({
|
|
|
7955
8150
|
});
|
|
7956
8151
|
|
|
7957
8152
|
// ../../node_modules/postgres/src/index.js
|
|
7958
|
-
import
|
|
7959
|
-
import
|
|
8153
|
+
import os6 from "os";
|
|
8154
|
+
import fs7 from "fs";
|
|
7960
8155
|
function Postgres(a, b2) {
|
|
7961
8156
|
const options = parseOptions(a, b2), subscribe = options.no_subscribe || Subscribe(Postgres, { ...options });
|
|
7962
8157
|
let ending = false;
|
|
@@ -8012,10 +8207,10 @@ function Postgres(a, b2) {
|
|
|
8012
8207
|
});
|
|
8013
8208
|
return query;
|
|
8014
8209
|
}
|
|
8015
|
-
function file2(
|
|
8210
|
+
function file2(path15, args = [], options2 = {}) {
|
|
8016
8211
|
arguments.length === 2 && !Array.isArray(args) && (options2 = args, args = []);
|
|
8017
8212
|
const query = new Query([], args, (query2) => {
|
|
8018
|
-
|
|
8213
|
+
fs7.readFile(path15, "utf8", (err, string4) => {
|
|
8019
8214
|
if (err)
|
|
8020
8215
|
return query2.reject(err);
|
|
8021
8216
|
query2.strings = [string4];
|
|
@@ -8333,7 +8528,7 @@ function parseUrl(url2) {
|
|
|
8333
8528
|
}
|
|
8334
8529
|
function osUsername() {
|
|
8335
8530
|
try {
|
|
8336
|
-
return
|
|
8531
|
+
return os6.userInfo().username;
|
|
8337
8532
|
} catch (_) {
|
|
8338
8533
|
return process.env.USERNAME || process.env.USER || process.env.LOGNAME;
|
|
8339
8534
|
}
|
|
@@ -8685,19 +8880,19 @@ var init_view_common2 = __esm({
|
|
|
8685
8880
|
});
|
|
8686
8881
|
|
|
8687
8882
|
// ../../node_modules/drizzle-orm/casing.js
|
|
8688
|
-
function toSnakeCase(
|
|
8689
|
-
const words =
|
|
8883
|
+
function toSnakeCase(input2) {
|
|
8884
|
+
const words = input2.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
|
|
8690
8885
|
return words.map((word) => word.toLowerCase()).join("_");
|
|
8691
8886
|
}
|
|
8692
|
-
function toCamelCase(
|
|
8693
|
-
const words =
|
|
8887
|
+
function toCamelCase(input2) {
|
|
8888
|
+
const words = input2.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
|
|
8694
8889
|
return words.reduce((acc, word, i) => {
|
|
8695
8890
|
const formattedWord = i === 0 ? word.toLowerCase() : `${word[0].toUpperCase()}${word.slice(1)}`;
|
|
8696
8891
|
return acc + formattedWord;
|
|
8697
8892
|
}, "");
|
|
8698
8893
|
}
|
|
8699
|
-
function noopCase(
|
|
8700
|
-
return
|
|
8894
|
+
function noopCase(input2) {
|
|
8895
|
+
return input2;
|
|
8701
8896
|
}
|
|
8702
8897
|
var CasingCache;
|
|
8703
8898
|
var init_casing = __esm({
|
|
@@ -12350,12 +12545,12 @@ var init_schema = __esm({
|
|
|
12350
12545
|
materializedView = (name, columns) => {
|
|
12351
12546
|
return pgMaterializedViewWithSchema(name, columns, this.schemaName);
|
|
12352
12547
|
};
|
|
12353
|
-
enum(enumName,
|
|
12354
|
-
return Array.isArray(
|
|
12548
|
+
enum(enumName, input2) {
|
|
12549
|
+
return Array.isArray(input2) ? pgEnumWithSchema(
|
|
12355
12550
|
enumName,
|
|
12356
|
-
[...
|
|
12551
|
+
[...input2],
|
|
12357
12552
|
this.schemaName
|
|
12358
|
-
) : pgEnumObjectWithSchema(enumName,
|
|
12553
|
+
) : pgEnumObjectWithSchema(enumName, input2, this.schemaName);
|
|
12359
12554
|
}
|
|
12360
12555
|
sequence = (name, options) => {
|
|
12361
12556
|
return pgSequenceWithSchema(name, options, this.schemaName);
|
|
@@ -13006,8 +13201,8 @@ function cached(getter) {
|
|
|
13006
13201
|
}
|
|
13007
13202
|
};
|
|
13008
13203
|
}
|
|
13009
|
-
function nullish(
|
|
13010
|
-
return
|
|
13204
|
+
function nullish(input2) {
|
|
13205
|
+
return input2 === null || input2 === void 0;
|
|
13011
13206
|
}
|
|
13012
13207
|
function cleanRegex(source) {
|
|
13013
13208
|
const start = source.startsWith("^") ? 1 : 0;
|
|
@@ -13073,10 +13268,10 @@ function mergeDefs(...defs) {
|
|
|
13073
13268
|
function cloneDef(schema) {
|
|
13074
13269
|
return mergeDefs(schema._zod.def);
|
|
13075
13270
|
}
|
|
13076
|
-
function getElementAtPath(obj,
|
|
13077
|
-
if (!
|
|
13271
|
+
function getElementAtPath(obj, path15) {
|
|
13272
|
+
if (!path15)
|
|
13078
13273
|
return obj;
|
|
13079
|
-
return
|
|
13274
|
+
return path15.reduce((acc, key) => acc?.[key], obj);
|
|
13080
13275
|
}
|
|
13081
13276
|
function promiseAllObject(promisesObj) {
|
|
13082
13277
|
const keys = Object.keys(promisesObj);
|
|
@@ -13100,8 +13295,8 @@ function randomString(length = 10) {
|
|
|
13100
13295
|
function esc(str) {
|
|
13101
13296
|
return JSON.stringify(str);
|
|
13102
13297
|
}
|
|
13103
|
-
function slugify(
|
|
13104
|
-
return
|
|
13298
|
+
function slugify(input2) {
|
|
13299
|
+
return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
13105
13300
|
}
|
|
13106
13301
|
function isObject(data) {
|
|
13107
13302
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
@@ -13388,11 +13583,11 @@ function aborted(x, startIndex = 0) {
|
|
|
13388
13583
|
}
|
|
13389
13584
|
return false;
|
|
13390
13585
|
}
|
|
13391
|
-
function prefixIssues(
|
|
13586
|
+
function prefixIssues(path15, issues) {
|
|
13392
13587
|
return issues.map((iss) => {
|
|
13393
13588
|
var _a2;
|
|
13394
13589
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
13395
|
-
iss.path.unshift(
|
|
13590
|
+
iss.path.unshift(path15);
|
|
13396
13591
|
return iss;
|
|
13397
13592
|
});
|
|
13398
13593
|
}
|
|
@@ -13412,19 +13607,19 @@ function finalizeIssue(iss, ctx, config2) {
|
|
|
13412
13607
|
}
|
|
13413
13608
|
return full;
|
|
13414
13609
|
}
|
|
13415
|
-
function getSizableOrigin(
|
|
13416
|
-
if (
|
|
13610
|
+
function getSizableOrigin(input2) {
|
|
13611
|
+
if (input2 instanceof Set)
|
|
13417
13612
|
return "set";
|
|
13418
|
-
if (
|
|
13613
|
+
if (input2 instanceof Map)
|
|
13419
13614
|
return "map";
|
|
13420
|
-
if (
|
|
13615
|
+
if (input2 instanceof File)
|
|
13421
13616
|
return "file";
|
|
13422
13617
|
return "unknown";
|
|
13423
13618
|
}
|
|
13424
|
-
function getLengthableOrigin(
|
|
13425
|
-
if (Array.isArray(
|
|
13619
|
+
function getLengthableOrigin(input2) {
|
|
13620
|
+
if (Array.isArray(input2))
|
|
13426
13621
|
return "array";
|
|
13427
|
-
if (typeof
|
|
13622
|
+
if (typeof input2 === "string")
|
|
13428
13623
|
return "string";
|
|
13429
13624
|
return "unknown";
|
|
13430
13625
|
}
|
|
@@ -13450,12 +13645,12 @@ function parsedType(data) {
|
|
|
13450
13645
|
return t;
|
|
13451
13646
|
}
|
|
13452
13647
|
function issue(...args) {
|
|
13453
|
-
const [iss,
|
|
13648
|
+
const [iss, input2, inst] = args;
|
|
13454
13649
|
if (typeof iss === "string") {
|
|
13455
13650
|
return {
|
|
13456
13651
|
message: iss,
|
|
13457
13652
|
code: "custom",
|
|
13458
|
-
input,
|
|
13653
|
+
input: input2,
|
|
13459
13654
|
inst
|
|
13460
13655
|
};
|
|
13461
13656
|
}
|
|
@@ -13634,7 +13829,7 @@ function formatError(error49, mapper = (issue2) => issue2.message) {
|
|
|
13634
13829
|
}
|
|
13635
13830
|
function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
13636
13831
|
const result = { errors: [] };
|
|
13637
|
-
const processError = (error50,
|
|
13832
|
+
const processError = (error50, path15 = []) => {
|
|
13638
13833
|
var _a2, _b;
|
|
13639
13834
|
for (const issue2 of error50.issues) {
|
|
13640
13835
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -13644,7 +13839,7 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
13644
13839
|
} else if (issue2.code === "invalid_element") {
|
|
13645
13840
|
processError({ issues: issue2.issues }, issue2.path);
|
|
13646
13841
|
} else {
|
|
13647
|
-
const fullpath = [...
|
|
13842
|
+
const fullpath = [...path15, ...issue2.path];
|
|
13648
13843
|
if (fullpath.length === 0) {
|
|
13649
13844
|
result.errors.push(mapper(issue2));
|
|
13650
13845
|
continue;
|
|
@@ -13676,8 +13871,8 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
13676
13871
|
}
|
|
13677
13872
|
function toDotPath(_path) {
|
|
13678
13873
|
const segs = [];
|
|
13679
|
-
const
|
|
13680
|
-
for (const seg of
|
|
13874
|
+
const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
13875
|
+
for (const seg of path15) {
|
|
13681
13876
|
if (typeof seg === "number")
|
|
13682
13877
|
segs.push(`[${seg}]`);
|
|
13683
13878
|
else if (typeof seg === "symbol")
|
|
@@ -14103,23 +14298,23 @@ var init_checks2 = __esm({
|
|
|
14103
14298
|
bag.pattern = integer2;
|
|
14104
14299
|
});
|
|
14105
14300
|
inst._zod.check = (payload) => {
|
|
14106
|
-
const
|
|
14301
|
+
const input2 = payload.value;
|
|
14107
14302
|
if (isInt) {
|
|
14108
|
-
if (!Number.isInteger(
|
|
14303
|
+
if (!Number.isInteger(input2)) {
|
|
14109
14304
|
payload.issues.push({
|
|
14110
14305
|
expected: origin,
|
|
14111
14306
|
format: def.format,
|
|
14112
14307
|
code: "invalid_type",
|
|
14113
14308
|
continue: false,
|
|
14114
|
-
input,
|
|
14309
|
+
input: input2,
|
|
14115
14310
|
inst
|
|
14116
14311
|
});
|
|
14117
14312
|
return;
|
|
14118
14313
|
}
|
|
14119
|
-
if (!Number.isSafeInteger(
|
|
14120
|
-
if (
|
|
14314
|
+
if (!Number.isSafeInteger(input2)) {
|
|
14315
|
+
if (input2 > 0) {
|
|
14121
14316
|
payload.issues.push({
|
|
14122
|
-
input,
|
|
14317
|
+
input: input2,
|
|
14123
14318
|
code: "too_big",
|
|
14124
14319
|
maximum: Number.MAX_SAFE_INTEGER,
|
|
14125
14320
|
note: "Integers must be within the safe integer range.",
|
|
@@ -14130,7 +14325,7 @@ var init_checks2 = __esm({
|
|
|
14130
14325
|
});
|
|
14131
14326
|
} else {
|
|
14132
14327
|
payload.issues.push({
|
|
14133
|
-
input,
|
|
14328
|
+
input: input2,
|
|
14134
14329
|
code: "too_small",
|
|
14135
14330
|
minimum: Number.MIN_SAFE_INTEGER,
|
|
14136
14331
|
note: "Integers must be within the safe integer range.",
|
|
@@ -14143,10 +14338,10 @@ var init_checks2 = __esm({
|
|
|
14143
14338
|
return;
|
|
14144
14339
|
}
|
|
14145
14340
|
}
|
|
14146
|
-
if (
|
|
14341
|
+
if (input2 < minimum) {
|
|
14147
14342
|
payload.issues.push({
|
|
14148
14343
|
origin: "number",
|
|
14149
|
-
input,
|
|
14344
|
+
input: input2,
|
|
14150
14345
|
code: "too_small",
|
|
14151
14346
|
minimum,
|
|
14152
14347
|
inclusive: true,
|
|
@@ -14154,10 +14349,10 @@ var init_checks2 = __esm({
|
|
|
14154
14349
|
continue: !def.abort
|
|
14155
14350
|
});
|
|
14156
14351
|
}
|
|
14157
|
-
if (
|
|
14352
|
+
if (input2 > maximum) {
|
|
14158
14353
|
payload.issues.push({
|
|
14159
14354
|
origin: "number",
|
|
14160
|
-
input,
|
|
14355
|
+
input: input2,
|
|
14161
14356
|
code: "too_big",
|
|
14162
14357
|
maximum,
|
|
14163
14358
|
inclusive: true,
|
|
@@ -14177,11 +14372,11 @@ var init_checks2 = __esm({
|
|
|
14177
14372
|
bag.maximum = maximum;
|
|
14178
14373
|
});
|
|
14179
14374
|
inst._zod.check = (payload) => {
|
|
14180
|
-
const
|
|
14181
|
-
if (
|
|
14375
|
+
const input2 = payload.value;
|
|
14376
|
+
if (input2 < minimum) {
|
|
14182
14377
|
payload.issues.push({
|
|
14183
14378
|
origin: "bigint",
|
|
14184
|
-
input,
|
|
14379
|
+
input: input2,
|
|
14185
14380
|
code: "too_small",
|
|
14186
14381
|
minimum,
|
|
14187
14382
|
inclusive: true,
|
|
@@ -14189,10 +14384,10 @@ var init_checks2 = __esm({
|
|
|
14189
14384
|
continue: !def.abort
|
|
14190
14385
|
});
|
|
14191
14386
|
}
|
|
14192
|
-
if (
|
|
14387
|
+
if (input2 > maximum) {
|
|
14193
14388
|
payload.issues.push({
|
|
14194
14389
|
origin: "bigint",
|
|
14195
|
-
input,
|
|
14390
|
+
input: input2,
|
|
14196
14391
|
code: "too_big",
|
|
14197
14392
|
maximum,
|
|
14198
14393
|
inclusive: true,
|
|
@@ -14215,16 +14410,16 @@ var init_checks2 = __esm({
|
|
|
14215
14410
|
inst2._zod.bag.maximum = def.maximum;
|
|
14216
14411
|
});
|
|
14217
14412
|
inst._zod.check = (payload) => {
|
|
14218
|
-
const
|
|
14219
|
-
const size2 =
|
|
14413
|
+
const input2 = payload.value;
|
|
14414
|
+
const size2 = input2.size;
|
|
14220
14415
|
if (size2 <= def.maximum)
|
|
14221
14416
|
return;
|
|
14222
14417
|
payload.issues.push({
|
|
14223
|
-
origin: getSizableOrigin(
|
|
14418
|
+
origin: getSizableOrigin(input2),
|
|
14224
14419
|
code: "too_big",
|
|
14225
14420
|
maximum: def.maximum,
|
|
14226
14421
|
inclusive: true,
|
|
14227
|
-
input,
|
|
14422
|
+
input: input2,
|
|
14228
14423
|
inst,
|
|
14229
14424
|
continue: !def.abort
|
|
14230
14425
|
});
|
|
@@ -14243,16 +14438,16 @@ var init_checks2 = __esm({
|
|
|
14243
14438
|
inst2._zod.bag.minimum = def.minimum;
|
|
14244
14439
|
});
|
|
14245
14440
|
inst._zod.check = (payload) => {
|
|
14246
|
-
const
|
|
14247
|
-
const size2 =
|
|
14441
|
+
const input2 = payload.value;
|
|
14442
|
+
const size2 = input2.size;
|
|
14248
14443
|
if (size2 >= def.minimum)
|
|
14249
14444
|
return;
|
|
14250
14445
|
payload.issues.push({
|
|
14251
|
-
origin: getSizableOrigin(
|
|
14446
|
+
origin: getSizableOrigin(input2),
|
|
14252
14447
|
code: "too_small",
|
|
14253
14448
|
minimum: def.minimum,
|
|
14254
14449
|
inclusive: true,
|
|
14255
|
-
input,
|
|
14450
|
+
input: input2,
|
|
14256
14451
|
inst,
|
|
14257
14452
|
continue: !def.abort
|
|
14258
14453
|
});
|
|
@@ -14272,13 +14467,13 @@ var init_checks2 = __esm({
|
|
|
14272
14467
|
bag.size = def.size;
|
|
14273
14468
|
});
|
|
14274
14469
|
inst._zod.check = (payload) => {
|
|
14275
|
-
const
|
|
14276
|
-
const size2 =
|
|
14470
|
+
const input2 = payload.value;
|
|
14471
|
+
const size2 = input2.size;
|
|
14277
14472
|
if (size2 === def.size)
|
|
14278
14473
|
return;
|
|
14279
14474
|
const tooBig = size2 > def.size;
|
|
14280
14475
|
payload.issues.push({
|
|
14281
|
-
origin: getSizableOrigin(
|
|
14476
|
+
origin: getSizableOrigin(input2),
|
|
14282
14477
|
...tooBig ? { code: "too_big", maximum: def.size } : { code: "too_small", minimum: def.size },
|
|
14283
14478
|
inclusive: true,
|
|
14284
14479
|
exact: true,
|
|
@@ -14301,17 +14496,17 @@ var init_checks2 = __esm({
|
|
|
14301
14496
|
inst2._zod.bag.maximum = def.maximum;
|
|
14302
14497
|
});
|
|
14303
14498
|
inst._zod.check = (payload) => {
|
|
14304
|
-
const
|
|
14305
|
-
const length =
|
|
14499
|
+
const input2 = payload.value;
|
|
14500
|
+
const length = input2.length;
|
|
14306
14501
|
if (length <= def.maximum)
|
|
14307
14502
|
return;
|
|
14308
|
-
const origin = getLengthableOrigin(
|
|
14503
|
+
const origin = getLengthableOrigin(input2);
|
|
14309
14504
|
payload.issues.push({
|
|
14310
14505
|
origin,
|
|
14311
14506
|
code: "too_big",
|
|
14312
14507
|
maximum: def.maximum,
|
|
14313
14508
|
inclusive: true,
|
|
14314
|
-
input,
|
|
14509
|
+
input: input2,
|
|
14315
14510
|
inst,
|
|
14316
14511
|
continue: !def.abort
|
|
14317
14512
|
});
|
|
@@ -14330,17 +14525,17 @@ var init_checks2 = __esm({
|
|
|
14330
14525
|
inst2._zod.bag.minimum = def.minimum;
|
|
14331
14526
|
});
|
|
14332
14527
|
inst._zod.check = (payload) => {
|
|
14333
|
-
const
|
|
14334
|
-
const length =
|
|
14528
|
+
const input2 = payload.value;
|
|
14529
|
+
const length = input2.length;
|
|
14335
14530
|
if (length >= def.minimum)
|
|
14336
14531
|
return;
|
|
14337
|
-
const origin = getLengthableOrigin(
|
|
14532
|
+
const origin = getLengthableOrigin(input2);
|
|
14338
14533
|
payload.issues.push({
|
|
14339
14534
|
origin,
|
|
14340
14535
|
code: "too_small",
|
|
14341
14536
|
minimum: def.minimum,
|
|
14342
14537
|
inclusive: true,
|
|
14343
|
-
input,
|
|
14538
|
+
input: input2,
|
|
14344
14539
|
inst,
|
|
14345
14540
|
continue: !def.abort
|
|
14346
14541
|
});
|
|
@@ -14360,11 +14555,11 @@ var init_checks2 = __esm({
|
|
|
14360
14555
|
bag.length = def.length;
|
|
14361
14556
|
});
|
|
14362
14557
|
inst._zod.check = (payload) => {
|
|
14363
|
-
const
|
|
14364
|
-
const length =
|
|
14558
|
+
const input2 = payload.value;
|
|
14559
|
+
const length = input2.length;
|
|
14365
14560
|
if (length === def.length)
|
|
14366
14561
|
return;
|
|
14367
|
-
const origin = getLengthableOrigin(
|
|
14562
|
+
const origin = getLengthableOrigin(input2);
|
|
14368
14563
|
const tooBig = length > def.length;
|
|
14369
14564
|
payload.issues.push({
|
|
14370
14565
|
origin,
|
|
@@ -14642,15 +14837,15 @@ function handleArrayResult(result, final, index2) {
|
|
|
14642
14837
|
}
|
|
14643
14838
|
final.value[index2] = result.value;
|
|
14644
14839
|
}
|
|
14645
|
-
function handlePropertyResult(result, final, key,
|
|
14840
|
+
function handlePropertyResult(result, final, key, input2, isOptionalOut) {
|
|
14646
14841
|
if (result.issues.length) {
|
|
14647
|
-
if (isOptionalOut && !(key in
|
|
14842
|
+
if (isOptionalOut && !(key in input2)) {
|
|
14648
14843
|
return;
|
|
14649
14844
|
}
|
|
14650
14845
|
final.issues.push(...prefixIssues(key, result.issues));
|
|
14651
14846
|
}
|
|
14652
14847
|
if (result.value === void 0) {
|
|
14653
|
-
if (key in
|
|
14848
|
+
if (key in input2) {
|
|
14654
14849
|
final.value[key] = void 0;
|
|
14655
14850
|
}
|
|
14656
14851
|
} else {
|
|
@@ -14673,31 +14868,31 @@ function normalizeDef(def) {
|
|
|
14673
14868
|
optionalKeys: new Set(okeys)
|
|
14674
14869
|
};
|
|
14675
14870
|
}
|
|
14676
|
-
function handleCatchall(proms,
|
|
14871
|
+
function handleCatchall(proms, input2, payload, ctx, def, inst) {
|
|
14677
14872
|
const unrecognized = [];
|
|
14678
14873
|
const keySet = def.keySet;
|
|
14679
14874
|
const _catchall = def.catchall._zod;
|
|
14680
14875
|
const t = _catchall.def.type;
|
|
14681
14876
|
const isOptionalOut = _catchall.optout === "optional";
|
|
14682
|
-
for (const key in
|
|
14877
|
+
for (const key in input2) {
|
|
14683
14878
|
if (keySet.has(key))
|
|
14684
14879
|
continue;
|
|
14685
14880
|
if (t === "never") {
|
|
14686
14881
|
unrecognized.push(key);
|
|
14687
14882
|
continue;
|
|
14688
14883
|
}
|
|
14689
|
-
const r = _catchall.run({ value:
|
|
14884
|
+
const r = _catchall.run({ value: input2[key], issues: [] }, ctx);
|
|
14690
14885
|
if (r instanceof Promise) {
|
|
14691
|
-
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key,
|
|
14886
|
+
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input2, isOptionalOut)));
|
|
14692
14887
|
} else {
|
|
14693
|
-
handlePropertyResult(r, payload, key,
|
|
14888
|
+
handlePropertyResult(r, payload, key, input2, isOptionalOut);
|
|
14694
14889
|
}
|
|
14695
14890
|
}
|
|
14696
14891
|
if (unrecognized.length) {
|
|
14697
14892
|
payload.issues.push({
|
|
14698
14893
|
code: "unrecognized_keys",
|
|
14699
14894
|
keys: unrecognized,
|
|
14700
|
-
input,
|
|
14895
|
+
input: input2,
|
|
14701
14896
|
inst
|
|
14702
14897
|
});
|
|
14703
14898
|
}
|
|
@@ -14840,7 +15035,7 @@ function handleTupleResult(result, final, index2) {
|
|
|
14840
15035
|
}
|
|
14841
15036
|
final.value[index2] = result.value;
|
|
14842
15037
|
}
|
|
14843
|
-
function handleMapResult(keyResult, valueResult, final, key,
|
|
15038
|
+
function handleMapResult(keyResult, valueResult, final, key, input2, inst, ctx) {
|
|
14844
15039
|
if (keyResult.issues.length) {
|
|
14845
15040
|
if (propertyKeyTypes.has(typeof key)) {
|
|
14846
15041
|
final.issues.push(...prefixIssues(key, keyResult.issues));
|
|
@@ -14848,7 +15043,7 @@ function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {
|
|
|
14848
15043
|
final.issues.push({
|
|
14849
15044
|
code: "invalid_key",
|
|
14850
15045
|
origin: "map",
|
|
14851
|
-
input,
|
|
15046
|
+
input: input2,
|
|
14852
15047
|
inst,
|
|
14853
15048
|
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
14854
15049
|
});
|
|
@@ -14861,7 +15056,7 @@ function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {
|
|
|
14861
15056
|
final.issues.push({
|
|
14862
15057
|
origin: "map",
|
|
14863
15058
|
code: "invalid_element",
|
|
14864
|
-
input,
|
|
15059
|
+
input: input2,
|
|
14865
15060
|
inst,
|
|
14866
15061
|
key,
|
|
14867
15062
|
issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
@@ -14876,8 +15071,8 @@ function handleSetResult(result, final) {
|
|
|
14876
15071
|
}
|
|
14877
15072
|
final.value.add(result.value);
|
|
14878
15073
|
}
|
|
14879
|
-
function handleOptionalResult(result,
|
|
14880
|
-
if (result.issues.length &&
|
|
15074
|
+
function handleOptionalResult(result, input2) {
|
|
15075
|
+
if (result.issues.length && input2 === void 0) {
|
|
14881
15076
|
return { issues: [], value: void 0 };
|
|
14882
15077
|
}
|
|
14883
15078
|
return result;
|
|
@@ -14937,11 +15132,11 @@ function handleReadonlyResult(payload) {
|
|
|
14937
15132
|
payload.value = Object.freeze(payload.value);
|
|
14938
15133
|
return payload;
|
|
14939
15134
|
}
|
|
14940
|
-
function handleRefineResult(result, payload,
|
|
15135
|
+
function handleRefineResult(result, payload, input2, inst) {
|
|
14941
15136
|
if (!result) {
|
|
14942
15137
|
const _iss = {
|
|
14943
15138
|
code: "custom",
|
|
14944
|
-
input,
|
|
15139
|
+
input: input2,
|
|
14945
15140
|
inst,
|
|
14946
15141
|
// incorporates params.error into issue reporting
|
|
14947
15142
|
path: [...inst._zod.def.path ?? []],
|
|
@@ -15354,15 +15549,15 @@ var init_schemas = __esm({
|
|
|
15354
15549
|
payload.value = Number(payload.value);
|
|
15355
15550
|
} catch (_) {
|
|
15356
15551
|
}
|
|
15357
|
-
const
|
|
15358
|
-
if (typeof
|
|
15552
|
+
const input2 = payload.value;
|
|
15553
|
+
if (typeof input2 === "number" && !Number.isNaN(input2) && Number.isFinite(input2)) {
|
|
15359
15554
|
return payload;
|
|
15360
15555
|
}
|
|
15361
|
-
const received = typeof
|
|
15556
|
+
const received = typeof input2 === "number" ? Number.isNaN(input2) ? "NaN" : !Number.isFinite(input2) ? "Infinity" : void 0 : void 0;
|
|
15362
15557
|
payload.issues.push({
|
|
15363
15558
|
expected: "number",
|
|
15364
15559
|
code: "invalid_type",
|
|
15365
|
-
input,
|
|
15560
|
+
input: input2,
|
|
15366
15561
|
inst,
|
|
15367
15562
|
...received ? { received } : {}
|
|
15368
15563
|
});
|
|
@@ -15382,13 +15577,13 @@ var init_schemas = __esm({
|
|
|
15382
15577
|
payload.value = Boolean(payload.value);
|
|
15383
15578
|
} catch (_) {
|
|
15384
15579
|
}
|
|
15385
|
-
const
|
|
15386
|
-
if (typeof
|
|
15580
|
+
const input2 = payload.value;
|
|
15581
|
+
if (typeof input2 === "boolean")
|
|
15387
15582
|
return payload;
|
|
15388
15583
|
payload.issues.push({
|
|
15389
15584
|
expected: "boolean",
|
|
15390
15585
|
code: "invalid_type",
|
|
15391
|
-
input,
|
|
15586
|
+
input: input2,
|
|
15392
15587
|
inst
|
|
15393
15588
|
});
|
|
15394
15589
|
return payload;
|
|
@@ -15421,13 +15616,13 @@ var init_schemas = __esm({
|
|
|
15421
15616
|
$ZodSymbol = /* @__PURE__ */ $constructor("$ZodSymbol", (inst, def) => {
|
|
15422
15617
|
$ZodType.init(inst, def);
|
|
15423
15618
|
inst._zod.parse = (payload, _ctx) => {
|
|
15424
|
-
const
|
|
15425
|
-
if (typeof
|
|
15619
|
+
const input2 = payload.value;
|
|
15620
|
+
if (typeof input2 === "symbol")
|
|
15426
15621
|
return payload;
|
|
15427
15622
|
payload.issues.push({
|
|
15428
15623
|
expected: "symbol",
|
|
15429
15624
|
code: "invalid_type",
|
|
15430
|
-
input,
|
|
15625
|
+
input: input2,
|
|
15431
15626
|
inst
|
|
15432
15627
|
});
|
|
15433
15628
|
return payload;
|
|
@@ -15440,13 +15635,13 @@ var init_schemas = __esm({
|
|
|
15440
15635
|
inst._zod.optin = "optional";
|
|
15441
15636
|
inst._zod.optout = "optional";
|
|
15442
15637
|
inst._zod.parse = (payload, _ctx) => {
|
|
15443
|
-
const
|
|
15444
|
-
if (typeof
|
|
15638
|
+
const input2 = payload.value;
|
|
15639
|
+
if (typeof input2 === "undefined")
|
|
15445
15640
|
return payload;
|
|
15446
15641
|
payload.issues.push({
|
|
15447
15642
|
expected: "undefined",
|
|
15448
15643
|
code: "invalid_type",
|
|
15449
|
-
input,
|
|
15644
|
+
input: input2,
|
|
15450
15645
|
inst
|
|
15451
15646
|
});
|
|
15452
15647
|
return payload;
|
|
@@ -15457,13 +15652,13 @@ var init_schemas = __esm({
|
|
|
15457
15652
|
inst._zod.pattern = _null;
|
|
15458
15653
|
inst._zod.values = /* @__PURE__ */ new Set([null]);
|
|
15459
15654
|
inst._zod.parse = (payload, _ctx) => {
|
|
15460
|
-
const
|
|
15461
|
-
if (
|
|
15655
|
+
const input2 = payload.value;
|
|
15656
|
+
if (input2 === null)
|
|
15462
15657
|
return payload;
|
|
15463
15658
|
payload.issues.push({
|
|
15464
15659
|
expected: "null",
|
|
15465
15660
|
code: "invalid_type",
|
|
15466
|
-
input,
|
|
15661
|
+
input: input2,
|
|
15467
15662
|
inst
|
|
15468
15663
|
});
|
|
15469
15664
|
return payload;
|
|
@@ -15492,13 +15687,13 @@ var init_schemas = __esm({
|
|
|
15492
15687
|
$ZodVoid = /* @__PURE__ */ $constructor("$ZodVoid", (inst, def) => {
|
|
15493
15688
|
$ZodType.init(inst, def);
|
|
15494
15689
|
inst._zod.parse = (payload, _ctx) => {
|
|
15495
|
-
const
|
|
15496
|
-
if (typeof
|
|
15690
|
+
const input2 = payload.value;
|
|
15691
|
+
if (typeof input2 === "undefined")
|
|
15497
15692
|
return payload;
|
|
15498
15693
|
payload.issues.push({
|
|
15499
15694
|
expected: "void",
|
|
15500
15695
|
code: "invalid_type",
|
|
15501
|
-
input,
|
|
15696
|
+
input: input2,
|
|
15502
15697
|
inst
|
|
15503
15698
|
});
|
|
15504
15699
|
return payload;
|
|
@@ -15513,15 +15708,15 @@ var init_schemas = __esm({
|
|
|
15513
15708
|
} catch (_err) {
|
|
15514
15709
|
}
|
|
15515
15710
|
}
|
|
15516
|
-
const
|
|
15517
|
-
const isDate =
|
|
15518
|
-
const isValidDate = isDate && !Number.isNaN(
|
|
15711
|
+
const input2 = payload.value;
|
|
15712
|
+
const isDate = input2 instanceof Date;
|
|
15713
|
+
const isValidDate = isDate && !Number.isNaN(input2.getTime());
|
|
15519
15714
|
if (isValidDate)
|
|
15520
15715
|
return payload;
|
|
15521
15716
|
payload.issues.push({
|
|
15522
15717
|
expected: "date",
|
|
15523
15718
|
code: "invalid_type",
|
|
15524
|
-
input,
|
|
15719
|
+
input: input2,
|
|
15525
15720
|
...isDate ? { received: "Invalid Date" } : {},
|
|
15526
15721
|
inst
|
|
15527
15722
|
});
|
|
@@ -15531,20 +15726,20 @@ var init_schemas = __esm({
|
|
|
15531
15726
|
$ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
15532
15727
|
$ZodType.init(inst, def);
|
|
15533
15728
|
inst._zod.parse = (payload, ctx) => {
|
|
15534
|
-
const
|
|
15535
|
-
if (!Array.isArray(
|
|
15729
|
+
const input2 = payload.value;
|
|
15730
|
+
if (!Array.isArray(input2)) {
|
|
15536
15731
|
payload.issues.push({
|
|
15537
15732
|
expected: "array",
|
|
15538
15733
|
code: "invalid_type",
|
|
15539
|
-
input,
|
|
15734
|
+
input: input2,
|
|
15540
15735
|
inst
|
|
15541
15736
|
});
|
|
15542
15737
|
return payload;
|
|
15543
15738
|
}
|
|
15544
|
-
payload.value = Array(
|
|
15739
|
+
payload.value = Array(input2.length);
|
|
15545
15740
|
const proms = [];
|
|
15546
|
-
for (let i = 0; i <
|
|
15547
|
-
const item =
|
|
15741
|
+
for (let i = 0; i < input2.length; i++) {
|
|
15742
|
+
const item = input2[i];
|
|
15548
15743
|
const result = def.element._zod.run({
|
|
15549
15744
|
value: item,
|
|
15550
15745
|
issues: []
|
|
@@ -15595,12 +15790,12 @@ var init_schemas = __esm({
|
|
|
15595
15790
|
let value;
|
|
15596
15791
|
inst._zod.parse = (payload, ctx) => {
|
|
15597
15792
|
value ?? (value = _normalized.value);
|
|
15598
|
-
const
|
|
15599
|
-
if (!isObject2(
|
|
15793
|
+
const input2 = payload.value;
|
|
15794
|
+
if (!isObject2(input2)) {
|
|
15600
15795
|
payload.issues.push({
|
|
15601
15796
|
expected: "object",
|
|
15602
15797
|
code: "invalid_type",
|
|
15603
|
-
input,
|
|
15798
|
+
input: input2,
|
|
15604
15799
|
inst
|
|
15605
15800
|
});
|
|
15606
15801
|
return payload;
|
|
@@ -15611,17 +15806,17 @@ var init_schemas = __esm({
|
|
|
15611
15806
|
for (const key of value.keys) {
|
|
15612
15807
|
const el = shape[key];
|
|
15613
15808
|
const isOptionalOut = el._zod.optout === "optional";
|
|
15614
|
-
const r = el._zod.run({ value:
|
|
15809
|
+
const r = el._zod.run({ value: input2[key], issues: [] }, ctx);
|
|
15615
15810
|
if (r instanceof Promise) {
|
|
15616
|
-
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key,
|
|
15811
|
+
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input2, isOptionalOut)));
|
|
15617
15812
|
} else {
|
|
15618
|
-
handlePropertyResult(r, payload, key,
|
|
15813
|
+
handlePropertyResult(r, payload, key, input2, isOptionalOut);
|
|
15619
15814
|
}
|
|
15620
15815
|
}
|
|
15621
15816
|
if (!catchall) {
|
|
15622
15817
|
return proms.length ? Promise.all(proms).then(() => payload) : payload;
|
|
15623
15818
|
}
|
|
15624
|
-
return handleCatchall(proms,
|
|
15819
|
+
return handleCatchall(proms, input2, payload, ctx, _normalized.value, inst);
|
|
15625
15820
|
};
|
|
15626
15821
|
});
|
|
15627
15822
|
$ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) => {
|
|
@@ -15702,12 +15897,12 @@ var init_schemas = __esm({
|
|
|
15702
15897
|
let value;
|
|
15703
15898
|
inst._zod.parse = (payload, ctx) => {
|
|
15704
15899
|
value ?? (value = _normalized.value);
|
|
15705
|
-
const
|
|
15706
|
-
if (!isObject2(
|
|
15900
|
+
const input2 = payload.value;
|
|
15901
|
+
if (!isObject2(input2)) {
|
|
15707
15902
|
payload.issues.push({
|
|
15708
15903
|
expected: "object",
|
|
15709
15904
|
code: "invalid_type",
|
|
15710
|
-
input,
|
|
15905
|
+
input: input2,
|
|
15711
15906
|
inst
|
|
15712
15907
|
});
|
|
15713
15908
|
return payload;
|
|
@@ -15718,7 +15913,7 @@ var init_schemas = __esm({
|
|
|
15718
15913
|
payload = fastpass(payload, ctx);
|
|
15719
15914
|
if (!catchall)
|
|
15720
15915
|
return payload;
|
|
15721
|
-
return handleCatchall([],
|
|
15916
|
+
return handleCatchall([], input2, payload, ctx, value, inst);
|
|
15722
15917
|
}
|
|
15723
15918
|
return superParse(payload, ctx);
|
|
15724
15919
|
};
|
|
@@ -15836,17 +16031,17 @@ var init_schemas = __esm({
|
|
|
15836
16031
|
return map2;
|
|
15837
16032
|
});
|
|
15838
16033
|
inst._zod.parse = (payload, ctx) => {
|
|
15839
|
-
const
|
|
15840
|
-
if (!isObject(
|
|
16034
|
+
const input2 = payload.value;
|
|
16035
|
+
if (!isObject(input2)) {
|
|
15841
16036
|
payload.issues.push({
|
|
15842
16037
|
code: "invalid_type",
|
|
15843
16038
|
expected: "object",
|
|
15844
|
-
input,
|
|
16039
|
+
input: input2,
|
|
15845
16040
|
inst
|
|
15846
16041
|
});
|
|
15847
16042
|
return payload;
|
|
15848
16043
|
}
|
|
15849
|
-
const opt = disc.value.get(
|
|
16044
|
+
const opt = disc.value.get(input2?.[def.discriminator]);
|
|
15850
16045
|
if (opt) {
|
|
15851
16046
|
return opt._zod.run(payload, ctx);
|
|
15852
16047
|
}
|
|
@@ -15858,7 +16053,7 @@ var init_schemas = __esm({
|
|
|
15858
16053
|
errors: [],
|
|
15859
16054
|
note: "No matching discriminator",
|
|
15860
16055
|
discriminator: def.discriminator,
|
|
15861
|
-
input,
|
|
16056
|
+
input: input2,
|
|
15862
16057
|
path: [def.discriminator],
|
|
15863
16058
|
inst
|
|
15864
16059
|
});
|
|
@@ -15868,9 +16063,9 @@ var init_schemas = __esm({
|
|
|
15868
16063
|
$ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
|
|
15869
16064
|
$ZodType.init(inst, def);
|
|
15870
16065
|
inst._zod.parse = (payload, ctx) => {
|
|
15871
|
-
const
|
|
15872
|
-
const left = def.left._zod.run({ value:
|
|
15873
|
-
const right = def.right._zod.run({ value:
|
|
16066
|
+
const input2 = payload.value;
|
|
16067
|
+
const left = def.left._zod.run({ value: input2, issues: [] }, ctx);
|
|
16068
|
+
const right = def.right._zod.run({ value: input2, issues: [] }, ctx);
|
|
15874
16069
|
const async = left instanceof Promise || right instanceof Promise;
|
|
15875
16070
|
if (async) {
|
|
15876
16071
|
return Promise.all([left, right]).then(([left2, right2]) => {
|
|
@@ -15884,10 +16079,10 @@ var init_schemas = __esm({
|
|
|
15884
16079
|
$ZodType.init(inst, def);
|
|
15885
16080
|
const items = def.items;
|
|
15886
16081
|
inst._zod.parse = (payload, ctx) => {
|
|
15887
|
-
const
|
|
15888
|
-
if (!Array.isArray(
|
|
16082
|
+
const input2 = payload.value;
|
|
16083
|
+
if (!Array.isArray(input2)) {
|
|
15889
16084
|
payload.issues.push({
|
|
15890
|
-
input,
|
|
16085
|
+
input: input2,
|
|
15891
16086
|
inst,
|
|
15892
16087
|
expected: "tuple",
|
|
15893
16088
|
code: "invalid_type"
|
|
@@ -15899,12 +16094,12 @@ var init_schemas = __esm({
|
|
|
15899
16094
|
const reversedIndex = [...items].reverse().findIndex((item) => item._zod.optin !== "optional");
|
|
15900
16095
|
const optStart = reversedIndex === -1 ? 0 : items.length - reversedIndex;
|
|
15901
16096
|
if (!def.rest) {
|
|
15902
|
-
const tooBig =
|
|
15903
|
-
const tooSmall =
|
|
16097
|
+
const tooBig = input2.length > items.length;
|
|
16098
|
+
const tooSmall = input2.length < optStart - 1;
|
|
15904
16099
|
if (tooBig || tooSmall) {
|
|
15905
16100
|
payload.issues.push({
|
|
15906
16101
|
...tooBig ? { code: "too_big", maximum: items.length, inclusive: true } : { code: "too_small", minimum: items.length },
|
|
15907
|
-
input,
|
|
16102
|
+
input: input2,
|
|
15908
16103
|
inst,
|
|
15909
16104
|
origin: "array"
|
|
15910
16105
|
});
|
|
@@ -15914,12 +16109,12 @@ var init_schemas = __esm({
|
|
|
15914
16109
|
let i = -1;
|
|
15915
16110
|
for (const item of items) {
|
|
15916
16111
|
i++;
|
|
15917
|
-
if (i >=
|
|
16112
|
+
if (i >= input2.length) {
|
|
15918
16113
|
if (i >= optStart)
|
|
15919
16114
|
continue;
|
|
15920
16115
|
}
|
|
15921
16116
|
const result = item._zod.run({
|
|
15922
|
-
value:
|
|
16117
|
+
value: input2[i],
|
|
15923
16118
|
issues: []
|
|
15924
16119
|
}, ctx);
|
|
15925
16120
|
if (result instanceof Promise) {
|
|
@@ -15929,7 +16124,7 @@ var init_schemas = __esm({
|
|
|
15929
16124
|
}
|
|
15930
16125
|
}
|
|
15931
16126
|
if (def.rest) {
|
|
15932
|
-
const rest =
|
|
16127
|
+
const rest = input2.slice(items.length);
|
|
15933
16128
|
for (const el of rest) {
|
|
15934
16129
|
i++;
|
|
15935
16130
|
const result = def.rest._zod.run({
|
|
@@ -15951,12 +16146,12 @@ var init_schemas = __esm({
|
|
|
15951
16146
|
$ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
15952
16147
|
$ZodType.init(inst, def);
|
|
15953
16148
|
inst._zod.parse = (payload, ctx) => {
|
|
15954
|
-
const
|
|
15955
|
-
if (!isPlainObject(
|
|
16149
|
+
const input2 = payload.value;
|
|
16150
|
+
if (!isPlainObject(input2)) {
|
|
15956
16151
|
payload.issues.push({
|
|
15957
16152
|
expected: "record",
|
|
15958
16153
|
code: "invalid_type",
|
|
15959
|
-
input,
|
|
16154
|
+
input: input2,
|
|
15960
16155
|
inst
|
|
15961
16156
|
});
|
|
15962
16157
|
return payload;
|
|
@@ -15969,7 +16164,7 @@ var init_schemas = __esm({
|
|
|
15969
16164
|
for (const key of values2) {
|
|
15970
16165
|
if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
|
|
15971
16166
|
recordKeys.add(typeof key === "number" ? key.toString() : key);
|
|
15972
|
-
const result = def.valueType._zod.run({ value:
|
|
16167
|
+
const result = def.valueType._zod.run({ value: input2[key], issues: [] }, ctx);
|
|
15973
16168
|
if (result instanceof Promise) {
|
|
15974
16169
|
proms.push(result.then((result2) => {
|
|
15975
16170
|
if (result2.issues.length) {
|
|
@@ -15986,7 +16181,7 @@ var init_schemas = __esm({
|
|
|
15986
16181
|
}
|
|
15987
16182
|
}
|
|
15988
16183
|
let unrecognized;
|
|
15989
|
-
for (const key in
|
|
16184
|
+
for (const key in input2) {
|
|
15990
16185
|
if (!recordKeys.has(key)) {
|
|
15991
16186
|
unrecognized = unrecognized ?? [];
|
|
15992
16187
|
unrecognized.push(key);
|
|
@@ -15995,14 +16190,14 @@ var init_schemas = __esm({
|
|
|
15995
16190
|
if (unrecognized && unrecognized.length > 0) {
|
|
15996
16191
|
payload.issues.push({
|
|
15997
16192
|
code: "unrecognized_keys",
|
|
15998
|
-
input,
|
|
16193
|
+
input: input2,
|
|
15999
16194
|
inst,
|
|
16000
16195
|
keys: unrecognized
|
|
16001
16196
|
});
|
|
16002
16197
|
}
|
|
16003
16198
|
} else {
|
|
16004
16199
|
payload.value = {};
|
|
16005
|
-
for (const key of Reflect.ownKeys(
|
|
16200
|
+
for (const key of Reflect.ownKeys(input2)) {
|
|
16006
16201
|
if (key === "__proto__")
|
|
16007
16202
|
continue;
|
|
16008
16203
|
let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
@@ -16021,7 +16216,7 @@ var init_schemas = __esm({
|
|
|
16021
16216
|
}
|
|
16022
16217
|
if (keyResult.issues.length) {
|
|
16023
16218
|
if (def.mode === "loose") {
|
|
16024
|
-
payload.value[key] =
|
|
16219
|
+
payload.value[key] = input2[key];
|
|
16025
16220
|
} else {
|
|
16026
16221
|
payload.issues.push({
|
|
16027
16222
|
code: "invalid_key",
|
|
@@ -16034,7 +16229,7 @@ var init_schemas = __esm({
|
|
|
16034
16229
|
}
|
|
16035
16230
|
continue;
|
|
16036
16231
|
}
|
|
16037
|
-
const result = def.valueType._zod.run({ value:
|
|
16232
|
+
const result = def.valueType._zod.run({ value: input2[key], issues: [] }, ctx);
|
|
16038
16233
|
if (result instanceof Promise) {
|
|
16039
16234
|
proms.push(result.then((result2) => {
|
|
16040
16235
|
if (result2.issues.length) {
|
|
@@ -16059,27 +16254,27 @@ var init_schemas = __esm({
|
|
|
16059
16254
|
$ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
|
|
16060
16255
|
$ZodType.init(inst, def);
|
|
16061
16256
|
inst._zod.parse = (payload, ctx) => {
|
|
16062
|
-
const
|
|
16063
|
-
if (!(
|
|
16257
|
+
const input2 = payload.value;
|
|
16258
|
+
if (!(input2 instanceof Map)) {
|
|
16064
16259
|
payload.issues.push({
|
|
16065
16260
|
expected: "map",
|
|
16066
16261
|
code: "invalid_type",
|
|
16067
|
-
input,
|
|
16262
|
+
input: input2,
|
|
16068
16263
|
inst
|
|
16069
16264
|
});
|
|
16070
16265
|
return payload;
|
|
16071
16266
|
}
|
|
16072
16267
|
const proms = [];
|
|
16073
16268
|
payload.value = /* @__PURE__ */ new Map();
|
|
16074
|
-
for (const [key, value] of
|
|
16269
|
+
for (const [key, value] of input2) {
|
|
16075
16270
|
const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
16076
16271
|
const valueResult = def.valueType._zod.run({ value, issues: [] }, ctx);
|
|
16077
16272
|
if (keyResult instanceof Promise || valueResult instanceof Promise) {
|
|
16078
16273
|
proms.push(Promise.all([keyResult, valueResult]).then(([keyResult2, valueResult2]) => {
|
|
16079
|
-
handleMapResult(keyResult2, valueResult2, payload, key,
|
|
16274
|
+
handleMapResult(keyResult2, valueResult2, payload, key, input2, inst, ctx);
|
|
16080
16275
|
}));
|
|
16081
16276
|
} else {
|
|
16082
|
-
handleMapResult(keyResult, valueResult, payload, key,
|
|
16277
|
+
handleMapResult(keyResult, valueResult, payload, key, input2, inst, ctx);
|
|
16083
16278
|
}
|
|
16084
16279
|
}
|
|
16085
16280
|
if (proms.length)
|
|
@@ -16090,10 +16285,10 @@ var init_schemas = __esm({
|
|
|
16090
16285
|
$ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
|
|
16091
16286
|
$ZodType.init(inst, def);
|
|
16092
16287
|
inst._zod.parse = (payload, ctx) => {
|
|
16093
|
-
const
|
|
16094
|
-
if (!(
|
|
16288
|
+
const input2 = payload.value;
|
|
16289
|
+
if (!(input2 instanceof Set)) {
|
|
16095
16290
|
payload.issues.push({
|
|
16096
|
-
input,
|
|
16291
|
+
input: input2,
|
|
16097
16292
|
inst,
|
|
16098
16293
|
expected: "set",
|
|
16099
16294
|
code: "invalid_type"
|
|
@@ -16102,7 +16297,7 @@ var init_schemas = __esm({
|
|
|
16102
16297
|
}
|
|
16103
16298
|
const proms = [];
|
|
16104
16299
|
payload.value = /* @__PURE__ */ new Set();
|
|
16105
|
-
for (const item of
|
|
16300
|
+
for (const item of input2) {
|
|
16106
16301
|
const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);
|
|
16107
16302
|
if (result instanceof Promise) {
|
|
16108
16303
|
proms.push(result.then((result2) => handleSetResult(result2, payload)));
|
|
@@ -16121,14 +16316,14 @@ var init_schemas = __esm({
|
|
|
16121
16316
|
inst._zod.values = valuesSet;
|
|
16122
16317
|
inst._zod.pattern = new RegExp(`^(${values2.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
|
|
16123
16318
|
inst._zod.parse = (payload, _ctx) => {
|
|
16124
|
-
const
|
|
16125
|
-
if (valuesSet.has(
|
|
16319
|
+
const input2 = payload.value;
|
|
16320
|
+
if (valuesSet.has(input2)) {
|
|
16126
16321
|
return payload;
|
|
16127
16322
|
}
|
|
16128
16323
|
payload.issues.push({
|
|
16129
16324
|
code: "invalid_value",
|
|
16130
16325
|
values: values2,
|
|
16131
|
-
input,
|
|
16326
|
+
input: input2,
|
|
16132
16327
|
inst
|
|
16133
16328
|
});
|
|
16134
16329
|
return payload;
|
|
@@ -16143,14 +16338,14 @@ var init_schemas = __esm({
|
|
|
16143
16338
|
inst._zod.values = values2;
|
|
16144
16339
|
inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
|
|
16145
16340
|
inst._zod.parse = (payload, _ctx) => {
|
|
16146
|
-
const
|
|
16147
|
-
if (values2.has(
|
|
16341
|
+
const input2 = payload.value;
|
|
16342
|
+
if (values2.has(input2)) {
|
|
16148
16343
|
return payload;
|
|
16149
16344
|
}
|
|
16150
16345
|
payload.issues.push({
|
|
16151
16346
|
code: "invalid_value",
|
|
16152
16347
|
values: def.values,
|
|
16153
|
-
input,
|
|
16348
|
+
input: input2,
|
|
16154
16349
|
inst
|
|
16155
16350
|
});
|
|
16156
16351
|
return payload;
|
|
@@ -16159,13 +16354,13 @@ var init_schemas = __esm({
|
|
|
16159
16354
|
$ZodFile = /* @__PURE__ */ $constructor("$ZodFile", (inst, def) => {
|
|
16160
16355
|
$ZodType.init(inst, def);
|
|
16161
16356
|
inst._zod.parse = (payload, _ctx) => {
|
|
16162
|
-
const
|
|
16163
|
-
if (
|
|
16357
|
+
const input2 = payload.value;
|
|
16358
|
+
if (input2 instanceof File)
|
|
16164
16359
|
return payload;
|
|
16165
16360
|
payload.issues.push({
|
|
16166
16361
|
expected: "file",
|
|
16167
16362
|
code: "invalid_type",
|
|
16168
|
-
input,
|
|
16363
|
+
input: input2,
|
|
16169
16364
|
inst
|
|
16170
16365
|
});
|
|
16171
16366
|
return payload;
|
|
@@ -16179,9 +16374,9 @@ var init_schemas = __esm({
|
|
|
16179
16374
|
}
|
|
16180
16375
|
const _out = def.transform(payload.value, payload);
|
|
16181
16376
|
if (ctx.async) {
|
|
16182
|
-
const
|
|
16183
|
-
return
|
|
16184
|
-
payload.value =
|
|
16377
|
+
const output3 = _out instanceof Promise ? _out : Promise.resolve(_out);
|
|
16378
|
+
return output3.then((output4) => {
|
|
16379
|
+
payload.value = output4;
|
|
16185
16380
|
return payload;
|
|
16186
16381
|
});
|
|
16187
16382
|
}
|
|
@@ -16533,12 +16728,12 @@ var init_schemas = __esm({
|
|
|
16533
16728
|
output: inst._def.output
|
|
16534
16729
|
});
|
|
16535
16730
|
};
|
|
16536
|
-
inst.output = (
|
|
16731
|
+
inst.output = (output3) => {
|
|
16537
16732
|
const F = inst.constructor;
|
|
16538
16733
|
return new F({
|
|
16539
16734
|
type: "function",
|
|
16540
16735
|
input: inst._def.input,
|
|
16541
|
-
output:
|
|
16736
|
+
output: output3
|
|
16542
16737
|
});
|
|
16543
16738
|
};
|
|
16544
16739
|
return inst;
|
|
@@ -16568,12 +16763,12 @@ var init_schemas = __esm({
|
|
|
16568
16763
|
return payload;
|
|
16569
16764
|
};
|
|
16570
16765
|
inst._zod.check = (payload) => {
|
|
16571
|
-
const
|
|
16572
|
-
const r = def.fn(
|
|
16766
|
+
const input2 = payload.value;
|
|
16767
|
+
const r = def.fn(input2);
|
|
16573
16768
|
if (r instanceof Promise) {
|
|
16574
|
-
return r.then((r2) => handleRefineResult(r2, payload,
|
|
16769
|
+
return r.then((r2) => handleRefineResult(r2, payload, input2, inst));
|
|
16575
16770
|
}
|
|
16576
|
-
handleRefineResult(r, payload,
|
|
16771
|
+
handleRefineResult(r, payload, input2, inst);
|
|
16577
16772
|
return;
|
|
16578
16773
|
};
|
|
16579
16774
|
});
|
|
@@ -23218,23 +23413,23 @@ function _overwrite(tx) {
|
|
|
23218
23413
|
}
|
|
23219
23414
|
// @__NO_SIDE_EFFECTS__
|
|
23220
23415
|
function _normalize(form) {
|
|
23221
|
-
return /* @__PURE__ */ _overwrite((
|
|
23416
|
+
return /* @__PURE__ */ _overwrite((input2) => input2.normalize(form));
|
|
23222
23417
|
}
|
|
23223
23418
|
// @__NO_SIDE_EFFECTS__
|
|
23224
23419
|
function _trim() {
|
|
23225
|
-
return /* @__PURE__ */ _overwrite((
|
|
23420
|
+
return /* @__PURE__ */ _overwrite((input2) => input2.trim());
|
|
23226
23421
|
}
|
|
23227
23422
|
// @__NO_SIDE_EFFECTS__
|
|
23228
23423
|
function _toLowerCase() {
|
|
23229
|
-
return /* @__PURE__ */ _overwrite((
|
|
23424
|
+
return /* @__PURE__ */ _overwrite((input2) => input2.toLowerCase());
|
|
23230
23425
|
}
|
|
23231
23426
|
// @__NO_SIDE_EFFECTS__
|
|
23232
23427
|
function _toUpperCase() {
|
|
23233
|
-
return /* @__PURE__ */ _overwrite((
|
|
23428
|
+
return /* @__PURE__ */ _overwrite((input2) => input2.toUpperCase());
|
|
23234
23429
|
}
|
|
23235
23430
|
// @__NO_SIDE_EFFECTS__
|
|
23236
23431
|
function _slugify() {
|
|
23237
|
-
return /* @__PURE__ */ _overwrite((
|
|
23432
|
+
return /* @__PURE__ */ _overwrite((input2) => slugify(input2));
|
|
23238
23433
|
}
|
|
23239
23434
|
// @__NO_SIDE_EFFECTS__
|
|
23240
23435
|
function _array(Class2, element, params) {
|
|
@@ -23539,8 +23734,8 @@ function _stringbool(Classes, _params) {
|
|
|
23539
23734
|
type: "pipe",
|
|
23540
23735
|
in: stringSchema,
|
|
23541
23736
|
out: booleanSchema,
|
|
23542
|
-
transform: ((
|
|
23543
|
-
let data =
|
|
23737
|
+
transform: ((input2, payload) => {
|
|
23738
|
+
let data = input2;
|
|
23544
23739
|
if (params.case !== "sensitive")
|
|
23545
23740
|
data = data.toLowerCase();
|
|
23546
23741
|
if (truthySet.has(data)) {
|
|
@@ -23559,8 +23754,8 @@ function _stringbool(Classes, _params) {
|
|
|
23559
23754
|
return {};
|
|
23560
23755
|
}
|
|
23561
23756
|
}),
|
|
23562
|
-
reverseTransform: ((
|
|
23563
|
-
if (
|
|
23757
|
+
reverseTransform: ((input2, _payload) => {
|
|
23758
|
+
if (input2 === true) {
|
|
23564
23759
|
return truthyArray[0] || "true";
|
|
23565
23760
|
} else {
|
|
23566
23761
|
return falsyArray[0] || "false";
|
|
@@ -23963,9 +24158,9 @@ var init_to_json_schema = __esm({
|
|
|
23963
24158
|
});
|
|
23964
24159
|
|
|
23965
24160
|
// ../../node_modules/zod/v4/core/json-schema-processors.js
|
|
23966
|
-
function toJSONSchema(
|
|
23967
|
-
if ("_idmap" in
|
|
23968
|
-
const registry2 =
|
|
24161
|
+
function toJSONSchema(input2, params) {
|
|
24162
|
+
if ("_idmap" in input2) {
|
|
24163
|
+
const registry2 = input2;
|
|
23969
24164
|
const ctx2 = initializeContext({ ...params, processors: allProcessors });
|
|
23970
24165
|
const defs = {};
|
|
23971
24166
|
for (const entry of registry2._idmap.entries()) {
|
|
@@ -23993,9 +24188,9 @@ function toJSONSchema(input, params) {
|
|
|
23993
24188
|
return { schemas };
|
|
23994
24189
|
}
|
|
23995
24190
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
23996
|
-
process2(
|
|
23997
|
-
extractDefs(ctx,
|
|
23998
|
-
return finalize(ctx,
|
|
24191
|
+
process2(input2, ctx);
|
|
24192
|
+
extractDefs(ctx, input2);
|
|
24193
|
+
return finalize(ctx, input2);
|
|
23999
24194
|
}
|
|
24000
24195
|
var formatMap, stringProcessor, numberProcessor, booleanProcessor, bigintProcessor, symbolProcessor, nullProcessor, undefinedProcessor, voidProcessor, neverProcessor, anyProcessor, unknownProcessor, dateProcessor, enumProcessor, literalProcessor, nanProcessor, templateLiteralProcessor, fileProcessor, successProcessor, customProcessor, functionProcessor, transformProcessor, mapProcessor, setProcessor, arrayProcessor, objectProcessor, unionProcessor, intersectionProcessor, tupleProcessor, recordProcessor, nullableProcessor, nonoptionalProcessor, defaultProcessor, prefaultProcessor, catchProcessor, pipeProcessor, readonlyProcessor, promiseProcessor, optionalProcessor, lazyProcessor, allProcessors;
|
|
24001
24196
|
var init_json_schema_processors = __esm({
|
|
@@ -26201,14 +26396,14 @@ var init_schemas2 = __esm({
|
|
|
26201
26396
|
payload.issues.push(util_exports.issue(_issue));
|
|
26202
26397
|
}
|
|
26203
26398
|
};
|
|
26204
|
-
const
|
|
26205
|
-
if (
|
|
26206
|
-
return
|
|
26207
|
-
payload.value =
|
|
26399
|
+
const output3 = def.transform(payload.value, payload);
|
|
26400
|
+
if (output3 instanceof Promise) {
|
|
26401
|
+
return output3.then((output4) => {
|
|
26402
|
+
payload.value = output4;
|
|
26208
26403
|
return payload;
|
|
26209
26404
|
});
|
|
26210
26405
|
}
|
|
26211
|
-
payload.value =
|
|
26406
|
+
payload.value = output3;
|
|
26212
26407
|
return payload;
|
|
26213
26408
|
};
|
|
26214
26409
|
});
|
|
@@ -26371,13 +26566,13 @@ function resolveRef(ref, ctx) {
|
|
|
26371
26566
|
if (!ref.startsWith("#")) {
|
|
26372
26567
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
26373
26568
|
}
|
|
26374
|
-
const
|
|
26375
|
-
if (
|
|
26569
|
+
const path15 = ref.slice(1).split("/").filter(Boolean);
|
|
26570
|
+
if (path15.length === 0) {
|
|
26376
26571
|
return ctx.rootSchema;
|
|
26377
26572
|
}
|
|
26378
26573
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
26379
|
-
if (
|
|
26380
|
-
const key =
|
|
26574
|
+
if (path15[0] === defsKey) {
|
|
26575
|
+
const key = path15[1];
|
|
26381
26576
|
if (!key || !ctx.defs[key]) {
|
|
26382
26577
|
throw new Error(`Reference not found: ${ref}`);
|
|
26383
26578
|
}
|
|
@@ -28177,7 +28372,8 @@ var init_enrollments = __esm({
|
|
|
28177
28372
|
expiresAt: timestamp("expires_at"),
|
|
28178
28373
|
// Story 3.5: Preview expiration (enrolledAt + 7 days)
|
|
28179
28374
|
setupChecklist: jsonb("setup_checklist").$type(),
|
|
28180
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
28375
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
|
|
28376
|
+
metadata: jsonb("metadata").$type().default({})
|
|
28181
28377
|
},
|
|
28182
28378
|
(table) => ({
|
|
28183
28379
|
userIdIdx: index("enrollments_user_id_idx").on(table.userId),
|
|
@@ -36021,6 +36217,80 @@ var init_student_course_memory = __esm({
|
|
|
36021
36217
|
}
|
|
36022
36218
|
});
|
|
36023
36219
|
|
|
36220
|
+
// ../../packages/database/src/schema/student-feedback.ts
|
|
36221
|
+
var studentFeedbackKindEnum, studentFeedbackSurfaceEnum, studentFeedbackCategoryEnum, studentFeedback;
|
|
36222
|
+
var init_student_feedback = __esm({
|
|
36223
|
+
"../../packages/database/src/schema/student-feedback.ts"() {
|
|
36224
|
+
"use strict";
|
|
36225
|
+
init_drizzle_orm();
|
|
36226
|
+
init_pg_core();
|
|
36227
|
+
init_courses3();
|
|
36228
|
+
init_lessons();
|
|
36229
|
+
init_module_exercises();
|
|
36230
|
+
init_study_module_sessions();
|
|
36231
|
+
init_users();
|
|
36232
|
+
studentFeedbackKindEnum = pgEnum("student_feedback_kind", [
|
|
36233
|
+
"free_text",
|
|
36234
|
+
"lesson_pulse"
|
|
36235
|
+
]);
|
|
36236
|
+
studentFeedbackSurfaceEnum = pgEnum("student_feedback_surface", [
|
|
36237
|
+
"lesson",
|
|
36238
|
+
"exercise",
|
|
36239
|
+
"chatstudy"
|
|
36240
|
+
]);
|
|
36241
|
+
studentFeedbackCategoryEnum = pgEnum("student_feedback_category", [
|
|
36242
|
+
"BUG",
|
|
36243
|
+
"UX",
|
|
36244
|
+
"FEAT",
|
|
36245
|
+
"CONTENT",
|
|
36246
|
+
"PERF",
|
|
36247
|
+
"INTEG"
|
|
36248
|
+
]);
|
|
36249
|
+
studentFeedback = pgTable(
|
|
36250
|
+
"student_feedback",
|
|
36251
|
+
{
|
|
36252
|
+
id: uuid("id").defaultRandom().primaryKey(),
|
|
36253
|
+
studentId: uuid("student_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
|
|
36254
|
+
courseId: uuid("course_id").references(() => courses.id, { onDelete: "cascade" }).notNull(),
|
|
36255
|
+
surface: studentFeedbackSurfaceEnum("surface").notNull(),
|
|
36256
|
+
routeOrSlug: text("route_or_slug").notNull(),
|
|
36257
|
+
kind: studentFeedbackKindEnum("kind").notNull().default("free_text"),
|
|
36258
|
+
category: studentFeedbackCategoryEnum("category"),
|
|
36259
|
+
comment: text("comment"),
|
|
36260
|
+
rating: integer("rating"),
|
|
36261
|
+
lessonId: uuid("lesson_id").references(() => lessons.id, { onDelete: "set null" }),
|
|
36262
|
+
exerciseId: uuid("exercise_id").references(() => moduleExercises.id, { onDelete: "set null" }),
|
|
36263
|
+
// Current fullscreen student flow uses v2 module sessions.
|
|
36264
|
+
chatSessionId: uuid("chat_session_id").references(() => studyModuleSessions.id, {
|
|
36265
|
+
onDelete: "set null"
|
|
36266
|
+
}),
|
|
36267
|
+
capturedAt: timestamp("captured_at", { withTimezone: true }).defaultNow().notNull(),
|
|
36268
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
36269
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
36270
|
+
},
|
|
36271
|
+
(table) => ({
|
|
36272
|
+
courseCapturedAtIdx: index("student_feedback_course_captured_at_idx").on(
|
|
36273
|
+
table.courseId,
|
|
36274
|
+
table.capturedAt
|
|
36275
|
+
),
|
|
36276
|
+
surfaceCapturedAtIdx: index("student_feedback_surface_captured_at_idx").on(
|
|
36277
|
+
table.surface,
|
|
36278
|
+
table.capturedAt
|
|
36279
|
+
),
|
|
36280
|
+
categoryCapturedAtIdx: index("student_feedback_category_captured_at_idx").on(
|
|
36281
|
+
table.category,
|
|
36282
|
+
table.capturedAt
|
|
36283
|
+
),
|
|
36284
|
+
studentCapturedAtIdx: index("student_feedback_student_captured_at_idx").on(
|
|
36285
|
+
table.studentId,
|
|
36286
|
+
table.capturedAt
|
|
36287
|
+
),
|
|
36288
|
+
lessonPulseUniqueIdx: uniqueIndex("student_feedback_lesson_pulse_unique_idx").on(table.studentId, table.lessonId).where(sql`${table.kind} = 'lesson_pulse' AND ${table.lessonId} IS NOT NULL`)
|
|
36289
|
+
})
|
|
36290
|
+
);
|
|
36291
|
+
}
|
|
36292
|
+
});
|
|
36293
|
+
|
|
36024
36294
|
// ../../packages/database/src/schema/student-module-progress.ts
|
|
36025
36295
|
var moduleProgressStatusEnum, studentModuleProgress;
|
|
36026
36296
|
var init_student_module_progress = __esm({
|
|
@@ -38198,6 +38468,10 @@ __export(schema_exports, {
|
|
|
38198
38468
|
stringifySettingValue: () => stringifySettingValue,
|
|
38199
38469
|
studentCourseMemory: () => studentCourseMemory,
|
|
38200
38470
|
studentCourseMemoryRelations: () => studentCourseMemoryRelations,
|
|
38471
|
+
studentFeedback: () => studentFeedback,
|
|
38472
|
+
studentFeedbackCategoryEnum: () => studentFeedbackCategoryEnum,
|
|
38473
|
+
studentFeedbackKindEnum: () => studentFeedbackKindEnum,
|
|
38474
|
+
studentFeedbackSurfaceEnum: () => studentFeedbackSurfaceEnum,
|
|
38201
38475
|
studentModuleProgress: () => studentModuleProgress,
|
|
38202
38476
|
studentNotes: () => studentNotes2,
|
|
38203
38477
|
studentNotesRelations: () => studentNotesRelations2,
|
|
@@ -38370,6 +38644,7 @@ var init_schema3 = __esm({
|
|
|
38370
38644
|
init_exercise_materials();
|
|
38371
38645
|
init_course_knowledge_bases();
|
|
38372
38646
|
init_student_course_memory();
|
|
38647
|
+
init_student_feedback();
|
|
38373
38648
|
init_student_module_progress();
|
|
38374
38649
|
init_course_projects();
|
|
38375
38650
|
init_source_extractions();
|
|
@@ -39818,6 +40093,32 @@ var init_exercise_types = __esm({
|
|
|
39818
40093
|
}
|
|
39819
40094
|
});
|
|
39820
40095
|
|
|
40096
|
+
// ../../packages/tostudy-core/src/workspace/lesson-exercise-data.ts
|
|
40097
|
+
var init_lesson_exercise_data = __esm({
|
|
40098
|
+
"../../packages/tostudy-core/src/workspace/lesson-exercise-data.ts"() {
|
|
40099
|
+
"use strict";
|
|
40100
|
+
}
|
|
40101
|
+
});
|
|
40102
|
+
|
|
40103
|
+
// ../../packages/tostudy-core/src/learning/sync-enrollment-progress.ts
|
|
40104
|
+
var init_sync_enrollment_progress = __esm({
|
|
40105
|
+
"../../packages/tostudy-core/src/learning/sync-enrollment-progress.ts"() {
|
|
40106
|
+
"use strict";
|
|
40107
|
+
init_src4();
|
|
40108
|
+
init_src();
|
|
40109
|
+
}
|
|
40110
|
+
});
|
|
40111
|
+
|
|
40112
|
+
// ../../packages/tostudy-core/src/learning/study-state-sync.ts
|
|
40113
|
+
var DEFAULT_MAX_SESSION_TIME_SECONDS;
|
|
40114
|
+
var init_study_state_sync = __esm({
|
|
40115
|
+
"../../packages/tostudy-core/src/learning/study-state-sync.ts"() {
|
|
40116
|
+
"use strict";
|
|
40117
|
+
init_src4();
|
|
40118
|
+
DEFAULT_MAX_SESSION_TIME_SECONDS = 2 * 60 * 60;
|
|
40119
|
+
}
|
|
40120
|
+
});
|
|
40121
|
+
|
|
39821
40122
|
// ../../packages/tostudy-core/src/learning/start-module-full.ts
|
|
39822
40123
|
var init_start_module_full = __esm({
|
|
39823
40124
|
"../../packages/tostudy-core/src/learning/start-module-full.ts"() {
|
|
@@ -39825,6 +40126,9 @@ var init_start_module_full = __esm({
|
|
|
39825
40126
|
init_src4();
|
|
39826
40127
|
init_parser();
|
|
39827
40128
|
init_exercise_types();
|
|
40129
|
+
init_lesson_exercise_data();
|
|
40130
|
+
init_sync_enrollment_progress();
|
|
40131
|
+
init_study_state_sync();
|
|
39828
40132
|
}
|
|
39829
40133
|
});
|
|
39830
40134
|
|
|
@@ -39834,6 +40138,9 @@ var init_next_lesson_full = __esm({
|
|
|
39834
40138
|
"use strict";
|
|
39835
40139
|
init_src4();
|
|
39836
40140
|
init_parser();
|
|
40141
|
+
init_lesson_exercise_data();
|
|
40142
|
+
init_sync_enrollment_progress();
|
|
40143
|
+
init_study_state_sync();
|
|
39837
40144
|
}
|
|
39838
40145
|
});
|
|
39839
40146
|
|
|
@@ -39844,6 +40151,8 @@ var init_validate_solution_full = __esm({
|
|
|
39844
40151
|
init_src4();
|
|
39845
40152
|
init_parser();
|
|
39846
40153
|
init_exercise_types();
|
|
40154
|
+
init_study_state_sync();
|
|
40155
|
+
init_sync_enrollment_progress();
|
|
39847
40156
|
}
|
|
39848
40157
|
});
|
|
39849
40158
|
|
|
@@ -39903,6 +40212,7 @@ var init_learning = __esm({
|
|
|
39903
40212
|
init_get_lesson_content_full();
|
|
39904
40213
|
init_get_hint_full();
|
|
39905
40214
|
init_explain_concept();
|
|
40215
|
+
init_sync_enrollment_progress();
|
|
39906
40216
|
}
|
|
39907
40217
|
});
|
|
39908
40218
|
|
|
@@ -39921,7 +40231,50 @@ var init_lessons2 = __esm({
|
|
|
39921
40231
|
|
|
39922
40232
|
// src/commands/start.ts
|
|
39923
40233
|
import { Command as Command8 } from "commander";
|
|
39924
|
-
|
|
40234
|
+
function buildOnboardingBlockerMessage(courseTitle, onboarding) {
|
|
40235
|
+
const lines = [`Onboarding obrigat\xF3rio pendente para "${courseTitle}".`];
|
|
40236
|
+
if (!onboarding.initReady) {
|
|
40237
|
+
lines.push("Execute `tostudy init` primeiro para configurar o tutor deste curso.");
|
|
40238
|
+
}
|
|
40239
|
+
if (!onboarding.workspaceReady) {
|
|
40240
|
+
lines.push("Execute `tostudy workspace setup` para criar o workspace local antes de iniciar.");
|
|
40241
|
+
}
|
|
40242
|
+
return lines.join("\n");
|
|
40243
|
+
}
|
|
40244
|
+
async function runStart(opts, deps = defaultDeps2) {
|
|
40245
|
+
try {
|
|
40246
|
+
const session = await deps.requireSession();
|
|
40247
|
+
const activeCourse = await deps.requireActiveCourse();
|
|
40248
|
+
const onboarding = await deps.getCourseOnboardingStatus(activeCourse);
|
|
40249
|
+
if (!onboarding.initReady || !onboarding.workspaceReady) {
|
|
40250
|
+
throw new StartBlockedError(
|
|
40251
|
+
buildOnboardingBlockerMessage(activeCourse.courseTitle, onboarding)
|
|
40252
|
+
);
|
|
40253
|
+
}
|
|
40254
|
+
const driftWarning = await deps.checkCourseDrift();
|
|
40255
|
+
if (driftWarning) deps.stderrWrite(driftWarning + "\n");
|
|
40256
|
+
const data = deps.createHttpProvider(session.apiUrl, session.token);
|
|
40257
|
+
const moduleData = await deps.startModule(
|
|
40258
|
+
{ enrollmentId: activeCourse.enrollmentId },
|
|
40259
|
+
{ data, logger: deps.logger }
|
|
40260
|
+
);
|
|
40261
|
+
await deps.setActiveCourse({ ...activeCourse, currentLessonId: moduleData.firstLesson.id });
|
|
40262
|
+
if (opts.json) {
|
|
40263
|
+
deps.output(moduleData, { json: true });
|
|
40264
|
+
} else {
|
|
40265
|
+
deps.output(deps.formatModuleStart(moduleData), { json: false });
|
|
40266
|
+
}
|
|
40267
|
+
} catch (err) {
|
|
40268
|
+
if (err instanceof CliApiError && err.status === 403 && err.message === "CHANNEL_MISMATCH") {
|
|
40269
|
+
process.stderr.write("Este curso n\xE3o est\xE1 dispon\xEDvel via CLI.\n");
|
|
40270
|
+
process.stderr.write("Acesse tostudy.ai para estudar este curso pelo ChatStudy.\n");
|
|
40271
|
+
process.exit(1);
|
|
40272
|
+
}
|
|
40273
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
40274
|
+
deps.error(msg);
|
|
40275
|
+
}
|
|
40276
|
+
}
|
|
40277
|
+
var logger5, defaultDeps2, StartBlockedError, startCommand;
|
|
39925
40278
|
var init_start = __esm({
|
|
39926
40279
|
"src/commands/start.ts"() {
|
|
39927
40280
|
"use strict";
|
|
@@ -39929,31 +40282,27 @@ var init_start = __esm({
|
|
|
39929
40282
|
init_lessons2();
|
|
39930
40283
|
init_http2();
|
|
39931
40284
|
init_session();
|
|
40285
|
+
init_status();
|
|
39932
40286
|
init_formatter();
|
|
39933
40287
|
logger5 = createLogger("cli:start");
|
|
40288
|
+
defaultDeps2 = {
|
|
40289
|
+
requireSession,
|
|
40290
|
+
requireActiveCourse,
|
|
40291
|
+
checkCourseDrift,
|
|
40292
|
+
getCourseOnboardingStatus,
|
|
40293
|
+
createHttpProvider,
|
|
40294
|
+
startModule,
|
|
40295
|
+
setActiveCourse,
|
|
40296
|
+
formatModuleStart,
|
|
40297
|
+
output,
|
|
40298
|
+
error,
|
|
40299
|
+
stderrWrite: (message) => process.stderr.write(message),
|
|
40300
|
+
logger: logger5
|
|
40301
|
+
};
|
|
40302
|
+
StartBlockedError = class extends Error {
|
|
40303
|
+
};
|
|
39934
40304
|
startCommand = new Command8("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
39935
|
-
|
|
39936
|
-
const session = await requireSession();
|
|
39937
|
-
const activeCourse = await requireActiveCourse();
|
|
39938
|
-
const driftWarning = await checkCourseDrift();
|
|
39939
|
-
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
39940
|
-
const data = createHttpProvider(session.apiUrl, session.token);
|
|
39941
|
-
const deps = { data, logger: logger5 };
|
|
39942
|
-
const moduleData = await startModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
39943
|
-
if (opts.json) {
|
|
39944
|
-
output(moduleData, { json: true });
|
|
39945
|
-
} else {
|
|
39946
|
-
output(formatModuleStart(moduleData), { json: false });
|
|
39947
|
-
}
|
|
39948
|
-
} catch (err) {
|
|
39949
|
-
if (err instanceof CliApiError && err.status === 403 && err.message === "CHANNEL_MISMATCH") {
|
|
39950
|
-
process.stderr.write("Este curso n\xE3o est\xE1 dispon\xEDvel via CLI.\n");
|
|
39951
|
-
process.stderr.write("Acesse tostudy.ai para estudar este curso pelo ChatStudy.\n");
|
|
39952
|
-
process.exit(1);
|
|
39953
|
-
}
|
|
39954
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
39955
|
-
error(msg);
|
|
39956
|
-
}
|
|
40305
|
+
await runStart(opts);
|
|
39957
40306
|
});
|
|
39958
40307
|
}
|
|
39959
40308
|
});
|
|
@@ -39979,12 +40328,18 @@ var init_start_next = __esm({
|
|
|
39979
40328
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
39980
40329
|
const deps = { data, logger: logger6 };
|
|
39981
40330
|
const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
40331
|
+
await setActiveCourse({ ...activeCourse, currentLessonId: moduleData.firstLesson.id });
|
|
39982
40332
|
if (opts.json) {
|
|
39983
40333
|
output(moduleData, { json: true });
|
|
39984
40334
|
} else {
|
|
39985
40335
|
output(formatModuleStart(moduleData), { json: false });
|
|
39986
40336
|
}
|
|
39987
40337
|
} catch (err) {
|
|
40338
|
+
if (err instanceof CliApiError && err.message === "COURSE_COMPLETE") {
|
|
40339
|
+
process.stderr.write("\u{1F389} Parab\xE9ns! Curso conclu\xEDdo!\n");
|
|
40340
|
+
process.stderr.write("\u2192 tostudy courses para ver outros cursos\n");
|
|
40341
|
+
process.exit(0);
|
|
40342
|
+
}
|
|
39988
40343
|
const msg = err instanceof Error ? err.message : String(err);
|
|
39989
40344
|
error(msg);
|
|
39990
40345
|
}
|
|
@@ -40016,16 +40371,34 @@ var init_next = __esm({
|
|
|
40016
40371
|
{ enrollmentId: activeCourse.enrollmentId, userConfirmation: "cli-next" },
|
|
40017
40372
|
deps
|
|
40018
40373
|
);
|
|
40374
|
+
await setActiveCourse({ ...activeCourse, currentLessonId: lessonData.lesson.id });
|
|
40019
40375
|
if (opts.json) {
|
|
40020
40376
|
output(lessonData, { json: true });
|
|
40021
40377
|
} else {
|
|
40022
40378
|
output(formatLesson(lessonData), { json: false });
|
|
40023
40379
|
}
|
|
40024
40380
|
} catch (err) {
|
|
40025
|
-
if (err instanceof CliApiError
|
|
40026
|
-
|
|
40027
|
-
|
|
40028
|
-
|
|
40381
|
+
if (err instanceof CliApiError) {
|
|
40382
|
+
if (err.status === 403 && err.message === "CHANNEL_MISMATCH") {
|
|
40383
|
+
process.stderr.write("Este curso n\xE3o est\xE1 dispon\xEDvel via CLI.\n");
|
|
40384
|
+
process.stderr.write("Acesse tostudy.ai para estudar este curso pelo ChatStudy.\n");
|
|
40385
|
+
process.exit(1);
|
|
40386
|
+
}
|
|
40387
|
+
if (err.message === "MODULE_COMPLETE") {
|
|
40388
|
+
process.stderr.write("\u2713 M\xF3dulo conclu\xEDdo!\n");
|
|
40389
|
+
process.stderr.write("\u2192 tostudy start-next para iniciar o pr\xF3ximo m\xF3dulo\n");
|
|
40390
|
+
process.exit(0);
|
|
40391
|
+
}
|
|
40392
|
+
if (err.message === "COURSE_COMPLETE") {
|
|
40393
|
+
process.stderr.write("\u{1F389} Parab\xE9ns! Curso conclu\xEDdo!\n");
|
|
40394
|
+
process.stderr.write("\u2192 tostudy courses para ver outros cursos\n");
|
|
40395
|
+
process.exit(0);
|
|
40396
|
+
}
|
|
40397
|
+
if (err.message === "NO_ACTIVE_LESSON") {
|
|
40398
|
+
process.stderr.write("Nenhuma li\xE7\xE3o em progresso.\n");
|
|
40399
|
+
process.stderr.write("\u2192 tostudy start-next para iniciar o pr\xF3ximo m\xF3dulo\n");
|
|
40400
|
+
process.exit(0);
|
|
40401
|
+
}
|
|
40029
40402
|
}
|
|
40030
40403
|
const msg = err instanceof Error ? err.message : String(err);
|
|
40031
40404
|
error(msg);
|
|
@@ -40036,11 +40409,19 @@ var init_next = __esm({
|
|
|
40036
40409
|
|
|
40037
40410
|
// src/commands/lesson.ts
|
|
40038
40411
|
import { Command as Command11 } from "commander";
|
|
40412
|
+
function adjustTimeEstimate(type, baseMinutes) {
|
|
40413
|
+
if (type === "exercise") return Math.max(baseMinutes, 30);
|
|
40414
|
+
return baseMinutes;
|
|
40415
|
+
}
|
|
40416
|
+
function isCheckpoint(title) {
|
|
40417
|
+
return /^checkpoint/i.test(title.trim());
|
|
40418
|
+
}
|
|
40039
40419
|
function formatLessonContent(data) {
|
|
40420
|
+
const time4 = adjustTimeEstimate(data.type, data.estimatedTimeMinutes);
|
|
40040
40421
|
const lines = [
|
|
40041
40422
|
`\u2501\u2501\u2501 Li\xE7\xE3o: ${data.title} \u2501\u2501\u2501`,
|
|
40042
40423
|
"",
|
|
40043
|
-
`Tipo: ${data.type} | Dura\xE7\xE3o estimada: ~${
|
|
40424
|
+
`Tipo: ${data.type} | Dura\xE7\xE3o estimada: ~${time4} min`,
|
|
40044
40425
|
"",
|
|
40045
40426
|
data.content
|
|
40046
40427
|
];
|
|
@@ -40050,12 +40431,20 @@ function formatLessonContent(data) {
|
|
|
40050
40431
|
if (data.hints && data.hints.length > 0) {
|
|
40051
40432
|
lines.push("", `Dicas dispon\xEDveis: ${data.hints.length}`);
|
|
40052
40433
|
}
|
|
40053
|
-
|
|
40054
|
-
|
|
40055
|
-
|
|
40056
|
-
|
|
40057
|
-
|
|
40058
|
-
|
|
40434
|
+
if (isCheckpoint(data.title)) {
|
|
40435
|
+
lines.push(
|
|
40436
|
+
"",
|
|
40437
|
+
"\u{1F4A1} Escreva suas respostas num arquivo (ex: checkpoint.md) e valide:",
|
|
40438
|
+
" tostudy validate checkpoint.md"
|
|
40439
|
+
);
|
|
40440
|
+
} else {
|
|
40441
|
+
lines.push(
|
|
40442
|
+
"",
|
|
40443
|
+
"\u2192 tostudy validate <arquivo> para validar sua solu\xE7\xE3o",
|
|
40444
|
+
"\u2192 tostudy hint para obter uma dica",
|
|
40445
|
+
"\u2192 tostudy next para avan\xE7ar para a pr\xF3xima li\xE7\xE3o"
|
|
40446
|
+
);
|
|
40447
|
+
}
|
|
40059
40448
|
return lines.join("\n");
|
|
40060
40449
|
}
|
|
40061
40450
|
var logger8, lessonCommand;
|
|
@@ -40067,6 +40456,7 @@ var init_lesson = __esm({
|
|
|
40067
40456
|
init_http2();
|
|
40068
40457
|
init_session();
|
|
40069
40458
|
init_formatter();
|
|
40459
|
+
init_resolve();
|
|
40070
40460
|
logger8 = createLogger("cli:lesson");
|
|
40071
40461
|
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").action(async (opts) => {
|
|
40072
40462
|
try {
|
|
@@ -40086,6 +40476,14 @@ var init_lesson = __esm({
|
|
|
40086
40476
|
} else {
|
|
40087
40477
|
output(formatLessonContent(content), { json: false });
|
|
40088
40478
|
}
|
|
40479
|
+
if (content.type === "exercise") {
|
|
40480
|
+
const ws = await resolveWorkspace(activeCourse.courseTitle);
|
|
40481
|
+
if (!ws.found) {
|
|
40482
|
+
process.stderr.write(
|
|
40483
|
+
"\n\u{1F4A1} Dica: rode `tostudy workspace setup` para criar um workspace local para exerc\xEDcios.\n"
|
|
40484
|
+
);
|
|
40485
|
+
}
|
|
40486
|
+
}
|
|
40089
40487
|
} catch (err) {
|
|
40090
40488
|
const msg = err instanceof Error ? err.message : String(err);
|
|
40091
40489
|
error(msg);
|
|
@@ -40132,13 +40530,13 @@ var init_hint = __esm({
|
|
|
40132
40530
|
});
|
|
40133
40531
|
|
|
40134
40532
|
// ../../packages/tostudy-core/src/exercises/validate-solution.ts
|
|
40135
|
-
async function validateSolution(
|
|
40136
|
-
deps.logger.info("tostudy-core: validateSolution", { lessonId:
|
|
40533
|
+
async function validateSolution(input2, deps) {
|
|
40534
|
+
deps.logger.info("tostudy-core: validateSolution", { lessonId: input2.lessonId });
|
|
40137
40535
|
return deps.data.exercises.validate(
|
|
40138
|
-
|
|
40139
|
-
|
|
40140
|
-
|
|
40141
|
-
|
|
40536
|
+
input2.lessonId,
|
|
40537
|
+
input2.solution,
|
|
40538
|
+
input2.userId,
|
|
40539
|
+
input2.enrollmentId
|
|
40142
40540
|
);
|
|
40143
40541
|
}
|
|
40144
40542
|
var init_validate_solution = __esm({
|
|
@@ -40158,134 +40556,26 @@ var init_exercises = __esm({
|
|
|
40158
40556
|
}
|
|
40159
40557
|
});
|
|
40160
40558
|
|
|
40161
|
-
// src/commands/validate.ts
|
|
40162
|
-
import fs6 from "node:fs";
|
|
40163
|
-
import { Command as Command13 } from "commander";
|
|
40164
|
-
var logger10, validateCommand;
|
|
40165
|
-
var init_validate = __esm({
|
|
40166
|
-
"src/commands/validate.ts"() {
|
|
40167
|
-
"use strict";
|
|
40168
|
-
init_src();
|
|
40169
|
-
init_exercises();
|
|
40170
|
-
init_http2();
|
|
40171
|
-
init_session();
|
|
40172
|
-
init_formatter();
|
|
40173
|
-
logger10 = createLogger("cli:validate");
|
|
40174
|
-
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 (file2, opts) => {
|
|
40175
|
-
try {
|
|
40176
|
-
const session = await requireSession();
|
|
40177
|
-
const activeCourse = await requireActiveCourse();
|
|
40178
|
-
const driftWarning = await checkCourseDrift();
|
|
40179
|
-
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
40180
|
-
const lessonId = activeCourse.currentLessonId;
|
|
40181
|
-
if (!lessonId) {
|
|
40182
|
-
error("Nenhuma li\xE7\xE3o ativa encontrada. Rode: tostudy start ou tostudy next");
|
|
40183
|
-
}
|
|
40184
|
-
let solution;
|
|
40185
|
-
if (opts.stdin) {
|
|
40186
|
-
solution = fs6.readFileSync("/dev/stdin", "utf-8");
|
|
40187
|
-
} else if (file2) {
|
|
40188
|
-
if (!fs6.existsSync(file2)) {
|
|
40189
|
-
error(`Arquivo n\xE3o encontrado: ${file2}`);
|
|
40190
|
-
}
|
|
40191
|
-
solution = fs6.readFileSync(file2, "utf-8");
|
|
40192
|
-
} else {
|
|
40193
|
-
error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
|
|
40194
|
-
}
|
|
40195
|
-
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40196
|
-
const deps = { data, logger: logger10 };
|
|
40197
|
-
const result = await validateSolution(
|
|
40198
|
-
{
|
|
40199
|
-
lessonId,
|
|
40200
|
-
solution,
|
|
40201
|
-
userId: session.userId,
|
|
40202
|
-
enrollmentId: activeCourse.enrollmentId
|
|
40203
|
-
},
|
|
40204
|
-
deps
|
|
40205
|
-
);
|
|
40206
|
-
if (opts.json) {
|
|
40207
|
-
output(result, { json: true });
|
|
40208
|
-
} else {
|
|
40209
|
-
output(formatValidation(result), { json: false });
|
|
40210
|
-
}
|
|
40211
|
-
process.exit(result.passed ? 0 : 1);
|
|
40212
|
-
} catch (err) {
|
|
40213
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
40214
|
-
error(msg);
|
|
40215
|
-
}
|
|
40216
|
-
});
|
|
40217
|
-
}
|
|
40218
|
-
});
|
|
40219
|
-
|
|
40220
|
-
// src/commands/menu.ts
|
|
40221
|
-
import { Command as Command14 } from "commander";
|
|
40222
|
-
var menuCommand;
|
|
40223
|
-
var init_menu = __esm({
|
|
40224
|
-
"src/commands/menu.ts"() {
|
|
40225
|
-
"use strict";
|
|
40226
|
-
init_session();
|
|
40227
|
-
init_formatter();
|
|
40228
|
-
menuCommand = new Command14("menu").description("Show available commands and current study context").action(async () => {
|
|
40229
|
-
const session = await getSession();
|
|
40230
|
-
const activeCourse = session ? await getActiveCourse() : null;
|
|
40231
|
-
const lines = [
|
|
40232
|
-
"\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",
|
|
40233
|
-
"\u2502 ToStudy CLI \u2014 Menu \u2502",
|
|
40234
|
-
"\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",
|
|
40235
|
-
""
|
|
40236
|
-
];
|
|
40237
|
-
if (!session) {
|
|
40238
|
-
lines.push(
|
|
40239
|
-
" Status: N\xE3o autenticado",
|
|
40240
|
-
"",
|
|
40241
|
-
" Para come\xE7ar:",
|
|
40242
|
-
" tostudy login Autenticar com sua conta ToStudy",
|
|
40243
|
-
""
|
|
40244
|
-
);
|
|
40245
|
-
} else {
|
|
40246
|
-
lines.push(` Usu\xE1rio: ${session.userName}`);
|
|
40247
|
-
if (activeCourse) {
|
|
40248
|
-
lines.push(` Curso ativo: ${activeCourse.courseTitle}`, "");
|
|
40249
|
-
} else {
|
|
40250
|
-
lines.push(
|
|
40251
|
-
" Curso ativo: (nenhum)",
|
|
40252
|
-
" \u2192 tostudy courses para ver seus cursos",
|
|
40253
|
-
" \u2192 tostudy select <n\xFAmero> para ativar um curso",
|
|
40254
|
-
""
|
|
40255
|
-
);
|
|
40256
|
-
}
|
|
40257
|
-
lines.push(
|
|
40258
|
-
" \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",
|
|
40259
|
-
" tostudy courses Listar seus cursos",
|
|
40260
|
-
" tostudy select <id> Ativar um curso",
|
|
40261
|
-
" tostudy progress Ver progresso do curso ativo",
|
|
40262
|
-
"",
|
|
40263
|
-
" \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",
|
|
40264
|
-
" tostudy start Iniciar/retomar o m\xF3dulo atual",
|
|
40265
|
-
" tostudy start-next Avan\xE7ar para o pr\xF3ximo m\xF3dulo",
|
|
40266
|
-
" tostudy next Avan\xE7ar para a pr\xF3xima li\xE7\xE3o",
|
|
40267
|
-
" tostudy lesson Ver conte\xFAdo da li\xE7\xE3o atual",
|
|
40268
|
-
"",
|
|
40269
|
-
" \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",
|
|
40270
|
-
" tostudy validate <arquivo> Validar sua solu\xE7\xE3o",
|
|
40271
|
-
" tostudy hint Obter uma dica progressiva",
|
|
40272
|
-
"",
|
|
40273
|
-
" \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",
|
|
40274
|
-
" Adicione --json a qualquer comando para sa\xEDda em JSON",
|
|
40275
|
-
" Adicione --help a qualquer comando para ver op\xE7\xF5es",
|
|
40276
|
-
""
|
|
40277
|
-
);
|
|
40278
|
-
}
|
|
40279
|
-
output(lines.join("\n"), { json: false });
|
|
40280
|
-
});
|
|
40281
|
-
}
|
|
40282
|
-
});
|
|
40283
|
-
|
|
40284
40559
|
// src/output/init-template.ts
|
|
40560
|
+
function detectTechFromTags(tags) {
|
|
40561
|
+
const found = /* @__PURE__ */ new Set();
|
|
40562
|
+
const keywords = Object.keys(LANGUAGE_TAGS);
|
|
40563
|
+
const joined = tags.map((t) => t.toLowerCase()).join(" ");
|
|
40564
|
+
for (const kw of keywords) {
|
|
40565
|
+
const pattern = new RegExp(`\\b${kw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`);
|
|
40566
|
+
if (pattern.test(joined)) {
|
|
40567
|
+
found.add(kw);
|
|
40568
|
+
}
|
|
40569
|
+
}
|
|
40570
|
+
return [...found];
|
|
40571
|
+
}
|
|
40285
40572
|
function formatCourseLanguage(tags) {
|
|
40286
40573
|
if (!tags || tags.length === 0) return "Programa\xE7\xE3o";
|
|
40287
|
-
const
|
|
40288
|
-
|
|
40574
|
+
const direct = tags.map((t) => LANGUAGE_TAGS[t.toLowerCase()]).filter(Boolean);
|
|
40575
|
+
if (direct.length > 0) return direct.slice(0, 3).join(" / ");
|
|
40576
|
+
const detected = detectTechFromTags(tags);
|
|
40577
|
+
const mapped = detected.map((t) => LANGUAGE_TAGS[t]).filter(Boolean);
|
|
40578
|
+
return mapped.length > 0 ? mapped.slice(0, 3).join(" / ") : "Programa\xE7\xE3o";
|
|
40289
40579
|
}
|
|
40290
40580
|
function formatCourseLevel(level) {
|
|
40291
40581
|
const map2 = {
|
|
@@ -40372,6 +40662,109 @@ function buildInitTemplate(userName, course, progress3) {
|
|
|
40372
40662
|
lines.push("- Instru\xE7\xF5es do ToStudy \u2192 fluxo de estudo (navega\xE7\xE3o, exerc\xEDcios, valida\xE7\xE3o)");
|
|
40373
40663
|
return lines.join("\n");
|
|
40374
40664
|
}
|
|
40665
|
+
function resolveTutorMode(level) {
|
|
40666
|
+
if (level === "beginner") return "guided";
|
|
40667
|
+
if (level === "advanced") return "direct";
|
|
40668
|
+
return "balanced";
|
|
40669
|
+
}
|
|
40670
|
+
function formatTutorMode(mode) {
|
|
40671
|
+
const map2 = {
|
|
40672
|
+
guided: "Guiado",
|
|
40673
|
+
balanced: "Equilibrado",
|
|
40674
|
+
direct: "Direto"
|
|
40675
|
+
};
|
|
40676
|
+
return map2[mode];
|
|
40677
|
+
}
|
|
40678
|
+
function buildTutorPersonalizationSection(course, learnerProfile) {
|
|
40679
|
+
const mode = resolveTutorMode(course.level);
|
|
40680
|
+
const lines = [];
|
|
40681
|
+
lines.push("## 6. Personaliza\xE7\xE3o do Tutor");
|
|
40682
|
+
lines.push(`- Modo inicial do tutor: ${formatTutorMode(mode)}`);
|
|
40683
|
+
lines.push(
|
|
40684
|
+
"- Na primeira intera\xE7\xE3o, apresente a escolha entre cen\xE1rio fict\xEDcio do curso e adapta\xE7\xE3o ao contexto real do aluno."
|
|
40685
|
+
);
|
|
40686
|
+
lines.push(
|
|
40687
|
+
`- O aluno atual j\xE1 optou por: ${learnerProfile.adaptToRealContext ? "Adaptar para o contexto real" : "Manter o cen\xE1rio fict\xEDcio"}`
|
|
40688
|
+
);
|
|
40689
|
+
lines.push(`- Segmento: ${learnerProfile.segment}`);
|
|
40690
|
+
lines.push(`- Empresa: ${learnerProfile.company}`);
|
|
40691
|
+
lines.push(`- Produtos/servi\xE7os: ${learnerProfile.productsOrServices}`);
|
|
40692
|
+
lines.push(`- Regi\xE3o: ${learnerProfile.region}`);
|
|
40693
|
+
lines.push(`- Equipe: ${learnerProfile.team}`);
|
|
40694
|
+
lines.push(`- Objetivo: ${learnerProfile.goal}`);
|
|
40695
|
+
lines.push(`- N\xEDvel declarado do aluno: ${formatCourseLevel(learnerProfile.learnerLevel)}`);
|
|
40696
|
+
if (learnerProfile.adaptToRealContext) {
|
|
40697
|
+
lines.push(
|
|
40698
|
+
"- Use o contexto do aluno como padr\xE3o para explica\xE7\xF5es, exemplos, exerc\xEDcios e framing."
|
|
40699
|
+
);
|
|
40700
|
+
lines.push(
|
|
40701
|
+
"- Troque nomes, entreg\xE1veis e restri\xE7\xF5es do cen\xE1rio fict\xEDcio por equivalentes reais."
|
|
40702
|
+
);
|
|
40703
|
+
lines.push(
|
|
40704
|
+
"- Preserve objetivos pedag\xF3gicos, crit\xE9rios de valida\xE7\xE3o e progress\xE3o de dificuldade."
|
|
40705
|
+
);
|
|
40706
|
+
} else {
|
|
40707
|
+
lines.push(
|
|
40708
|
+
"- Preserve o cen\xE1rio fict\xEDcio como padr\xE3o e conecte os conceitos ao neg\xF3cio real quando isso ajudar."
|
|
40709
|
+
);
|
|
40710
|
+
lines.push(
|
|
40711
|
+
"- Se o aluno quiser migrar para o contexto real depois, oriente a rodar `tostudy init` novamente."
|
|
40712
|
+
);
|
|
40713
|
+
}
|
|
40714
|
+
if (mode === "guided") {
|
|
40715
|
+
lines.push(
|
|
40716
|
+
"- No modo guiado, explique o porqu\xEA de cada passo, proponha checkpoints curtos e confirme entendimento antes de avan\xE7ar."
|
|
40717
|
+
);
|
|
40718
|
+
} else if (mode === "direct") {
|
|
40719
|
+
lines.push(
|
|
40720
|
+
"- Mesmo no modo mais direto, continue sem dar a resposta pronta e preserve a progress\xE3o pedag\xF3gica."
|
|
40721
|
+
);
|
|
40722
|
+
} else {
|
|
40723
|
+
lines.push(
|
|
40724
|
+
"- No modo equilibrado, combine explica\xE7\xF5es curtas com autonomia entre checkpoints."
|
|
40725
|
+
);
|
|
40726
|
+
}
|
|
40727
|
+
return lines.join("\n");
|
|
40728
|
+
}
|
|
40729
|
+
function buildLearnerBrief(userName, course, learnerProfile) {
|
|
40730
|
+
const lines = [];
|
|
40731
|
+
lines.push("# ToStudy CLI \u2014 Brief do Aluno");
|
|
40732
|
+
lines.push("");
|
|
40733
|
+
lines.push("Este documento resume o contexto real do aluno para orientar exemplos e exercicios.");
|
|
40734
|
+
lines.push("");
|
|
40735
|
+
lines.push("## 1. Identificacao");
|
|
40736
|
+
lines.push(`- Aluno: ${userName}`);
|
|
40737
|
+
lines.push(`- Curso: "${course.title}"`);
|
|
40738
|
+
lines.push(`- Segmento: ${learnerProfile.segment}`);
|
|
40739
|
+
lines.push(`- Empresa: ${learnerProfile.company}`);
|
|
40740
|
+
lines.push(`- Produtos/servicos: ${learnerProfile.productsOrServices}`);
|
|
40741
|
+
lines.push(`- Regiao: ${learnerProfile.region}`);
|
|
40742
|
+
lines.push(`- Equipe: ${learnerProfile.team}`);
|
|
40743
|
+
lines.push("");
|
|
40744
|
+
lines.push("## 2. Objetivo e Contexto");
|
|
40745
|
+
lines.push(`- Objetivo principal: ${learnerProfile.goal}`);
|
|
40746
|
+
lines.push(`- Nivel do aluno: ${formatCourseLevel(learnerProfile.learnerLevel)}`);
|
|
40747
|
+
lines.push(
|
|
40748
|
+
`- Adaptar curso ao contexto real: ${learnerProfile.adaptToRealContext ? "Sim" : "Nao"}`
|
|
40749
|
+
);
|
|
40750
|
+
lines.push("");
|
|
40751
|
+
lines.push("## 3. Como usar este brief");
|
|
40752
|
+
lines.push("- Reutilize este contexto para adaptar exemplos, cenarios e exercicios.");
|
|
40753
|
+
lines.push("- Preserve a proposta pedagogica do curso antes de customizar o contexto.");
|
|
40754
|
+
lines.push(
|
|
40755
|
+
"- Se algo mudar no negocio do aluno, rode `tostudy init` novamente para atualizar o brief."
|
|
40756
|
+
);
|
|
40757
|
+
return lines.join("\n");
|
|
40758
|
+
}
|
|
40759
|
+
function buildInitArtifacts(userName, course, progress3, learnerProfile) {
|
|
40760
|
+
return {
|
|
40761
|
+
tutorInstructions: [
|
|
40762
|
+
buildInitTemplate(userName, course, progress3),
|
|
40763
|
+
buildTutorPersonalizationSection(course, learnerProfile)
|
|
40764
|
+
].join("\n\n"),
|
|
40765
|
+
learnerBrief: buildLearnerBrief(userName, course, learnerProfile)
|
|
40766
|
+
};
|
|
40767
|
+
}
|
|
40375
40768
|
var LANGUAGE_TAGS;
|
|
40376
40769
|
var init_init_template = __esm({
|
|
40377
40770
|
"src/output/init-template.ts"() {
|
|
@@ -40405,104 +40798,489 @@ var init_init_template = __esm({
|
|
|
40405
40798
|
}
|
|
40406
40799
|
});
|
|
40407
40800
|
|
|
40408
|
-
// src/commands/
|
|
40409
|
-
import
|
|
40410
|
-
|
|
40411
|
-
|
|
40412
|
-
|
|
40801
|
+
// src/commands/validate.ts
|
|
40802
|
+
import fs8 from "node:fs";
|
|
40803
|
+
import path7 from "node:path";
|
|
40804
|
+
import { Command as Command13 } from "commander";
|
|
40805
|
+
var logger10, validateCommand;
|
|
40806
|
+
var init_validate = __esm({
|
|
40807
|
+
"src/commands/validate.ts"() {
|
|
40413
40808
|
"use strict";
|
|
40414
40809
|
init_src();
|
|
40415
|
-
|
|
40810
|
+
init_exercises();
|
|
40416
40811
|
init_http2();
|
|
40417
40812
|
init_session();
|
|
40418
40813
|
init_formatter();
|
|
40419
40814
|
init_init_template();
|
|
40420
|
-
|
|
40421
|
-
|
|
40815
|
+
logger10 = createLogger("cli:validate");
|
|
40816
|
+
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 (file2, opts) => {
|
|
40817
|
+
try {
|
|
40818
|
+
const session = await requireSession();
|
|
40819
|
+
const activeCourse = await requireActiveCourse();
|
|
40820
|
+
const driftWarning = await checkCourseDrift();
|
|
40821
|
+
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
40822
|
+
const lessonId = activeCourse.currentLessonId;
|
|
40823
|
+
if (!lessonId) {
|
|
40824
|
+
error("Nenhuma li\xE7\xE3o ativa encontrada. Rode: tostudy start ou tostudy next");
|
|
40825
|
+
}
|
|
40826
|
+
let solution;
|
|
40827
|
+
if (opts.stdin) {
|
|
40828
|
+
solution = fs8.readFileSync("/dev/stdin", "utf-8");
|
|
40829
|
+
} else if (file2) {
|
|
40830
|
+
if (!fs8.existsSync(file2)) {
|
|
40831
|
+
error(`Arquivo n\xE3o encontrado: ${file2}`);
|
|
40832
|
+
}
|
|
40833
|
+
solution = fs8.readFileSync(file2, "utf-8");
|
|
40834
|
+
} else {
|
|
40835
|
+
error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
|
|
40836
|
+
}
|
|
40837
|
+
if (file2 && activeCourse.courseTags?.length) {
|
|
40838
|
+
const ext = path7.extname(file2).toLowerCase();
|
|
40839
|
+
const LANG_EXTENSIONS = {
|
|
40840
|
+
".html": ["html", "html5"],
|
|
40841
|
+
".css": ["css"],
|
|
40842
|
+
".js": ["javascript", "node", "nodejs", "react", "vue", "angular", "svelte", "nextjs"],
|
|
40843
|
+
".ts": ["typescript", "react", "angular", "nextjs"],
|
|
40844
|
+
".tsx": ["typescript", "react", "nextjs"],
|
|
40845
|
+
".jsx": ["javascript", "react"],
|
|
40846
|
+
".py": ["python"],
|
|
40847
|
+
".go": ["go"],
|
|
40848
|
+
".rs": ["rust"],
|
|
40849
|
+
".java": ["java"],
|
|
40850
|
+
".kt": ["kotlin"],
|
|
40851
|
+
".swift": ["swift"],
|
|
40852
|
+
".rb": ["ruby"],
|
|
40853
|
+
".php": ["php"],
|
|
40854
|
+
".cs": ["csharp", "c#"],
|
|
40855
|
+
".cpp": ["cpp"],
|
|
40856
|
+
".sql": ["sql"],
|
|
40857
|
+
".vue": ["vue"]
|
|
40858
|
+
};
|
|
40859
|
+
const expectedTags = LANG_EXTENSIONS[ext];
|
|
40860
|
+
if (expectedTags) {
|
|
40861
|
+
const courseTech = detectTechFromTags(activeCourse.courseTags);
|
|
40862
|
+
const matches = expectedTags.some((t) => courseTech.includes(t));
|
|
40863
|
+
if (!matches) {
|
|
40864
|
+
const lang = formatCourseLanguage(activeCourse.courseTags);
|
|
40865
|
+
process.stderr.write(
|
|
40866
|
+
`\u26A0\uFE0F Arquivo ${ext} \u2014 este curso \xE9 de ${lang}. Verifique se est\xE1 enviando o arquivo correto.
|
|
40867
|
+
|
|
40868
|
+
`
|
|
40869
|
+
);
|
|
40870
|
+
}
|
|
40871
|
+
}
|
|
40872
|
+
}
|
|
40873
|
+
const data = createHttpProvider(session.apiUrl, session.token);
|
|
40874
|
+
const deps = { data, logger: logger10 };
|
|
40875
|
+
const result = await validateSolution(
|
|
40876
|
+
{
|
|
40877
|
+
lessonId,
|
|
40878
|
+
solution,
|
|
40879
|
+
userId: session.userId,
|
|
40880
|
+
enrollmentId: activeCourse.enrollmentId
|
|
40881
|
+
},
|
|
40882
|
+
deps
|
|
40883
|
+
);
|
|
40884
|
+
if (opts.json) {
|
|
40885
|
+
output(result, { json: true });
|
|
40886
|
+
} else {
|
|
40887
|
+
output(formatValidation(result), { json: false });
|
|
40888
|
+
}
|
|
40889
|
+
process.exit(result.passed ? 0 : 1);
|
|
40890
|
+
} catch (err) {
|
|
40891
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
40892
|
+
error(msg);
|
|
40893
|
+
}
|
|
40894
|
+
});
|
|
40895
|
+
}
|
|
40896
|
+
});
|
|
40897
|
+
|
|
40898
|
+
// src/commands/menu.ts
|
|
40899
|
+
import { Command as Command14 } from "commander";
|
|
40900
|
+
var menuCommand;
|
|
40901
|
+
var init_menu = __esm({
|
|
40902
|
+
"src/commands/menu.ts"() {
|
|
40903
|
+
"use strict";
|
|
40904
|
+
init_session();
|
|
40905
|
+
init_formatter();
|
|
40906
|
+
menuCommand = new Command14("menu").description("Show available commands and current study context").action(async () => {
|
|
40422
40907
|
const session = await getSession();
|
|
40908
|
+
const activeCourse = session ? await getActiveCourse() : null;
|
|
40909
|
+
const lines = [
|
|
40910
|
+
"\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",
|
|
40911
|
+
"\u2502 ToStudy CLI \u2014 Menu \u2502",
|
|
40912
|
+
"\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",
|
|
40913
|
+
""
|
|
40914
|
+
];
|
|
40423
40915
|
if (!session) {
|
|
40424
|
-
|
|
40425
|
-
|
|
40916
|
+
lines.push(
|
|
40917
|
+
" Status: N\xE3o autenticado",
|
|
40918
|
+
"",
|
|
40919
|
+
" Para come\xE7ar:",
|
|
40920
|
+
" tostudy login Autenticar com sua conta ToStudy",
|
|
40921
|
+
""
|
|
40922
|
+
);
|
|
40923
|
+
} else {
|
|
40924
|
+
lines.push(` Usu\xE1rio: ${session.userName}`);
|
|
40925
|
+
if (activeCourse) {
|
|
40926
|
+
lines.push(` Curso ativo: ${activeCourse.courseTitle}`, "");
|
|
40927
|
+
} else {
|
|
40928
|
+
lines.push(
|
|
40929
|
+
" Curso ativo: (nenhum)",
|
|
40930
|
+
" \u2192 tostudy courses para ver seus cursos",
|
|
40931
|
+
" \u2192 tostudy select <n\xFAmero> para ativar um curso",
|
|
40932
|
+
""
|
|
40933
|
+
);
|
|
40934
|
+
}
|
|
40935
|
+
lines.push(
|
|
40936
|
+
" \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",
|
|
40937
|
+
" tostudy courses Listar seus cursos",
|
|
40938
|
+
" tostudy select <id> Ativar um curso",
|
|
40939
|
+
" tostudy progress Ver progresso do curso ativo",
|
|
40940
|
+
"",
|
|
40941
|
+
" \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",
|
|
40942
|
+
" tostudy start Iniciar/retomar o m\xF3dulo atual",
|
|
40943
|
+
" tostudy start-next Avan\xE7ar para o pr\xF3ximo m\xF3dulo",
|
|
40944
|
+
" tostudy next Avan\xE7ar para a pr\xF3xima li\xE7\xE3o",
|
|
40945
|
+
" tostudy lesson Ver conte\xFAdo da li\xE7\xE3o atual",
|
|
40946
|
+
"",
|
|
40947
|
+
" \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",
|
|
40948
|
+
" tostudy validate <arquivo> Validar sua solu\xE7\xE3o",
|
|
40949
|
+
" tostudy hint Obter uma dica progressiva",
|
|
40950
|
+
"",
|
|
40951
|
+
" \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",
|
|
40952
|
+
" Adicione --json a qualquer comando para sa\xEDda em JSON",
|
|
40953
|
+
" Adicione --help a qualquer comando para ver op\xE7\xF5es",
|
|
40954
|
+
""
|
|
40955
|
+
);
|
|
40426
40956
|
}
|
|
40427
|
-
|
|
40428
|
-
|
|
40429
|
-
|
|
40430
|
-
|
|
40431
|
-
|
|
40432
|
-
|
|
40433
|
-
|
|
40434
|
-
|
|
40435
|
-
|
|
40957
|
+
output(lines.join("\n"), { json: false });
|
|
40958
|
+
});
|
|
40959
|
+
}
|
|
40960
|
+
});
|
|
40961
|
+
|
|
40962
|
+
// src/onboarding/learner-context.ts
|
|
40963
|
+
import readline from "node:readline/promises";
|
|
40964
|
+
import { stdin as input, stdout as output2 } from "node:process";
|
|
40965
|
+
async function askNonEmpty(question, deps, defaultValue) {
|
|
40966
|
+
while (true) {
|
|
40967
|
+
const answer = (await deps.ask(question)).trim();
|
|
40968
|
+
if (answer.length > 0) return answer;
|
|
40969
|
+
if (defaultValue) return defaultValue;
|
|
40970
|
+
}
|
|
40971
|
+
}
|
|
40972
|
+
async function askChoice(question, choices, deps, defaultChoice) {
|
|
40973
|
+
while (true) {
|
|
40974
|
+
const rawAnswer = (await deps.ask(question)).trim().toLowerCase();
|
|
40975
|
+
if (rawAnswer.length === 0 && defaultChoice) return defaultChoice;
|
|
40976
|
+
const answer = rawAnswer;
|
|
40977
|
+
if (choices.includes(answer)) return answer;
|
|
40978
|
+
}
|
|
40979
|
+
}
|
|
40980
|
+
function createPromptDeps() {
|
|
40981
|
+
const rl = readline.createInterface({ input, output: output2 });
|
|
40982
|
+
return {
|
|
40983
|
+
ask: (question) => rl.question(question),
|
|
40984
|
+
write: (content) => output2.write(content),
|
|
40985
|
+
close: () => rl.close()
|
|
40986
|
+
};
|
|
40987
|
+
}
|
|
40988
|
+
async function collectLearnerContextProfileWithDeps(input2, deps) {
|
|
40989
|
+
const existingProfile = input2.existingProfile;
|
|
40990
|
+
if (existingProfile) {
|
|
40991
|
+
deps.write(
|
|
40992
|
+
[
|
|
40993
|
+
"",
|
|
40994
|
+
`Brief existente encontrado (${input2.existingSource === "web" ? "web" : "CLI"}):`,
|
|
40995
|
+
`- Segmento: ${existingProfile.segment}`,
|
|
40996
|
+
`- Empresa: ${existingProfile.company}`,
|
|
40997
|
+
`- Produtos/servicos: ${existingProfile.productsOrServices}`,
|
|
40998
|
+
`- Regiao: ${existingProfile.region}`,
|
|
40999
|
+
`- Equipe: ${existingProfile.team}`,
|
|
41000
|
+
`- Objetivo: ${existingProfile.goal}`,
|
|
41001
|
+
`- Nivel: ${existingProfile.learnerLevel}`,
|
|
41002
|
+
`- Contexto real: ${existingProfile.adaptToRealContext ? "sim" : "nao"}`,
|
|
41003
|
+
""
|
|
41004
|
+
].join("\n")
|
|
41005
|
+
);
|
|
41006
|
+
}
|
|
41007
|
+
const action = existingProfile ? await askChoice(
|
|
41008
|
+
"Manter este brief ou editar? (keep/edit): ",
|
|
41009
|
+
["keep", "edit"],
|
|
41010
|
+
deps,
|
|
41011
|
+
"keep"
|
|
41012
|
+
) : "edit";
|
|
41013
|
+
const baseProfile = existingProfile;
|
|
41014
|
+
const segment = action === "keep" && baseProfile ? baseProfile.segment : await askNonEmpty(
|
|
41015
|
+
baseProfile ? `Segmento ou nicho do aluno [${baseProfile.segment}]: ` : "Segmento ou nicho do aluno: ",
|
|
41016
|
+
deps,
|
|
41017
|
+
baseProfile?.segment
|
|
41018
|
+
);
|
|
41019
|
+
const company = action === "keep" && baseProfile ? baseProfile.company : await askNonEmpty(
|
|
41020
|
+
baseProfile ? `Empresa ou tipo de negocio [${baseProfile.company}]: ` : "Empresa ou tipo de negocio: ",
|
|
41021
|
+
deps,
|
|
41022
|
+
baseProfile?.company
|
|
41023
|
+
);
|
|
41024
|
+
const productsOrServices = action === "keep" && baseProfile ? baseProfile.productsOrServices : await askNonEmpty(
|
|
41025
|
+
baseProfile ? `Produtos ou servicos principais [${baseProfile.productsOrServices}]: ` : "Produtos ou servicos principais: ",
|
|
41026
|
+
deps,
|
|
41027
|
+
baseProfile?.productsOrServices
|
|
41028
|
+
);
|
|
41029
|
+
const region = action === "keep" && baseProfile ? baseProfile.region : await askNonEmpty(
|
|
41030
|
+
baseProfile ? `Regiao de atuacao [${baseProfile.region}]: ` : "Regiao de atuacao: ",
|
|
41031
|
+
deps,
|
|
41032
|
+
baseProfile?.region
|
|
41033
|
+
);
|
|
41034
|
+
const team = action === "keep" && baseProfile ? baseProfile.team : await askNonEmpty(
|
|
41035
|
+
baseProfile ? `Equipe envolvida neste contexto [${baseProfile.team}]: ` : "Equipe envolvida neste contexto: ",
|
|
41036
|
+
deps,
|
|
41037
|
+
baseProfile?.team
|
|
41038
|
+
);
|
|
41039
|
+
const goal = action === "keep" && baseProfile ? baseProfile.goal : await askNonEmpty(
|
|
41040
|
+
baseProfile ? `Objetivo principal com este curso [${baseProfile.goal}]: ` : "Objetivo principal com este curso: ",
|
|
41041
|
+
deps,
|
|
41042
|
+
baseProfile?.goal
|
|
41043
|
+
);
|
|
41044
|
+
const learnerLevel = action === "keep" && baseProfile ? baseProfile.learnerLevel : await askChoice(
|
|
41045
|
+
baseProfile ? `Nivel do aluno (beginner/intermediate/advanced) [${baseProfile.learnerLevel}]: ` : "Nivel do aluno (beginner/intermediate/advanced): ",
|
|
41046
|
+
["beginner", "intermediate", "advanced"],
|
|
41047
|
+
deps,
|
|
41048
|
+
baseProfile?.learnerLevel
|
|
41049
|
+
);
|
|
41050
|
+
const adaptToRealContext = await askChoice(
|
|
41051
|
+
baseProfile ? `Quer que o tutor adapte exemplos ao seu contexto real ou prefere usar os cenarios ficticios do curso? (yes/no) [${baseProfile.adaptToRealContext ? "yes" : "no"}]: ` : "Quer que o tutor adapte exemplos ao seu contexto real ou prefere usar os cenarios ficticios do curso? (yes/no): ",
|
|
41052
|
+
["yes", "no"],
|
|
41053
|
+
deps,
|
|
41054
|
+
baseProfile ? baseProfile.adaptToRealContext ? "yes" : "no" : void 0
|
|
41055
|
+
) === "yes";
|
|
41056
|
+
return {
|
|
41057
|
+
segment,
|
|
41058
|
+
company,
|
|
41059
|
+
productsOrServices,
|
|
41060
|
+
region,
|
|
41061
|
+
team,
|
|
41062
|
+
goal,
|
|
41063
|
+
learnerLevel,
|
|
41064
|
+
adaptToRealContext
|
|
41065
|
+
};
|
|
41066
|
+
}
|
|
41067
|
+
async function collectLearnerContextProfile(input2) {
|
|
41068
|
+
const deps = createPromptDeps();
|
|
41069
|
+
try {
|
|
41070
|
+
return await collectLearnerContextProfileWithDeps(input2, deps);
|
|
41071
|
+
} finally {
|
|
41072
|
+
deps.close();
|
|
41073
|
+
}
|
|
41074
|
+
}
|
|
41075
|
+
var init_learner_context = __esm({
|
|
41076
|
+
"src/onboarding/learner-context.ts"() {
|
|
41077
|
+
"use strict";
|
|
41078
|
+
}
|
|
41079
|
+
});
|
|
41080
|
+
|
|
41081
|
+
// src/onboarding/api.ts
|
|
41082
|
+
async function apiFetch2(url2, token2, init) {
|
|
41083
|
+
const response = await fetch(url2, {
|
|
41084
|
+
...init,
|
|
41085
|
+
headers: {
|
|
41086
|
+
"Content-Type": "application/json",
|
|
41087
|
+
Authorization: `Bearer ${token2}`,
|
|
41088
|
+
...init?.headers
|
|
41089
|
+
}
|
|
41090
|
+
});
|
|
41091
|
+
const body = await response.json();
|
|
41092
|
+
if (!response.ok) {
|
|
41093
|
+
throw new CliApiError(body.error ?? `API error ${response.status}`, response.status);
|
|
41094
|
+
}
|
|
41095
|
+
return body;
|
|
41096
|
+
}
|
|
41097
|
+
async function getRemoteEnrollmentOnboarding(input2) {
|
|
41098
|
+
const url2 = new URL(`${input2.apiUrl}/api/cli/onboarding`);
|
|
41099
|
+
url2.searchParams.set("enrollmentId", input2.enrollmentId);
|
|
41100
|
+
const response = await apiFetch2(
|
|
41101
|
+
url2.toString(),
|
|
41102
|
+
input2.token
|
|
41103
|
+
);
|
|
41104
|
+
return response.onboarding;
|
|
41105
|
+
}
|
|
41106
|
+
async function saveRemoteEnrollmentOnboarding(input2) {
|
|
41107
|
+
const response = await apiFetch2(
|
|
41108
|
+
`${input2.apiUrl}/api/cli/onboarding`,
|
|
41109
|
+
input2.token,
|
|
41110
|
+
{
|
|
41111
|
+
method: "POST",
|
|
41112
|
+
body: JSON.stringify({
|
|
41113
|
+
enrollmentId: input2.enrollmentId,
|
|
41114
|
+
learnerBrief: input2.learnerBrief,
|
|
41115
|
+
learnerProfile: input2.learnerProfile
|
|
41116
|
+
})
|
|
41117
|
+
}
|
|
41118
|
+
);
|
|
41119
|
+
return response.onboarding;
|
|
41120
|
+
}
|
|
41121
|
+
var init_api2 = __esm({
|
|
41122
|
+
"src/onboarding/api.ts"() {
|
|
41123
|
+
"use strict";
|
|
41124
|
+
init_http2();
|
|
41125
|
+
}
|
|
41126
|
+
});
|
|
41127
|
+
|
|
41128
|
+
// src/commands/init.ts
|
|
41129
|
+
import { Command as Command15 } from "commander";
|
|
41130
|
+
async function runInit(deps = defaultDeps3) {
|
|
41131
|
+
const session = await deps.getSession();
|
|
41132
|
+
if (!session) {
|
|
41133
|
+
deps.output("Nao autenticado. Rode `tostudy login` para comecar.", { json: false });
|
|
41134
|
+
return;
|
|
41135
|
+
}
|
|
41136
|
+
const data = deps.createHttpProvider(session.apiUrl, session.token);
|
|
41137
|
+
const apiDeps = { data, logger: deps.logger };
|
|
41138
|
+
const activeCourse = await deps.getActiveCourse();
|
|
41139
|
+
if (!activeCourse) {
|
|
41140
|
+
try {
|
|
41141
|
+
const courses3 = await deps.listCourses({ userId: session.userId }, apiDeps);
|
|
41142
|
+
const courseListStr = courses3.length > 0 ? courses3.map((c, i) => ` ${i + 1}. ${c.title} (${c.progress}%)`).join("\n") : " (nenhum curso encontrado)";
|
|
41143
|
+
deps.output(
|
|
41144
|
+
`Nenhum curso ativo.
|
|
40436
41145
|
|
|
40437
41146
|
Seus cursos:
|
|
40438
41147
|
${courseListStr}
|
|
40439
41148
|
|
|
40440
41149
|
Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
|
|
40441
|
-
|
|
40442
|
-
|
|
40443
|
-
|
|
40444
|
-
|
|
40445
|
-
|
|
40446
|
-
|
|
40447
|
-
|
|
40448
|
-
|
|
40449
|
-
|
|
40450
|
-
|
|
40451
|
-
|
|
40452
|
-
|
|
40453
|
-
|
|
40454
|
-
|
|
40455
|
-
|
|
40456
|
-
|
|
40457
|
-
|
|
40458
|
-
|
|
40459
|
-
|
|
40460
|
-
|
|
40461
|
-
|
|
40462
|
-
|
|
40463
|
-
|
|
40464
|
-
|
|
40465
|
-
|
|
40466
|
-
|
|
40467
|
-
|
|
40468
|
-
|
|
40469
|
-
|
|
40470
|
-
|
|
40471
|
-
|
|
40472
|
-
|
|
40473
|
-
|
|
40474
|
-
|
|
40475
|
-
|
|
40476
|
-
|
|
40477
|
-
|
|
40478
|
-
|
|
40479
|
-
|
|
40480
|
-
|
|
41150
|
+
{ json: false }
|
|
41151
|
+
);
|
|
41152
|
+
} catch {
|
|
41153
|
+
deps.output("Nenhum curso ativo. Rode `tostudy courses` e `tostudy select <n\xFAmero>`.", {
|
|
41154
|
+
json: false
|
|
41155
|
+
});
|
|
41156
|
+
}
|
|
41157
|
+
return;
|
|
41158
|
+
}
|
|
41159
|
+
let matchedCourse = null;
|
|
41160
|
+
try {
|
|
41161
|
+
const courses3 = await deps.listCourses({ userId: session.userId }, apiDeps);
|
|
41162
|
+
matchedCourse = courses3.find((course) => course.courseId === activeCourse.courseId) ?? null;
|
|
41163
|
+
} catch (err) {
|
|
41164
|
+
deps.logger.warn("Failed to fetch course metadata for init", { error: err });
|
|
41165
|
+
}
|
|
41166
|
+
if (!matchedCourse) {
|
|
41167
|
+
matchedCourse = {
|
|
41168
|
+
enrollmentId: activeCourse.enrollmentId,
|
|
41169
|
+
courseId: activeCourse.courseId,
|
|
41170
|
+
title: activeCourse.courseTitle,
|
|
41171
|
+
progress: 0,
|
|
41172
|
+
creatorName: "Desconhecido",
|
|
41173
|
+
teachingApproach: "hybrid",
|
|
41174
|
+
enrolledAt: /* @__PURE__ */ new Date()
|
|
41175
|
+
};
|
|
41176
|
+
}
|
|
41177
|
+
let progressData = null;
|
|
41178
|
+
try {
|
|
41179
|
+
progressData = await deps.getProgress({ enrollmentId: activeCourse.enrollmentId }, apiDeps);
|
|
41180
|
+
} catch (err) {
|
|
41181
|
+
deps.logger.warn("Failed to fetch progress for init", { error: err });
|
|
41182
|
+
}
|
|
41183
|
+
let remoteOnboarding = null;
|
|
41184
|
+
try {
|
|
41185
|
+
remoteOnboarding = await deps.getRemoteEnrollmentOnboarding({
|
|
41186
|
+
apiUrl: session.apiUrl,
|
|
41187
|
+
token: session.token,
|
|
41188
|
+
enrollmentId: activeCourse.enrollmentId
|
|
41189
|
+
});
|
|
41190
|
+
} catch (err) {
|
|
41191
|
+
deps.logger.warn("Failed to fetch remote enrollment onboarding", { error: err });
|
|
41192
|
+
}
|
|
41193
|
+
const onboardingState = await deps.getCourseOnboardingState(activeCourse.courseId);
|
|
41194
|
+
const existingProfile = remoteOnboarding?.learnerProfile ?? onboardingState?.learnerProfile;
|
|
41195
|
+
const existingSource = remoteOnboarding?.source ?? (onboardingState?.learnerProfile ? "cli" : void 0);
|
|
41196
|
+
const learnerProfile = await deps.collectLearnerContextProfile({
|
|
41197
|
+
userName: session.userName,
|
|
41198
|
+
course: matchedCourse,
|
|
41199
|
+
activeCourse,
|
|
41200
|
+
...existingProfile ? {
|
|
41201
|
+
existingProfile,
|
|
41202
|
+
existingSource
|
|
41203
|
+
} : {}
|
|
41204
|
+
});
|
|
41205
|
+
const artifacts = deps.buildInitArtifacts(
|
|
41206
|
+
session.userName,
|
|
41207
|
+
matchedCourse,
|
|
41208
|
+
progressData,
|
|
41209
|
+
learnerProfile
|
|
41210
|
+
);
|
|
41211
|
+
await deps.saveRemoteEnrollmentOnboarding({
|
|
41212
|
+
apiUrl: session.apiUrl,
|
|
41213
|
+
token: session.token,
|
|
41214
|
+
enrollmentId: activeCourse.enrollmentId,
|
|
41215
|
+
learnerBrief: artifacts.learnerBrief,
|
|
41216
|
+
learnerProfile,
|
|
41217
|
+
source: "cli"
|
|
41218
|
+
});
|
|
41219
|
+
await deps.saveCourseLearnerProfile(activeCourse, learnerProfile, artifacts);
|
|
41220
|
+
try {
|
|
41221
|
+
await deps.setLastInitCourseId(activeCourse.courseId);
|
|
41222
|
+
} catch (err) {
|
|
41223
|
+
deps.logger.warn("Failed to save lastInitCourseId", { error: err });
|
|
41224
|
+
}
|
|
41225
|
+
deps.output(artifacts.tutorInstructions, { json: false });
|
|
41226
|
+
deps.output(artifacts.learnerBrief, { json: false });
|
|
41227
|
+
}
|
|
41228
|
+
var logger11, defaultDeps3, initCommand;
|
|
41229
|
+
var init_init = __esm({
|
|
41230
|
+
"src/commands/init.ts"() {
|
|
41231
|
+
"use strict";
|
|
41232
|
+
init_src();
|
|
41233
|
+
init_courses();
|
|
41234
|
+
init_http2();
|
|
41235
|
+
init_session();
|
|
41236
|
+
init_formatter();
|
|
41237
|
+
init_init_template();
|
|
41238
|
+
init_learner_context();
|
|
41239
|
+
init_api2();
|
|
41240
|
+
logger11 = createLogger("cli:init");
|
|
41241
|
+
defaultDeps3 = {
|
|
41242
|
+
getSession,
|
|
41243
|
+
getActiveCourse,
|
|
41244
|
+
listCourses,
|
|
41245
|
+
getProgress,
|
|
41246
|
+
getRemoteEnrollmentOnboarding,
|
|
41247
|
+
saveRemoteEnrollmentOnboarding,
|
|
41248
|
+
setLastInitCourseId,
|
|
41249
|
+
getCourseOnboardingState,
|
|
41250
|
+
collectLearnerContextProfile,
|
|
41251
|
+
saveCourseLearnerProfile,
|
|
41252
|
+
buildInitArtifacts,
|
|
41253
|
+
output,
|
|
41254
|
+
logger: logger11,
|
|
41255
|
+
createHttpProvider
|
|
41256
|
+
};
|
|
41257
|
+
initCommand = new Command15("init").description("Generate tutor instructions and learner brief for the active course").action(async () => {
|
|
41258
|
+
await runInit();
|
|
40481
41259
|
});
|
|
40482
41260
|
}
|
|
40483
41261
|
});
|
|
40484
41262
|
|
|
40485
41263
|
// ../../packages/tostudy-core/src/workspace/setup-workspace.ts
|
|
40486
|
-
import
|
|
40487
|
-
import
|
|
40488
|
-
async function setupWorkspace(
|
|
40489
|
-
const workspacePath =
|
|
41264
|
+
import fs9 from "node:fs/promises";
|
|
41265
|
+
import path8 from "node:path";
|
|
41266
|
+
async function setupWorkspace(input2) {
|
|
41267
|
+
const workspacePath = path8.join(input2.basePath, input2.courseSlug);
|
|
40490
41268
|
for (const dir of WORKSPACE_DIRS) {
|
|
40491
|
-
await
|
|
41269
|
+
await fs9.mkdir(path8.join(workspacePath, dir), { recursive: true });
|
|
40492
41270
|
}
|
|
40493
|
-
const configPath =
|
|
41271
|
+
const configPath = path8.join(workspacePath, ".ana-config.json");
|
|
40494
41272
|
const config2 = {
|
|
40495
|
-
courseId:
|
|
40496
|
-
courseSlug:
|
|
40497
|
-
courseName:
|
|
41273
|
+
courseId: input2.courseId,
|
|
41274
|
+
courseSlug: input2.courseSlug,
|
|
41275
|
+
courseName: input2.courseName,
|
|
40498
41276
|
workspacePath,
|
|
40499
|
-
locale:
|
|
41277
|
+
locale: input2.locale,
|
|
40500
41278
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40501
41279
|
lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
40502
41280
|
};
|
|
40503
|
-
await
|
|
41281
|
+
await fs9.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
|
|
40504
41282
|
const readme = [
|
|
40505
|
-
`# ${
|
|
41283
|
+
`# ${input2.courseName}`,
|
|
40506
41284
|
"",
|
|
40507
41285
|
"Workspace de estudo gerado pelo ToStudy.",
|
|
40508
41286
|
"",
|
|
@@ -40525,7 +41303,7 @@ async function setupWorkspace(input) {
|
|
|
40525
41303
|
"tostudy vault sync # Sincronizar progresso",
|
|
40526
41304
|
"```"
|
|
40527
41305
|
].join("\n");
|
|
40528
|
-
await
|
|
41306
|
+
await fs9.writeFile(path8.join(workspacePath, "README.md"), readme, "utf-8");
|
|
40529
41307
|
return { workspacePath, directories: WORKSPACE_DIRS, configPath };
|
|
40530
41308
|
}
|
|
40531
41309
|
var WORKSPACE_DIRS;
|
|
@@ -40626,8 +41404,8 @@ var init_templates = __esm({
|
|
|
40626
41404
|
});
|
|
40627
41405
|
|
|
40628
41406
|
// ../../packages/tostudy-core/src/workspace/extract-exercise.ts
|
|
40629
|
-
import
|
|
40630
|
-
import
|
|
41407
|
+
import fs10 from "node:fs/promises";
|
|
41408
|
+
import path9 from "node:path";
|
|
40631
41409
|
function padOrder(n) {
|
|
40632
41410
|
return String(n).padStart(2, "0");
|
|
40633
41411
|
}
|
|
@@ -40647,20 +41425,20 @@ function getStarterCode(structuredData) {
|
|
|
40647
41425
|
const data = sd.data;
|
|
40648
41426
|
return data?.starterCode ?? null;
|
|
40649
41427
|
}
|
|
40650
|
-
async function extractExercise(
|
|
40651
|
-
const { lessonData, exerciseTier, workspacePath } =
|
|
41428
|
+
async function extractExercise(input2) {
|
|
41429
|
+
const { lessonData, exerciseTier, workspacePath } = input2;
|
|
40652
41430
|
const moduleDir = `${padOrder(lessonData.moduleOrder)}-${lessonData.moduleSlug}`;
|
|
40653
41431
|
const lessonDir = `${padOrder(lessonData.lessonOrder)}-${lessonData.lessonSlug}`;
|
|
40654
|
-
const exercisePath =
|
|
40655
|
-
await
|
|
41432
|
+
const exercisePath = path9.join(workspacePath, "exercises", moduleDir, lessonDir);
|
|
41433
|
+
await fs10.mkdir(exercisePath, { recursive: true });
|
|
40656
41434
|
const extractedFiles = [];
|
|
40657
41435
|
let hasStarterCode = false;
|
|
40658
41436
|
if (lessonData.sandpackConfig?.files) {
|
|
40659
41437
|
for (const [filePath, fileData] of Object.entries(lessonData.sandpackConfig.files)) {
|
|
40660
41438
|
const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
40661
|
-
const fullPath =
|
|
40662
|
-
await
|
|
40663
|
-
await
|
|
41439
|
+
const fullPath = path9.join(exercisePath, cleanPath);
|
|
41440
|
+
await fs10.mkdir(path9.dirname(fullPath), { recursive: true });
|
|
41441
|
+
await fs10.writeFile(fullPath, fileData.code, "utf-8");
|
|
40664
41442
|
extractedFiles.push(cleanPath);
|
|
40665
41443
|
hasStarterCode = true;
|
|
40666
41444
|
}
|
|
@@ -40668,13 +41446,13 @@ async function extractExercise(input) {
|
|
|
40668
41446
|
const tierData = getTierData(lessonData.structuredData, exerciseTier);
|
|
40669
41447
|
const tierCode = tierData?.code;
|
|
40670
41448
|
if (tierCode) {
|
|
40671
|
-
await
|
|
41449
|
+
await fs10.writeFile(path9.join(exercisePath, "exercise.js"), tierCode, "utf-8");
|
|
40672
41450
|
extractedFiles.push("exercise.js");
|
|
40673
41451
|
hasStarterCode = true;
|
|
40674
41452
|
} else {
|
|
40675
41453
|
const starter = getStarterCode(lessonData.structuredData);
|
|
40676
41454
|
if (starter) {
|
|
40677
|
-
await
|
|
41455
|
+
await fs10.writeFile(path9.join(exercisePath, "exercise.js"), starter, "utf-8");
|
|
40678
41456
|
extractedFiles.push("exercise.js");
|
|
40679
41457
|
hasStarterCode = true;
|
|
40680
41458
|
}
|
|
@@ -40692,8 +41470,8 @@ async function extractExercise(input) {
|
|
|
40692
41470
|
...exerciseDeps
|
|
40693
41471
|
}
|
|
40694
41472
|
};
|
|
40695
|
-
await
|
|
40696
|
-
|
|
41473
|
+
await fs10.writeFile(
|
|
41474
|
+
path9.join(exercisePath, "package.json"),
|
|
40697
41475
|
JSON.stringify(pkgJson, null, 2),
|
|
40698
41476
|
"utf-8"
|
|
40699
41477
|
);
|
|
@@ -40705,20 +41483,20 @@ async function extractExercise(input) {
|
|
|
40705
41483
|
);
|
|
40706
41484
|
for (const [configFile, configContent] of Object.entries(scaffold.configs)) {
|
|
40707
41485
|
if (!sandpackFileNames.has(configFile)) {
|
|
40708
|
-
await
|
|
41486
|
+
await fs10.writeFile(path9.join(exercisePath, configFile), configContent, "utf-8");
|
|
40709
41487
|
extractedFiles.push(configFile);
|
|
40710
41488
|
}
|
|
40711
41489
|
}
|
|
40712
41490
|
const setupSh = `#!/bin/sh
|
|
40713
41491
|
${scaffold.setupScript}
|
|
40714
41492
|
`;
|
|
40715
|
-
await
|
|
41493
|
+
await fs10.writeFile(path9.join(exercisePath, "setup.sh"), setupSh, "utf-8");
|
|
40716
41494
|
extractedFiles.push("setup.sh");
|
|
40717
41495
|
}
|
|
40718
41496
|
}
|
|
40719
41497
|
const readme = generateReadme(lessonData, exerciseTier);
|
|
40720
|
-
const readmePath =
|
|
40721
|
-
await
|
|
41498
|
+
const readmePath = path9.join(exercisePath, "README.md");
|
|
41499
|
+
await fs10.writeFile(readmePath, readme, "utf-8");
|
|
40722
41500
|
extractedFiles.push("README.md");
|
|
40723
41501
|
return {
|
|
40724
41502
|
exercisePath,
|
|
@@ -40784,14 +41562,15 @@ var init_workspace = __esm({
|
|
|
40784
41562
|
init_extract_exercise();
|
|
40785
41563
|
init_export_artifact();
|
|
40786
41564
|
init_templates();
|
|
41565
|
+
init_lesson_exercise_data();
|
|
40787
41566
|
}
|
|
40788
41567
|
});
|
|
40789
41568
|
|
|
40790
41569
|
// src/commands/workspace.ts
|
|
40791
41570
|
import { Command as Command16 } from "commander";
|
|
40792
|
-
import
|
|
40793
|
-
import
|
|
40794
|
-
import
|
|
41571
|
+
import path10 from "node:path";
|
|
41572
|
+
import os7 from "node:os";
|
|
41573
|
+
import fs11 from "node:fs/promises";
|
|
40795
41574
|
var logger12, workspaceCommand;
|
|
40796
41575
|
var init_workspace2 = __esm({
|
|
40797
41576
|
"src/commands/workspace.ts"() {
|
|
@@ -40803,7 +41582,7 @@ var init_workspace2 = __esm({
|
|
|
40803
41582
|
workspaceCommand = new Command16("workspace").description(
|
|
40804
41583
|
"Gerenciar workspace de estudo local"
|
|
40805
41584
|
);
|
|
40806
|
-
workspaceCommand.command("setup").description("Criar estrutura do workspace para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
41585
|
+
workspaceCommand.command("setup").description("Criar estrutura do workspace para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path10.join(os7.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
40807
41586
|
try {
|
|
40808
41587
|
await requireSession();
|
|
40809
41588
|
const activeCourse = await requireActiveCourse();
|
|
@@ -40814,6 +41593,7 @@ var init_workspace2 = __esm({
|
|
|
40814
41593
|
basePath: opts.path,
|
|
40815
41594
|
locale: "pt-BR"
|
|
40816
41595
|
});
|
|
41596
|
+
await setCourseWorkspacePath(activeCourse.courseId, result.workspacePath);
|
|
40817
41597
|
if (opts.json) {
|
|
40818
41598
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
40819
41599
|
} else {
|
|
@@ -40835,14 +41615,14 @@ Pr\xF3ximo passo: tostudy export
|
|
|
40835
41615
|
process.exit(1);
|
|
40836
41616
|
}
|
|
40837
41617
|
});
|
|
40838
|
-
workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
41618
|
+
workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path10.join(os7.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
40839
41619
|
try {
|
|
40840
41620
|
const activeCourse = await requireActiveCourse();
|
|
40841
|
-
const
|
|
40842
|
-
const workspacePath =
|
|
41621
|
+
const courseSlug2 = activeCourse.courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
41622
|
+
const workspacePath = path10.join(opts.path, courseSlug2);
|
|
40843
41623
|
let configData = null;
|
|
40844
41624
|
try {
|
|
40845
|
-
const raw = await
|
|
41625
|
+
const raw = await fs11.readFile(path10.join(workspacePath, ".ana-config.json"), "utf-8");
|
|
40846
41626
|
configData = JSON.parse(raw);
|
|
40847
41627
|
} catch {
|
|
40848
41628
|
process.stderr.write(
|
|
@@ -40850,42 +41630,42 @@ Pr\xF3ximo passo: tostudy export
|
|
|
40850
41630
|
);
|
|
40851
41631
|
process.exit(1);
|
|
40852
41632
|
}
|
|
40853
|
-
const exercisesDir =
|
|
41633
|
+
const exercisesDir = path10.join(workspacePath, "exercises");
|
|
40854
41634
|
let exerciseCount = 0;
|
|
40855
41635
|
try {
|
|
40856
|
-
const moduleDirs = await
|
|
41636
|
+
const moduleDirs = await fs11.readdir(exercisesDir);
|
|
40857
41637
|
for (const modDir of moduleDirs) {
|
|
40858
|
-
const modPath =
|
|
40859
|
-
const stat = await
|
|
41638
|
+
const modPath = path10.join(exercisesDir, modDir);
|
|
41639
|
+
const stat = await fs11.stat(modPath);
|
|
40860
41640
|
if (stat.isDirectory()) {
|
|
40861
|
-
const lessonDirs = await
|
|
41641
|
+
const lessonDirs = await fs11.readdir(modPath);
|
|
40862
41642
|
for (const lessonDir of lessonDirs) {
|
|
40863
|
-
const lessonPath =
|
|
40864
|
-
const lstat = await
|
|
41643
|
+
const lessonPath = path10.join(modPath, lessonDir);
|
|
41644
|
+
const lstat = await fs11.stat(lessonPath);
|
|
40865
41645
|
if (lstat.isDirectory()) exerciseCount++;
|
|
40866
41646
|
}
|
|
40867
41647
|
}
|
|
40868
41648
|
}
|
|
40869
41649
|
} catch {
|
|
40870
41650
|
}
|
|
40871
|
-
const generatedDir =
|
|
41651
|
+
const generatedDir = path10.join(workspacePath, "generated");
|
|
40872
41652
|
let artifactCount = 0;
|
|
40873
41653
|
try {
|
|
40874
|
-
const files = await
|
|
41654
|
+
const files = await fs11.readdir(generatedDir);
|
|
40875
41655
|
artifactCount = files.length;
|
|
40876
41656
|
} catch {
|
|
40877
41657
|
}
|
|
40878
|
-
const diagramsDir =
|
|
41658
|
+
const diagramsDir = path10.join(workspacePath, "diagrams");
|
|
40879
41659
|
let diagramCount = 0;
|
|
40880
41660
|
try {
|
|
40881
|
-
const files = await
|
|
41661
|
+
const files = await fs11.readdir(diagramsDir);
|
|
40882
41662
|
diagramCount = files.length;
|
|
40883
41663
|
} catch {
|
|
40884
41664
|
}
|
|
40885
|
-
const vaultDir =
|
|
41665
|
+
const vaultDir = path10.join(workspacePath, "vault");
|
|
40886
41666
|
let hasVault = false;
|
|
40887
41667
|
try {
|
|
40888
|
-
await
|
|
41668
|
+
await fs11.access(path10.join(vaultDir, ".ana-vault.json"));
|
|
40889
41669
|
hasVault = true;
|
|
40890
41670
|
} catch {
|
|
40891
41671
|
}
|
|
@@ -40929,19 +41709,8 @@ Pr\xF3ximo passo: tostudy export
|
|
|
40929
41709
|
|
|
40930
41710
|
// src/commands/export.ts
|
|
40931
41711
|
import { Command as Command17 } from "commander";
|
|
40932
|
-
import
|
|
40933
|
-
import
|
|
40934
|
-
import os7 from "node:os";
|
|
40935
|
-
async function findWorkspacePath(courseTitle, basePath) {
|
|
40936
|
-
const slug = courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
40937
|
-
const candidate = path8.join(basePath, slug);
|
|
40938
|
-
try {
|
|
40939
|
-
const config2 = await fs10.readFile(path8.join(candidate, ".ana-config.json"), "utf-8");
|
|
40940
|
-
if (config2) return candidate;
|
|
40941
|
-
} catch {
|
|
40942
|
-
}
|
|
40943
|
-
return null;
|
|
40944
|
-
}
|
|
41712
|
+
import path11 from "node:path";
|
|
41713
|
+
import os8 from "node:os";
|
|
40945
41714
|
var logger13, exportCommand;
|
|
40946
41715
|
var init_export = __esm({
|
|
40947
41716
|
"src/commands/export.ts"() {
|
|
@@ -40950,8 +41719,9 @@ var init_export = __esm({
|
|
|
40950
41719
|
init_workspace();
|
|
40951
41720
|
init_http2();
|
|
40952
41721
|
init_session();
|
|
41722
|
+
init_resolve();
|
|
40953
41723
|
logger13 = createLogger("cli:export");
|
|
40954
|
-
exportCommand = new Command17("export").description("Extrair exerc\xEDcio atual para o workspace local").option("--tier <tier>", "Tier do exerc\xEDcio: guided, semiGuided, challenging", "guided").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
41724
|
+
exportCommand = new Command17("export").description("Extrair exerc\xEDcio atual para o workspace local").option("--tier <tier>", "Tier do exerc\xEDcio: guided, semiGuided, challenging", "guided").option("--path <dir>", "Diret\xF3rio base do workspace", path11.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
40955
41725
|
try {
|
|
40956
41726
|
const session = await requireSession();
|
|
40957
41727
|
const activeCourse = await requireActiveCourse();
|
|
@@ -40961,8 +41731,8 @@ var init_export = __esm({
|
|
|
40961
41731
|
process.stderr.write("\u274C Nenhuma li\xE7\xE3o ativa. Execute 'tostudy start' primeiro.\n");
|
|
40962
41732
|
process.exit(1);
|
|
40963
41733
|
}
|
|
40964
|
-
const
|
|
40965
|
-
if (!
|
|
41734
|
+
const ws = await resolveWorkspace(activeCourse.courseTitle, opts.path);
|
|
41735
|
+
if (!ws.found) {
|
|
40966
41736
|
process.stderr.write(
|
|
40967
41737
|
"\u274C Workspace n\xE3o encontrado. Execute 'tostudy workspace setup' primeiro.\n"
|
|
40968
41738
|
);
|
|
@@ -40974,7 +41744,7 @@ var init_export = __esm({
|
|
|
40974
41744
|
const result = await extractExercise({
|
|
40975
41745
|
lessonData,
|
|
40976
41746
|
exerciseTier: tier,
|
|
40977
|
-
workspacePath
|
|
41747
|
+
workspacePath: ws.workspacePath
|
|
40978
41748
|
});
|
|
40979
41749
|
if (opts.json) {
|
|
40980
41750
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
@@ -41007,14 +41777,14 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
|
|
|
41007
41777
|
// src/commands/open.ts
|
|
41008
41778
|
import { Command as Command18 } from "commander";
|
|
41009
41779
|
import { execFile as execFile3 } from "node:child_process";
|
|
41010
|
-
import
|
|
41011
|
-
import
|
|
41012
|
-
import
|
|
41013
|
-
async function
|
|
41780
|
+
import fs12 from "node:fs/promises";
|
|
41781
|
+
import path12 from "node:path";
|
|
41782
|
+
import os9 from "node:os";
|
|
41783
|
+
async function findWorkspacePath(courseTitle, basePath) {
|
|
41014
41784
|
const slug = courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
41015
|
-
const candidate =
|
|
41785
|
+
const candidate = path12.join(basePath, slug);
|
|
41016
41786
|
try {
|
|
41017
|
-
await
|
|
41787
|
+
await fs12.access(path12.join(candidate, ".ana-config.json"));
|
|
41018
41788
|
return candidate;
|
|
41019
41789
|
} catch {
|
|
41020
41790
|
return null;
|
|
@@ -41027,10 +41797,10 @@ var init_open = __esm({
|
|
|
41027
41797
|
init_src();
|
|
41028
41798
|
init_session();
|
|
41029
41799
|
logger14 = createLogger("cli:open");
|
|
41030
|
-
openCommand = new Command18("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
41800
|
+
openCommand = new Command18("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path12.join(os9.homedir(), "study")).action(async (opts) => {
|
|
41031
41801
|
try {
|
|
41032
41802
|
const activeCourse = await requireActiveCourse();
|
|
41033
|
-
const workspacePath = await
|
|
41803
|
+
const workspacePath = await findWorkspacePath(activeCourse.courseTitle, opts.path);
|
|
41034
41804
|
if (!workspacePath) {
|
|
41035
41805
|
process.stderr.write(
|
|
41036
41806
|
"\u274C Workspace n\xE3o encontrado. Execute 'tostudy workspace setup' primeiro.\n"
|
|
@@ -41076,24 +41846,24 @@ var init_types3 = __esm({
|
|
|
41076
41846
|
});
|
|
41077
41847
|
|
|
41078
41848
|
// ../../packages/tostudy-core/src/vault/write-vault.ts
|
|
41079
|
-
import
|
|
41080
|
-
import
|
|
41081
|
-
async function writeVaultFiles(files, outputPath, courseId,
|
|
41849
|
+
import fs13 from "node:fs/promises";
|
|
41850
|
+
import path13 from "node:path";
|
|
41851
|
+
async function writeVaultFiles(files, outputPath, courseId, courseSlug2) {
|
|
41082
41852
|
for (const file2 of files) {
|
|
41083
|
-
const fullPath =
|
|
41084
|
-
await
|
|
41085
|
-
await
|
|
41853
|
+
const fullPath = path13.join(outputPath, file2.relativePath);
|
|
41854
|
+
await fs13.mkdir(path13.dirname(fullPath), { recursive: true });
|
|
41855
|
+
await fs13.writeFile(fullPath, file2.content, "utf-8");
|
|
41086
41856
|
}
|
|
41087
|
-
const vaultPath =
|
|
41857
|
+
const vaultPath = path13.join(outputPath, courseSlug2);
|
|
41088
41858
|
const marker = {
|
|
41089
41859
|
courseId,
|
|
41090
|
-
courseSlug,
|
|
41860
|
+
courseSlug: courseSlug2,
|
|
41091
41861
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
41092
41862
|
version: VAULT_MARKER_VERSION
|
|
41093
41863
|
};
|
|
41094
|
-
await
|
|
41095
|
-
await
|
|
41096
|
-
|
|
41864
|
+
await fs13.mkdir(vaultPath, { recursive: true });
|
|
41865
|
+
await fs13.writeFile(
|
|
41866
|
+
path13.join(vaultPath, VAULT_MARKER_FILENAME),
|
|
41097
41867
|
JSON.stringify(marker, null, 2),
|
|
41098
41868
|
"utf-8"
|
|
41099
41869
|
);
|
|
@@ -41118,9 +41888,9 @@ var init_vault = __esm({
|
|
|
41118
41888
|
|
|
41119
41889
|
// src/commands/vault.ts
|
|
41120
41890
|
import { Command as Command19 } from "commander";
|
|
41121
|
-
import
|
|
41122
|
-
import
|
|
41123
|
-
import
|
|
41891
|
+
import path14 from "node:path";
|
|
41892
|
+
import os10 from "node:os";
|
|
41893
|
+
import fs14 from "node:fs/promises";
|
|
41124
41894
|
var logger15, vaultCommand;
|
|
41125
41895
|
var init_vault2 = __esm({
|
|
41126
41896
|
"src/commands/vault.ts"() {
|
|
@@ -41132,15 +41902,15 @@ var init_vault2 = __esm({
|
|
|
41132
41902
|
init_session();
|
|
41133
41903
|
logger15 = createLogger("cli:vault");
|
|
41134
41904
|
vaultCommand = new Command19("vault").description("Gerenciar vault Obsidian do curso");
|
|
41135
|
-
vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
41905
|
+
vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path14.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
41136
41906
|
try {
|
|
41137
41907
|
const session = await requireSession();
|
|
41138
41908
|
const activeCourse = await requireActiveCourse();
|
|
41139
41909
|
const driftWarning = await checkCourseDrift();
|
|
41140
41910
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
41141
|
-
const
|
|
41142
|
-
const workspacePath =
|
|
41143
|
-
const vaultOutputPath =
|
|
41911
|
+
const courseSlug2 = activeCourse.courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
41912
|
+
const workspacePath = path14.join(opts.path, courseSlug2);
|
|
41913
|
+
const vaultOutputPath = path14.join(workspacePath, "vault");
|
|
41144
41914
|
const res = await fetch(`${session.apiUrl}/api/cli/vault/init`, {
|
|
41145
41915
|
method: "POST",
|
|
41146
41916
|
headers: {
|
|
@@ -41162,7 +41932,7 @@ var init_vault2 = __esm({
|
|
|
41162
41932
|
data.files,
|
|
41163
41933
|
vaultOutputPath,
|
|
41164
41934
|
activeCourse.courseId,
|
|
41165
|
-
|
|
41935
|
+
courseSlug2
|
|
41166
41936
|
);
|
|
41167
41937
|
logger15.info("Vault generated", {
|
|
41168
41938
|
courseId: activeCourse.courseId,
|
|
@@ -41203,16 +41973,16 @@ Para visualizar:
|
|
|
41203
41973
|
process.exit(1);
|
|
41204
41974
|
}
|
|
41205
41975
|
});
|
|
41206
|
-
vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
41976
|
+
vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace", path14.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
41207
41977
|
try {
|
|
41208
41978
|
const session = await requireSession();
|
|
41209
41979
|
const activeCourse = await requireActiveCourse();
|
|
41210
41980
|
const driftWarning = await checkCourseDrift();
|
|
41211
41981
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
41212
|
-
const
|
|
41213
|
-
const vaultPath =
|
|
41982
|
+
const courseSlug2 = activeCourse.courseTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
41983
|
+
const vaultPath = path14.join(opts.path, courseSlug2, "vault");
|
|
41214
41984
|
try {
|
|
41215
|
-
await
|
|
41985
|
+
await fs14.access(path14.join(vaultPath, ".ana-vault.json"));
|
|
41216
41986
|
} catch {
|
|
41217
41987
|
process.stderr.write("\u274C Vault n\xE3o encontrado. Execute 'tostudy vault init' primeiro.\n");
|
|
41218
41988
|
process.exit(1);
|
|
@@ -41220,8 +41990,8 @@ Para visualizar:
|
|
|
41220
41990
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
41221
41991
|
const deps = { data, logger: logger15 };
|
|
41222
41992
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
41223
|
-
const markerPath =
|
|
41224
|
-
const markerRaw = await
|
|
41993
|
+
const markerPath = path14.join(vaultPath, ".ana-vault.json");
|
|
41994
|
+
const markerRaw = await fs14.readFile(markerPath, "utf-8");
|
|
41225
41995
|
const marker = JSON.parse(markerRaw);
|
|
41226
41996
|
marker.lastSyncedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
41227
41997
|
marker.progress = {
|
|
@@ -41229,10 +41999,10 @@ Para visualizar:
|
|
|
41229
41999
|
currentModule: progress3.currentModule.title,
|
|
41230
42000
|
currentLesson: progress3.currentLesson.title
|
|
41231
42001
|
};
|
|
41232
|
-
await
|
|
41233
|
-
const courseIndexPath =
|
|
42002
|
+
await fs14.writeFile(markerPath, JSON.stringify(marker, null, 2), "utf-8");
|
|
42003
|
+
const courseIndexPath = path14.join(vaultPath, courseSlug2, "index.md");
|
|
41234
42004
|
try {
|
|
41235
|
-
let indexContent = await
|
|
42005
|
+
let indexContent = await fs14.readFile(courseIndexPath, "utf-8");
|
|
41236
42006
|
indexContent = indexContent.replace(/\n---\n\n> 📊 Progresso:.*\n/g, "");
|
|
41237
42007
|
const titleEnd = indexContent.indexOf("\n");
|
|
41238
42008
|
if (titleEnd !== -1) {
|
|
@@ -41243,7 +42013,7 @@ Para visualizar:
|
|
|
41243
42013
|
`;
|
|
41244
42014
|
indexContent = indexContent.slice(0, titleEnd) + banner + indexContent.slice(titleEnd);
|
|
41245
42015
|
}
|
|
41246
|
-
await
|
|
42016
|
+
await fs14.writeFile(courseIndexPath, indexContent, "utf-8");
|
|
41247
42017
|
} catch {
|
|
41248
42018
|
}
|
|
41249
42019
|
const syncedAt = marker.lastSyncedAt;
|
|
@@ -41290,7 +42060,7 @@ __export(cli_exports, {
|
|
|
41290
42060
|
import { Command as Command20 } from "commander";
|
|
41291
42061
|
function createProgram() {
|
|
41292
42062
|
const program2 = new Command20();
|
|
41293
|
-
program2.name("tostudy").description("ToStudy CLI \u2014 study courses from the terminal").version(CLI_VERSION).option("--
|
|
42063
|
+
program2.name("tostudy").description("ToStudy CLI \u2014 study courses from the terminal").version(CLI_VERSION).option("--verbose", "Enable debug output").option("--course <id>", "Override active course ID");
|
|
41294
42064
|
program2.addCommand(setupCommand);
|
|
41295
42065
|
program2.addCommand(doctorCommand);
|
|
41296
42066
|
program2.addCommand(initCommand);
|
|
@@ -41335,7 +42105,7 @@ var init_cli = __esm({
|
|
|
41335
42105
|
init_export();
|
|
41336
42106
|
init_open();
|
|
41337
42107
|
init_vault2();
|
|
41338
|
-
CLI_VERSION = "0.
|
|
42108
|
+
CLI_VERSION = "0.6.0";
|
|
41339
42109
|
}
|
|
41340
42110
|
});
|
|
41341
42111
|
|