@learnpack/learnpack 5.0.297 → 5.0.300
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/logout.js +3 -3
- package/lib/commands/serve.js +32 -11
- package/lib/creatorDist/assets/{index-D25zkBaN.js → index-DoYRptnk.js} +11875 -11992
- package/lib/creatorDist/index.html +1 -1
- package/lib/managers/config/index.js +77 -77
- package/lib/utils/creatorUtilities.js +14 -14
- package/lib/utils/templates/isolated/exercises/01-hello-world/README.es.md +26 -26
- package/lib/utils/templates/isolated/exercises/01-hello-world/README.md +26 -26
- package/lib/utils/templates/scorm/adlcp_rootv1p2.xsd +110 -110
- package/lib/utils/templates/scorm/config/index.html +209 -209
- package/lib/utils/templates/scorm/ims_xml.xsd +1 -1
- package/lib/utils/templates/scorm/imscp_rootv1p1p2.xsd +345 -345
- package/lib/utils/templates/scorm/imsmanifest.xml +38 -38
- package/lib/utils/templates/scorm/imsmd_rootv1p2p1.xsd +573 -573
- 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/logout.ts +38 -38
- package/src/commands/serve.ts +49 -26
- package/src/commands/start.ts +333 -333
- package/src/commands/translate.ts +123 -123
- package/src/creator/README.md +54 -54
- package/src/creator/package-lock.json +6621 -6621
- package/src/creator/package.json +55 -55
- package/src/creator/src/App.tsx +569 -569
- package/src/creator/src/components/FileUploader.tsx +302 -302
- package/src/creator/src/components/Icon.tsx +18 -18
- package/src/creator/src/components/LessonItem.tsx +152 -152
- package/src/creator/src/components/Login.tsx +259 -259
- package/src/creator/src/components/syllabus/ContentIndex.tsx +323 -323
- package/src/creator/src/components/syllabus/SyllabusEditor.tsx +337 -337
- package/src/creator/src/i18n.ts +28 -28
- package/src/creator/src/locales/en.json +127 -127
- package/src/creator/src/locales/es.json +127 -127
- 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/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-D25zkBaN.js → index-DoYRptnk.js} +11875 -11992
- package/src/creatorDist/index.html +1 -1
- 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/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/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/utils/BaseCommand.ts +56 -56
- package/src/utils/audit.ts +392 -392
- package/src/utils/checkNotInstalled.ts +267 -267
- package/src/utils/convertCreds.js +34 -34
- package/src/utils/creatorUtilities.ts +504 -504
- package/src/utils/export/README.md +178 -178
- package/src/utils/incrementVersion.js +74 -74
- package/src/utils/misc.ts +58 -58
- 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/src/utils/templates/scorm/adlcp_rootv1p2.xsd +110 -110
- package/src/utils/templates/scorm/config/index.html +209 -209
- package/src/utils/templates/scorm/ims_xml.xsd +1 -1
- package/src/utils/templates/scorm/imscp_rootv1p1p2.xsd +345 -345
- package/src/utils/templates/scorm/imsmanifest.xml +38 -38
- package/src/utils/templates/scorm/imsmd_rootv1p2p1.xsd +573 -573
@@ -1,67 +1,67 @@
|
|
1
|
-
import { flags } from "@oclif/command"
|
2
|
-
import BaseCommand from "../utils/BaseCommand"
|
3
|
-
|
4
|
-
import Console from "../utils/console"
|
5
|
-
|
6
|
-
import {
|
7
|
-
extractParagraphs,
|
8
|
-
splitIntoSyllables,
|
9
|
-
extractWords,
|
10
|
-
countSentences,
|
11
|
-
fleschKincaidGrade,
|
12
|
-
} from "../utils/creatorUtilities"
|
13
|
-
|
14
|
-
const exampleMd = `# How to Install Node.js
|
15
|
-
|
16
|
-
Node.js lets you run JavaScript outside a web browser.
|
17
|
-
|
18
|
-
## Step 1: Download Node.js
|
19
|
-
|
20
|
-
Get the Node.js installer from the [official site](https://nodejs.org/en/download/).
|
21
|
-
|
22
|
-
## Step 2: Install Node.js
|
23
|
-
|
24
|
-
Open the installer and follow the steps to finish.
|
25
|
-
|
26
|
-
## Step 3: Verify the Installation
|
27
|
-
|
28
|
-
Open a terminal and type:
|
29
|
-
|
30
|
-
\`\`\`bash
|
31
|
-
node -v
|
32
|
-
\`\`\`
|
33
|
-
`
|
34
|
-
|
35
|
-
class BreakTokenCommand extends BaseCommand {
|
36
|
-
static description = "Break the token"
|
37
|
-
|
38
|
-
static flags = {
|
39
|
-
...BaseCommand.flags,
|
40
|
-
grading: flags.help({ char: "h" }),
|
41
|
-
}
|
42
|
-
|
43
|
-
async run() {
|
44
|
-
const { flags } = this.parse(BreakTokenCommand)
|
45
|
-
|
46
|
-
// await SessionManager.breakToken()
|
47
|
-
const paragraphs = extractParagraphs(exampleMd)
|
48
|
-
for (const paragraph of paragraphs) {
|
49
|
-
const syllables = splitIntoSyllables(paragraph)
|
50
|
-
const words = extractWords(paragraph)
|
51
|
-
const sentences = countSentences(paragraph)
|
52
|
-
const fkgl = fleschKincaidGrade(paragraph)
|
53
|
-
Console.info(paragraph)
|
54
|
-
Console.info(`Number of syllables: ${syllables.length}`)
|
55
|
-
Console.info(syllables)
|
56
|
-
Console.info(`Number of words: ${words.length}`)
|
57
|
-
Console.info(words)
|
58
|
-
Console.info(`Number of sentences: ${sentences}`)
|
59
|
-
Console.info(`FKGL: ${fkgl}`)
|
60
|
-
Console.info("---")
|
61
|
-
}
|
62
|
-
|
63
|
-
process.exit(0)
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
export default BreakTokenCommand
|
1
|
+
import { flags } from "@oclif/command"
|
2
|
+
import BaseCommand from "../utils/BaseCommand"
|
3
|
+
|
4
|
+
import Console from "../utils/console"
|
5
|
+
|
6
|
+
import {
|
7
|
+
extractParagraphs,
|
8
|
+
splitIntoSyllables,
|
9
|
+
extractWords,
|
10
|
+
countSentences,
|
11
|
+
fleschKincaidGrade,
|
12
|
+
} from "../utils/creatorUtilities"
|
13
|
+
|
14
|
+
const exampleMd = `# How to Install Node.js
|
15
|
+
|
16
|
+
Node.js lets you run JavaScript outside a web browser.
|
17
|
+
|
18
|
+
## Step 1: Download Node.js
|
19
|
+
|
20
|
+
Get the Node.js installer from the [official site](https://nodejs.org/en/download/).
|
21
|
+
|
22
|
+
## Step 2: Install Node.js
|
23
|
+
|
24
|
+
Open the installer and follow the steps to finish.
|
25
|
+
|
26
|
+
## Step 3: Verify the Installation
|
27
|
+
|
28
|
+
Open a terminal and type:
|
29
|
+
|
30
|
+
\`\`\`bash
|
31
|
+
node -v
|
32
|
+
\`\`\`
|
33
|
+
`
|
34
|
+
|
35
|
+
class BreakTokenCommand extends BaseCommand {
|
36
|
+
static description = "Break the token"
|
37
|
+
|
38
|
+
static flags = {
|
39
|
+
...BaseCommand.flags,
|
40
|
+
grading: flags.help({ char: "h" }),
|
41
|
+
}
|
42
|
+
|
43
|
+
async run() {
|
44
|
+
const { flags } = this.parse(BreakTokenCommand)
|
45
|
+
|
46
|
+
// await SessionManager.breakToken()
|
47
|
+
const paragraphs = extractParagraphs(exampleMd)
|
48
|
+
for (const paragraph of paragraphs) {
|
49
|
+
const syllables = splitIntoSyllables(paragraph)
|
50
|
+
const words = extractWords(paragraph)
|
51
|
+
const sentences = countSentences(paragraph)
|
52
|
+
const fkgl = fleschKincaidGrade(paragraph)
|
53
|
+
Console.info(paragraph)
|
54
|
+
Console.info(`Number of syllables: ${syllables.length}`)
|
55
|
+
Console.info(syllables)
|
56
|
+
Console.info(`Number of words: ${words.length}`)
|
57
|
+
Console.info(words)
|
58
|
+
Console.info(`Number of sentences: ${sentences}`)
|
59
|
+
Console.info(`FKGL: ${fkgl}`)
|
60
|
+
Console.info("---")
|
61
|
+
}
|
62
|
+
|
63
|
+
process.exit(0)
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
export default BreakTokenCommand
|
package/src/commands/clean.ts
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
// import {flags} from '@oclif/command'
|
2
|
-
import Console from "../utils/console"
|
3
|
-
import SessionCommand from "../utils/SessionCommand"
|
4
|
-
|
5
|
-
class CleanCommand extends SessionCommand {
|
6
|
-
static description = `Clean the configuration object
|
7
|
-
...
|
8
|
-
Extra documentation goes here
|
9
|
-
`
|
10
|
-
|
11
|
-
static flags: any = {
|
12
|
-
// name: flags.string({char: 'n', description: 'name to print'}),
|
13
|
-
}
|
14
|
-
|
15
|
-
async init() {
|
16
|
-
const { flags } = this.parse(CleanCommand)
|
17
|
-
await this.initSession(flags)
|
18
|
-
}
|
19
|
-
|
20
|
-
async run() {
|
21
|
-
const { flags } = this.parse(CleanCommand)
|
22
|
-
|
23
|
-
this.configManager?.buildIndex()
|
24
|
-
await this.configManager?.clean()
|
25
|
-
|
26
|
-
Console.success("Package cleaned successfully, ready to publish")
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
export default CleanCommand
|
1
|
+
// import {flags} from '@oclif/command'
|
2
|
+
import Console from "../utils/console"
|
3
|
+
import SessionCommand from "../utils/SessionCommand"
|
4
|
+
|
5
|
+
class CleanCommand extends SessionCommand {
|
6
|
+
static description = `Clean the configuration object
|
7
|
+
...
|
8
|
+
Extra documentation goes here
|
9
|
+
`
|
10
|
+
|
11
|
+
static flags: any = {
|
12
|
+
// name: flags.string({char: 'n', description: 'name to print'}),
|
13
|
+
}
|
14
|
+
|
15
|
+
async init() {
|
16
|
+
const { flags } = this.parse(CleanCommand)
|
17
|
+
await this.initSession(flags)
|
18
|
+
}
|
19
|
+
|
20
|
+
async run() {
|
21
|
+
const { flags } = this.parse(CleanCommand)
|
22
|
+
|
23
|
+
this.configManager?.buildIndex()
|
24
|
+
await this.configManager?.clean()
|
25
|
+
|
26
|
+
Console.success("Package cleaned successfully, ready to publish")
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
export default CleanCommand
|
package/src/commands/logout.ts
CHANGED
@@ -1,38 +1,38 @@
|
|
1
|
-
import SessionCommand from "../utils/SessionCommand"
|
2
|
-
import SessionManager from "../managers/session"
|
3
|
-
import Console from "../utils/console"
|
4
|
-
|
5
|
-
class LogoutCommand extends SessionCommand {
|
6
|
-
static description = `Describe the command here
|
7
|
-
...
|
8
|
-
Extra documentation goes here
|
9
|
-
`
|
10
|
-
|
11
|
-
static flags: any = {
|
12
|
-
// name: flags.string({char: 'n', description: 'name to print'}),
|
13
|
-
}
|
14
|
-
|
15
|
-
static args = [
|
16
|
-
{
|
17
|
-
name: "package", // name of arg to show in help and reference with args[name]
|
18
|
-
required: false, // make the arg required with `required: true`
|
19
|
-
description:
|
20
|
-
"The unique string that identifies this package on learnpack", // help description
|
21
|
-
hidden: false, // hide this arg from help
|
22
|
-
},
|
23
|
-
]
|
24
|
-
|
25
|
-
async init() {
|
26
|
-
const { flags } = this.parse(LogoutCommand)
|
27
|
-
// await this.initSession(flags)
|
28
|
-
Console.debug("Logout command")
|
29
|
-
}
|
30
|
-
|
31
|
-
async run() {
|
32
|
-
// const {flags, args} = this.parse(LogoutCommand)
|
33
|
-
|
34
|
-
SessionManager.destroy()
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
export default LogoutCommand
|
1
|
+
import SessionCommand from "../utils/SessionCommand"
|
2
|
+
import SessionManager from "../managers/session"
|
3
|
+
import Console from "../utils/console"
|
4
|
+
|
5
|
+
class LogoutCommand extends SessionCommand {
|
6
|
+
static description = `Describe the command here
|
7
|
+
...
|
8
|
+
Extra documentation goes here
|
9
|
+
`
|
10
|
+
|
11
|
+
static flags: any = {
|
12
|
+
// name: flags.string({char: 'n', description: 'name to print'}),
|
13
|
+
}
|
14
|
+
|
15
|
+
static args = [
|
16
|
+
{
|
17
|
+
name: "package", // name of arg to show in help and reference with args[name]
|
18
|
+
required: false, // make the arg required with `required: true`
|
19
|
+
description:
|
20
|
+
"The unique string that identifies this package on learnpack", // help description
|
21
|
+
hidden: false, // hide this arg from help
|
22
|
+
},
|
23
|
+
]
|
24
|
+
|
25
|
+
async init() {
|
26
|
+
const { flags } = this.parse(LogoutCommand)
|
27
|
+
// await this.initSession(flags)
|
28
|
+
Console.debug("Logout command")
|
29
|
+
}
|
30
|
+
|
31
|
+
async run() {
|
32
|
+
// const {flags, args} = this.parse(LogoutCommand)
|
33
|
+
|
34
|
+
SessionManager.destroy()
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
export default LogoutCommand
|
package/src/commands/serve.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require("newrelic")
|
2
|
+
|
2
3
|
import { flags } from "@oclif/command"
|
3
4
|
|
4
5
|
import { Buffer } from "buffer"
|
@@ -51,10 +52,7 @@ import {
|
|
51
52
|
import axios from "axios"
|
52
53
|
import * as FormData from "form-data"
|
53
54
|
import api, { RIGOBOT_HOST, RIGOBOT_REALTIME_HOST } from "../utils/api"
|
54
|
-
import {
|
55
|
-
createUploadMiddleware,
|
56
|
-
minutesToISO8601Duration,
|
57
|
-
} from "../utils/misc"
|
55
|
+
import { createUploadMiddleware, minutesToISO8601Duration } from "../utils/misc"
|
58
56
|
import { buildConfig, ConfigResponse } from "../utils/configBuilder"
|
59
57
|
import { checkReadability, slugify } from "../utils/creatorUtilities"
|
60
58
|
import { checkAndFixSidebarPure } from "../utils/sidebarGenerator"
|
@@ -1029,9 +1027,13 @@ export default class ServeCommand extends SessionCommand {
|
|
1029
1027
|
if (files && Array.isArray(files)) {
|
1030
1028
|
console.log("✅ Processing files for coding challenge...")
|
1031
1029
|
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1030
|
+
const configFile = await bucket.file(
|
1031
|
+
`courses/${courseSlug}/.learn/config.json`
|
1032
|
+
)
|
1033
|
+
const [configContent] = await configFile.download()
|
1034
|
+
const { exercises } = JSON.parse(configContent.toString())
|
1035
|
+
|
1036
|
+
const exercise = exercises[parseInt(exercisePosition)]
|
1035
1037
|
|
1036
1038
|
if (!exercise) {
|
1037
1039
|
console.error(
|
@@ -1040,8 +1042,7 @@ export default class ServeCommand extends SessionCommand {
|
|
1040
1042
|
return res.status(404).json({ error: "Exercise not found" })
|
1041
1043
|
}
|
1042
1044
|
|
1043
|
-
const
|
1044
|
-
const exerciseDir = `courses/${courseSlug}/exercises/${exSlug}`
|
1045
|
+
const exerciseDir = `courses/${courseSlug}/exercises/${exercise.slug}`
|
1045
1046
|
|
1046
1047
|
for (const fileStr of files) {
|
1047
1048
|
try {
|
@@ -1070,9 +1071,7 @@ export default class ServeCommand extends SessionCommand {
|
|
1070
1071
|
fileObj.solution,
|
1071
1072
|
solutionFilePath
|
1072
1073
|
)
|
1073
|
-
console.log(
|
1074
|
-
`✅ Saved solution file: ${solutionFilePath}`
|
1075
|
-
)
|
1074
|
+
console.log(`✅ Saved solution file: ${solutionFilePath}`)
|
1076
1075
|
} else {
|
1077
1076
|
// If no extension, just add .solution.hide
|
1078
1077
|
const solutionFileName = `${fileObj.name}.solution.hide`
|
@@ -1083,9 +1082,7 @@ export default class ServeCommand extends SessionCommand {
|
|
1083
1082
|
fileObj.solution,
|
1084
1083
|
solutionFilePath
|
1085
1084
|
)
|
1086
|
-
console.log(
|
1087
|
-
`✅ Saved solution file: ${solutionFilePath}`
|
1088
|
-
)
|
1085
|
+
console.log(`✅ Saved solution file: ${solutionFilePath}`)
|
1089
1086
|
}
|
1090
1087
|
}
|
1091
1088
|
} catch (parseError) {
|
@@ -2753,6 +2750,39 @@ export default class ServeCommand extends SessionCommand {
|
|
2753
2750
|
}
|
2754
2751
|
)
|
2755
2752
|
|
2753
|
+
app.delete(
|
2754
|
+
"/courses/:courseSlug/exercises/:exerciseSlug/file/:filename",
|
2755
|
+
async (req, res) => {
|
2756
|
+
console.log(
|
2757
|
+
"DELETE /courses/:courseSlug/exercises/:exerciseSlug/file/:filename",
|
2758
|
+
req.params
|
2759
|
+
)
|
2760
|
+
const { courseSlug, exerciseSlug, filename } = req.params
|
2761
|
+
|
2762
|
+
try {
|
2763
|
+
const filePath = `courses/${courseSlug}/exercises/${exerciseSlug}/${filename}`
|
2764
|
+
const file = bucket.file(filePath)
|
2765
|
+
const [exists] = await file.exists()
|
2766
|
+
|
2767
|
+
if (!exists) {
|
2768
|
+
return res.status(404).json({ error: "File not found" })
|
2769
|
+
}
|
2770
|
+
|
2771
|
+
await file.delete()
|
2772
|
+
console.log(`✅ Deleted file: ${filePath}`)
|
2773
|
+
return res.json({
|
2774
|
+
success: true,
|
2775
|
+
message: "File deleted successfully",
|
2776
|
+
})
|
2777
|
+
} catch (error) {
|
2778
|
+
console.error("❌ Error deleting file:", error)
|
2779
|
+
return res.status(500).json({
|
2780
|
+
error: (error as Error).message || "Unable to delete file",
|
2781
|
+
})
|
2782
|
+
}
|
2783
|
+
}
|
2784
|
+
)
|
2785
|
+
|
2756
2786
|
const YT_REGEX = /(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]{11})/
|
2757
2787
|
|
2758
2788
|
app.get("/actions/fetch/:link", async (req, res) => {
|
@@ -2795,9 +2825,7 @@ export default class ServeCommand extends SessionCommand {
|
|
2795
2825
|
})
|
2796
2826
|
} catch (error: any) {
|
2797
2827
|
console.error("❌ /actions/fetch error:", error.message || error)
|
2798
|
-
res
|
2799
|
-
.status(500)
|
2800
|
-
.json({ error: error.message || "Failed to fetch link" })
|
2828
|
+
res.status(500).json({ error: error.message || "Failed to fetch link" })
|
2801
2829
|
}
|
2802
2830
|
})
|
2803
2831
|
app.delete("/packages/:slug", async (req, res) => {
|
@@ -2977,10 +3005,7 @@ export default class ServeCommand extends SessionCommand {
|
|
2977
3005
|
!metadata.rights ||
|
2978
3006
|
!metadata.lang
|
2979
3007
|
) {
|
2980
|
-
console.log(
|
2981
|
-
"Missing required metadata for EPUB export",
|
2982
|
-
metadata
|
2983
|
-
)
|
3008
|
+
console.log("Missing required metadata for EPUB export", metadata)
|
2984
3009
|
return res.status(400).json({
|
2985
3010
|
error: "Missing required metadata for EPUB export",
|
2986
3011
|
required: ["creator", "publisher", "title", "rights", "lang"],
|
@@ -3025,9 +3050,7 @@ export default class ServeCommand extends SessionCommand {
|
|
3025
3050
|
})
|
3026
3051
|
} catch (error: any) {
|
3027
3052
|
console.error("Export error:", error)
|
3028
|
-
res
|
3029
|
-
.status(500)
|
3030
|
-
.json({ error: "Export failed", details: error.message })
|
3053
|
+
res.status(500).json({ error: "Export failed", details: error.message })
|
3031
3054
|
}
|
3032
3055
|
})
|
3033
3056
|
|