@learnpack/learnpack 5.0.290 → 5.0.291
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 +13 -3
- package/lib/creatorDist/assets/{index-7zTdUX04.js → index-wLKEQIG6.js} +2 -2
- package/lib/creatorDist/index.html +1 -1
- package/lib/utils/configBuilder.js +20 -1
- package/package.json +1 -1
- package/src/commands/serve.ts +71 -58
- package/src/creator/src/App.tsx +1 -2
- package/src/creatorDist/assets/{index-7zTdUX04.js → index-wLKEQIG6.js} +2 -2
- package/src/creatorDist/index.html +1 -1
- package/src/ui/_app/app.js +397 -397
- package/src/ui/app.tar.gz +0 -0
- package/src/utils/configBuilder.ts +100 -82
package/lib/commands/serve.js
CHANGED
@@ -121,9 +121,17 @@ const createMultiLangAsset = async (bucket, rigoToken, bcToken, courseSlug, cour
|
|
121
121
|
for (const lang of availableLangs) {
|
122
122
|
// eslint-disable-next-line no-await-in-loop
|
123
123
|
const indexReadme = await bucket.file(`courses/${courseSlug}/README${(0, creatorUtilities_1.getReadmeExtension)(lang)}`);
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
let indexReadmeString = "";
|
125
|
+
try {
|
126
|
+
// eslint-disable-next-line no-await-in-loop
|
127
|
+
const [indexReadmeContent] = await indexReadme.download();
|
128
|
+
indexReadmeString = indexReadmeContent.toString();
|
129
|
+
}
|
130
|
+
catch (error) {
|
131
|
+
console.error("Error downloading index readme", error);
|
132
|
+
// TODO: Trigger generation of the index readme
|
133
|
+
indexReadmeString = "";
|
134
|
+
}
|
127
135
|
const b64IndexReadme = buffer_1.Buffer.from(indexReadmeString).toString("base64");
|
128
136
|
// eslint-disable-next-line no-await-in-loop
|
129
137
|
const asset = await (0, publish_1.handleAssetCreation)({ token: bcToken, rigobotToken: rigoToken.trim() }, courseJson, lang, deployUrl, b64IndexReadme, all_translations);
|
@@ -660,6 +668,8 @@ class ServeCommand extends SessionCommand_1.default {
|
|
660
668
|
try {
|
661
669
|
console.log("GET CONFIG, COURSE SLUG", courseSlug);
|
662
670
|
const { config, exercises } = await (0, configBuilder_1.buildConfig)(bucket, courseSlug);
|
671
|
+
console.log("CONFIG", config);
|
672
|
+
console.log("EXERCISES", exercises);
|
663
673
|
res.set("X-Creator-Web", "true");
|
664
674
|
res.set("Access-Control-Expose-Headers", "X-Creator-Web");
|
665
675
|
await uploadFileToBucket(bucket, JSON.stringify({ config, exercises }), `courses/${courseSlug}/.learn/config.json`);
|
@@ -21654,7 +21654,7 @@ function OT() {
|
|
21654
21654
|
]);
|
21655
21655
|
if (
|
21656
21656
|
(oe && oe.toLowerCase().trim() === "true" && b(),
|
21657
|
-
I &&
|
21657
|
+
I && s({ description: I }),
|
21658
21658
|
ee && !isNaN(parseInt(ee)))
|
21659
21659
|
)
|
21660
21660
|
if (["30", "60", "120"].includes(ee)) {
|
@@ -21757,7 +21757,7 @@ function OT() {
|
|
21757
21757
|
required: !0,
|
21758
21758
|
content: E.jsx(DT, {
|
21759
21759
|
onFinish: (te) => {
|
21760
|
-
s({ purpose: te, currentStep: "
|
21760
|
+
s({ purpose: te, currentStep: "duration" });
|
21761
21761
|
},
|
21762
21762
|
}),
|
21763
21763
|
},
|
@@ -10,7 +10,7 @@
|
|
10
10
|
/>
|
11
11
|
|
12
12
|
<title>Learnpack Creator: Craft tutorials in seconds!</title>
|
13
|
-
<script type="module" crossorigin src="/creator/assets/index-
|
13
|
+
<script type="module" crossorigin src="/creator/assets/index-wLKEQIG6.js"></script>
|
14
14
|
<link rel="stylesheet" crossorigin href="/creator/assets/index-C39zeF3W.css">
|
15
15
|
</head>
|
16
16
|
<body>
|
@@ -1,6 +1,23 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.buildConfig = buildConfig;
|
4
|
+
function naturalCompare(a, b) {
|
5
|
+
// Split by dots and hyphens, compare numbers as numbers
|
6
|
+
const regex = /(\d+|\D+)/g;
|
7
|
+
const ax = a.match(regex);
|
8
|
+
const bx = b.match(regex);
|
9
|
+
for (let i = 0; i < Math.max(ax.length, bx.length); i++) {
|
10
|
+
const an = parseInt(ax[i], 10);
|
11
|
+
const bn = parseInt(bx[i], 10);
|
12
|
+
if (!isNaN(an) && !isNaN(bn)) {
|
13
|
+
if (an !== bn)
|
14
|
+
return an - bn;
|
15
|
+
}
|
16
|
+
else if (ax[i] !== bx[i])
|
17
|
+
return (ax[i] || "").localeCompare(bx[i] || "");
|
18
|
+
}
|
19
|
+
return 0;
|
20
|
+
}
|
4
21
|
/**
|
5
22
|
* Crea la configuración y lista de ejercicios para un curso.
|
6
23
|
*
|
@@ -45,7 +62,9 @@ async function buildConfig(bucket, courseSlug) {
|
|
45
62
|
});
|
46
63
|
}
|
47
64
|
}
|
48
|
-
const exercises = Object.values(map)
|
65
|
+
const exercises = Object.values(map)
|
66
|
+
.sort((a, b) => naturalCompare(a.slug, b.slug))
|
67
|
+
.map((ex, i) => (Object.assign(Object.assign({}, ex), { position: i })));
|
49
68
|
return {
|
50
69
|
config: Object.assign({}, learnJson),
|
51
70
|
exercises,
|
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.
|
4
|
+
"version": "5.0.291",
|
5
5
|
"author": "Alejandro Sanchez @alesanchezr",
|
6
6
|
"contributors": [
|
7
7
|
{
|
package/src/commands/serve.ts
CHANGED
@@ -211,9 +211,17 @@ const createMultiLangAsset = async (
|
|
211
211
|
const indexReadme = await bucket.file(
|
212
212
|
`courses/${courseSlug}/README${getReadmeExtension(lang)}`
|
213
213
|
)
|
214
|
-
|
215
|
-
|
216
|
-
|
214
|
+
let indexReadmeString = ""
|
215
|
+
try {
|
216
|
+
// eslint-disable-next-line no-await-in-loop
|
217
|
+
const [indexReadmeContent] = await indexReadme.download()
|
218
|
+
indexReadmeString = indexReadmeContent.toString()
|
219
|
+
} catch (error) {
|
220
|
+
console.error("Error downloading index readme", error)
|
221
|
+
// TODO: Trigger generation of the index readme
|
222
|
+
indexReadmeString = ""
|
223
|
+
}
|
224
|
+
|
217
225
|
const b64IndexReadme = Buffer.from(indexReadmeString).toString("base64")
|
218
226
|
|
219
227
|
// eslint-disable-next-line no-await-in-loop
|
@@ -1018,6 +1026,8 @@ export default class ServeCommand extends SessionCommand {
|
|
1018
1026
|
try {
|
1019
1027
|
console.log("GET CONFIG, COURSE SLUG", courseSlug)
|
1020
1028
|
const { config, exercises } = await buildConfig(bucket, courseSlug)
|
1029
|
+
console.log("CONFIG", config)
|
1030
|
+
console.log("EXERCISES", exercises)
|
1021
1031
|
res.set("X-Creator-Web", "true")
|
1022
1032
|
res.set("Access-Control-Expose-Headers", "X-Creator-Web")
|
1023
1033
|
|
@@ -2001,68 +2011,71 @@ export default class ServeCommand extends SessionCommand {
|
|
2001
2011
|
let filename: string
|
2002
2012
|
|
2003
2013
|
switch (format) {
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
})
|
2011
|
-
filename = `${course_slug}-scorm.zip`
|
2012
|
-
|
2013
|
-
break
|
2014
|
-
}
|
2015
|
-
|
2016
|
-
case "zip": {
|
2017
|
-
outputPath = await exportToZip({
|
2018
|
-
courseSlug: course_slug,
|
2019
|
-
format: "zip",
|
2020
|
-
bucket,
|
2021
|
-
outDir: path.join(__dirname, "../output/directory"),
|
2022
|
-
})
|
2023
|
-
filename = `${course_slug}.zip`
|
2024
|
-
|
2025
|
-
break
|
2026
|
-
}
|
2027
|
-
|
2028
|
-
case "epub": {
|
2029
|
-
console.log("EPUB export", metadata)
|
2030
|
-
// Validate required metadata for EPUB
|
2031
|
-
if (
|
2032
|
-
!metadata ||
|
2033
|
-
!metadata.creator ||
|
2034
|
-
!metadata.publisher ||
|
2035
|
-
!metadata.title ||
|
2036
|
-
!metadata.rights ||
|
2037
|
-
!metadata.lang
|
2038
|
-
) {
|
2039
|
-
console.log("Missing required metadata for EPUB export", metadata)
|
2040
|
-
return res.status(400).json({
|
2041
|
-
error: "Missing required metadata for EPUB export",
|
2042
|
-
required: ["creator", "publisher", "title", "rights", "lang"],
|
2014
|
+
case "scorm": {
|
2015
|
+
outputPath = await exportToScorm({
|
2016
|
+
courseSlug: course_slug,
|
2017
|
+
format: "scorm",
|
2018
|
+
bucket,
|
2019
|
+
outDir: path.join(__dirname, "../output/directory"),
|
2043
2020
|
})
|
2021
|
+
filename = `${course_slug}-scorm.zip`
|
2022
|
+
|
2023
|
+
break
|
2044
2024
|
}
|
2045
2025
|
|
2046
|
-
|
2047
|
-
{
|
2026
|
+
case "zip": {
|
2027
|
+
outputPath = await exportToZip({
|
2048
2028
|
courseSlug: course_slug,
|
2049
|
-
format: "
|
2029
|
+
format: "zip",
|
2050
2030
|
bucket,
|
2051
2031
|
outDir: path.join(__dirname, "../output/directory"),
|
2052
|
-
|
2053
|
-
}
|
2054
|
-
metadata
|
2055
|
-
)
|
2056
|
-
filename = `${course_slug}.epub`
|
2057
|
-
|
2058
|
-
break
|
2059
|
-
}
|
2032
|
+
})
|
2033
|
+
filename = `${course_slug}.zip`
|
2060
2034
|
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2035
|
+
break
|
2036
|
+
}
|
2037
|
+
|
2038
|
+
case "epub": {
|
2039
|
+
console.log("EPUB export", metadata)
|
2040
|
+
// Validate required metadata for EPUB
|
2041
|
+
if (
|
2042
|
+
!metadata ||
|
2043
|
+
!metadata.creator ||
|
2044
|
+
!metadata.publisher ||
|
2045
|
+
!metadata.title ||
|
2046
|
+
!metadata.rights ||
|
2047
|
+
!metadata.lang
|
2048
|
+
) {
|
2049
|
+
console.log(
|
2050
|
+
"Missing required metadata for EPUB export",
|
2051
|
+
metadata
|
2052
|
+
)
|
2053
|
+
return res.status(400).json({
|
2054
|
+
error: "Missing required metadata for EPUB export",
|
2055
|
+
required: ["creator", "publisher", "title", "rights", "lang"],
|
2056
|
+
})
|
2057
|
+
}
|
2058
|
+
|
2059
|
+
outputPath = await exportToEpub(
|
2060
|
+
{
|
2061
|
+
courseSlug: course_slug,
|
2062
|
+
format: "epub",
|
2063
|
+
bucket,
|
2064
|
+
outDir: path.join(__dirname, "../output/directory"),
|
2065
|
+
language: language,
|
2066
|
+
},
|
2067
|
+
metadata
|
2068
|
+
)
|
2069
|
+
filename = `${course_slug}.epub`
|
2070
|
+
|
2071
|
+
break
|
2072
|
+
}
|
2073
|
+
|
2074
|
+
default: {
|
2075
|
+
return res.status(400).json({
|
2076
|
+
error: "Invalid format. Supported formats: scorm, epub, zip",
|
2077
|
+
})
|
2078
|
+
}
|
2066
2079
|
}
|
2067
2080
|
|
2068
2081
|
// Send the file and clean up
|
package/src/creator/src/App.tsx
CHANGED
@@ -123,7 +123,6 @@ function App() {
|
|
123
123
|
}
|
124
124
|
|
125
125
|
if (description) {
|
126
|
-
console.log("description", description)
|
127
126
|
setFormState({
|
128
127
|
description: description,
|
129
128
|
})
|
@@ -295,7 +294,7 @@ function App() {
|
|
295
294
|
onFinish={(purpose) => {
|
296
295
|
setFormState({
|
297
296
|
purpose: purpose,
|
298
|
-
currentStep: "
|
297
|
+
currentStep: "duration",
|
299
298
|
})
|
300
299
|
}}
|
301
300
|
/>
|
@@ -21654,7 +21654,7 @@ function OT() {
|
|
21654
21654
|
]);
|
21655
21655
|
if (
|
21656
21656
|
(oe && oe.toLowerCase().trim() === "true" && b(),
|
21657
|
-
I &&
|
21657
|
+
I && s({ description: I }),
|
21658
21658
|
ee && !isNaN(parseInt(ee)))
|
21659
21659
|
)
|
21660
21660
|
if (["30", "60", "120"].includes(ee)) {
|
@@ -21757,7 +21757,7 @@ function OT() {
|
|
21757
21757
|
required: !0,
|
21758
21758
|
content: E.jsx(DT, {
|
21759
21759
|
onFinish: (te) => {
|
21760
|
-
s({ purpose: te, currentStep: "
|
21760
|
+
s({ purpose: te, currentStep: "duration" });
|
21761
21761
|
},
|
21762
21762
|
}),
|
21763
21763
|
},
|
@@ -10,7 +10,7 @@
|
|
10
10
|
/>
|
11
11
|
|
12
12
|
<title>Learnpack Creator: Craft tutorials in seconds!</title>
|
13
|
-
<script type="module" crossorigin src="/creator/assets/index-
|
13
|
+
<script type="module" crossorigin src="/creator/assets/index-wLKEQIG6.js"></script>
|
14
14
|
<link rel="stylesheet" crossorigin href="/creator/assets/index-C39zeF3W.css">
|
15
15
|
</head>
|
16
16
|
<body>
|