@learnpack/learnpack 2.1.25 → 2.1.27
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +16 -16
- package/bin/run +17 -17
- package/bin/run.cmd +3 -3
- package/oclif.manifest.json +1 -1
- package/package.json +139 -138
- package/src/commands/audit.ts +134 -109
- package/src/commands/clean.ts +29 -29
- package/src/commands/download.ts +62 -62
- package/src/commands/init.ts +39 -39
- package/src/commands/login.ts +42 -42
- package/src/commands/logout.ts +43 -43
- package/src/commands/publish.ts +107 -107
- package/src/commands/start.ts +264 -234
- package/src/commands/test.ts +85 -85
- package/src/index.ts +1 -1
- package/src/managers/config/allowed_files.ts +29 -29
- package/src/managers/config/defaults.ts +4 -2
- package/src/managers/config/exercise.ts +309 -302
- package/src/managers/config/index.ts +159 -138
- package/src/managers/file.ts +178 -169
- package/src/managers/gitpod.ts +84 -84
- package/src/managers/server/index.ts +78 -69
- package/src/managers/server/routes.ts +139 -90
- package/src/managers/session.ts +147 -118
- package/src/managers/socket.ts +252 -239
- package/src/managers/test.ts +83 -83
- package/src/models/action.ts +10 -3
- package/src/models/config-manager.ts +23 -23
- package/src/models/config.ts +9 -2
- package/src/models/counter.ts +11 -11
- package/src/models/errors.ts +22 -22
- package/src/models/exercise-obj.ts +6 -3
- package/src/models/file.ts +5 -5
- package/src/models/findings.ts +18 -18
- package/src/models/flags.ts +10 -10
- package/src/models/front-matter.ts +11 -11
- package/src/models/gitpod-data.ts +19 -19
- package/src/models/language.ts +4 -4
- package/src/models/package.ts +7 -7
- package/src/models/plugin-config.ts +17 -17
- package/src/models/session.ts +29 -26
- package/src/models/socket.ts +54 -48
- package/src/models/status.ts +16 -15
- package/src/models/success-types.ts +1 -1
- package/src/plugin/command/compile.ts +17 -17
- package/src/plugin/command/test.ts +30 -30
- package/src/plugin/index.ts +6 -6
- package/src/plugin/plugin.ts +94 -94
- package/src/plugin/utils.ts +87 -87
- package/src/types/node-fetch.d.ts +1 -1
- package/src/ui/download.ts +71 -71
- package/src/utils/BaseCommand.ts +48 -48
- package/src/utils/SessionCommand.ts +48 -48
- package/src/utils/api.ts +246 -194
- package/src/utils/audit.ts +392 -395
- package/src/utils/console.ts +24 -24
- package/src/utils/errors.ts +117 -117
- package/src/utils/exercisesQueue.ts +51 -51
- package/src/utils/fileQueue.ts +198 -198
- package/src/utils/misc.ts +23 -23
- package/src/utils/templates/gitignore.txt +19 -19
- package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.es.md +24 -24
- package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.md +24 -24
- package/src/utils/templates/incremental/README.ejs +4 -4
- package/src/utils/templates/incremental/README.es.ejs +4 -4
- package/src/utils/templates/isolated/01-hello-world/README.es.md +26 -26
- package/src/utils/templates/isolated/01-hello-world/README.md +26 -26
- package/src/utils/templates/isolated/README.ejs +4 -4
- package/src/utils/templates/isolated/README.es.ejs +4 -4
- package/src/utils/templates/no-grading/README.ejs +4 -4
- package/src/utils/templates/no-grading/README.es.ejs +4 -4
- package/src/utils/validators.ts +18 -18
- package/src/utils/watcher.ts +14 -14
- package/lib/commands/audit.d.ts +0 -6
- package/lib/commands/audit.js +0 -317
- 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 -37
- package/lib/managers/config/defaults.js +0 -38
- package/lib/managers/config/exercise.d.ts +0 -36
- package/lib/managers/config/exercise.js +0 -230
- package/lib/managers/config/index.d.ts +0 -3
- package/lib/managers/config/index.js +0 -302
- 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 -51
- 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 -60
- 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,78 +1,117 @@
|
|
1
|
-
import Console from "../../utils/console"
|
2
|
-
import * as express from "express"
|
3
|
-
import * as fs from "fs"
|
4
|
-
import * as bodyParser from "body-parser"
|
5
|
-
import socket from "../socket"
|
6
|
-
import queue from "../../utils/fileQueue"
|
1
|
+
import Console from "../../utils/console"
|
2
|
+
import * as express from "express"
|
3
|
+
import * as fs from "fs"
|
4
|
+
import * as bodyParser from "body-parser"
|
5
|
+
import socket from "../socket"
|
6
|
+
import queue from "../../utils/fileQueue"
|
7
7
|
// import gitpod from '../gitpod'
|
8
|
-
import { detect, filterFiles } from "../config/exercise"
|
9
|
-
import { IFile } from "../../models/file"
|
10
|
-
import { IConfigObj, TEntries } from "../../models/config"
|
11
|
-
import { IConfigManager } from "../../models/config-manager"
|
12
|
-
import { IExercise } from "../../models/exercise-obj"
|
8
|
+
import { detect, filterFiles } from "../config/exercise"
|
9
|
+
import { IFile } from "../../models/file"
|
10
|
+
import { IConfigObj, TEntries } from "../../models/config"
|
11
|
+
import { IConfigManager } from "../../models/config-manager"
|
12
|
+
import { IExercise } from "../../models/exercise-obj"
|
13
|
+
import SessionManager from "../../managers/session"
|
13
14
|
|
14
15
|
const withHandler =
|
15
16
|
(func: (req: express.Request, res: express.Response) => void) =>
|
16
17
|
(req: express.Request, res: express.Response) => {
|
17
18
|
try {
|
18
|
-
func(req, res)
|
19
|
+
func(req, res)
|
19
20
|
} catch (error) {
|
20
|
-
Console.debug(error)
|
21
|
+
Console.debug(error)
|
21
22
|
const _err = {
|
22
23
|
message: (error as TypeError).message || "There has been an error",
|
23
24
|
status: (error as any).status || 500,
|
24
25
|
type: (error as any).type || null,
|
25
|
-
}
|
26
|
-
Console.error(_err.message)
|
26
|
+
}
|
27
|
+
Console.error(_err.message)
|
27
28
|
|
28
29
|
// send rep to the server
|
29
|
-
res.status(_err.status)
|
30
|
-
res.json(_err)
|
30
|
+
res.status(_err.status)
|
31
|
+
res.json(_err)
|
31
32
|
}
|
32
|
-
}
|
33
|
+
}
|
33
34
|
|
34
35
|
export default async function (
|
35
36
|
app: express.Application,
|
36
37
|
configObject: IConfigObj,
|
37
38
|
configManager: IConfigManager
|
38
39
|
) {
|
39
|
-
const { config, exercises } = configObject
|
40
|
+
const { config, exercises } = configObject
|
41
|
+
const session = await SessionManager.get(configManager?.get())
|
40
42
|
|
41
43
|
const dispatcher = queue.dispatcher({
|
42
44
|
create: true,
|
43
45
|
path: `${config?.dirPath}/vscode_queue.json`,
|
44
|
-
})
|
46
|
+
})
|
45
47
|
app.get(
|
46
48
|
"/config",
|
47
49
|
withHandler((_: express.Request, res: express.Response) => {
|
48
|
-
res.json(configObject)
|
50
|
+
res.json(configObject)
|
49
51
|
})
|
50
|
-
)
|
52
|
+
)
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
54
|
+
// Added this line to parse the json body
|
55
|
+
|
56
|
+
const jsonBodyParser = bodyParser.json()
|
57
|
+
// Trying to log in from frontend
|
58
|
+
app.post(
|
59
|
+
"/login",
|
60
|
+
jsonBodyParser,
|
61
|
+
withHandler(async (req: express.Request, res: express.Response) => {
|
62
|
+
const email = req.body.email
|
63
|
+
const password = req.body.password
|
64
|
+
|
65
|
+
SessionManager.destroy()
|
66
|
+
const payload = await SessionManager.loginWeb(email, password)
|
67
|
+
|
68
|
+
res.json(payload)
|
69
|
+
})
|
70
|
+
)
|
71
|
+
app.post(
|
72
|
+
"/set-openai-token",
|
73
|
+
jsonBodyParser,
|
74
|
+
withHandler(async (req: express.Request, res: express.Response) => {
|
75
|
+
const token = req.body.token
|
76
|
+
console.log("Setting openai token")
|
77
|
+
|
78
|
+
const tokenSaved = await SessionManager.setOpenAIToken(token)
|
79
|
+
if (tokenSaved) {
|
80
|
+
res.json({ status: "ok" })
|
81
|
+
} else {
|
82
|
+
res.status(400)
|
83
|
+
}
|
84
|
+
})
|
85
|
+
)
|
86
|
+
|
87
|
+
app.get(
|
88
|
+
"/check/rigo/status",
|
89
|
+
withHandler(async (_: express.Request, res: express.Response) => {
|
90
|
+
const payload = await SessionManager.getPayload()
|
91
|
+
const openaiToken = await SessionManager.getOpenAIToken()
|
92
|
+
// console.log("Looking Rigo creds");
|
93
|
+
|
94
|
+
if (payload && payload.rigobot && payload.rigobot.key) {
|
95
|
+
res.json({ rigoToken: payload.rigobot.key })
|
96
|
+
} else if (openaiToken) {
|
97
|
+
res.json({ openaiToken })
|
98
|
+
} else {
|
99
|
+
res
|
100
|
+
.status(400)
|
101
|
+
.json({ details: `Rigobot token not found, please log in first!` })
|
102
|
+
}
|
103
|
+
})
|
104
|
+
)
|
66
105
|
|
67
106
|
// symbolic link to maintain path compatiblity
|
68
107
|
const fetchStaticAsset = withHandler((req, res) => {
|
69
|
-
const filePath = `${config?.dirPath}/assets/${req.params.filePath}
|
108
|
+
const filePath = `${config?.dirPath}/assets/${req.params.filePath}`
|
70
109
|
if (!fs.existsSync(filePath))
|
71
|
-
throw new Error("File not found: " + filePath)
|
72
|
-
const content = fs.readFileSync(filePath)
|
73
|
-
res.write(content)
|
74
|
-
res.end()
|
75
|
-
})
|
110
|
+
throw new Error("File not found: " + filePath)
|
111
|
+
const content = fs.readFileSync(filePath)
|
112
|
+
res.write(content)
|
113
|
+
res.end()
|
114
|
+
})
|
76
115
|
|
77
116
|
app.get(
|
78
117
|
`${
|
@@ -81,16 +120,16 @@ export default async function (
|
|
81
120
|
config?.dirPath
|
82
121
|
}/assets/:filePath`,
|
83
122
|
fetchStaticAsset
|
84
|
-
)
|
123
|
+
)
|
85
124
|
|
86
|
-
app.get("/assets/:filePath", fetchStaticAsset)
|
125
|
+
app.get("/assets/:filePath", fetchStaticAsset)
|
87
126
|
|
88
127
|
app.get(
|
89
128
|
"/exercise",
|
90
129
|
withHandler((_: express.Request, res: express.Response) => {
|
91
|
-
res.json(exercises)
|
130
|
+
res.json(exercises)
|
92
131
|
})
|
93
|
-
)
|
132
|
+
)
|
94
133
|
|
95
134
|
app.get(
|
96
135
|
"/exercise/:slug/readme",
|
@@ -99,30 +138,30 @@ export default async function (
|
|
99
138
|
{ params: { slug }, query: { lang } }: express.Request,
|
100
139
|
res: express.Response
|
101
140
|
) => {
|
102
|
-
const exercise: IExercise = configManager.getExercise(slug)
|
141
|
+
const exercise: IExercise = configManager.getExercise(slug)
|
103
142
|
|
104
143
|
if (exercise && exercise.getReadme) {
|
105
|
-
const readme = exercise.getReadme((lang as string) || null)
|
106
|
-
res.json(readme)
|
144
|
+
const readme = exercise.getReadme((lang as string) || null)
|
145
|
+
res.json(readme)
|
107
146
|
} else {
|
108
|
-
res.status(400)
|
147
|
+
res.status(400)
|
109
148
|
}
|
110
149
|
}
|
111
150
|
)
|
112
|
-
)
|
151
|
+
)
|
113
152
|
|
114
153
|
app.get(
|
115
154
|
"/exercise/:slug/report",
|
116
155
|
withHandler(
|
117
156
|
({ params: { slug } }: express.Request, res: express.Response) => {
|
118
|
-
const exercise = configManager.getExercise(slug)
|
157
|
+
const exercise = configManager.getExercise(slug)
|
119
158
|
if (exercise && exercise.getTestReport) {
|
120
|
-
const report = exercise.getTestReport()
|
121
|
-
res.json(JSON.stringify(report))
|
159
|
+
const report = exercise.getTestReport()
|
160
|
+
res.json(JSON.stringify(report))
|
122
161
|
}
|
123
162
|
}
|
124
163
|
)
|
125
|
-
)
|
164
|
+
)
|
126
165
|
|
127
166
|
app.get(
|
128
167
|
"/exercise/:slug",
|
@@ -132,13 +171,13 @@ export default async function (
|
|
132
171
|
configObject.currentExercise &&
|
133
172
|
req.params.slug === configObject.currentExercise
|
134
173
|
) {
|
135
|
-
const exercise = configManager.getExercise(req.params.slug)
|
136
|
-
res.json(exercise)
|
137
|
-
return
|
174
|
+
const exercise = configManager.getExercise(req.params.slug)
|
175
|
+
res.json(exercise)
|
176
|
+
return
|
138
177
|
}
|
139
178
|
|
140
|
-
const exercise = configManager.startExercise(req.params.slug)
|
141
|
-
dispatcher.enqueue(dispatcher.events.START_EXERCISE, req.params.slug)
|
179
|
+
const exercise = configManager.startExercise(req.params.slug)
|
180
|
+
dispatcher.enqueue(dispatcher.events.START_EXERCISE, req.params.slug)
|
142
181
|
|
143
182
|
type TEntry = "python3" | "html" | "node" | "react" | "java";
|
144
183
|
|
@@ -146,19 +185,19 @@ export default async function (
|
|
146
185
|
Object.keys(config?.entries!).map(
|
147
186
|
lang => config?.entries[lang as TEntry]
|
148
187
|
)
|
149
|
-
)
|
188
|
+
)
|
150
189
|
|
151
190
|
// if we are in incremental grading, the entry file can by dinamically detected
|
152
191
|
// based on the changes the student is making during the exercise
|
153
192
|
if (config?.grading === "incremental") {
|
154
|
-
const scanedFiles = fs.readdirSync("./")
|
193
|
+
const scanedFiles = fs.readdirSync("./")
|
155
194
|
|
156
195
|
// update the file hierarchy with updates
|
157
196
|
exercise.files = [
|
158
197
|
...exercise.files.filter(f => f.name.includes("test.")),
|
159
198
|
...filterFiles(scanedFiles),
|
160
|
-
]
|
161
|
-
Console.debug(`Exercise updated files: `, exercise.files)
|
199
|
+
]
|
200
|
+
Console.debug(`Exercise updated files: `, exercise.files)
|
162
201
|
}
|
163
202
|
|
164
203
|
const detected = detect(
|
@@ -166,31 +205,31 @@ export default async function (
|
|
166
205
|
exercise.files
|
167
206
|
.filter(fileName => entries.has(fileName.name))
|
168
207
|
.map(f => f.name || f) as string[]
|
169
|
-
)
|
208
|
+
)
|
170
209
|
|
171
210
|
// if a new language for the testing engine is detected, we replace it
|
172
211
|
// if not we leave it as it was before
|
173
212
|
if (config?.language && !["", "auto"].includes(config?.language)) {
|
174
213
|
Console.debug(
|
175
214
|
`Exercise language ignored, instead imported from configuration ${config?.language}`
|
176
|
-
)
|
177
|
-
exercise.language = detected?.language
|
215
|
+
)
|
216
|
+
exercise.language = detected?.language
|
178
217
|
} else if (
|
179
218
|
detected?.language &&
|
180
219
|
(!config?.language || config?.language === "auto")
|
181
220
|
) {
|
182
221
|
Console.debug(
|
183
222
|
`Switching to ${detected.language} engine in this exercise`
|
184
|
-
)
|
185
|
-
exercise.language = detected.language
|
223
|
+
)
|
224
|
+
exercise.language = detected.language
|
186
225
|
}
|
187
226
|
|
188
227
|
// WARNING: has to be the FULL PATH to the entry path
|
189
228
|
// We need to detect entry in both gradings: Incremental and Isolate
|
190
|
-
exercise.entry = detected?.entry
|
229
|
+
exercise.entry = detected?.entry
|
191
230
|
Console.debug(
|
192
231
|
`Exercise detected entry: ${detected?.entry} and language ${exercise.language}`
|
193
|
-
)
|
232
|
+
)
|
194
233
|
|
195
234
|
// exercises.graded and exercises.disableGrading deprecated.
|
196
235
|
if (
|
@@ -198,15 +237,15 @@ export default async function (
|
|
198
237
|
config?.disableGrading ||
|
199
238
|
config?.disabledActions?.includes("test")
|
200
239
|
) {
|
201
|
-
socket.removeAllowed("test")
|
240
|
+
socket.removeAllowed("test")
|
202
241
|
} else {
|
203
|
-
socket.addAllowed("test")
|
242
|
+
socket.addAllowed("test")
|
204
243
|
}
|
205
244
|
|
206
245
|
if (!exercise.entry || config?.disabledActions?.includes("build")) {
|
207
|
-
socket.removeAllowed("build")
|
246
|
+
socket.removeAllowed("build")
|
208
247
|
} else {
|
209
|
-
socket.addAllowed("build")
|
248
|
+
socket.addAllowed("build")
|
210
249
|
}
|
211
250
|
|
212
251
|
if (
|
@@ -217,44 +256,54 @@ export default async function (
|
|
217
256
|
).length === 0 ||
|
218
257
|
config?.disabledActions?.includes("reset")
|
219
258
|
) {
|
220
|
-
socket.removeAllowed("reset")
|
259
|
+
socket.removeAllowed("reset")
|
221
260
|
} else if (!config?.disabledActions?.includes("reset")) {
|
222
|
-
socket.addAllowed("reset")
|
261
|
+
socket.addAllowed("reset")
|
223
262
|
}
|
224
263
|
|
225
|
-
socket.log("ready")
|
264
|
+
socket.log("ready")
|
226
265
|
|
227
|
-
res.json(exercise)
|
266
|
+
res.json(exercise)
|
228
267
|
})
|
229
|
-
)
|
268
|
+
)
|
230
269
|
|
231
270
|
app.get(
|
232
271
|
"/exercise/:slug/file/:fileName",
|
233
272
|
withHandler((req: express.Request, res: express.Response) => {
|
234
|
-
const exercise = configManager.getExercise(req.params.slug)
|
273
|
+
const exercise = configManager.getExercise(req.params.slug)
|
235
274
|
if (exercise && exercise.getFile) {
|
236
|
-
res.write(exercise.getFile(req.params.fileName))
|
237
|
-
res.end()
|
275
|
+
res.write(exercise.getFile(req.params.fileName))
|
276
|
+
res.end()
|
238
277
|
}
|
239
278
|
})
|
279
|
+
)
|
280
|
+
|
281
|
+
/*
|
282
|
+
app.post(
|
283
|
+
"/exercise/:slug/file/:fileName",
|
284
|
+
withHandler((req: express.Request, res: express.Response) => {
|
285
|
+
get tokens but also, add allowed action for 'generate'
|
286
|
+
use the sessionManager to keep compatibility with the cli login command.
|
287
|
+
})
|
240
288
|
);
|
289
|
+
*/
|
241
290
|
|
242
|
-
const textBodyParser = bodyParser.text()
|
291
|
+
const textBodyParser = bodyParser.text()
|
243
292
|
app.put(
|
244
293
|
"/exercise/:slug/file/:fileName",
|
245
294
|
textBodyParser,
|
246
295
|
withHandler((req: express.Request, res: express.Response) => {
|
247
|
-
const exercise = configManager.getExercise(req.params.slug)
|
296
|
+
const exercise = configManager.getExercise(req.params.slug)
|
248
297
|
if (exercise && exercise.saveFile) {
|
249
|
-
exercise.saveFile(req.params.fileName, req.body)
|
250
|
-
res.end()
|
298
|
+
exercise.saveFile(req.params.fileName, req.body)
|
299
|
+
res.end()
|
251
300
|
}
|
252
301
|
})
|
253
|
-
)
|
302
|
+
)
|
254
303
|
|
255
304
|
if (config?.outputPath) {
|
256
|
-
app.use("/preview", express.static(config.outputPath))
|
305
|
+
app.use("/preview", express.static(config.outputPath))
|
257
306
|
}
|
258
307
|
|
259
|
-
app.use("/", express.static(`${config?.dirPath}/_app`))
|
308
|
+
app.use("/", express.static(`${config?.dirPath}/_app`))
|
260
309
|
}
|
package/src/managers/session.ts
CHANGED
@@ -1,118 +1,147 @@
|
|
1
|
-
import Console from
|
2
|
-
import api from
|
3
|
-
|
4
|
-
import v from
|
5
|
-
import {ValidationError, InternalError} from
|
6
|
-
|
7
|
-
import * as fs from
|
8
|
-
import cli from
|
9
|
-
import * as storage from
|
10
|
-
|
11
|
-
import {IPayload, ISession, IStartProps} from
|
12
|
-
import {IConfigObj} from
|
13
|
-
|
14
|
-
const Session: ISession = {
|
15
|
-
sessionStarted: false,
|
16
|
-
token: null,
|
17
|
-
config: null,
|
18
|
-
currentCohort: null,
|
19
|
-
initialize: async function () {
|
20
|
-
if (!this.sessionStarted) {
|
21
|
-
if (!this.config) {
|
22
|
-
throw InternalError(
|
23
|
-
}
|
24
|
-
|
25
|
-
if (!fs.existsSync(this.config.dirPath)) {
|
26
|
-
fs.mkdirSync(this.config.dirPath)
|
27
|
-
}
|
28
|
-
|
29
|
-
await storage.init({dir: `${this.config.dirPath}/.session`})
|
30
|
-
this.sessionStarted = true
|
31
|
-
}
|
32
|
-
|
33
|
-
return true
|
34
|
-
},
|
35
|
-
|
36
|
-
await this.initialize()
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
},
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
}
|
88
|
-
|
89
|
-
const
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
if (
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
1
|
+
import Console from "../utils/console"
|
2
|
+
import api from "../utils/api"
|
3
|
+
|
4
|
+
import v from "validator"
|
5
|
+
import { ValidationError, InternalError } from "../utils/errors"
|
6
|
+
|
7
|
+
import * as fs from "fs"
|
8
|
+
import cli from "cli-ux"
|
9
|
+
import * as storage from "node-persist"
|
10
|
+
|
11
|
+
import { IPayload, ISession, IStartProps } from "../models/session"
|
12
|
+
import { IConfigObj } from "../models/config"
|
13
|
+
|
14
|
+
const Session: ISession = {
|
15
|
+
sessionStarted: false,
|
16
|
+
token: null,
|
17
|
+
config: null,
|
18
|
+
currentCohort: null,
|
19
|
+
initialize: async function () {
|
20
|
+
if (!this.sessionStarted) {
|
21
|
+
if (!this.config) {
|
22
|
+
throw InternalError("Configuration not found")
|
23
|
+
}
|
24
|
+
|
25
|
+
if (!fs.existsSync(this.config.dirPath)) {
|
26
|
+
fs.mkdirSync(this.config.dirPath)
|
27
|
+
}
|
28
|
+
|
29
|
+
await storage.init({ dir: `${this.config.dirPath}/.session` })
|
30
|
+
this.sessionStarted = true
|
31
|
+
}
|
32
|
+
|
33
|
+
return true
|
34
|
+
},
|
35
|
+
getOpenAIToken: async function () {
|
36
|
+
await this.initialize()
|
37
|
+
let token = null
|
38
|
+
try {
|
39
|
+
token = await storage.getItem("openai-token")
|
40
|
+
} catch {
|
41
|
+
Console.debug("Error retriving openai token")
|
42
|
+
}
|
43
|
+
|
44
|
+
return token
|
45
|
+
},
|
46
|
+
setOpenAIToken: async function (token: string) {
|
47
|
+
await this.initialize()
|
48
|
+
await storage.setItem("openai-token", token)
|
49
|
+
Console.debug("OpenAI token successfuly set")
|
50
|
+
return true
|
51
|
+
},
|
52
|
+
setPayload: async function (value: IPayload) {
|
53
|
+
await this.initialize()
|
54
|
+
await storage.setItem("bc-payload", { token: this.token, ...value })
|
55
|
+
Console.debug("Payload successfuly found and set for " + value.email)
|
56
|
+
return true
|
57
|
+
},
|
58
|
+
getPayload: async function () {
|
59
|
+
await this.initialize()
|
60
|
+
let payload = null
|
61
|
+
try {
|
62
|
+
payload = await storage.getItem("bc-payload")
|
63
|
+
} catch (error) {
|
64
|
+
// TODO: Remove it
|
65
|
+
console.log(error)
|
66
|
+
Console.debug("Error retriving session payload")
|
67
|
+
}
|
68
|
+
|
69
|
+
return payload
|
70
|
+
},
|
71
|
+
isActive: function () {
|
72
|
+
/* if (this.token) {
|
73
|
+
return true
|
74
|
+
} else {
|
75
|
+
return false
|
76
|
+
} */
|
77
|
+
return !!this.token
|
78
|
+
},
|
79
|
+
get: async function (configObj?: IConfigObj) {
|
80
|
+
if (configObj && configObj.config) {
|
81
|
+
this.config = configObj.config
|
82
|
+
}
|
83
|
+
|
84
|
+
await this.sync()
|
85
|
+
if (!this.isActive()) {
|
86
|
+
return null
|
87
|
+
}
|
88
|
+
|
89
|
+
const payload = await this.getPayload()
|
90
|
+
|
91
|
+
return {
|
92
|
+
payload,
|
93
|
+
token: this.token,
|
94
|
+
}
|
95
|
+
},
|
96
|
+
login: async function () {
|
97
|
+
const email = await cli.prompt("What is your email?")
|
98
|
+
if (!v.isEmail(email)) {
|
99
|
+
throw ValidationError("Invalid email")
|
100
|
+
}
|
101
|
+
|
102
|
+
const password = await cli.prompt("What is your password?", {
|
103
|
+
type: "hide",
|
104
|
+
})
|
105
|
+
|
106
|
+
const data = await api.login(email, password)
|
107
|
+
if (data) {
|
108
|
+
cli.log(data)
|
109
|
+
this.start({ token: data.token, payload: data })
|
110
|
+
}
|
111
|
+
},
|
112
|
+
loginWeb: async function (email, password) {
|
113
|
+
if (!v.isEmail(email)) {
|
114
|
+
throw ValidationError("Invalid email")
|
115
|
+
}
|
116
|
+
|
117
|
+
const data = await api.login(email, password)
|
118
|
+
if (data) {
|
119
|
+
this.start({ token: data.token, payload: data })
|
120
|
+
return data
|
121
|
+
}
|
122
|
+
},
|
123
|
+
sync: async function () {
|
124
|
+
const payload = await this.getPayload()
|
125
|
+
if (payload) {
|
126
|
+
this.token = payload.token
|
127
|
+
}
|
128
|
+
},
|
129
|
+
start: async function ({ token, payload = null }: IStartProps) {
|
130
|
+
if (!token) {
|
131
|
+
throw new Error("A token and email is needed to start a session")
|
132
|
+
}
|
133
|
+
|
134
|
+
this.token = token
|
135
|
+
|
136
|
+
if (payload && (await this.setPayload(payload))) {
|
137
|
+
Console.success(`Successfully logged in as ${payload.email}`)
|
138
|
+
}
|
139
|
+
},
|
140
|
+
destroy: async function () {
|
141
|
+
await storage.clear()
|
142
|
+
this.token = null
|
143
|
+
Console.success("You have logged out")
|
144
|
+
},
|
145
|
+
}
|
146
|
+
|
147
|
+
export default Session
|