@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.
Files changed (41) hide show
  1. package/lib/commands/serve.js +44 -7
  2. package/lib/creatorDist/assets/{index-B7s5Nmq8.css → index-Cco3XhDR.css} +96 -0
  3. package/lib/creatorDist/assets/{index-CqVEKiJR.js → index-o3Cw0bsF.js} +69682 -66808
  4. package/lib/creatorDist/index.html +2 -2
  5. package/lib/utils/api.d.ts +0 -9
  6. package/lib/utils/api.js +1 -65
  7. package/lib/utils/lessonRecovery.d.ts +18 -0
  8. package/lib/utils/lessonRecovery.js +31 -0
  9. package/package.json +1 -1
  10. package/src/commands/serve.ts +65 -18
  11. package/src/creator/package-lock.json +297 -3
  12. package/src/creator/package.json +1 -0
  13. package/src/creator/src/App.test.tsx +124 -1
  14. package/src/creator/src/App.tsx +52 -36
  15. package/src/creator/src/components/FileCard.tsx +63 -19
  16. package/src/creator/src/components/FileReadListener.test.tsx +128 -0
  17. package/src/creator/src/components/FileReadListener.tsx +75 -0
  18. package/src/creator/src/components/FileReviewModal.test.tsx +193 -0
  19. package/src/creator/src/components/FileReviewModal.tsx +128 -0
  20. package/src/creator/src/components/FileUploader.test.tsx +229 -0
  21. package/src/creator/src/components/FileUploader.tsx +212 -58
  22. package/src/creator/src/components/GenerationErrorCard.tsx +57 -0
  23. package/src/creator/src/components/MarkdownRenderer.tsx +4 -2
  24. package/src/creator/src/components/syllabus/SyllabusEditor.tsx +6 -9
  25. package/src/creator/src/index.css +45 -0
  26. package/src/creator/src/locales/en.json +27 -5
  27. package/src/creator/src/locales/es.json +27 -5
  28. package/src/creator/src/main.tsx +2 -0
  29. package/src/creator/src/utils/completionResult.test.ts +61 -0
  30. package/src/creator/src/utils/completionResult.ts +61 -2
  31. package/src/creator/src/utils/courseLanguage.test.ts +6 -0
  32. package/src/creator/src/utils/creationRequest.test.ts +53 -18
  33. package/src/creator/src/utils/creationRequest.ts +17 -12
  34. package/src/creator/src/utils/fileRead.ts +60 -0
  35. package/src/creator/src/utils/lib.ts +0 -5
  36. package/src/creator/src/utils/store.ts +0 -10
  37. package/src/creatorDist/assets/{index-B7s5Nmq8.css → index-Cco3XhDR.css} +96 -0
  38. package/src/creatorDist/assets/{index-CqVEKiJR.js → index-o3Cw0bsF.js} +69682 -66808
  39. package/src/creatorDist/index.html +2 -2
  40. package/src/utils/api.ts +0 -83
  41. 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-CqVEKiJR.js"></script>
14
- <link rel="stylesheet" crossorigin href="/creator/assets/index-B7s5Nmq8.css">
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
+ }