@learnpack/learnpack 5.0.361 → 5.0.363
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/lib/commands/serve.js +44 -7
- package/lib/creatorDist/assets/{index-B7s5Nmq8.css → index-Cco3XhDR.css} +96 -0
- package/lib/creatorDist/assets/{index-CqVEKiJR.js → index-o3Cw0bsF.js} +69682 -66808
- package/lib/creatorDist/index.html +2 -2
- package/lib/utils/api.d.ts +0 -9
- package/lib/utils/api.js +1 -65
- package/lib/utils/lessonRecovery.d.ts +18 -0
- package/lib/utils/lessonRecovery.js +31 -0
- package/package.json +1 -1
- package/src/commands/serve.ts +65 -18
- package/src/creator/package-lock.json +297 -3
- package/src/creator/package.json +1 -0
- package/src/creator/src/App.test.tsx +124 -1
- package/src/creator/src/App.tsx +52 -36
- package/src/creator/src/components/FileCard.tsx +63 -19
- package/src/creator/src/components/FileReadListener.test.tsx +128 -0
- package/src/creator/src/components/FileReadListener.tsx +75 -0
- package/src/creator/src/components/FileReviewModal.test.tsx +193 -0
- package/src/creator/src/components/FileReviewModal.tsx +128 -0
- package/src/creator/src/components/FileUploader.test.tsx +229 -0
- package/src/creator/src/components/FileUploader.tsx +212 -58
- package/src/creator/src/components/GenerationErrorCard.tsx +57 -0
- package/src/creator/src/components/MarkdownRenderer.tsx +4 -2
- package/src/creator/src/components/syllabus/SyllabusEditor.tsx +6 -9
- package/src/creator/src/index.css +45 -0
- package/src/creator/src/locales/en.json +27 -5
- package/src/creator/src/locales/es.json +27 -5
- package/src/creator/src/main.tsx +2 -0
- package/src/creator/src/utils/completionResult.test.ts +61 -0
- package/src/creator/src/utils/completionResult.ts +61 -2
- package/src/creator/src/utils/courseLanguage.test.ts +6 -0
- package/src/creator/src/utils/creationRequest.test.ts +53 -18
- package/src/creator/src/utils/creationRequest.ts +17 -12
- package/src/creator/src/utils/fileRead.ts +60 -0
- package/src/creator/src/utils/lib.ts +0 -5
- package/src/creator/src/utils/store.ts +0 -10
- package/src/creatorDist/assets/{index-B7s5Nmq8.css → index-Cco3XhDR.css} +96 -0
- package/src/creatorDist/assets/{index-CqVEKiJR.js → index-o3Cw0bsF.js} +69682 -66808
- package/src/creatorDist/index.html +2 -2
- package/src/utils/api.ts +0 -83
- package/src/utils/lessonRecovery.ts +32 -0
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
/>
|
|
11
11
|
|
|
12
12
|
<title>Learnpack Creator: Craft tutorials in seconds!</title>
|
|
13
|
-
<script type="module" crossorigin src="/creator/assets/index-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/creator/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/creator/assets/index-o3Cw0bsF.js"></script>
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/creator/assets/index-Cco3XhDR.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
package/src/utils/api.ts
CHANGED
|
@@ -776,87 +776,6 @@ const createRigoPackage = async (token: string, slug: string, config: any) => {
|
|
|
776
776
|
}
|
|
777
777
|
}
|
|
778
778
|
|
|
779
|
-
type TTechnology = {
|
|
780
|
-
slug: string;
|
|
781
|
-
lang: string;
|
|
782
|
-
};
|
|
783
|
-
|
|
784
|
-
let technologiesCache: TTechnology[] = []
|
|
785
|
-
|
|
786
|
-
/**
|
|
787
|
-
* Strip .env comments (e.g. "token # comment") so the token is sent without spaces.
|
|
788
|
-
* @param token - Raw token value from env, possibly with trailing comment.
|
|
789
|
-
* @returns Trimmed token with inline `#` comments removed, or empty string if missing.
|
|
790
|
-
*/
|
|
791
|
-
function sanitizeToken(token: string | undefined): string {
|
|
792
|
-
if (!token) return ""
|
|
793
|
-
const trimmed = token.trim()
|
|
794
|
-
const beforeComment = trimmed.split(/\s+#/)[0].trim()
|
|
795
|
-
return beforeComment
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
export const fetchTechnologies = async () => {
|
|
799
|
-
const rawToken = process.env.BREATHECODE_PERMANENT_TOKEN
|
|
800
|
-
const BREATHECODE_PERMANENT_TOKEN = sanitizeToken(rawToken)
|
|
801
|
-
const LANGS = ["en", "es"]
|
|
802
|
-
|
|
803
|
-
if (!BREATHECODE_PERMANENT_TOKEN) {
|
|
804
|
-
throw new Error(
|
|
805
|
-
"BREATHECODE_PERMANENT_TOKEN is not defined in environment variables"
|
|
806
|
-
)
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
const headers = {
|
|
810
|
-
Authorization: `Token ${BREATHECODE_PERMANENT_TOKEN}`,
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
const results = await Promise.all(
|
|
814
|
-
LANGS.map(lang =>
|
|
815
|
-
axios
|
|
816
|
-
.get(`${HOST}/v1/registry/technology?lang=${lang}`, { headers })
|
|
817
|
-
.then(res => {
|
|
818
|
-
return res.data
|
|
819
|
-
})
|
|
820
|
-
.then(data =>
|
|
821
|
-
data.map((item: any) => ({
|
|
822
|
-
slug: item.slug,
|
|
823
|
-
lang: lang,
|
|
824
|
-
}))
|
|
825
|
-
)
|
|
826
|
-
)
|
|
827
|
-
)
|
|
828
|
-
|
|
829
|
-
const allItems = results.flat()
|
|
830
|
-
|
|
831
|
-
// Remove duplicates by slug+lang combination
|
|
832
|
-
const unique = []
|
|
833
|
-
const seen = new Set()
|
|
834
|
-
for (const item of allItems) {
|
|
835
|
-
const key = `${item.slug}:${item.lang}`
|
|
836
|
-
if (!seen.has(key)) {
|
|
837
|
-
seen.add(key)
|
|
838
|
-
unique.push(item)
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
return unique
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
// Function to update the cache and schedule the next update
|
|
846
|
-
async function updateTechnologiesPeriodically() {
|
|
847
|
-
try {
|
|
848
|
-
technologiesCache = await fetchTechnologies()
|
|
849
|
-
// Uncomment for debugging:
|
|
850
|
-
// console.log('Technologies list updated:', technologiesCache);
|
|
851
|
-
} catch (error: any) {
|
|
852
|
-
console.error("Error updating technologies list:", error)
|
|
853
|
-
} finally {
|
|
854
|
-
setTimeout(updateTechnologiesPeriodically, 24 * 60 * 60 * 1000)
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
export const getCurrentTechnologies = () => technologiesCache
|
|
859
|
-
|
|
860
779
|
export default {
|
|
861
780
|
login,
|
|
862
781
|
publish,
|
|
@@ -876,6 +795,4 @@ export default {
|
|
|
876
795
|
getCategories,
|
|
877
796
|
updateRigoPackage,
|
|
878
797
|
createRigoPackage,
|
|
879
|
-
getCurrentTechnologies,
|
|
880
|
-
updateTechnologiesPeriodically,
|
|
881
798
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a lesson README holds generated content. The file starts as a
|
|
3
|
+
* `loader` block, and the generated content replaces it.
|
|
4
|
+
* @param readme - The README text, or null when the file does not exist.
|
|
5
|
+
* @returns True when the lesson has its generated content.
|
|
6
|
+
*/
|
|
7
|
+
export const hasGeneratedContent = (readme: string | null): boolean =>
|
|
8
|
+
readme !== null && readme.trim() !== "" && !readme.includes("```loader")
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Finds the lessons marked as ERROR that were generated anyway. Publishing and
|
|
12
|
+
* translating wait for every lesson, and the retry screen only shows while the
|
|
13
|
+
* README has its `loader`, so these lessons would otherwise stay stuck.
|
|
14
|
+
* @param lessons - The lessons of the syllabus.
|
|
15
|
+
* @param readReadme - Reads the README of a lesson, or null if it has none.
|
|
16
|
+
* @returns The lessons to mark as done.
|
|
17
|
+
*/
|
|
18
|
+
export const findFinishedLessons = async <T extends { status?: string }>(
|
|
19
|
+
lessons: T[],
|
|
20
|
+
readReadme: (lesson: T) => Promise<string | null>
|
|
21
|
+
): Promise<T[]> => {
|
|
22
|
+
const finished: T[] = []
|
|
23
|
+
|
|
24
|
+
for (const lesson of lessons) {
|
|
25
|
+
if (lesson.status !== "ERROR") continue
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line no-await-in-loop
|
|
28
|
+
if (hasGeneratedContent(await readReadme(lesson))) finished.push(lesson)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return finished
|
|
32
|
+
}
|