@learnpack/learnpack 2.1.26 → 2.1.27
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +10 -10
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
- package/src/commands/audit.ts +113 -113
- package/src/commands/clean.ts +10 -10
- package/src/commands/download.ts +18 -18
- package/src/commands/init.ts +39 -39
- package/src/commands/login.ts +13 -13
- package/src/commands/logout.ts +9 -9
- package/src/commands/publish.ts +25 -25
- package/src/commands/start.ts +101 -75
- package/src/commands/test.ts +34 -34
- package/src/managers/config/allowed_files.ts +2 -2
- package/src/managers/config/defaults.ts +2 -2
- package/src/managers/config/exercise.ts +79 -79
- package/src/managers/config/index.ts +145 -145
- package/src/managers/file.ts +74 -65
- package/src/managers/server/index.ts +32 -31
- package/src/managers/server/routes.ts +139 -90
- package/src/managers/session.ts +53 -24
- package/src/managers/socket.ts +92 -79
- package/src/models/action.ts +8 -1
- package/src/models/config-manager.ts +2 -2
- package/src/models/config.ts +7 -2
- package/src/models/exercise-obj.ts +6 -3
- package/src/models/plugin-config.ts +2 -2
- package/src/models/session.ts +5 -2
- package/src/models/socket.ts +12 -6
- package/src/models/status.ts +15 -14
- package/src/plugin/command/compile.ts +10 -10
- package/src/plugin/command/test.ts +14 -14
- package/src/plugin/index.ts +5 -5
- package/src/plugin/plugin.ts +26 -26
- package/src/plugin/utils.ts +23 -23
- package/src/utils/BaseCommand.ts +16 -16
- package/src/utils/api.ts +143 -91
- package/src/utils/audit.ts +93 -96
- package/src/utils/exercisesQueue.ts +15 -15
- package/src/utils/fileQueue.ts +85 -85
- package/src/utils/watcher.ts +14 -14
- package/lib/commands/audit.d.ts +0 -6
- package/lib/commands/audit.js +0 -342
- package/lib/commands/clean.d.ts +0 -8
- package/lib/commands/clean.js +0 -25
- package/lib/commands/download.d.ts +0 -13
- package/lib/commands/download.js +0 -55
- package/lib/commands/init.d.ts +0 -9
- package/lib/commands/init.js +0 -123
- package/lib/commands/login.d.ts +0 -14
- package/lib/commands/login.js +0 -37
- package/lib/commands/logout.d.ts +0 -14
- package/lib/commands/logout.js +0 -37
- package/lib/commands/publish.d.ts +0 -14
- package/lib/commands/publish.js +0 -82
- package/lib/commands/start.d.ts +0 -7
- package/lib/commands/start.js +0 -165
- package/lib/commands/test.d.ts +0 -6
- package/lib/commands/test.js +0 -62
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -4
- package/lib/managers/config/allowed_files.d.ts +0 -5
- package/lib/managers/config/allowed_files.js +0 -30
- package/lib/managers/config/defaults.d.ts +0 -39
- package/lib/managers/config/defaults.js +0 -40
- package/lib/managers/config/exercise.d.ts +0 -36
- package/lib/managers/config/exercise.js +0 -233
- package/lib/managers/config/index.d.ts +0 -3
- package/lib/managers/config/index.js +0 -320
- package/lib/managers/file.d.ts +0 -13
- package/lib/managers/file.js +0 -134
- package/lib/managers/gitpod.d.ts +0 -3
- package/lib/managers/gitpod.js +0 -67
- package/lib/managers/server/index.d.ts +0 -6
- package/lib/managers/server/index.js +0 -58
- package/lib/managers/server/routes.d.ts +0 -4
- package/lib/managers/server/routes.js +0 -167
- package/lib/managers/session.d.ts +0 -3
- package/lib/managers/session.js +0 -104
- package/lib/managers/socket.d.ts +0 -3
- package/lib/managers/socket.js +0 -164
- package/lib/managers/test.d.ts +0 -0
- package/lib/managers/test.js +0 -84
- package/lib/models/action.d.ts +0 -2
- package/lib/models/action.js +0 -2
- package/lib/models/audit.d.ts +0 -15
- package/lib/models/audit.js +0 -2
- package/lib/models/config-manager.d.ts +0 -21
- package/lib/models/config-manager.js +0 -2
- package/lib/models/config.d.ts +0 -62
- package/lib/models/config.js +0 -2
- package/lib/models/counter.d.ts +0 -11
- package/lib/models/counter.js +0 -2
- package/lib/models/errors.d.ts +0 -15
- package/lib/models/errors.js +0 -2
- package/lib/models/exercise-obj.d.ts +0 -27
- package/lib/models/exercise-obj.js +0 -2
- package/lib/models/file.d.ts +0 -5
- package/lib/models/file.js +0 -2
- package/lib/models/findings.d.ts +0 -17
- package/lib/models/findings.js +0 -2
- package/lib/models/flags.d.ts +0 -10
- package/lib/models/flags.js +0 -2
- package/lib/models/front-matter.d.ts +0 -11
- package/lib/models/front-matter.js +0 -2
- package/lib/models/gitpod-data.d.ts +0 -16
- package/lib/models/gitpod-data.js +0 -2
- package/lib/models/language.d.ts +0 -4
- package/lib/models/language.js +0 -2
- package/lib/models/package.d.ts +0 -7
- package/lib/models/package.js +0 -2
- package/lib/models/plugin-config.d.ts +0 -16
- package/lib/models/plugin-config.js +0 -2
- package/lib/models/session.d.ts +0 -23
- package/lib/models/session.js +0 -2
- package/lib/models/socket.d.ts +0 -31
- package/lib/models/socket.js +0 -2
- package/lib/models/status.d.ts +0 -1
- package/lib/models/status.js +0 -2
- package/lib/models/success-types.d.ts +0 -1
- package/lib/models/success-types.js +0 -2
- package/lib/plugin/command/compile.d.ts +0 -6
- package/lib/plugin/command/compile.js +0 -18
- package/lib/plugin/command/test.d.ts +0 -6
- package/lib/plugin/command/test.js +0 -25
- package/lib/plugin/index.d.ts +0 -27
- package/lib/plugin/index.js +0 -7
- package/lib/plugin/plugin.d.ts +0 -8
- package/lib/plugin/plugin.js +0 -68
- package/lib/plugin/utils.d.ts +0 -16
- package/lib/plugin/utils.js +0 -58
- package/lib/ui/download.d.ts +0 -5
- package/lib/ui/download.js +0 -61
- package/lib/utils/BaseCommand.d.ts +0 -8
- package/lib/utils/BaseCommand.js +0 -41
- package/lib/utils/SessionCommand.d.ts +0 -10
- package/lib/utils/SessionCommand.js +0 -47
- package/lib/utils/api.d.ts +0 -12
- package/lib/utils/api.js +0 -173
- package/lib/utils/audit.d.ts +0 -16
- package/lib/utils/audit.js +0 -302
- package/lib/utils/console.d.ts +0 -12
- package/lib/utils/console.js +0 -19
- package/lib/utils/errors.d.ts +0 -17
- package/lib/utils/errors.js +0 -100
- package/lib/utils/exercisesQueue.d.ts +0 -9
- package/lib/utils/exercisesQueue.js +0 -38
- package/lib/utils/fileQueue.d.ts +0 -40
- package/lib/utils/fileQueue.js +0 -168
- package/lib/utils/misc.d.ts +0 -1
- package/lib/utils/misc.js +0 -23
- package/lib/utils/validators.d.ts +0 -5
- package/lib/utils/validators.js +0 -17
- package/lib/utils/watcher.d.ts +0 -2
- package/lib/utils/watcher.js +0 -23
@@ -1,12 +1,12 @@
|
|
1
|
-
import * as p from "path"
|
1
|
+
import * as p from "path"
|
2
2
|
// import frontMatter from 'front-matter'
|
3
|
-
import * as fs from "fs"
|
4
|
-
import Console from "../../utils/console"
|
5
|
-
import allowed from "./allowed_files"
|
3
|
+
import * as fs from "fs"
|
4
|
+
import Console from "../../utils/console"
|
5
|
+
import allowed from "./allowed_files"
|
6
6
|
|
7
|
-
import { IConfigObj } from "../../models/config"
|
8
|
-
import { IFile } from "../../models/file"
|
9
|
-
import { IExercise } from "../../models/exercise-obj"
|
7
|
+
import { IConfigObj } from "../../models/config"
|
8
|
+
import { IFile } from "../../models/file"
|
9
|
+
import { IExercise } from "../../models/exercise-obj"
|
10
10
|
|
11
11
|
// eslint-disable-next-line
|
12
12
|
const frontMatter = require("front-matter");
|
@@ -16,17 +16,17 @@ export const exercise = (
|
|
16
16
|
position: number,
|
17
17
|
configObject: IConfigObj
|
18
18
|
): IExercise => {
|
19
|
-
const { config, exercises } = configObject
|
20
|
-
let slug = p.basename(path)
|
19
|
+
const { config, exercises } = configObject
|
20
|
+
let slug = p.basename(path)
|
21
21
|
|
22
22
|
if (!validateExerciseDirectoryName(slug)) {
|
23
23
|
Console.error(
|
24
24
|
`Exercise directory ${slug} has an invalid name, it has to start with two or three digits followed by words separated by underscors or hyphen (no white spaces). e.g: 01.12-hello-world`
|
25
|
-
)
|
25
|
+
)
|
26
26
|
}
|
27
27
|
|
28
28
|
// get all the files
|
29
|
-
const files = fs.readdirSync(path)
|
29
|
+
const files = fs.readdirSync(path)
|
30
30
|
|
31
31
|
/**
|
32
32
|
* build the translation array like:
|
@@ -35,23 +35,23 @@ export const exercise = (
|
|
35
35
|
"es": "path/to/Readme.es.md"
|
36
36
|
}
|
37
37
|
*/
|
38
|
-
const translations: { [key: string]: string } = {}
|
38
|
+
const translations: { [key: string]: string } = {}
|
39
39
|
for (const file of files.filter(file =>
|
40
40
|
file.toLowerCase().includes("readme")
|
41
41
|
)) {
|
42
|
-
const parts = file.split(".")
|
42
|
+
const parts = file.split(".")
|
43
43
|
|
44
44
|
if (parts.length === 3)
|
45
|
-
translations[parts[1]] = file
|
45
|
+
translations[parts[1]] = file
|
46
46
|
else
|
47
|
-
translations.us = file
|
47
|
+
translations.us = file
|
48
48
|
}
|
49
49
|
|
50
50
|
// if the slug is a dot, it means there is not "exercises" folder, and its just a single README.md
|
51
51
|
if (slug === ".")
|
52
|
-
slug = "default-index"
|
52
|
+
slug = "default-index"
|
53
53
|
|
54
|
-
const detected = detect(configObject, files)
|
54
|
+
const detected = detect(configObject, files)
|
55
55
|
|
56
56
|
const exerciseObj: IExercise = {
|
57
57
|
position,
|
@@ -77,52 +77,52 @@ slug = "default-index";
|
|
77
77
|
false,
|
78
78
|
getReadme: function (lang = null) {
|
79
79
|
if (lang === "us")
|
80
|
-
lang = null
|
80
|
+
lang = null // <-- english is default, no need to append it to the file name
|
81
81
|
|
82
82
|
if (!fs.existsSync(`${this.path}/README${lang ? "." + lang : ""}.md`)) {
|
83
83
|
Console.error(
|
84
84
|
`Language ${lang} not found for exercise ${slug}, switching to default language`
|
85
|
-
)
|
85
|
+
)
|
86
86
|
|
87
87
|
if (lang)
|
88
|
-
lang = null
|
88
|
+
lang = null
|
89
89
|
|
90
90
|
if (!fs.existsSync(`${this.path}/README${lang ? "." + lang : ""}.md`))
|
91
91
|
throw new Error(
|
92
92
|
"Readme file not found for exercise: " + this.path + "/README.md"
|
93
|
-
)
|
93
|
+
)
|
94
94
|
}
|
95
95
|
|
96
96
|
const content = fs.readFileSync(
|
97
97
|
`${this.path}/README${lang ? "." + lang : ""}.md`,
|
98
98
|
"utf8"
|
99
|
-
)
|
100
|
-
const attr = frontMatter(content)
|
101
|
-
return attr
|
99
|
+
)
|
100
|
+
const attr = frontMatter(content)
|
101
|
+
return attr
|
102
102
|
},
|
103
103
|
getFile: function (name: string) {
|
104
104
|
const file: IFile | undefined = this.files.find(
|
105
105
|
(f: IFile) => f.name === name
|
106
|
-
)
|
106
|
+
)
|
107
107
|
|
108
108
|
if (!file || !fs.existsSync(file.path)) {
|
109
|
-
throw new Error(`File not found: + ${file?.path}`)
|
109
|
+
throw new Error(`File not found: + ${file?.path}`)
|
110
110
|
} else if (fs.lstatSync(file.path).isDirectory()) {
|
111
111
|
return (
|
112
112
|
"Error: This is not a file to be read, but a directory: " + file.path
|
113
|
-
)
|
113
|
+
)
|
114
114
|
}
|
115
115
|
|
116
116
|
// get file content
|
117
|
-
const content = fs.readFileSync(file.path)
|
117
|
+
const content = fs.readFileSync(file.path)
|
118
118
|
|
119
119
|
// create reset folder
|
120
120
|
if (!fs.existsSync(`${config?.dirPath}/resets`))
|
121
|
-
fs.mkdirSync(`${config?.dirPath}/resets`)
|
121
|
+
fs.mkdirSync(`${config?.dirPath}/resets`)
|
122
122
|
if (!fs.existsSync(`${config?.dirPath}/resets/` + this.slug)) {
|
123
|
-
fs.mkdirSync(`${config?.dirPath}/resets/` + this.slug)
|
123
|
+
fs.mkdirSync(`${config?.dirPath}/resets/` + this.slug)
|
124
124
|
for (const _file of this.files) {
|
125
|
-
const fileContent = fs.readFileSync(_file.path)
|
125
|
+
const fileContent = fs.readFileSync(_file.path)
|
126
126
|
if (
|
127
127
|
!fs.existsSync(
|
128
128
|
`${config?.dirPath}/resets/${this.slug}/${_file.name}`
|
@@ -131,57 +131,57 @@ lang = null;
|
|
131
131
|
fs.writeFileSync(
|
132
132
|
`${config?.dirPath}/resets/${this.slug}/${_file.name}`,
|
133
133
|
fileContent
|
134
|
-
)
|
134
|
+
)
|
135
135
|
}
|
136
136
|
}
|
137
137
|
}
|
138
138
|
|
139
|
-
return content
|
139
|
+
return content
|
140
140
|
},
|
141
141
|
saveFile: function (name: string, content: string) {
|
142
142
|
const file: IFile | undefined = this.files.find(
|
143
143
|
(f: IFile) => f.name === name
|
144
|
-
)
|
144
|
+
)
|
145
145
|
|
146
146
|
if (file) {
|
147
147
|
if (!fs.existsSync(file.path)) {
|
148
|
-
throw new Error("File not found: " + file.path)
|
148
|
+
throw new Error("File not found: " + file.path)
|
149
149
|
}
|
150
150
|
|
151
|
-
return fs.writeFileSync(file.path, content, "utf8")
|
151
|
+
return fs.writeFileSync(file.path, content, "utf8")
|
152
152
|
}
|
153
153
|
},
|
154
154
|
getTestReport: function () {
|
155
|
-
const _path = `${configObject?.confPath?.base}/reports/${this.slug}.json
|
155
|
+
const _path = `${configObject?.confPath?.base}/reports/${this.slug}.json`
|
156
156
|
|
157
157
|
if (!fs.existsSync(_path))
|
158
|
-
return {}
|
158
|
+
return {}
|
159
159
|
|
160
|
-
const content = fs.readFileSync(_path)
|
161
|
-
const data = JSON.parse(`${content}`)
|
162
|
-
return data
|
160
|
+
const content = fs.readFileSync(_path)
|
161
|
+
const data = JSON.parse(`${content}`)
|
162
|
+
return data
|
163
163
|
},
|
164
|
-
}
|
164
|
+
}
|
165
165
|
|
166
|
-
return exerciseObj
|
167
|
-
}
|
166
|
+
return exerciseObj
|
167
|
+
}
|
168
168
|
|
169
169
|
export const validateExerciseDirectoryName = (str: string) => {
|
170
170
|
if (str === "./")
|
171
|
-
return true
|
171
|
+
return true
|
172
172
|
// TODO: Add nameValidationREgex from the config
|
173
|
-
const regex = /^(\d{2,3}(\.\d{1,2})?-([\dA-Za-z]+(-|_)?)+)
|
174
|
-
return regex.test(str)
|
175
|
-
}
|
173
|
+
const regex = /^(\d{2,3}(\.\d{1,2})?-([\dA-Za-z]+(-|_)?)+)$/
|
174
|
+
return regex.test(str)
|
175
|
+
}
|
176
176
|
|
177
177
|
export const isCodable = (str: string) => {
|
178
|
-
const extension = p.extname(str)
|
179
|
-
return allowed.extensions.includes(extension.slice(1).toLowerCase())
|
180
|
-
}
|
178
|
+
const extension = p.extname(str)
|
179
|
+
return allowed.extensions.includes(extension.slice(1).toLowerCase())
|
180
|
+
}
|
181
181
|
|
182
182
|
const isNotConfiguration = (str: string) => {
|
183
|
-
return !allowed.names.includes(str)
|
184
|
-
}
|
183
|
+
return !allowed.names.includes(str)
|
184
|
+
}
|
185
185
|
|
186
186
|
export const shouldBeVisible = function (file: IFile) {
|
187
187
|
return (
|
@@ -201,56 +201,56 @@ export const shouldBeVisible = function (file: IFile) {
|
|
201
201
|
!file.name.toLowerCase().includes("readme.") &&
|
202
202
|
!isDirectory(file.path) &&
|
203
203
|
file.name.charAt(0) !== "_"
|
204
|
-
)
|
205
|
-
}
|
204
|
+
)
|
205
|
+
}
|
206
206
|
|
207
207
|
export const isDirectory = (source: string) => {
|
208
208
|
// if(path.basename(source) === path.basename(config.dirPath)) return false
|
209
|
-
return fs.lstatSync(source).isDirectory()
|
210
|
-
}
|
209
|
+
return fs.lstatSync(source).isDirectory()
|
210
|
+
}
|
211
211
|
|
212
212
|
export const detect = (
|
213
213
|
configObject: IConfigObj | undefined,
|
214
214
|
files: Array<string>
|
215
215
|
) => {
|
216
216
|
if (!configObject) {
|
217
|
-
return
|
217
|
+
return
|
218
218
|
}
|
219
219
|
|
220
|
-
const { config } = configObject
|
220
|
+
const { config } = configObject
|
221
221
|
|
222
222
|
if (!config)
|
223
|
-
throw new Error("No configuration found during the engine detection")
|
223
|
+
throw new Error("No configuration found during the engine detection")
|
224
224
|
|
225
225
|
if (!config.entries)
|
226
226
|
throw new Error(
|
227
227
|
"No configuration found for entries, please add a 'entries' object with the default file name for your exercise entry file that is going to be used while compiling, for example: index.html for html, app.py for python3, etc."
|
228
|
-
)
|
228
|
+
)
|
229
229
|
// A language was found on the config object, but this language will only be used as last resort, learnpack will try to guess each exercise language independently based on file extension (js, jsx, html, etc.)
|
230
230
|
|
231
|
-
let hasFiles = files.filter(f => f.includes(".py"))
|
231
|
+
let hasFiles = files.filter(f => f.includes(".py"))
|
232
232
|
if (hasFiles.length > 0)
|
233
233
|
return {
|
234
234
|
language: "python3",
|
235
235
|
entry: hasFiles.find(f => config.entries.python3 === f),
|
236
|
-
}
|
236
|
+
}
|
237
237
|
|
238
|
-
hasFiles = files.filter(f => f.includes(".java"))
|
238
|
+
hasFiles = files.filter(f => f.includes(".java"))
|
239
239
|
if (hasFiles.length > 0)
|
240
240
|
return {
|
241
241
|
language: "java",
|
242
242
|
entry: hasFiles.find(f => config.entries.java === f),
|
243
|
-
}
|
243
|
+
}
|
244
244
|
|
245
|
-
hasFiles = files.filter(f => f.includes(".jsx"))
|
245
|
+
hasFiles = files.filter(f => f.includes(".jsx"))
|
246
246
|
if (hasFiles.length > 0)
|
247
247
|
return {
|
248
248
|
language: "react",
|
249
249
|
entry: hasFiles.find(f => config.entries.react === f),
|
250
|
-
}
|
251
|
-
const hasHTML = files.filter(f => f.includes("index.html"))
|
252
|
-
const hasIndexJS = files.find(f => f.includes("index.js"))
|
253
|
-
const hasJS = files.filter(f => f.includes(".js"))
|
250
|
+
}
|
251
|
+
const hasHTML = files.filter(f => f.includes("index.html"))
|
252
|
+
const hasIndexJS = files.find(f => f.includes("index.js"))
|
253
|
+
const hasJS = files.filter(f => f.includes(".js"))
|
254
254
|
// angular, vue, vanillajs needs to have at least 2 files (html,css,js),
|
255
255
|
// the test.js and the entry file in js
|
256
256
|
// if not its just another HTML
|
@@ -259,23 +259,23 @@ export const detect = (
|
|
259
259
|
return {
|
260
260
|
language: "vanillajs",
|
261
261
|
entry: hasIndexJS,
|
262
|
-
}
|
262
|
+
}
|
263
263
|
if (hasHTML.length > 0)
|
264
264
|
return {
|
265
265
|
language: "html",
|
266
266
|
entry: hasHTML.find(f => config.entries.html === f),
|
267
|
-
}
|
267
|
+
}
|
268
268
|
if (hasJS.length > 0)
|
269
269
|
return {
|
270
270
|
language: "node",
|
271
271
|
entry: hasJS.find(f => config.entries.node === f),
|
272
|
-
}
|
272
|
+
}
|
273
273
|
|
274
274
|
return {
|
275
275
|
language: null,
|
276
276
|
entry: null,
|
277
|
-
}
|
278
|
-
}
|
277
|
+
}
|
278
|
+
}
|
279
279
|
|
280
280
|
export const filterFiles = (files: Array<string>, basePath = ".") =>
|
281
281
|
files
|
@@ -298,12 +298,12 @@ export const filterFiles = (files: Array<string>, basePath = ".") =>
|
|
298
298
|
"index.css": 2,
|
299
299
|
"index.scss": 2,
|
300
300
|
"index.js": 3,
|
301
|
-
}
|
302
|
-
return score[f1.name] < score[f2.name] ? -1 : 1
|
303
|
-
})
|
301
|
+
}
|
302
|
+
return score[f1.name] < score[f2.name] ? -1 : 1
|
303
|
+
})
|
304
304
|
|
305
305
|
export default {
|
306
306
|
exercise,
|
307
307
|
detect,
|
308
308
|
filterFiles,
|
309
|
-
}
|
309
|
+
}
|