@learnpack/learnpack 4.0.10 → 4.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. package/README.md +16 -20
  2. package/lib/commands/audit.d.ts +6 -6
  3. package/lib/commands/audit.js +327 -327
  4. package/lib/commands/clean.d.ts +8 -8
  5. package/lib/commands/clean.js +22 -22
  6. package/lib/commands/download.d.ts +13 -13
  7. package/lib/commands/download.js +52 -52
  8. package/lib/commands/init.d.ts +9 -9
  9. package/lib/commands/init.js +127 -127
  10. package/lib/commands/login.d.ts +14 -14
  11. package/lib/commands/login.js +34 -34
  12. package/lib/commands/logout.d.ts +14 -14
  13. package/lib/commands/logout.js +34 -34
  14. package/lib/commands/publish.d.ts +11 -14
  15. package/lib/commands/publish.js +160 -82
  16. package/lib/commands/start.d.ts +7 -7
  17. package/lib/commands/start.js +252 -250
  18. package/lib/commands/test.d.ts +6 -6
  19. package/lib/commands/test.js +62 -62
  20. package/lib/index.d.ts +1 -1
  21. package/lib/index.js +4 -4
  22. package/lib/managers/config/allowed_files.d.ts +5 -5
  23. package/lib/managers/config/allowed_files.js +30 -30
  24. package/lib/managers/config/defaults.d.ts +47 -48
  25. package/lib/managers/config/defaults.js +51 -51
  26. package/lib/managers/config/exercise.d.ts +36 -36
  27. package/lib/managers/config/exercise.js +243 -236
  28. package/lib/managers/config/index.d.ts +3 -3
  29. package/lib/managers/config/index.js +464 -459
  30. package/lib/managers/file.d.ts +14 -14
  31. package/lib/managers/file.js +190 -184
  32. package/lib/managers/gitpod.d.ts +3 -3
  33. package/lib/managers/gitpod.js +67 -67
  34. package/lib/managers/server/index.d.ts +5 -6
  35. package/lib/managers/server/index.js +58 -58
  36. package/lib/managers/server/routes.d.ts +4 -4
  37. package/lib/managers/server/routes.js +228 -220
  38. package/lib/managers/session.d.ts +3 -3
  39. package/lib/managers/session.js +125 -125
  40. package/lib/managers/socket.d.ts +3 -3
  41. package/lib/managers/socket.js +188 -186
  42. package/lib/managers/telemetry.d.ts +74 -74
  43. package/lib/managers/telemetry.js +215 -214
  44. package/lib/managers/test.js +84 -84
  45. package/lib/models/action.d.ts +2 -2
  46. package/lib/models/action.js +2 -2
  47. package/lib/models/audit.d.ts +15 -15
  48. package/lib/models/audit.js +2 -2
  49. package/lib/models/config-manager.d.ts +21 -21
  50. package/lib/models/config-manager.js +2 -2
  51. package/lib/models/config.d.ts +86 -86
  52. package/lib/models/config.js +2 -2
  53. package/lib/models/counter.d.ts +11 -11
  54. package/lib/models/counter.js +2 -2
  55. package/lib/models/errors.d.ts +15 -15
  56. package/lib/models/errors.js +2 -2
  57. package/lib/models/exercise-obj.d.ts +29 -30
  58. package/lib/models/exercise-obj.js +2 -2
  59. package/lib/models/file.d.ts +5 -5
  60. package/lib/models/file.js +2 -2
  61. package/lib/models/findings.d.ts +17 -17
  62. package/lib/models/findings.js +2 -2
  63. package/lib/models/flags.d.ts +10 -10
  64. package/lib/models/flags.js +2 -2
  65. package/lib/models/front-matter.d.ts +11 -11
  66. package/lib/models/front-matter.js +2 -2
  67. package/lib/models/gitpod-data.d.ts +16 -16
  68. package/lib/models/gitpod-data.js +2 -2
  69. package/lib/models/language.d.ts +4 -4
  70. package/lib/models/language.js +2 -2
  71. package/lib/models/package.d.ts +7 -7
  72. package/lib/models/package.js +2 -2
  73. package/lib/models/plugin-config.d.ts +16 -16
  74. package/lib/models/plugin-config.js +2 -2
  75. package/lib/models/session.d.ts +31 -31
  76. package/lib/models/session.js +2 -2
  77. package/lib/models/socket.d.ts +37 -37
  78. package/lib/models/socket.js +2 -2
  79. package/lib/models/status.d.ts +1 -1
  80. package/lib/models/status.js +2 -2
  81. package/lib/models/success-types.d.ts +1 -1
  82. package/lib/models/success-types.js +2 -2
  83. package/lib/plugin/command/compile.d.ts +6 -6
  84. package/lib/plugin/command/compile.js +18 -18
  85. package/lib/plugin/command/test.d.ts +6 -6
  86. package/lib/plugin/command/test.js +25 -25
  87. package/lib/plugin/index.d.ts +27 -27
  88. package/lib/plugin/index.js +7 -7
  89. package/lib/plugin/plugin.d.ts +8 -8
  90. package/lib/plugin/plugin.js +68 -68
  91. package/lib/plugin/utils.d.ts +16 -16
  92. package/lib/plugin/utils.js +58 -58
  93. package/lib/ui/download.d.ts +5 -5
  94. package/lib/ui/download.js +62 -61
  95. package/lib/utils/BaseCommand.d.ts +8 -8
  96. package/lib/utils/BaseCommand.js +41 -41
  97. package/lib/utils/SessionCommand.d.ts +10 -10
  98. package/lib/utils/SessionCommand.js +43 -43
  99. package/lib/utils/api.d.ts +14 -14
  100. package/lib/utils/api.js +255 -255
  101. package/lib/utils/audit.d.ts +16 -16
  102. package/lib/utils/audit.js +303 -303
  103. package/lib/utils/checkNotInstalled.d.ts +8 -8
  104. package/lib/utils/checkNotInstalled.js +185 -181
  105. package/lib/utils/console.d.ts +12 -12
  106. package/lib/utils/console.js +19 -19
  107. package/lib/utils/errors.d.ts +17 -17
  108. package/lib/utils/errors.js +107 -100
  109. package/lib/utils/exercisesQueue.d.ts +9 -9
  110. package/lib/utils/exercisesQueue.js +38 -38
  111. package/lib/utils/fileQueue.d.ts +43 -43
  112. package/lib/utils/fileQueue.js +169 -169
  113. package/lib/utils/misc.d.ts +1 -1
  114. package/lib/utils/misc.js +24 -23
  115. package/lib/utils/osOperations.d.ts +5 -5
  116. package/lib/utils/osOperations.js +72 -72
  117. package/lib/utils/validators.d.ts +5 -5
  118. package/lib/utils/validators.js +16 -17
  119. package/lib/utils/watcher.d.ts +2 -2
  120. package/lib/utils/watcher.js +25 -25
  121. package/oclif.manifest.json +1 -1
  122. package/package.json +6 -4
  123. package/src/commands/publish.ts +181 -107
  124. package/src/managers/config/index.ts +5 -0
  125. package/src/managers/server/routes.ts +10 -0
  126. package/src/managers/session.ts +145 -145
