@learnpack/learnpack 5.0.148 → 5.0.152

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.
@@ -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-ETBXfIew.js"></script>
14
- <link rel="stylesheet" crossorigin href="/creator/assets/index-DUPYM87B.css">
13
+ <script type="module" crossorigin src="/creator/assets/index-l0lFNoeD.js"></script>
14
+ <link rel="stylesheet" crossorigin href="/creator/assets/index-CztA582_.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -1 +1 @@
1
- {"version":"5.0.148","commands":{"audit":{"id":"audit","description":"learnpack audit is the command in charge of creating an auditory of the repository\n...\nlearnpack audit checks for the following information in a repository:\n 1. The configuration object has slug, repository and description. (Error)\n 2. The command learnpack clean has been run. (Error)\n 3. If a markdown or test file doesn't have any content. (Error)\n 4. The links are accessing to valid servers. (Error)\n 5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)\n 6. The external images are working (If they are pointing to a valid server). (Error)\n 7. The exercises directory names are valid. (Error)\n 8. If an exercise doesn't have a README file. (Error)\n 9. The exercises array (Of the config file) has content. (Error)\n 10. The exercses have the same translations. (Warning)\n 11. The .gitignore file exists. (Warning)\n 12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false}},"args":[]},"breakToken":{"id":"breakToken","description":"Break the token","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"clean":{"id":"clean","description":"Clean the configuration object\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"download":{"id":"download","description":"Describe the command here\n...\nExtra documentation goes here\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"init":{"id":"init","description":"Create a new learning package: Book, Tutorial or Exercise","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"login":{"id":"login","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"logout":{"id":"logout","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"publish":{"id":"publish","description":"Builds the project by copying necessary files and directories into a zip file","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"serve":{"id":"serve","description":"Runs a small server to build tutorials","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"disableGrading":{"name":"disableGrading","type":"boolean","char":"D","description":"disble grading functionality","allowNo":false},"watch":{"name":"watch","type":"boolean","char":"w","description":"Watch for file changes","allowNo":false},"editor":{"name":"editor","type":"option","char":"e","description":"[preview, extension]","options":["extension","preview"]},"version":{"name":"version","type":"option","char":"v","description":"E.g: 1.0.1"},"grading":{"name":"grading","type":"option","char":"g","description":"[isolated, incremental]","options":["isolated","incremental"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"test":{"id":"test","description":"Test exercises","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false}},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]},"translate":{"id":"translate","description":"List all the lessons, the user is able of select many of them to translate to the given languages","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false}},"args":[]}}}
1
+ {"version":"5.0.152","commands":{"audit":{"id":"audit","description":"learnpack audit is the command in charge of creating an auditory of the repository\n...\nlearnpack audit checks for the following information in a repository:\n 1. The configuration object has slug, repository and description. (Error)\n 2. The command learnpack clean has been run. (Error)\n 3. If a markdown or test file doesn't have any content. (Error)\n 4. The links are accessing to valid servers. (Error)\n 5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)\n 6. The external images are working (If they are pointing to a valid server). (Error)\n 7. The exercises directory names are valid. (Error)\n 8. If an exercise doesn't have a README file. (Error)\n 9. The exercises array (Of the config file) has content. (Error)\n 10. The exercses have the same translations. (Warning)\n 11. The .gitignore file exists. (Warning)\n 12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false}},"args":[]},"breakToken":{"id":"breakToken","description":"Break the token","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"clean":{"id":"clean","description":"Clean the configuration object\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"download":{"id":"download","description":"Describe the command here\n...\nExtra documentation goes here\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"init":{"id":"init","description":"Create a new learning package: Book, Tutorial or Exercise","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"login":{"id":"login","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"logout":{"id":"logout","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"publish":{"id":"publish","description":"Builds the project by copying necessary files and directories into a zip file","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"serve":{"id":"serve","description":"Runs a small server to build tutorials","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"disableGrading":{"name":"disableGrading","type":"boolean","char":"D","description":"disble grading functionality","allowNo":false},"watch":{"name":"watch","type":"boolean","char":"w","description":"Watch for file changes","allowNo":false},"editor":{"name":"editor","type":"option","char":"e","description":"[preview, extension]","options":["extension","preview"]},"version":{"name":"version","type":"option","char":"v","description":"E.g: 1.0.1"},"grading":{"name":"grading","type":"option","char":"g","description":"[isolated, incremental]","options":["isolated","incremental"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"test":{"id":"test","description":"Test exercises","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false}},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]},"translate":{"id":"translate","description":"List all the lessons, the user is able of select many of them to translate to the given languages","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false}},"args":[]}}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@learnpack/learnpack",
3
3
  "description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
4
- "version": "5.0.148",
4
+ "version": "5.0.152",
5
5
  "author": "Alejandro Sanchez @alesanchezr",
6
6
  "contributors": [
7
7
  {
@@ -45,6 +45,11 @@ dotenv.config()
45
45
  export const createLearnJson = (courseInfo: FormState) => {
46
46
  console.log("courseInfo to create learn json", courseInfo)
47
47
 
48
+ const expectedPreviewUrl = `https://${slugify(
49
+ courseInfo.title as string
50
+ )}.learn-pack.com/preview.png`
51
+ console.log("Preview url in generated learn.json", expectedPreviewUrl)
52
+
48
53
  const learnJson = {
49
54
  slug: slugify(courseInfo.title as string),
50
55
  title: {
@@ -59,7 +64,7 @@ export const createLearnJson = (courseInfo: FormState) => {
59
64
  telemetry: {
60
65
  batch: "https://breathecode.herokuapp.com/v1/assignment/me/telemetry",
61
66
  },
62
- preview: "preview.png",
67
+ preview: expectedPreviewUrl,
63
68
  }
64
69
  return learnJson
65
70
  }
@@ -292,7 +297,7 @@ const fixPreviewUrl = (slug: string, previewUrl: string) => {
292
297
  }
293
298
 
294
299
  const expectedUrl = `https://${slug}.learn-pack.com/preview.png`
295
- console.log("EXPECTED URL", expectedUrl)
300
+ console.log("Preview url fixed!", expectedUrl)
296
301
  return expectedUrl
297
302
  }
298
303
 
@@ -473,8 +478,13 @@ export default class ServeCommand extends SessionCommand {
473
478
 
474
479
  app.get("/config", async (req, res) => {
475
480
  const courseSlug = req.query.slug as string
481
+ // GEt the x-rigo-token
482
+ // const rigoToken = req.header("x-rigo-token")
483
+
476
484
  if (!courseSlug) {
477
- return res.status(400).json({ error: "Course slug required" })
485
+ return res
486
+ .status(400)
487
+ .json({ error: "Course slug and rigo token required" })
478
488
  }
479
489
 
480
490
  try {
@@ -878,15 +888,14 @@ export default class ServeCommand extends SessionCommand {
878
888
  const { slug } = req.params
879
889
  const rigoToken = req.header("x-rigo-token")
880
890
  const bcToken = req.header("x-breathecode-token")
881
- const { academyId, categoryId } = req.body
891
+ // const { academyId, categoryId } = req.body
882
892
 
883
- if (!rigoToken || !bcToken || !academyId || !categoryId) {
893
+ if (!rigoToken || !bcToken) {
884
894
  return res
885
895
  .status(400)
886
896
  .json({ error: "Faltan tokens o academy/category" })
887
897
  }
888
898
 
889
- // 2) Leer y construir config.json vía buildConfig
890
899
  const { config, exercises }: ConfigResponse = await buildConfig(
891
900
  bucket,
892
901
  slug
@@ -6,13 +6,14 @@ import { useNavigate } from "react-router"
6
6
  import { useShallow } from "zustand/react/shallow"
7
7
  import useStore from "./utils/store"
8
8
 
9
- import { interactiveCreation } from "./utils/rigo"
9
+ import { interactiveCreation, isHuman } from "./utils/rigo"
10
10
  import { checkParams, loginWithToken, parseLesson } from "./utils/lib"
11
11
 
12
12
  import { Uploader } from "./components/Uploader"
13
13
  import toast from "react-hot-toast"
14
14
  import { ParamsChecker } from "./components/ParamsChecker"
15
15
  import { RIGO_FLOAT_GIT } from "./utils/constants"
16
+ import TurnstileChallenge from "./components/TurnstileChallenge"
16
17
  // import TurnstileChallenge from "./components/TurnstileChallenge"
17
18
 
18
19
  function App() {
@@ -227,18 +228,10 @@ function App() {
227
228
  <SelectableCard
228
229
  title="🛠️ No, help me create one"
229
230
  onClick={() => {
230
- if (!formState.contentIndex && !formState.description) {
231
- toast.error(
232
- "Please provide at least a description for your course!"
233
- )
234
- setFormState({
235
- currentStep: "description",
236
- })
237
- return
238
- }
239
231
  setFormState({
240
232
  hasContentIndex: false,
241
- isCompleted: true,
233
+ currentStep: "verifyHuman",
234
+ // isCompleted: true,
242
235
  })
243
236
  }}
244
237
  selected={false}
@@ -258,12 +251,35 @@ function App() {
258
251
  onFinish={(text) => {
259
252
  setFormState({
260
253
  contentIndex: text,
261
- isCompleted: true,
254
+ currentStep: "verifyHuman",
255
+ // isCompleted: true,
262
256
  })
263
257
  }}
264
258
  />
265
259
  ),
266
260
  },
261
+ {
262
+ title: "Please verify you are a human",
263
+ slug: "verifyHuman",
264
+ isCompleted: false,
265
+ content: (
266
+ <TurnstileChallenge
267
+ siteKey={"0x4AAAAAABeKMBYYinMU4Ib0"}
268
+ onSuccess={async (token) => {
269
+ const _isHuman = await isHuman(token)
270
+ if (_isHuman) {
271
+ toast.success("You are a human! 👌🏻")
272
+ setFormState({ isCompleted: true })
273
+ } else {
274
+ toast.error("You are not a human! 🤖")
275
+ setFormState({
276
+ currentStep: "hasContentIndex",
277
+ })
278
+ }
279
+ }}
280
+ />
281
+ ),
282
+ },
267
283
  ]
268
284
 
269
285
  return steps.filter(
@@ -61,18 +61,11 @@ const TurnstileChallenge = ({
61
61
  return () => clearInterval(interval)
62
62
  }, [siteKey, autoStart, onSuccess, onError])
63
63
 
64
- // const reset = () => {
65
- // if (widgetId.current && window.turnstile) {
66
- // window.turnstile.reset(widgetId.current)
67
- // }
68
- // }
69
64
 
70
65
  return (
71
- // <div className="flex flex-col gap-4 bg-white w-full fixed bottom-0 left-0 right-0 p-4 h-full items-center justify-center">
66
+
72
67
  <div className="">
73
- {/* <h3 className="text-center text-2xl font-bold">
74
- We must verify you are human
75
- </h3> */}
68
+
76
69
  <div id={containerId} data-refresh-timeout="auto" />
77
70
  {!ready && <p className="">...</p>}
78
71
  {/* <button onClick={reset}>RESET</button> */}
@@ -1,18 +1,5 @@
1
- import { Lesson } from "../components/LessonItem"
2
1
  import { eventBus } from "./eventBus"
3
- import {
4
- generateImage,
5
- getFilenameFromUrl,
6
- uploadFileToBucket,
7
- uploadImageToBucket,
8
- } from "./lib"
9
- import {
10
- makeReadmeReadable,
11
- readmeCreator,
12
- checkReadability,
13
- createCodeFile,
14
- } from "./rigo"
15
- import { FormState } from "./store"
2
+ import { generateImage, getFilenameFromUrl, uploadImageToBucket } from "./lib"
16
3
 
17
4
  export const slugify = (text: string) => {
18
5
  return text
@@ -21,133 +8,6 @@ export const slugify = (text: string) => {
21
8
  .replace(/[^\w.-]+/g, "")
22
9
  }
23
10
 
24
- export const createLearnJson = (courseInfo: FormState) => {
25
- console.log("courseInfo to create learn json", courseInfo)
26
-
27
- const learnJson = {
28
- slug: slugify(courseInfo.title as string),
29
- title: {
30
- us: courseInfo.title,
31
- },
32
- technologies: courseInfo.technologies || [],
33
- difficulty: "beginner",
34
- description: {
35
- us: courseInfo.description,
36
- },
37
- grading: "isolated",
38
- telemetry: {
39
- batch: "https://breathecode.herokuapp.com/v1/assignment/me/telemetry",
40
- },
41
- preview: "preview.png",
42
- }
43
- return learnJson
44
- }
45
-
46
- const PARAMS = {
47
- expected_grade_level: "6",
48
- max_fkgl: 8,
49
- max_words: 200,
50
- max_rewrite_attempts: 3,
51
- max_title_length: 50,
52
- }
53
- export async function processExercise(
54
- rigoToken: string,
55
- steps: Lesson[],
56
- packageContext: string,
57
- exercise: Lesson,
58
- exercisesDir: string
59
- ): Promise<string> {
60
- // const tid = toast.loading("Generating lesson...")
61
- setTimeout(() => {
62
- eventBus.emit("course-generation", {
63
- message: `✍🏻 Generating lesson ${exercise.id} - ${exercise.title}...`,
64
- })
65
- }, 500)
66
- const readme = await readmeCreator(rigoToken, {
67
- title: `${exercise.id} - ${exercise.title}`,
68
- output_lang: "en",
69
- list_of_exercises: JSON.stringify(steps),
70
- tutorial_description: packageContext,
71
- lesson_description: exercise.description,
72
- kind: exercise.type.toLowerCase(),
73
- })
74
-
75
- const duration = exercise.duration
76
- let attempts = 0
77
- let readability = checkReadability(readme.parsed.content, 200, duration || 1)
78
-
79
- while (
80
- readability.fkglResult.fkgl > PARAMS.max_fkgl &&
81
- attempts < PARAMS.max_rewrite_attempts
82
- ) {
83
- setTimeout(() => {
84
- eventBus.emit("course-generation", {
85
- message: `🔄 The lesson ${exercise.id} - ${
86
- exercise.title
87
- } has a readability score of ${
88
- readability.fkglResult.fkgl
89
- }. Rewriting it... (Attempt ${attempts + 1})`,
90
- })
91
- }, 500)
92
- // eslint-disable-next-line
93
- const reducedReadme = await makeReadmeReadable(rigoToken, {
94
- lesson: readability.body,
95
- number_of_words: readability.minutes.toString(),
96
- expected_number_words: PARAMS.max_words.toString(),
97
- fkgl_results: JSON.stringify(readability.fkglResult),
98
- expected_grade_level: PARAMS.expected_grade_level,
99
- })
100
-
101
- if (!reducedReadme) break
102
-
103
- readability = checkReadability(
104
- reducedReadme.parsed.content,
105
- PARAMS.max_words,
106
- duration || 1
107
- )
108
-
109
- attempts++
110
- }
111
-
112
- setTimeout(() => {
113
- eventBus.emit("course-generation", {
114
- message: `✅ After ${attempts} attempts, the lesson ${
115
- exercise.title
116
- } has a readability score of ${
117
- readability.fkglResult.fkgl
118
- } using FKGL. And it has ${readability.minutes.toFixed(
119
- 2
120
- )} minutes of reading time.`,
121
- })
122
- }, 500)
123
-
124
- const readmeFilename = "README.md"
125
-
126
- const targetDir = `${exercisesDir}/${slugify(
127
- exercise.id + "-" + exercise.title
128
- )}`
129
- await uploadFileToBucket(
130
- readability.newMarkdown,
131
- `${targetDir}/${readmeFilename}`
132
- )
133
-
134
- if (exercise.type.toLowerCase() === "code") {
135
- eventBus.emit("course-generation", {
136
- message: `🔍 Creating code file for ${exercise.title}`,
137
- })
138
- const codeFile = await createCodeFile(rigoToken, {
139
- readme: readability.newMarkdown,
140
- tutorial_info: packageContext,
141
- })
142
- await uploadFileToBucket(
143
- codeFile.parsed.content,
144
- `${targetDir}/index.${codeFile.parsed.extension.replace(".", "")}`
145
- )
146
- }
147
-
148
- return readability.newMarkdown
149
- }
150
-
151
11
  export const randomUUID = () => {
152
12
  return Math.random().toString(36).substring(2, 15)
153
13
  }