@learnpack/learnpack 5.0.50 → 5.0.52
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 +12 -12
- package/lib/commands/audit.js +17 -0
- package/lib/commands/clean.js +6 -5
- package/lib/commands/init.js +30 -14
- package/lib/commands/publish.js +38 -7
- package/lib/managers/config/index.js +16 -1
- package/lib/utils/api.d.ts +20 -0
- package/lib/utils/api.js +95 -4
- package/lib/utils/creatorUtilities.js +1 -1
- package/lib/utils/misc.d.ts +1 -0
- package/lib/utils/misc.js +23 -0
- package/lib/utils/rigoActions.d.ts +5 -0
- package/lib/utils/rigoActions.js +13 -7
- package/lib/utils/sidebarGenerator.d.ts +2 -0
- package/lib/utils/sidebarGenerator.js +49 -1
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/src/commands/audit.ts +17 -0
- package/src/commands/clean.ts +30 -29
- package/src/commands/init.ts +43 -22
- package/src/commands/publish.ts +56 -6
- package/src/managers/config/index.ts +26 -7
- package/src/models/config-manager.ts +1 -0
- package/src/utils/api.ts +120 -3
- package/src/utils/creatorUtilities.ts +1 -1
- package/src/utils/misc.ts +52 -23
- package/src/utils/rigoActions.ts +26 -6
- package/src/utils/sidebarGenerator.ts +75 -0
package/src/utils/misc.ts
CHANGED
@@ -1,23 +1,52 @@
|
|
1
|
-
export const prioritizeHTMLFile = (entryFiles: string[]) => {
|
2
|
-
let files = []
|
3
|
-
|
4
|
-
// Find the html file and put it as latest in the files array
|
5
|
-
// in order to keep the html file opened in vscode plugin
|
6
|
-
const index = entryFiles.findIndex(file => {
|
7
|
-
return /.*\.html$/.test(file)
|
8
|
-
})
|
9
|
-
|
10
|
-
if (index !== -1) {
|
11
|
-
for (const [i, entryFile] of entryFiles.entries()) {
|
12
|
-
if (i !== index) {
|
13
|
-
files.push(entryFile)
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
files.push(entryFiles[index])
|
18
|
-
} else {
|
19
|
-
files = entryFiles
|
20
|
-
}
|
21
|
-
|
22
|
-
return files
|
23
|
-
}
|
1
|
+
export const prioritizeHTMLFile = (entryFiles: string[]) => {
|
2
|
+
let files = []
|
3
|
+
|
4
|
+
// Find the html file and put it as latest in the files array
|
5
|
+
// in order to keep the html file opened in vscode plugin
|
6
|
+
const index = entryFiles.findIndex(file => {
|
7
|
+
return /.*\.html$/.test(file)
|
8
|
+
})
|
9
|
+
|
10
|
+
if (index !== -1) {
|
11
|
+
for (const [i, entryFile] of entryFiles.entries()) {
|
12
|
+
if (i !== index) {
|
13
|
+
files.push(entryFile)
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
files.push(entryFiles[index])
|
18
|
+
} else {
|
19
|
+
files = entryFiles
|
20
|
+
}
|
21
|
+
|
22
|
+
return files
|
23
|
+
}
|
24
|
+
|
25
|
+
export function minutesToISO8601Duration(minutes: number): string {
|
26
|
+
if (minutes <= 0)
|
27
|
+
return "PT0M"
|
28
|
+
|
29
|
+
const weeks = Math.floor(minutes / (60 * 24 * 7))
|
30
|
+
minutes %= 60 * 24 * 7
|
31
|
+
|
32
|
+
const days = Math.floor(minutes / (60 * 24))
|
33
|
+
minutes %= 60 * 24
|
34
|
+
|
35
|
+
const hours = Math.floor(minutes / 60)
|
36
|
+
const mins = minutes % 60
|
37
|
+
|
38
|
+
let duration = "P"
|
39
|
+
if (weeks)
|
40
|
+
duration += `${weeks}W`
|
41
|
+
if (days)
|
42
|
+
duration += `${days}D`
|
43
|
+
|
44
|
+
if (hours || mins)
|
45
|
+
duration += "T"
|
46
|
+
if (hours)
|
47
|
+
duration += `${hours}H`
|
48
|
+
if (mins)
|
49
|
+
duration += `${mins}M`
|
50
|
+
|
51
|
+
return duration
|
52
|
+
}
|
package/src/utils/rigoActions.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import axios from "axios"
|
2
|
-
import { writeFile } from "fs"
|
2
|
+
import { writeFile } from "fs/promises"
|
3
3
|
import Console from "../utils/console"
|
4
4
|
import { PackageInfo } from "./creatorUtilities"
|
5
5
|
import * as fs from "fs"
|
@@ -100,13 +100,10 @@ export async function downloadImage(
|
|
100
100
|
savePath: string
|
101
101
|
): Promise<void> {
|
102
102
|
const response = await axios.get(imageUrl, { responseType: "arraybuffer" })
|
103
|
+
|
103
104
|
const buffer = Buffer.from(response.data, "binary")
|
104
105
|
|
105
|
-
writeFile(savePath, buffer
|
106
|
-
if (err) {
|
107
|
-
Console.error(`Error saving the image: ${err}`)
|
108
|
-
}
|
109
|
-
})
|
106
|
+
await writeFile(savePath, buffer)
|
110
107
|
}
|
111
108
|
|
112
109
|
type TTranslateInputs = {
|
@@ -359,3 +356,26 @@ export const generateCourseShortName = async (
|
|
359
356
|
|
360
357
|
return response.data
|
361
358
|
}
|
359
|
+
|
360
|
+
type TFillSidebarJSONInputs = {
|
361
|
+
needed_translations: string
|
362
|
+
sidebar_json: string
|
363
|
+
}
|
364
|
+
|
365
|
+
export const fillSidebarJSON = async (
|
366
|
+
token: string,
|
367
|
+
inputs: TFillSidebarJSONInputs
|
368
|
+
) => {
|
369
|
+
const response = await axios.post(
|
370
|
+
`${RIGOBOT_HOST}/v1/prompting/completion/951/`,
|
371
|
+
{ inputs, include_purpose_objective: false, execute_async: false },
|
372
|
+
{
|
373
|
+
headers: {
|
374
|
+
"Content-Type": "application/json",
|
375
|
+
Authorization: "Token " + token,
|
376
|
+
},
|
377
|
+
}
|
378
|
+
)
|
379
|
+
|
380
|
+
return response.data
|
381
|
+
}
|
@@ -1,6 +1,11 @@
|
|
1
1
|
import path = require("path")
|
2
|
+
|
3
|
+
import Console from "./console"
|
2
4
|
import fs = require("fs")
|
3
5
|
import { IExercise, IExerciseData } from "../models/exercise-obj"
|
6
|
+
import { IConfigObj } from "../models/config"
|
7
|
+
import SessionManager from "../managers/session"
|
8
|
+
import { fillSidebarJSON } from "./rigoActions"
|
4
9
|
|
5
10
|
type TTitleTranslations = {
|
6
11
|
[key: string]: string
|
@@ -50,3 +55,73 @@ export const addExerciseToSidebar = (
|
|
50
55
|
|
51
56
|
return sidebar
|
52
57
|
}
|
58
|
+
|
59
|
+
export const checkAndFixSidebar = async (
|
60
|
+
configObj: IConfigObj,
|
61
|
+
autoFix = false
|
62
|
+
): Promise<boolean> => {
|
63
|
+
if (
|
64
|
+
configObj.config &&
|
65
|
+
fs.existsSync(configObj.config.dirPath + "/sidebar.json")
|
66
|
+
) {
|
67
|
+
let hasErrors = false
|
68
|
+
const sidebar = fs.readFileSync(
|
69
|
+
configObj.config.dirPath + "/sidebar.json",
|
70
|
+
"utf8"
|
71
|
+
)
|
72
|
+
// parse the sidebar.json file
|
73
|
+
const sidebarJson = JSON.parse(sidebar)
|
74
|
+
|
75
|
+
const exerciseTranslations: Set<string> = new Set()
|
76
|
+
configObj.exercises?.map(e =>
|
77
|
+
// eslint-disable-next-line
|
78
|
+
Object.keys((e.translations || {}) as any).forEach((t) =>
|
79
|
+
exerciseTranslations.add(t)
|
80
|
+
)
|
81
|
+
)
|
82
|
+
// Validation
|
83
|
+
for (const [key, value] of Object.entries(sidebarJson) as [
|
84
|
+
string,
|
85
|
+
TTitleTranslations
|
86
|
+
][]) {
|
87
|
+
for (const lang of exerciseTranslations) {
|
88
|
+
if (!Object.prototype.hasOwnProperty.call(value, lang)) {
|
89
|
+
hasErrors = true
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
if (hasErrors && autoFix) {
|
95
|
+
Console.warning("Filling sidebar.json file with missing translations")
|
96
|
+
const sessionPayload = await SessionManager.getPayload()
|
97
|
+
|
98
|
+
const rigoToken = sessionPayload.rigobot.key
|
99
|
+
|
100
|
+
if (!rigoToken) {
|
101
|
+
Console.error("No Rigobot token found, please login first!")
|
102
|
+
return false
|
103
|
+
}
|
104
|
+
|
105
|
+
const response = await fillSidebarJSON(rigoToken, {
|
106
|
+
needed_translations: JSON.stringify(exerciseTranslations),
|
107
|
+
sidebar_json: JSON.stringify(sidebarJson),
|
108
|
+
})
|
109
|
+
|
110
|
+
const newSidebarJson = JSON.parse(response.parsed.new_sidebar_file)
|
111
|
+
fs.writeFileSync(
|
112
|
+
configObj.config.dirPath + "/sidebar.json",
|
113
|
+
JSON.stringify(newSidebarJson, null, 4)
|
114
|
+
)
|
115
|
+
Console.info("Sidebar.json was filled with missing translations")
|
116
|
+
return true
|
117
|
+
}
|
118
|
+
|
119
|
+
if (hasErrors && !autoFix) {
|
120
|
+
return false
|
121
|
+
}
|
122
|
+
|
123
|
+
return true
|
124
|
+
}
|
125
|
+
|
126
|
+
return false
|
127
|
+
}
|