@learnpack/learnpack 5.0.270 → 5.0.274
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +409 -409
- package/lib/commands/audit.js +15 -15
- package/lib/commands/breakToken.js +19 -19
- package/lib/commands/clean.js +3 -3
- package/lib/commands/init.js +41 -41
- package/lib/commands/logout.js +3 -3
- package/lib/commands/serve.js +48 -20
- package/lib/creatorDist/assets/{index-CQXTTbaZ.js → index-BfLyIQVh.js} +11535 -11409
- package/lib/creatorDist/assets/{index-B4khtb0r.css → index-C39zeF3W.css} +3 -3
- package/lib/creatorDist/index.html +2 -2
- package/lib/managers/config/index.js +77 -77
- package/lib/models/creator.d.ts +1 -0
- package/lib/utils/api.js +1 -0
- package/lib/utils/creatorUtilities.js +14 -14
- package/package.json +1 -1
- package/src/commands/audit.ts +487 -487
- package/src/commands/breakToken.ts +67 -67
- package/src/commands/clean.ts +30 -30
- package/src/commands/init.ts +650 -650
- package/src/commands/logout.ts +38 -38
- package/src/commands/publish.ts +522 -522
- package/src/commands/serve.ts +64 -33
- package/src/commands/start.ts +333 -333
- package/src/commands/translate.ts +123 -123
- package/src/creator/README.md +54 -54
- package/src/creator/eslint.config.js +28 -28
- package/src/creator/src/components/syllabus/ContentIndex.tsx +1 -1
- package/src/creator/src/components/syllabus/SyllabusEditor.tsx +3 -1
- package/src/creator/src/i18n.ts +28 -28
- package/src/creator/src/index.css +217 -217
- package/src/creator/src/locales/en.json +1 -0
- package/src/creator/src/locales/es.json +1 -0
- package/src/creator/src/utils/configTypes.ts +122 -122
- package/src/creator/src/utils/constants.ts +13 -13
- package/src/creator/src/utils/creatorUtils.ts +46 -46
- package/src/creator/src/utils/eventBus.ts +2 -2
- package/src/creator/src/utils/lib.ts +468 -468
- package/src/creator/src/utils/rigo.ts +26 -26
- package/src/creator/src/utils/socket.ts +61 -61
- package/src/creator/src/utils/store.ts +222 -222
- package/src/creator/src/vite-env.d.ts +1 -1
- package/src/creator/vite.config.ts +13 -13
- package/src/creatorDist/assets/{index-CQXTTbaZ.js → index-BfLyIQVh.js} +11535 -11409
- package/src/creatorDist/assets/{index-B4khtb0r.css → index-C39zeF3W.css} +3 -3
- package/src/creatorDist/index.html +2 -2
- package/src/managers/config/defaults.ts +49 -49
- package/src/managers/config/exercise.ts +364 -364
- package/src/managers/config/index.ts +775 -775
- package/src/managers/file.ts +236 -236
- package/src/managers/server/routes.ts +554 -554
- package/src/managers/session.ts +182 -182
- package/src/managers/telemetry.ts +188 -188
- package/src/models/action.ts +13 -13
- package/src/models/config-manager.ts +28 -28
- package/src/models/config.ts +106 -106
- package/src/models/creator.ts +40 -39
- package/src/models/exercise-obj.ts +30 -30
- package/src/models/session.ts +39 -39
- package/src/models/socket.ts +61 -61
- package/src/models/status.ts +16 -16
- package/src/ui/_app/app.css +1 -1
- package/src/ui/_app/app.js +435 -414
- package/src/ui/_app/learnpack.svg +7 -7
- package/src/ui/app.tar.gz +0 -0
- package/src/utils/BaseCommand.ts +56 -56
- package/src/utils/api.ts +31 -30
- package/src/utils/audit.ts +392 -392
- package/src/utils/checkNotInstalled.ts +267 -267
- package/src/utils/configBuilder.ts +82 -82
- package/src/utils/convertCreds.js +34 -34
- package/src/utils/creatorUtilities.ts +504 -504
- package/src/utils/incrementVersion.js +74 -74
- package/src/utils/misc.ts +58 -58
- package/src/utils/rigoActions.ts +500 -500
- package/src/utils/sidebarGenerator.ts +195 -195
- package/src/utils/templates/isolated/exercises/01-hello-world/README.es.md +26 -26
- package/src/utils/templates/isolated/exercises/01-hello-world/README.md +26 -26
package/lib/commands/audit.js
CHANGED
@@ -369,21 +369,21 @@ class AuditCommand extends SessionCommand_1.default {
|
|
369
369
|
}
|
370
370
|
}
|
371
371
|
}
|
372
|
-
AuditCommand.description = `learnpack audit is the command in charge of creating an auditory of the repository
|
373
|
-
...
|
374
|
-
learnpack audit checks for the following information in a repository:
|
375
|
-
1. The configuration object has slug, repository and description. (Error)
|
376
|
-
2. The command learnpack clean has been run. (Error)
|
377
|
-
3. If a markdown or test file doesn't have any content. (Error)
|
378
|
-
4. The links are accessing to valid servers. (Error)
|
379
|
-
5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)
|
380
|
-
6. The external images are working (If they are pointing to a valid server). (Error)
|
381
|
-
7. The exercises directory names are valid. (Error)
|
382
|
-
8. If an exercise doesn't have a README file. (Error)
|
383
|
-
9. The exercises array (Of the config file) has content. (Error)
|
384
|
-
10. The exercses have the same translations. (Warning)
|
385
|
-
11. The .gitignore file exists. (Warning)
|
386
|
-
12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
|
372
|
+
AuditCommand.description = `learnpack audit is the command in charge of creating an auditory of the repository
|
373
|
+
...
|
374
|
+
learnpack audit checks for the following information in a repository:
|
375
|
+
1. The configuration object has slug, repository and description. (Error)
|
376
|
+
2. The command learnpack clean has been run. (Error)
|
377
|
+
3. If a markdown or test file doesn't have any content. (Error)
|
378
|
+
4. The links are accessing to valid servers. (Error)
|
379
|
+
5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)
|
380
|
+
6. The external images are working (If they are pointing to a valid server). (Error)
|
381
|
+
7. The exercises directory names are valid. (Error)
|
382
|
+
8. If an exercise doesn't have a README file. (Error)
|
383
|
+
9. The exercises array (Of the config file) has content. (Error)
|
384
|
+
10. The exercses have the same translations. (Warning)
|
385
|
+
11. The .gitignore file exists. (Warning)
|
386
|
+
12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
|
387
387
|
`;
|
388
388
|
AuditCommand.flags = {
|
389
389
|
strict: command_1.flags.boolean({
|
@@ -4,25 +4,25 @@ const command_1 = require("@oclif/command");
|
|
4
4
|
const BaseCommand_1 = require("../utils/BaseCommand");
|
5
5
|
const console_1 = require("../utils/console");
|
6
6
|
const creatorUtilities_1 = require("../utils/creatorUtilities");
|
7
|
-
const exampleMd = `# How to Install Node.js
|
8
|
-
|
9
|
-
Node.js lets you run JavaScript outside a web browser.
|
10
|
-
|
11
|
-
## Step 1: Download Node.js
|
12
|
-
|
13
|
-
Get the Node.js installer from the [official site](https://nodejs.org/en/download/).
|
14
|
-
|
15
|
-
## Step 2: Install Node.js
|
16
|
-
|
17
|
-
Open the installer and follow the steps to finish.
|
18
|
-
|
19
|
-
## Step 3: Verify the Installation
|
20
|
-
|
21
|
-
Open a terminal and type:
|
22
|
-
|
23
|
-
\`\`\`bash
|
24
|
-
node -v
|
25
|
-
\`\`\`
|
7
|
+
const exampleMd = `# How to Install Node.js
|
8
|
+
|
9
|
+
Node.js lets you run JavaScript outside a web browser.
|
10
|
+
|
11
|
+
## Step 1: Download Node.js
|
12
|
+
|
13
|
+
Get the Node.js installer from the [official site](https://nodejs.org/en/download/).
|
14
|
+
|
15
|
+
## Step 2: Install Node.js
|
16
|
+
|
17
|
+
Open the installer and follow the steps to finish.
|
18
|
+
|
19
|
+
## Step 3: Verify the Installation
|
20
|
+
|
21
|
+
Open a terminal and type:
|
22
|
+
|
23
|
+
\`\`\`bash
|
24
|
+
node -v
|
25
|
+
\`\`\`
|
26
26
|
`;
|
27
27
|
class BreakTokenCommand extends BaseCommand_1.default {
|
28
28
|
async run() {
|
package/lib/commands/clean.js
CHANGED
@@ -16,9 +16,9 @@ class CleanCommand extends SessionCommand_1.default {
|
|
16
16
|
console_1.default.success("Package cleaned successfully, ready to publish");
|
17
17
|
}
|
18
18
|
}
|
19
|
-
CleanCommand.description = `Clean the configuration object
|
20
|
-
...
|
21
|
-
Extra documentation goes here
|
19
|
+
CleanCommand.description = `Clean the configuration object
|
20
|
+
...
|
21
|
+
Extra documentation goes here
|
22
22
|
`;
|
23
23
|
CleanCommand.flags = {
|
24
24
|
// name: flags.string({char: 'n', description: 'name to print'}),
|
package/lib/commands/init.js
CHANGED
@@ -107,9 +107,9 @@ const initializeInteractiveCreation = async (rigoToken, courseInfo) => {
|
|
107
107
|
while (!isReady) {
|
108
108
|
const spinner = (0, ora_1.default)("Thinking...").start();
|
109
109
|
let wholeInfo = courseInfo;
|
110
|
-
wholeInfo += `
|
111
|
-
Current title: ${currentTitle}
|
112
|
-
Current description: ${currentDescription}
|
110
|
+
wholeInfo += `
|
111
|
+
Current title: ${currentTitle}
|
112
|
+
Current description: ${currentDescription}
|
113
113
|
`;
|
114
114
|
// eslint-disable-next-line
|
115
115
|
const res = await (0, rigoActions_1.interactiveCreation)(rigoToken, {
|
@@ -200,56 +200,56 @@ const handleAILogic = async (tutorialDir, packageInfo) => {
|
|
200
200
|
fs.mkdirSync(rulesDir, { recursive: true });
|
201
201
|
fs.writeFileSync(path.join(rulesDir, "airules.txt"), airules);
|
202
202
|
}
|
203
|
-
let packageContext = `
|
204
|
-
\n
|
205
|
-
Title: "${packageInfo.title.us}"
|
206
|
-
Description: "${packageInfo.description.us}"
|
207
|
-
Target Audience: "${targetAudience}"
|
208
|
-
Estimated Duration: "${estimatedDuration} minutes"
|
209
|
-
|
203
|
+
let packageContext = `
|
204
|
+
\n
|
205
|
+
Title: "${packageInfo.title.us}"
|
206
|
+
Description: "${packageInfo.description.us}"
|
207
|
+
Target Audience: "${targetAudience}"
|
208
|
+
Estimated Duration: "${estimatedDuration} minutes"
|
209
|
+
|
210
210
|
${contentIndex ?
|
211
|
-
`Content Index submitted by the user, use this to guide your creation. Keep in mind that your tutorial should contain these topics:
|
212
|
-
---
|
213
|
-
${contentIndex}
|
214
|
-
---
|
211
|
+
`Content Index submitted by the user, use this to guide your creation. Keep in mind that your tutorial should contain these topics:
|
212
|
+
---
|
213
|
+
${contentIndex}
|
214
|
+
---
|
215
215
|
` :
|
216
|
-
""}
|
217
|
-
|
218
|
-
This is the duration for each type of step, use it to estimate the number of steps to create:
|
216
|
+
""}
|
217
|
+
|
218
|
+
This is the duration for each type of step, use it to estimate the number of steps to create:
|
219
219
|
${Object.entries(durationByKind)
|
220
220
|
.map(([key, value]) => `${key}: ${value} minutes`)
|
221
|
-
.join("\n")}
|
222
|
-
|
223
|
-
|
224
|
-
Within the estimated duration, is possible to have the following activities:
|
225
|
-
Format=
|
226
|
-
Activity: Maximum number of steps for duration
|
227
|
-
|
228
|
-
Estimated activities:
|
229
|
-
${JSON.stringify(estimateActivities(estimatedDuration))}
|
230
|
-
|
231
|
-
You should create a tutorial that is engaging and fun to follow.
|
232
|
-
|
233
|
-
|
221
|
+
.join("\n")}
|
222
|
+
|
223
|
+
|
224
|
+
Within the estimated duration, is possible to have the following activities:
|
225
|
+
Format=
|
226
|
+
Activity: Maximum number of steps for duration
|
227
|
+
|
228
|
+
Estimated activities:
|
229
|
+
${JSON.stringify(estimateActivities(estimatedDuration))}
|
230
|
+
|
231
|
+
You should create a tutorial that is engaging and fun to follow.
|
232
|
+
|
233
|
+
|
234
234
|
${airules ?
|
235
|
-
`
|
236
|
-
This is a list of rules you need to follow when creating the tutorial:
|
237
|
-
${airules}
|
235
|
+
`
|
236
|
+
This is a list of rules you need to follow when creating the tutorial:
|
237
|
+
${airules}
|
238
238
|
` :
|
239
|
-
""}
|
239
|
+
""}
|
240
240
|
`;
|
241
241
|
const { steps, title, description, duration, difficulty } = await initializeInteractiveCreation(rigoToken, packageContext);
|
242
242
|
packageInfo.title.us = title;
|
243
243
|
packageInfo.description.us = description;
|
244
244
|
packageInfo.duration = duration;
|
245
245
|
packageInfo.difficulty = difficulty;
|
246
|
-
packageContext = `
|
247
|
-
Title: "${title}"
|
248
|
-
Description: "${description}"
|
249
|
-
Target Audience: "${targetAudience}"
|
250
|
-
List of exercises: ${steps.join(", ")}
|
251
|
-
|
252
|
-
AI Rules: ${airules}
|
246
|
+
packageContext = `
|
247
|
+
Title: "${title}"
|
248
|
+
Description: "${description}"
|
249
|
+
Target Audience: "${targetAudience}"
|
250
|
+
List of exercises: ${steps.join(", ")}
|
251
|
+
|
252
|
+
AI Rules: ${airules}
|
253
253
|
`;
|
254
254
|
const exercisesDir = path.join(tutorialDir, "exercises");
|
255
255
|
fs.ensureDirSync(exercisesDir);
|
package/lib/commands/logout.js
CHANGED
@@ -14,9 +14,9 @@ class LogoutCommand extends SessionCommand_1.default {
|
|
14
14
|
session_1.default.destroy();
|
15
15
|
}
|
16
16
|
}
|
17
|
-
LogoutCommand.description = `Describe the command here
|
18
|
-
...
|
19
|
-
Extra documentation goes here
|
17
|
+
LogoutCommand.description = `Describe the command here
|
18
|
+
...
|
19
|
+
Extra documentation goes here
|
20
20
|
`;
|
21
21
|
LogoutCommand.flags = {
|
22
22
|
// name: flags.string({char: 'n', description: 'name to print'}),
|
package/lib/commands/serve.js
CHANGED
@@ -105,9 +105,7 @@ const uploadInitialReadme = async (bucket, exSlug, targetDir, packageContext) =>
|
|
105
105
|
:rigo
|
106
106
|
\`\`\`
|
107
107
|
`;
|
108
|
-
const readmeFilename = `README
|
109
|
-
`${packageContext.language}.` :
|
110
|
-
""}md`;
|
108
|
+
const readmeFilename = `README${(0, creatorUtilities_1.getReadmeExtension)(packageContext.language || "en")}`;
|
111
109
|
await uploadFileToBucket(bucket, isGeneratingText, `${targetDir}/${readmeFilename}`);
|
112
110
|
};
|
113
111
|
const cleanFormState = (formState) => {
|
@@ -134,12 +132,12 @@ const createMultiLangAsset = async (bucket, rigoToken, bcToken, courseSlug, cour
|
|
134
132
|
all_translations.push(asset.slug);
|
135
133
|
}
|
136
134
|
};
|
137
|
-
async function startExerciseGeneration(
|
135
|
+
async function startExerciseGeneration(rigoToken, steps, packageContext, exercise, courseSlug, purposeSlug, lastLesson = "") {
|
138
136
|
const exSlug = (0, creatorUtilities_2.slugify)(exercise.id + "-" + exercise.title);
|
139
137
|
console.log("Starting generation of", exSlug);
|
140
138
|
const webhookUrl = `${process.env.HOST}/webhooks/${courseSlug}/exercise-processor/${exercise.id}/${rigoToken}`;
|
141
139
|
console.log("WEBHOOK URL", webhookUrl);
|
142
|
-
await (0, rigoActions_1.readmeCreator)(rigoToken, {
|
140
|
+
const res = await (0, rigoActions_1.readmeCreator)(rigoToken, {
|
143
141
|
title: `${exercise.id} - ${exercise.title}`,
|
144
142
|
output_lang: packageContext.language || "en",
|
145
143
|
list_of_exercises: JSON.stringify(steps.map(step => step.id + "-" + step.title)),
|
@@ -148,6 +146,7 @@ async function startExerciseGeneration(bucket, rigoToken, steps, packageContext,
|
|
148
146
|
kind: exercise.type.toLowerCase(),
|
149
147
|
last_lesson: lastLesson,
|
150
148
|
}, purposeSlug, webhookUrl);
|
149
|
+
console.log("README CREATOR RES", res);
|
151
150
|
}
|
152
151
|
async function createInitialReadme(tutorialInfo, tutorialSlug, rigoToken) {
|
153
152
|
const webhookUrl = `${process.env.HOST}/webhooks/${tutorialSlug}/initial-readme-processor`;
|
@@ -356,7 +355,6 @@ class ServeCommand extends SessionCommand_1.default {
|
|
356
355
|
});
|
357
356
|
return res.json({ status: "ERROR" });
|
358
357
|
}
|
359
|
-
fs.writeFileSync(`image-${imageId}.json`, JSON.stringify(body, null, 2));
|
360
358
|
const imageUrl = body.image_url;
|
361
359
|
const format = body.format;
|
362
360
|
const imagePath = `courses/${courseSlug}/.learn/assets/${imageId}`;
|
@@ -434,9 +432,19 @@ class ServeCommand extends SessionCommand_1.default {
|
|
434
432
|
previousReadme = content.toString();
|
435
433
|
}
|
436
434
|
}
|
437
|
-
await startExerciseGeneration(
|
435
|
+
await startExerciseGeneration(rigoToken, syllabusJson.lessons, syllabusJson.courseInfo, exercise, courseSlug, syllabusJson.courseInfo.purpose, previousReadme +
|
438
436
|
"\n\nThe user provided the following feedback related to the content of the course so far: \n\n" +
|
439
437
|
feedback);
|
438
|
+
syllabusJson.lessons[parseInt(position)].status = "GENERATING";
|
439
|
+
if (syllabusJson.feedback &&
|
440
|
+
typeof syllabusJson.feedback === "string") {
|
441
|
+
syllabusJson.feedback += "\n\n" + feedback;
|
442
|
+
}
|
443
|
+
else {
|
444
|
+
syllabusJson.feedback = feedback;
|
445
|
+
}
|
446
|
+
await uploadFileToBucket(bucket, JSON.stringify(syllabusJson), `courses/${courseSlug}/.learn/initialSyllabus.json`);
|
447
|
+
res.json({ status: "SUCCESS" });
|
440
448
|
});
|
441
449
|
app.post("/webhooks/:courseSlug/exercise-processor/:lessonID/:rigoToken", async (req, res) => {
|
442
450
|
// console.log("Receiving a webhook to exercise processor")
|
@@ -493,7 +501,11 @@ class ServeCommand extends SessionCommand_1.default {
|
|
493
501
|
let nextStarted = false;
|
494
502
|
if (nextExercise &&
|
495
503
|
(exerciseIndex === 0 || !(exerciseIndex % 3 === 0))) {
|
496
|
-
|
504
|
+
let feedback = "";
|
505
|
+
if (syllabusJson.feedback) {
|
506
|
+
feedback = `\n\nThe user added the following feedback with relation to the previous generations: ${syllabusJson.feedback}`;
|
507
|
+
}
|
508
|
+
startExerciseGeneration(rigoToken, syllabusJson.lessons, syllabusJson.courseInfo, nextExercise, courseSlug, syllabusJson.courseInfo.purpose, readme.parsed.content + "\n\n" + feedback);
|
497
509
|
nextStarted = true;
|
498
510
|
}
|
499
511
|
else {
|
@@ -511,8 +523,8 @@ class ServeCommand extends SessionCommand_1.default {
|
|
511
523
|
await (0, exports.processImage)(image.url, image.alt, rigoToken, courseSlug);
|
512
524
|
}
|
513
525
|
}
|
514
|
-
const newSyllabus = Object.assign(Object.assign({}, syllabusJson), { lessons: syllabusJson.lessons.map(lesson => {
|
515
|
-
if (
|
526
|
+
const newSyllabus = Object.assign(Object.assign({}, syllabusJson), { lessons: syllabusJson.lessons.map((lesson, index) => {
|
527
|
+
if (index === exerciseIndex) {
|
516
528
|
return Object.assign(Object.assign({}, lesson), { generated: true, status: "DONE" });
|
517
529
|
}
|
518
530
|
if (nextExercise && nextExercise.id === lesson.id && nextStarted) {
|
@@ -924,7 +936,7 @@ class ServeCommand extends SessionCommand_1.default {
|
|
924
936
|
await uploadFileToBucket(bucket, JSON.stringify(sidebar), `${tutorialDir}/.learn/sidebar.json`);
|
925
937
|
const firstLesson = syllabus.lessons[0];
|
926
938
|
const lastResult = "---";
|
927
|
-
await startExerciseGeneration(
|
939
|
+
await startExerciseGeneration(rigoToken, syllabus.lessons, syllabus.courseInfo, firstLesson, courseSlug, syllabus.courseInfo.purpose, lastResult);
|
928
940
|
await createInitialReadme(JSON.stringify(syllabus.courseInfo), courseSlug, rigoToken);
|
929
941
|
return res.json({
|
930
942
|
message: "Course generation started",
|
@@ -961,7 +973,7 @@ class ServeCommand extends SessionCommand_1.default {
|
|
961
973
|
const lastGeneratedLesson = findLast(syllabusJson.lessons, lesson => { var _a; return (_a = lesson.generated) !== null && _a !== void 0 ? _a : false; });
|
962
974
|
console.log("ABout to generate", notGeneratedLessons.length, "lessons");
|
963
975
|
const firstLessonToGenerate = notGeneratedLessons[0];
|
964
|
-
await startExerciseGeneration(
|
976
|
+
await startExerciseGeneration(rigoToken, syllabusJson.lessons, syllabusJson.courseInfo, firstLessonToGenerate, courseSlug, syllabusJson.courseInfo.purpose, JSON.stringify(lastGeneratedLesson) +
|
965
977
|
`\n\nThe user provided this feedback in relation to the course: ${feedback}`);
|
966
978
|
return res.json({
|
967
979
|
message: "Course continued",
|
@@ -1124,7 +1136,9 @@ class ServeCommand extends SessionCommand_1.default {
|
|
1124
1136
|
console.error("❌ Error fetching file:", error);
|
1125
1137
|
return res
|
1126
1138
|
.status(500)
|
1127
|
-
.json({
|
1139
|
+
.json({
|
1140
|
+
error: error.message || "Unable to fetch file",
|
1141
|
+
});
|
1128
1142
|
}
|
1129
1143
|
});
|
1130
1144
|
const YT_REGEX = /(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]{11})/;
|
@@ -1136,20 +1150,32 @@ class ServeCommand extends SessionCommand_1.default {
|
|
1136
1150
|
const ytMatch = decoded.match(YT_REGEX);
|
1137
1151
|
if (ytMatch) {
|
1138
1152
|
const videoId = ytMatch[1];
|
1153
|
+
console.log("VIDEO ID", videoId);
|
1139
1154
|
// fetch metadata
|
1140
1155
|
const items = await youtube_transcript_1.YoutubeTranscript.fetchTranscript(videoId);
|
1156
|
+
console.log("ITEMS FROM YOUTUBE TRANSCRIPT", items);
|
1141
1157
|
const transcript = items.map(i => i.text).join(" ");
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1158
|
+
let meta = null;
|
1159
|
+
try {
|
1160
|
+
const { data: meta } = await axios_1.default.get("https://www.youtube.com/oembed", {
|
1161
|
+
params: { url: decoded, format: "json" },
|
1162
|
+
});
|
1163
|
+
console.log("META", meta);
|
1164
|
+
}
|
1165
|
+
catch (error) {
|
1166
|
+
console.error("ERROR FETCHING META", error);
|
1167
|
+
meta = null;
|
1168
|
+
}
|
1169
|
+
throw new Error("test");
|
1145
1170
|
return res.json({
|
1146
1171
|
url: decoded,
|
1147
|
-
title: meta.title,
|
1148
|
-
author: meta.author_name,
|
1149
|
-
thumbnail: meta.thumbnail_url,
|
1172
|
+
title: (meta === null || meta === void 0 ? void 0 : meta.title) || null,
|
1173
|
+
author: (meta === null || meta === void 0 ? void 0 : meta.author_name) || null,
|
1174
|
+
thumbnail: (meta === null || meta === void 0 ? void 0 : meta.thumbnail_url) || null,
|
1150
1175
|
transcript,
|
1151
1176
|
});
|
1152
1177
|
}
|
1178
|
+
console.log("NOT A YOUTUBE LINK", decoded);
|
1153
1179
|
const response = await axios_1.default.get(decoded, { responseType: "text" });
|
1154
1180
|
const html = response.data;
|
1155
1181
|
const title = getTitleFromHTML(html);
|
@@ -1163,7 +1189,9 @@ class ServeCommand extends SessionCommand_1.default {
|
|
1163
1189
|
}
|
1164
1190
|
catch (error) {
|
1165
1191
|
console.error("❌ /actions/fetch error:", error.message || error);
|
1166
|
-
res
|
1192
|
+
res
|
1193
|
+
.status(500)
|
1194
|
+
.json({ error: error.message || "Failed to fetch link" });
|
1167
1195
|
}
|
1168
1196
|
});
|
1169
1197
|
app.delete("/packages/:slug", async (req, res) => {
|