@@ -1,58 +1,58 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TEST_SERVER = void 0;
4
- const express = require("express");
5
- // eslint-disable-next-line
6
- const cors = require("cors");
7
- const console_1 = require("../../utils/console");
8
- const routes_1 = require("./routes");
9
- const cli_ux_1 = require("cli-ux");
10
- async function default_1(configObj, configManager, isTestingEnvironment = false) {
11
- const { config } = configObj;
12
- const app = express();
13
- let server;
14
- if (isTestingEnvironment) {
15
- if (exports.TEST_SERVER === undefined)
16
- exports.TEST_SERVER = require("http").Server(app);
17
- server = exports.TEST_SERVER;
18
- }
19
- else
20
- server = require("http").Server(app);
21
- app.use(cors());
22
- // app.use(function(req, res, next) {
23
- // res.header("Access-Control-Allow-Origin", "*")
24
- // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
25
- // res.header("Access-Control-Allow-Methods", "GET,PUT")
26
- // next()
27
- // })
28
- // add all needed endpoints
29
- await routes_1.default(app, configObj, configManager);
30
- server.listen(isTestingEnvironment ? 5000 : config === null || config === void 0 ? void 0 : config.port, function () {
31
- if (!isTestingEnvironment) {
32
- console_1.default.success(`Exercises are running 😃 Open your browser to start practicing!`);
33
- console_1.default.success(`\n Open the exercise on this link:`);
34
- console_1.default.log(` ${config === null || config === void 0 ? void 0 : config.publicUrl}`);
35
- if ((config === null || config === void 0 ? void 0 : config.editor.mode) === "preview")
36
- cli_ux_1.default.open(`${config.publicUrl}`);
37
- }
38
- });
39
- const sockets = new Set();
40
- server.on("connection", (socket) => {
41
- sockets.add(socket);
42
- server.once("close", () => {
43
- sockets.delete(socket);
44
- });
45
- });
46
- /**
47
- * Forcefully terminates HTTP server.
48
- */
49
- server.terminate = (callback) => {
50
- for (const socket of sockets) {
51
- socket.destroy();
52
- sockets.delete(socket);
53
- }
54
- server.close(callback);
55
- };
56
- return server;
57
- }
58
- exports.default = default_1;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEST_SERVER = void 0;
4
+ exports.default = default_1;
5
+ const express = require("express");
6
+ // eslint-disable-next-line
7
+ const cors = require("cors");
8
+ const console_1 = require("../../utils/console");
9
+ const routes_1 = require("./routes");
10
+ const cli_ux_1 = require("cli-ux");
11
+ async function default_1(configObj, configManager, isTestingEnvironment = false) {
12
+ const { config } = configObj;
13
+ const app = express();
14
+ let server;
15
+ if (isTestingEnvironment) {
16
+ if (exports.TEST_SERVER === undefined)
17
+ exports.TEST_SERVER = require("http").Server(app);
18
+ server = exports.TEST_SERVER;
19
+ }
20
+ else
21
+ server = require("http").Server(app);
22
+ app.use(cors());
23
+ // app.use(function(req, res, next) {
24
+ // res.header("Access-Control-Allow-Origin", "*")
25
+ // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
26
+ // res.header("Access-Control-Allow-Methods", "GET,PUT")
27
+ // next()
28
+ // })
29
+ // add all needed endpoints
30
+ await (0, routes_1.default)(app, configObj, configManager);
31
+ server.listen(isTestingEnvironment ? 5000 : config === null || config === void 0 ? void 0 : config.port, function () {
32
+ if (!isTestingEnvironment) {
33
+ console_1.default.success(`Exercises are running 😃 Open your browser to start practicing!`);
34
+ console_1.default.success(`\n Open the exercise on this link:`);
35
+ console_1.default.log(` ${config === null || config === void 0 ? void 0 : config.publicUrl}`);
36
+ if ((config === null || config === void 0 ? void 0 : config.editor.mode) === "preview")
37
+ cli_ux_1.default.open(`${config.publicUrl}`);
38
+ }
39
+ });
40
+ const sockets = new Set();
41
+ server.on("connection", (socket) => {
42
+ sockets.add(socket);
43
+ server.once("close", () => {
44
+ sockets.delete(socket);
45
+ });
46
+ });
47
+ /**
48
+ * Forcefully terminates HTTP server.
49
+ */
50
+ server.terminate = (callback) => {
51
+ for (const socket of sockets) {
52
+ socket.destroy();
53
+ sockets.delete(socket);
54
+ }
55
+ server.close(callback);
56
+ };
57
+ return server;
58
+ }
@@ -1,4 +1,4 @@
1
- import * as express from "express";
2
- import { IConfigObj } from "../../models/config";
3
- import { IConfigManager } from "../../models/config-manager";
4
- export default function (app: express.Application, configObject: IConfigObj, configManager: IConfigManager): Promise<void>;
1
+ import * as express from "express";
2
+ import { IConfigObj } from "../../models/config";
3
+ import { IConfigManager } from "../../models/config-manager";
4
+ export default function (app: express.Application, configObject: IConfigObj, configManager: IConfigManager): Promise<void>;
@@ -1,220 +1,228 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const console_1 = require("../../utils/console");
4
- const express = require("express");
5
- const fs = require("fs");
6
- const bodyParser = require("body-parser");
7
- const socket_1 = require("../socket");
8
- const fileQueue_1 = require("../../utils/fileQueue");
9
- // import gitpod from '../gitpod'
10
- const exercise_1 = require("../config/exercise");
11
- const session_1 = require("../../managers/session");
12
- const telemetry_1 = require("../telemetry");
13
- const osOperations_1 = require("../../utils/osOperations");
14
- const withHandler = (func) => (req, res) => {
15
- try {
16
- func(req, res);
17
- }
18
- catch (error) {
19
- console_1.default.debug(error);
20
- const _err = {
21
- message: error.message || "There has been an error",
22
- status: error.status || 500,
23
- type: error.type || null,
24
- };
25
- console_1.default.error(_err.message);
26
- // send rep to the server
27
- res.status(_err.status);
28
- res.json(_err);
29
- }
30
- };
31
- async function default_1(app, configObject, configManager) {
32
- const { config, exercises } = configObject;
33
- const session = await session_1.default.get(configManager === null || configManager === void 0 ? void 0 : configManager.get());
34
- const dispatcher = fileQueue_1.default.dispatcher({
35
- create: true,
36
- path: `${config === null || config === void 0 ? void 0 : config.dirPath}/vscode_queue.json`,
37
- });
38
- app.get("/config", withHandler((_, res) => {
39
- const confObject = configManager.get();
40
- res.json(confObject);
41
- }));
42
- // Added this line to parse the json body
43
- const jsonBodyParser = bodyParser.json();
44
- // Trying to log in from frontend
45
- app.post("/login", jsonBodyParser, withHandler(async (req, res) => {
46
- const email = req.body.email;
47
- const password = req.body.password;
48
- session_1.default.destroy();
49
- const payload = await session_1.default.loginWeb(email, password);
50
- res.json(payload);
51
- }));
52
- app.post("/set-rigobot-token", jsonBodyParser, withHandler(async (req, res) => {
53
- const token = req.body.token;
54
- // Ensure token is provided in the request body
55
- if (!token) {
56
- return res.status(400).json({ error: "Token is required" });
57
- }
58
- try {
59
- const tokenSaved = await session_1.default.setRigoToken(token);
60
- // Check if the token was saved successfully
61
- if (tokenSaved) {
62
- res.json({ status: "ok" });
63
- }
64
- else {
65
- res.status(500).json({ error: "Failed to save the token" });
66
- }
67
- }
68
- catch (_a) {
69
- // Handle any unexpected errors during the process
70
- res.status(500).json({ error: "Internal server error" });
71
- }
72
- }));
73
- app.get("/check/rigo/status", withHandler(async (_, res) => {
74
- const payload = await session_1.default.getPayload();
75
- if (payload && payload.rigobot && payload.rigobot.key) {
76
- res.json({ rigoToken: payload.rigobot.key, payload: payload });
77
- }
78
- else {
79
- res
80
- .status(400)
81
- .json({ details: `Rigobot token not found, please log in first!` });
82
- }
83
- }));
84
- // symbolic link to maintain path compatiblity
85
- const fetchStaticAsset = withHandler((req, res) => {
86
- const filePath = `${config === null || config === void 0 ? void 0 : config.dirPath}/assets/${req.params.filePath}`;
87
- if (!fs.existsSync(filePath))
88
- throw new Error("File not found: " + filePath);
89
- const content = fs.readFileSync(filePath);
90
- res.write(content);
91
- res.end();
92
- });
93
- app.get(`${(config === null || config === void 0 ? void 0 : config.dirPath.indexOf("./")) === 0 ?
94
- config.dirPath.slice(1) : config === null || config === void 0 ? void 0 : config.dirPath}/assets/:filePath`, fetchStaticAsset);
95
- app.get("/assets/:filePath", fetchStaticAsset);
96
- app.get("/exercise", withHandler((_, res) => {
97
- res.json(exercises);
98
- }));
99
- app.get("/exercise/:slug/readme", withHandler(({ params: { slug }, query: { lang } }, res) => {
100
- const exercise = configManager.getExercise(slug);
101
- if (exercise && exercise.getReadme) {
102
- const readme = exercise.getReadme(lang || null);
103
- res.json(readme);
104
- }
105
- else {
106
- res.status(400);
107
- }
108
- }));
109
- app.get("/exercise/:slug/report", withHandler(({ params: { slug } }, res) => {
110
- const exercise = configManager.getExercise(slug);
111
- if (exercise && exercise.getTestReport) {
112
- const report = exercise.getTestReport();
113
- res.json(JSON.stringify(report));
114
- }
115
- }));
116
- app.get("/exercise/:slug", withHandler((req, res) => {
117
- var _a, _b, _c, _d, _e;
118
- // no need to re-start exercise if it's already started
119
- if (configObject.currentExercise &&
120
- req.params.slug === configObject.currentExercise) {
121
- const exercise = configManager.getExercise(req.params.slug);
122
- res.json(exercise);
123
- if (exercise.position) {
124
- telemetry_1.default.registerStepEvent(exercise.position, "open_step", {});
125
- }
126
- return;
127
- }
128
- const exercise = configManager.startExercise(req.params.slug);
129
- if (exercise.position) {
130
- telemetry_1.default.registerStepEvent(exercise.position, "open_step", {});
131
- }
132
- if (((_a = configObject.config) === null || _a === void 0 ? void 0 : _a.editor.agent) === "os") {
133
- osOperations_1.eventManager.enqueue(dispatcher.events.START_EXERCISE, exercise);
134
- }
135
- else {
136
- dispatcher.enqueue(dispatcher.events.START_EXERCISE, req.params.slug);
137
- }
138
- const entries = new Set(Object.keys(config === null || config === void 0 ? void 0 : config.entries).map(lang => config === null || config === void 0 ? void 0 : config.entries[lang]));
139
- // if we are in incremental grading, the entry file can by dinamically detected
140
- // based on the changes the student is making during the exercise
141
- if ((config === null || config === void 0 ? void 0 : config.grading) === "incremental") {
142
- const scanedFiles = fs.readdirSync("./");
143
- // update the file hierarchy with updates
144
- exercise.files = [
145
- ...exercise.files.filter(f => f.name.includes("test.")),
146
- ...exercise_1.filterFiles(scanedFiles),
147
- ];
148
- console_1.default.debug(`Exercise updated files: `, exercise.files);
149
- }
150
- const detected = exercise_1.detect(configObject, exercise.files
151
- .filter(fileName => entries.has(fileName.name))
152
- .map(f => f.name || f));
153
- // if a new language for the testing engine is detected, we replace it
154
- // if not we leave it as it was before
155
- if ((config === null || config === void 0 ? void 0 : config.language) && !["", "auto"].includes(config === null || config === void 0 ? void 0 : config.language)) {
156
- console_1.default.debug(`Exercise language ignored, instead imported from configuration ${config === null || config === void 0 ? void 0 : config.language}`);
157
- exercise.language = detected === null || detected === void 0 ? void 0 : detected.language;
158
- }
159
- else if ((detected === null || detected === void 0 ? void 0 : detected.language) &&
160
- (!(config === null || config === void 0 ? void 0 : config.language) || (config === null || config === void 0 ? void 0 : config.language) === "auto")) {
161
- console_1.default.debug(`Switching to ${detected.language} engine in this exercise`);
162
- exercise.language = detected.language;
163
- }
164
- // WARNING: has to be the FULL PATH to the entry path
165
- // We need to detect entry in both gradings: Incremental and Isolate
166
- exercise.entry = detected === null || detected === void 0 ? void 0 : detected.entry;
167
- console_1.default.debug(`Exercise detected entry: ${detected === null || detected === void 0 ? void 0 : detected.entry} and language ${exercise.language}`);
168
- // exercises.graded and exercises.disableGrading deprecated.
169
- if (!exercise.graded || (config === null || config === void 0 ? void 0 : config.disableGrading) || ((_b = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _b === void 0 ? void 0 : _b.includes("test"))) {
170
- socket_1.default.removeAllowed("test");
171
- }
172
- else {
173
- socket_1.default.addAllowed("test");
174
- }
175
- if (!exercise.entry || ((_c = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _c === void 0 ? void 0 : _c.includes("build"))) {
176
- socket_1.default.removeAllowed("build");
177
- }
178
- else {
179
- socket_1.default.addAllowed("build");
180
- }
181
- if (exercise.files.filter((f) => !f.name.toLowerCase().includes("readme.") &&
182
- !f.name.toLowerCase().includes("test.")).length === 0 || ((_d = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _d === void 0 ? void 0 : _d.includes("reset"))) {
183
- socket_1.default.removeAllowed("reset");
184
- }
185
- else if (!((_e = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _e === void 0 ? void 0 : _e.includes("reset"))) {
186
- socket_1.default.addAllowed("reset");
187
- }
188
- socket_1.default.log("ready");
189
- res.json(exercise);
190
- }));
191
- app.get("/exercise/:slug/file/:fileName", withHandler((req, res) => {
192
- const exercise = configManager.getExercise(req.params.slug);
193
- if (exercise && exercise.getFile) {
194
- res.write(exercise.getFile(req.params.fileName));
195
- res.end();
196
- }
197
- }));
198
- /*
199
- app.post(
200
- "/exercise/:slug/file/:fileName",
201
- withHandler((req: express.Request, res: express.Response) => {
202
- get tokens but also, add allowed action for 'generate'
203
- use the sessionManager to keep compatibility with the cli login command.
204
- })
205
- );
206
- */
207
- const textBodyParser = bodyParser.text();
208
- app.put("/exercise/:slug/file/:fileName", textBodyParser, withHandler((req, res) => {
209
- const exercise = configManager.getExercise(req.params.slug);
210
- if (exercise && exercise.saveFile) {
211
- exercise.saveFile(req.params.fileName, req.body);
212
- res.end();
213
- }
214
- }));
215
- if (config === null || config === void 0 ? void 0 : config.outputPath) {
216
- app.use("/preview", express.static(config.outputPath));
217
- }
218
- app.use("/", express.static(`${config === null || config === void 0 ? void 0 : config.dirPath}/_app`));
219
- }
220
- exports.default = default_1;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const console_1 = require("../../utils/console");
5
+ const express = require("express");
6
+ const fs = require("fs");
7
+ const bodyParser = require("body-parser");
8
+ const socket_1 = require("../socket");
9
+ const fileQueue_1 = require("../../utils/fileQueue");
10
+ // import gitpod from '../gitpod'
11
+ const exercise_1 = require("../config/exercise");
12
+ const session_1 = require("../../managers/session");
13
+ const telemetry_1 = require("../telemetry");
14
+ const osOperations_1 = require("../../utils/osOperations");
15
+ const withHandler = (func) => (req, res) => {
16
+ try {
17
+ func(req, res);
18
+ }
19
+ catch (error) {
20
+ console_1.default.debug(error);
21
+ const _err = {
22
+ message: error.message || "There has been an error",
23
+ status: error.status || 500,
24
+ type: error.type || null,
25
+ };
26
+ console_1.default.error(_err.message);
27
+ // send rep to the server
28
+ res.status(_err.status);
29
+ res.json(_err);
30
+ }
31
+ };
32
+ async function default_1(app, configObject, configManager) {
33
+ const { config, exercises } = configObject;
34
+ const session = await session_1.default.get(configManager === null || configManager === void 0 ? void 0 : configManager.get());
35
+ const dispatcher = fileQueue_1.default.dispatcher({
36
+ create: true,
37
+ path: `${config === null || config === void 0 ? void 0 : config.dirPath}/vscode_queue.json`,
38
+ });
39
+ app.get("/config", withHandler((_, res) => {
40
+ const confObject = configManager.get();
41
+ res.json(confObject);
42
+ }));
43
+ // Added this line to parse the json body
44
+ const jsonBodyParser = bodyParser.json();
45
+ // Trying to log in from frontend
46
+ app.post("/login", jsonBodyParser, withHandler(async (req, res) => {
47
+ const email = req.body.email;
48
+ const password = req.body.password;
49
+ session_1.default.destroy();
50
+ const payload = await session_1.default.loginWeb(email, password);
51
+ res.json(payload);
52
+ }));
53
+ app.post("/logout", jsonBodyParser, withHandler(async (req, res) => {
54
+ session_1.default.destroy();
55
+ res.json({ message: "You've logged out from Breathecode and Rigobot" });
56
+ }));
57
+ app.post("/set-rigobot-token", jsonBodyParser, withHandler(async (req, res) => {
58
+ const token = req.body.token;
59
+ // Ensure token is provided in the request body
60
+ if (!token) {
61
+ return res.status(400).json({ error: "Token is required" });
62
+ }
63
+ try {
64
+ const tokenSaved = await session_1.default.setRigoToken(token);
65
+ // Check if the token was saved successfully
66
+ if (tokenSaved) {
67
+ res.json({ status: "ok" });
68
+ }
69
+ else {
70
+ res.status(500).json({ error: "Failed to save the token" });
71
+ }
72
+ }
73
+ catch (_a) {
74
+ // Handle any unexpected errors during the process
75
+ res.status(500).json({ error: "Internal server error" });
76
+ }
77
+ }));
78
+ app.get("/check/rigo/status", withHandler(async (_, res) => {
79
+ const payload = await session_1.default.getPayload();
80
+ if (payload && payload.rigobot && payload.rigobot.key) {
81
+ res.json({ rigoToken: payload.rigobot.key, payload: payload });
82
+ }
83
+ else {
84
+ res
85
+ .status(400)
86
+ .json({ details: `Rigobot token not found, please log in first!` });
87
+ }
88
+ }));
89
+ // symbolic link to maintain path compatiblity
90
+ const fetchStaticAsset = withHandler((req, res) => {
91
+ const filePath = `${config === null || config === void 0 ? void 0 : config.dirPath}/assets/${req.params.filePath}`;
92
+ if (!fs.existsSync(filePath))
93
+ throw new Error("File not found: " + filePath);
94
+ const content = fs.readFileSync(filePath);
95
+ res.write(content);
96
+ res.end();
97
+ });
98
+ app.get(`${(config === null || config === void 0 ? void 0 : config.dirPath.indexOf("./")) === 0 ?
99
+ config.dirPath.slice(1) :
100
+ config === null || config === void 0 ? void 0 : config.dirPath}/assets/:filePath`, fetchStaticAsset);
101
+ app.get("/assets/:filePath", fetchStaticAsset);
102
+ app.get("/exercise", withHandler((_, res) => {
103
+ res.json(exercises);
104
+ }));
105
+ app.get("/exercise/:slug/readme", withHandler(({ params: { slug }, query: { lang } }, res) => {
106
+ const exercise = configManager.getExercise(slug);
107
+ if (exercise && exercise.getReadme) {
108
+ const readme = exercise.getReadme(lang || null);
109
+ res.json(readme);
110
+ }
111
+ else {
112
+ res.status(400);
113
+ }
114
+ }));
115
+ app.get("/exercise/:slug/report", withHandler(({ params: { slug } }, res) => {
116
+ const exercise = configManager.getExercise(slug);
117
+ if (exercise && exercise.getTestReport) {
118
+ const report = exercise.getTestReport();
119
+ res.json(JSON.stringify(report));
120
+ }
121
+ }));
122
+ app.get("/exercise/:slug", withHandler((req, res) => {
123
+ var _a, _b, _c, _d, _e;
124
+ // no need to re-start exercise if it's already started
125
+ if (configObject.currentExercise &&
126
+ req.params.slug === configObject.currentExercise) {
127
+ const exercise = configManager.getExercise(req.params.slug);
128
+ res.json(exercise);
129
+ if (exercise.position) {
130
+ telemetry_1.default.registerStepEvent(exercise.position, "open_step", {});
131
+ }
132
+ return;
133
+ }
134
+ const exercise = configManager.startExercise(req.params.slug);
135
+ if (exercise.position) {
136
+ telemetry_1.default.registerStepEvent(exercise.position, "open_step", {});
137
+ }
138
+ if (((_a = configObject.config) === null || _a === void 0 ? void 0 : _a.editor.agent) === "os") {
139
+ osOperations_1.eventManager.enqueue(dispatcher.events.START_EXERCISE, exercise);
140
+ }
141
+ else {
142
+ dispatcher.enqueue(dispatcher.events.START_EXERCISE, req.params.slug);
143
+ }
144
+ const entries = new Set(Object.keys(config === null || config === void 0 ? void 0 : config.entries).map(lang => config === null || config === void 0 ? void 0 : config.entries[lang]));
145
+ // if we are in incremental grading, the entry file can by dinamically detected
146
+ // based on the changes the student is making during the exercise
147
+ if ((config === null || config === void 0 ? void 0 : config.grading) === "incremental") {
148
+ const scanedFiles = fs.readdirSync("./");
149
+ // update the file hierarchy with updates
150
+ exercise.files = [
151
+ ...exercise.files.filter(f => f.name.includes("test.")),
152
+ ...(0, exercise_1.filterFiles)(scanedFiles),
153
+ ];
154
+ console_1.default.debug(`Exercise updated files: `, exercise.files);
155
+ }
156
+ const detected = (0, exercise_1.detect)(configObject, exercise.files
157
+ .filter(fileName => entries.has(fileName.name))
158
+ .map(f => f.name || f));
159
+ // if a new language for the testing engine is detected, we replace it
160
+ // if not we leave it as it was before
161
+ if ((config === null || config === void 0 ? void 0 : config.language) && !["", "auto"].includes(config === null || config === void 0 ? void 0 : config.language)) {
162
+ console_1.default.debug(`Exercise language ignored, instead imported from configuration ${config === null || config === void 0 ? void 0 : config.language}`);
163
+ exercise.language = detected === null || detected === void 0 ? void 0 : detected.language;
164
+ }
165
+ else if ((detected === null || detected === void 0 ? void 0 : detected.language) &&
166
+ (!(config === null || config === void 0 ? void 0 : config.language) || (config === null || config === void 0 ? void 0 : config.language) === "auto")) {
167
+ console_1.default.debug(`Switching to ${detected.language} engine in this exercise`);
168
+ exercise.language = detected.language;
169
+ }
170
+ // WARNING: has to be the FULL PATH to the entry path
171
+ // We need to detect entry in both gradings: Incremental and Isolate
172
+ exercise.entry = detected === null || detected === void 0 ? void 0 : detected.entry;
173
+ console_1.default.debug(`Exercise detected entry: ${detected === null || detected === void 0 ? void 0 : detected.entry} and language ${exercise.language}`);
174
+ // exercises.graded and exercises.disableGrading deprecated.
175
+ if (!exercise.graded ||
176
+ (config === null || config === void 0 ? void 0 : config.disableGrading) ||
177
+ ((_b = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _b === void 0 ? void 0 : _b.includes("test"))) {
178
+ socket_1.default.removeAllowed("test");
179
+ }
180
+ else {
181
+ socket_1.default.addAllowed("test");
182
+ }
183
+ if (!exercise.entry || ((_c = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _c === void 0 ? void 0 : _c.includes("build"))) {
184
+ socket_1.default.removeAllowed("build");
185
+ }
186
+ else {
187
+ socket_1.default.addAllowed("build");
188
+ }
189
+ if (exercise.files.filter((f) => !f.name.toLowerCase().includes("readme.") &&
190
+ !f.name.toLowerCase().includes("test.")).length === 0 ||
191
+ ((_d = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _d === void 0 ? void 0 : _d.includes("reset"))) {
192
+ socket_1.default.removeAllowed("reset");
193
+ }
194
+ else if (!((_e = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _e === void 0 ? void 0 : _e.includes("reset"))) {
195
+ socket_1.default.addAllowed("reset");
196
+ }
197
+ socket_1.default.log("ready");
198
+ res.json(exercise);
199
+ }));
200
+ app.get("/exercise/:slug/file/:fileName", withHandler((req, res) => {
201
+ const exercise = configManager.getExercise(req.params.slug);
202
+ if (exercise && exercise.getFile) {
203
+ res.write(exercise.getFile(req.params.fileName));
204
+ res.end();
205
+ }
206
+ }));
207
+ /*
208
+ app.post(
209
+ "/exercise/:slug/file/:fileName",
210
+ withHandler((req: express.Request, res: express.Response) => {
211
+ get tokens but also, add allowed action for 'generate'
212
+ use the sessionManager to keep compatibility with the cli login command.
213
+ })
214
+ );
215
+ */
216
+ const textBodyParser = bodyParser.text();
217
+ app.put("/exercise/:slug/file/:fileName", textBodyParser, withHandler((req, res) => {
218
+ const exercise = configManager.getExercise(req.params.slug);
219
+ if (exercise && exercise.saveFile) {
220
+ exercise.saveFile(req.params.fileName, req.body);
221
+ res.end();
222
+ }
223
+ }));
224
+ if (config === null || config === void 0 ? void 0 : config.outputPath) {
225
+ app.use("/preview", express.static(config.outputPath));
226
+ }
227
+ app.use("/", express.static(`${config === null || config === void 0 ? void 0 : config.dirPath}/_app`));
228
+ }
@@ -1,3 +1,3 @@
1
- import { ISession } from "../models/session";
2
- declare const Session: ISession;
3
- export default Session;
1
+ import { ISession } from "../models/session";
2
+ declare const Session: ISession;
3
+ export default Session;