@learnpack/learnpack 2.1.26 → 2.1.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. package/README.md +10 -10
  2. package/lib/commands/start.js +15 -4
  3. package/lib/managers/file.d.ts +1 -0
  4. package/lib/managers/file.js +8 -1
  5. package/lib/managers/server/routes.js +48 -14
  6. package/lib/managers/session.d.ts +1 -1
  7. package/lib/managers/session.js +39 -12
  8. package/lib/managers/socket.d.ts +1 -1
  9. package/lib/managers/socket.js +57 -43
  10. package/lib/models/action.d.ts +1 -1
  11. package/lib/models/config.d.ts +1 -1
  12. package/lib/models/exercise-obj.d.ts +3 -0
  13. package/lib/models/session.d.ts +4 -1
  14. package/lib/models/socket.d.ts +7 -6
  15. package/lib/models/status.d.ts +1 -1
  16. package/lib/utils/api.d.ts +2 -0
  17. package/lib/utils/api.js +51 -6
  18. package/oclif.manifest.json +1 -1
  19. package/package.json +3 -1
  20. package/src/commands/audit.ts +113 -113
  21. package/src/commands/clean.ts +10 -10
  22. package/src/commands/download.ts +18 -18
  23. package/src/commands/init.ts +39 -39
  24. package/src/commands/login.ts +13 -13
  25. package/src/commands/logout.ts +9 -9
  26. package/src/commands/publish.ts +25 -25
  27. package/src/commands/start.ts +101 -75
  28. package/src/commands/test.ts +34 -34
  29. package/src/managers/config/allowed_files.ts +2 -2
  30. package/src/managers/config/defaults.ts +2 -2
  31. package/src/managers/config/exercise.ts +79 -79
  32. package/src/managers/config/index.ts +145 -145
  33. package/src/managers/file.ts +74 -65
  34. package/src/managers/server/index.ts +32 -31
  35. package/src/managers/server/routes.ts +139 -90
  36. package/src/managers/session.ts +53 -24
  37. package/src/managers/socket.ts +92 -79
  38. package/src/models/action.ts +8 -1
  39. package/src/models/config-manager.ts +2 -2
  40. package/src/models/config.ts +7 -2
  41. package/src/models/exercise-obj.ts +6 -3
  42. package/src/models/plugin-config.ts +2 -2
  43. package/src/models/session.ts +5 -2
  44. package/src/models/socket.ts +12 -6
  45. package/src/models/status.ts +15 -14
  46. package/src/plugin/command/compile.ts +10 -10
  47. package/src/plugin/command/test.ts +14 -14
  48. package/src/plugin/index.ts +5 -5
  49. package/src/plugin/plugin.ts +26 -26
  50. package/src/plugin/utils.ts +23 -23
  51. package/src/utils/BaseCommand.ts +16 -16
  52. package/src/utils/api.ts +143 -91
  53. package/src/utils/audit.ts +93 -96
  54. package/src/utils/exercisesQueue.ts +15 -15
  55. package/src/utils/fileQueue.ts +85 -85
  56. package/src/utils/watcher.ts +14 -14
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @learnpack/learnpack
21
21
  $ learnpack COMMAND
22
22
  running command...
23
23
  $ learnpack (-v|--version|version)
24
- @learnpack/learnpack/2.1.26 darwin-arm64 node-v16.20.0
24
+ @learnpack/learnpack/2.1.28 darwin-arm64 node-v16.20.0
25
25
  $ learnpack --help [COMMAND]
26
26
  USAGE
27
27
  $ learnpack COMMAND
@@ -74,7 +74,7 @@ DESCRIPTION
74
74
  12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
75
75
  ```
76
76
 
77
- _See code: [src/commands/audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/audit.ts)_
77
+ _See code: [src/commands/audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/audit.ts)_
78
78
 
79
79
  ## `learnpack clean`
80
80
 
@@ -89,7 +89,7 @@ DESCRIPTION
89
89
  Extra documentation goes here
90
90
  ```
91
91
 
92
- _See code: [src/commands/clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/clean.ts)_
92
+ _See code: [src/commands/clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/clean.ts)_
93
93
 
94
94
  ## `learnpack download [PACKAGE]`
95
95
 
@@ -107,7 +107,7 @@ DESCRIPTION
107
107
  Extra documentation goes here
108
108
  ```
109
109
 
110
- _See code: [src/commands/download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/download.ts)_
110
+ _See code: [src/commands/download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/download.ts)_
111
111
 
112
112
  ## `learnpack help [COMMAND]`
113
113
 
@@ -138,7 +138,7 @@ OPTIONS
138
138
  -h, --grading show CLI help
139
139
  ```
140
140
 
141
- _See code: [src/commands/init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/init.ts)_
141
+ _See code: [src/commands/init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/init.ts)_
142
142
 
143
143
  ## `learnpack login [PACKAGE]`
144
144
 
@@ -156,7 +156,7 @@ DESCRIPTION
156
156
  Extra documentation goes here
157
157
  ```
158
158
 
159
- _See code: [src/commands/login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/login.ts)_
159
+ _See code: [src/commands/login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/login.ts)_
160
160
 
161
161
  ## `learnpack logout [PACKAGE]`
162
162
 
@@ -174,7 +174,7 @@ DESCRIPTION
174
174
  Extra documentation goes here
175
175
  ```
176
176
 
177
- _See code: [src/commands/logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/logout.ts)_
177
+ _See code: [src/commands/logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/logout.ts)_
178
178
 
179
179
  ## `learnpack plugins`
180
180
 
@@ -309,7 +309,7 @@ DESCRIPTION
309
309
  Extra documentation goes here
310
310
  ```
311
311
 
312
- _See code: [src/commands/publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/publish.ts)_
312
+ _See code: [src/commands/publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/publish.ts)_
313
313
 
314
314
  ## `learnpack start`
315
315
 
@@ -330,7 +330,7 @@ OPTIONS
330
330
  -w, --watch Watch for file changes
331
331
  ```
332
332
 
333
- _See code: [src/commands/start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/start.ts)_
333
+ _See code: [src/commands/start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/start.ts)_
334
334
 
335
335
  ## `learnpack test [EXERCISESLUG]`
336
336
 
@@ -344,5 +344,5 @@ ARGUMENTS
344
344
  EXERCISESLUG The name of the exercise to test
345
345
  ```
346
346
 
347
- _See code: [src/commands/test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.26/src/commands/test.ts)_
347
+ _See code: [src/commands/test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.28/src/commands/test.ts)_
348
348
  <!-- commandsstop -->
@@ -27,10 +27,13 @@ class StartCommand extends SessionCommand_1.default {
27
27
  (_b = this.configManager) === null || _b === void 0 ? void 0 : _b.buildIndex();
28
28
  console_1.default.debug(`Grading: ${config === null || config === void 0 ? void 0 : config.grading} ${((_c = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _c === void 0 ? void 0 : _c.includes("test")) ? "(disabled)" : ""}, editor: ${config === null || config === void 0 ? void 0 : config.editor.mode} ${config === null || config === void 0 ? void 0 : config.editor.version}, for ${Array.isArray(configObject === null || configObject === void 0 ? void 0 : configObject.exercises) ? configObject === null || configObject === void 0 ? void 0 : configObject.exercises.length :
29
29
  0} exercises found`);
30
- // download app and decompress
31
- await file_1.downloadEditor(config === null || config === void 0 ? void 0 : config.editor.version, `${config === null || config === void 0 ? void 0 : config.dirPath}/app.tar.gz`);
32
- console_1.default.info("Decompressing LearnPack UI, this may take a minute...");
33
- await file_1.decompress(`${config === null || config === void 0 ? void 0 : config.dirPath}/app.tar.gz`, `${config === null || config === void 0 ? void 0 : config.dirPath}/_app/`);
30
+ const appAlreadyExists = file_1.checkIfDirectoryExists(`${config === null || config === void 0 ? void 0 : config.dirPath}/_app`);
31
+ if (!appAlreadyExists) {
32
+ // download app and decompress
33
+ await file_1.downloadEditor(config === null || config === void 0 ? void 0 : config.editor.version, `${config === null || config === void 0 ? void 0 : config.dirPath}/app.tar.gz`);
34
+ console_1.default.info("Decompressing LearnPack UI, this may take a minute...");
35
+ await file_1.decompress(`${config === null || config === void 0 ? void 0 : config.dirPath}/app.tar.gz`, `${config === null || config === void 0 ? void 0 : config.dirPath}/_app/`);
36
+ }
34
37
  // listen to socket commands
35
38
  if (config && this.configManager) {
36
39
  const server = await server_1.default(configObject, this.configManager, process.env.NODE_ENV === "test");
@@ -41,13 +44,16 @@ class StartCommand extends SessionCommand_1.default {
41
44
  socket_1.default.start(config, server, false);
42
45
  socket_1.default.on("open", (data) => {
43
46
  console_1.default.debug("Opening these files: ", data);
47
+ console.log("Opening files", data);
44
48
  const files = misc_1.prioritizeHTMLFile(data.files);
49
+ // console.log("files",files);
45
50
  dispatcher.enqueue(dispatcher.events.OPEN_FILES, files);
46
51
  socket_1.default.ready("Ready to compile...");
47
52
  });
48
53
  socket_1.default.on("open_window", (data) => {
49
54
  console_1.default.debug("Opening window: ", data);
50
55
  dispatcher.enqueue(dispatcher.events.OPEN_WINDOW, data);
56
+ console.log(data);
51
57
  socket_1.default.ready("Ready to compile...");
52
58
  });
53
59
  socket_1.default.on("reset", (exercise) => {
@@ -89,9 +95,13 @@ class StartCommand extends SessionCommand_1.default {
89
95
  exercise,
90
96
  });
91
97
  });
98
+ socket_1.default.on("generate", async (data) => {
99
+ console.log("data", data);
100
+ });
92
101
  socket_1.default.on("test", async (data) => {
93
102
  var _a, _b;
94
103
  const exercise = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.getExercise(data.exerciseSlug);
104
+ console.log("data", data);
95
105
  if (!(exercise === null || exercise === void 0 ? void 0 : exercise.language)) {
96
106
  socket_1.default.error("compiler-error", "Impossible to detect engine language for testing for " +
97
107
  data.exerciseSlug +
@@ -103,6 +113,7 @@ class StartCommand extends SessionCommand_1.default {
103
113
  return true;
104
114
  }
105
115
  socket_1.default.log("testing", "Testing your exercise using the " + exercise.language + " engine.");
116
+ console.log("About to call runHook");
106
117
  await this.config.runHook("action", {
107
118
  action: "test",
108
119
  socket: socket_1.default,
@@ -3,6 +3,7 @@ export declare const downloadEditor: (version: string | undefined, destination:
3
3
  export declare const download: (url: string, dest: string) => Promise<unknown>;
4
4
  export declare const clone: (repository?: string, folder?: string) => Promise<unknown>;
5
5
  export declare const rmSync: (path: string) => void;
6
+ export declare const checkIfDirectoryExists: (path: string) => boolean;
6
7
  declare const _default: {
7
8
  download: (url: string, dest: string) => Promise<unknown>;
8
9
  decompress: (sourcePath: string, destinationPath: string) => Promise<unknown>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rmSync = exports.clone = exports.download = exports.downloadEditor = exports.decompress = void 0;
3
+ exports.checkIfDirectoryExists = exports.rmSync = exports.clone = exports.download = exports.downloadEditor = exports.decompress = void 0;
4
4
  const fs = require("fs");
5
5
  const p = require("path");
6
6
  const shell = require("shelljs");
@@ -131,4 +131,11 @@ exports.rmSync = function (path) {
131
131
  fs.rmdirSync(path);
132
132
  }
133
133
  };
134
+ exports.checkIfDirectoryExists = (path) => {
135
+ const fs = require("fs");
136
+ if (fs.existsSync(path)) {
137
+ return true;
138
+ }
139
+ return false;
140
+ };
134
141
  exports.default = { download: exports.download, decompress: exports.decompress, downloadEditor: exports.downloadEditor, clone: exports.clone, rmSync: exports.rmSync };
@@ -8,6 +8,7 @@ const socket_1 = require("../socket");
8
8
  const fileQueue_1 = require("../../utils/fileQueue");
9
9
  // import gitpod from '../gitpod'
10
10
  const exercise_1 = require("../config/exercise");
11
+ const session_1 = require("../../managers/session");
11
12
  const withHandler = (func) => (req, res) => {
12
13
  try {
13
14
  func(req, res);
@@ -27,6 +28,7 @@ const withHandler = (func) => (req, res) => {
27
28
  };
28
29
  async function default_1(app, configObject, configManager) {
29
30
  const { config, exercises } = configObject;
31
+ const session = await session_1.default.get(configManager === null || configManager === void 0 ? void 0 : configManager.get());
30
32
  const dispatcher = fileQueue_1.default.dispatcher({
31
33
  create: true,
32
34
  path: `${config === null || config === void 0 ? void 0 : config.dirPath}/vscode_queue.json`,
@@ -34,20 +36,43 @@ async function default_1(app, configObject, configManager) {
34
36
  app.get("/config", withHandler((_, res) => {
35
37
  res.json(configObject);
36
38
  }));
37
- /**
38
- * TODO: replicate a socket action, the request payload must be passed to the socket as well
39
-
40
- const jsonBodyParser = bodyParser.json()
41
-
42
- type ISocketActions = "addAllowed" | "removeAllowed" | "start" | "on" | "clean" | "ask" | "reload" | "openWindow" | "log" | "emit" | "ready" | "error" | "fatal" | "success" | "onTestingFinished";
43
-
44
- app.post('/socket/:actionName', jsonBodyParser, withHandler((req, res) => {
45
- if (socket[req.params.actionName as ISocketActions] instanceof Function) {
46
- socket[req.params.actionName as ISocketActions](req.body ? req.body.data : null)
47
- res.json({ "details": "Socket call executed sucessfully" })
48
- } else res.status(400).json({ "details": `Socket action ${req.params.actionName} not found` })
49
- }))
50
- */
39
+ // Added this line to parse the json body
40
+ const jsonBodyParser = bodyParser.json();
41
+ // Trying to log in from frontend
42
+ app.post("/login", jsonBodyParser, withHandler(async (req, res) => {
43
+ const email = req.body.email;
44
+ const password = req.body.password;
45
+ session_1.default.destroy();
46
+ const payload = await session_1.default.loginWeb(email, password);
47
+ res.json(payload);
48
+ }));
49
+ app.post("/set-openai-token", jsonBodyParser, withHandler(async (req, res) => {
50
+ const token = req.body.token;
51
+ console.log("Setting openai token");
52
+ const tokenSaved = await session_1.default.setOpenAIToken(token);
53
+ if (tokenSaved) {
54
+ res.json({ status: "ok" });
55
+ }
56
+ else {
57
+ res.status(400);
58
+ }
59
+ }));
60
+ app.get("/check/rigo/status", withHandler(async (_, res) => {
61
+ const payload = await session_1.default.getPayload();
62
+ const openaiToken = await session_1.default.getOpenAIToken();
63
+ // console.log("Looking Rigo creds");
64
+ if (payload && payload.rigobot && payload.rigobot.key) {
65
+ res.json({ rigoToken: payload.rigobot.key });
66
+ }
67
+ else if (openaiToken) {
68
+ res.json({ openaiToken });
69
+ }
70
+ else {
71
+ res
72
+ .status(400)
73
+ .json({ details: `Rigobot token not found, please log in first!` });
74
+ }
75
+ }));
51
76
  // symbolic link to maintain path compatiblity
52
77
  const fetchStaticAsset = withHandler((req, res) => {
53
78
  const filePath = `${config === null || config === void 0 ? void 0 : config.dirPath}/assets/${req.params.filePath}`;
@@ -151,6 +176,15 @@ async function default_1(app, configObject, configManager) {
151
176
  res.end();
152
177
  }
153
178
  }));
179
+ /*
180
+ app.post(
181
+ "/exercise/:slug/file/:fileName",
182
+ withHandler((req: express.Request, res: express.Response) => {
183
+ get tokens but also, add allowed action for 'generate'
184
+ use the sessionManager to keep compatibility with the cli login command.
185
+ })
186
+ );
187
+ */
154
188
  const textBodyParser = bodyParser.text();
155
189
  app.put("/exercise/:slug/file/:fileName", textBodyParser, withHandler((req, res) => {
156
190
  const exercise = configManager.getExercise(req.params.slug);
@@ -1,3 +1,3 @@
1
- import { ISession } from '../models/session';
1
+ import { ISession } from "../models/session";
2
2
  declare const Session: ISession;
3
3
  export default Session;
@@ -4,7 +4,6 @@ const console_1 = require("../utils/console");
4
4
  const api_1 = require("../utils/api");
5
5
  const validator_1 = require("validator");
6
6
  const errors_1 = require("../utils/errors");
7
- // import moment from 'moment'
8
7
  const fs = require("fs");
9
8
  const cli_ux_1 = require("cli-ux");
10
9
  const storage = require("node-persist");
@@ -16,7 +15,7 @@ const Session = {
16
15
  initialize: async function () {
17
16
  if (!this.sessionStarted) {
18
17
  if (!this.config) {
19
- throw errors_1.InternalError('Configuration not found');
18
+ throw errors_1.InternalError("Configuration not found");
20
19
  }
21
20
  if (!fs.existsSync(this.config.dirPath)) {
22
21
  fs.mkdirSync(this.config.dirPath);
@@ -26,22 +25,39 @@ const Session = {
26
25
  }
27
26
  return true;
28
27
  },
28
+ getOpenAIToken: async function () {
29
+ await this.initialize();
30
+ let token = null;
31
+ try {
32
+ token = await storage.getItem("openai-token");
33
+ }
34
+ catch (_a) {
35
+ console_1.default.debug("Error retriving openai token");
36
+ }
37
+ return token;
38
+ },
39
+ setOpenAIToken: async function (token) {
40
+ await this.initialize();
41
+ await storage.setItem("openai-token", token);
42
+ console_1.default.debug("OpenAI token successfuly set");
43
+ return true;
44
+ },
29
45
  setPayload: async function (value) {
30
46
  await this.initialize();
31
- await storage.setItem('bc-payload', Object.assign({ token: this.token }, value));
32
- console_1.default.debug('Payload successfuly found and set for ' + value.email);
47
+ await storage.setItem("bc-payload", Object.assign({ token: this.token }, value));
48
+ console_1.default.debug("Payload successfuly found and set for " + value.email);
33
49
  return true;
34
50
  },
35
51
  getPayload: async function () {
36
52
  await this.initialize();
37
53
  let payload = null;
38
54
  try {
39
- payload = await storage.getItem('bc-payload');
55
+ payload = await storage.getItem("bc-payload");
40
56
  }
41
57
  catch (error) {
42
58
  // TODO: Remove it
43
59
  console.log(error);
44
- console_1.default.debug('Error retriving session payload');
60
+ console_1.default.debug("Error retriving session payload");
45
61
  }
46
62
  return payload;
47
63
  },
@@ -68,16 +84,27 @@ const Session = {
68
84
  };
69
85
  },
70
86
  login: async function () {
71
- const email = await cli_ux_1.default.prompt('What is your email?');
87
+ const email = await cli_ux_1.default.prompt("What is your email?");
72
88
  if (!validator_1.default.isEmail(email)) {
73
- throw errors_1.ValidationError('Invalid email');
89
+ throw errors_1.ValidationError("Invalid email");
74
90
  }
75
- const password = await cli_ux_1.default.prompt('What is your password?', {
76
- type: 'hide',
91
+ const password = await cli_ux_1.default.prompt("What is your password?", {
92
+ type: "hide",
77
93
  });
78
94
  const data = await api_1.default.login(email, password);
95
+ if (data) {
96
+ cli_ux_1.default.log(data);
97
+ this.start({ token: data.token, payload: data });
98
+ }
99
+ },
100
+ loginWeb: async function (email, password) {
101
+ if (!validator_1.default.isEmail(email)) {
102
+ throw errors_1.ValidationError("Invalid email");
103
+ }
104
+ const data = await api_1.default.login(email, password);
79
105
  if (data) {
80
106
  this.start({ token: data.token, payload: data });
107
+ return data;
81
108
  }
82
109
  },
83
110
  sync: async function () {
@@ -88,7 +115,7 @@ const Session = {
88
115
  },
89
116
  start: async function ({ token, payload = null }) {
90
117
  if (!token) {
91
- throw new Error('A token and email is needed to start a session');
118
+ throw new Error("A token and email is needed to start a session");
92
119
  }
93
120
  this.token = token;
94
121
  if (payload && (await this.setPayload(payload))) {
@@ -98,7 +125,7 @@ const Session = {
98
125
  destroy: async function () {
99
126
  await storage.clear();
100
127
  this.token = null;
101
- console_1.default.success('You have logged out');
128
+ console_1.default.success("You have logged out");
102
129
  },
103
130
  };
104
131
  exports.default = Session;
@@ -1,3 +1,3 @@
1
- import { ISocket } from '../models/socket';
1
+ import { ISocket } from "../models/socket";
2
2
  declare const SocketManager: ISocket;
3
3
  export default SocketManager;
@@ -7,7 +7,7 @@ const SocketManager = {
7
7
  socket: null,
8
8
  config: null,
9
9
  allowedActions: [],
10
- possibleActions: ['build', 'reset', 'test', 'tutorial'],
10
+ possibleActions: ["build", "reset", "test", "tutorial"],
11
11
  isTestingEnvironment: false,
12
12
  actionCallBacks: {
13
13
  clean: (_, s) => {
@@ -19,8 +19,8 @@ const SocketManager = {
19
19
  if (!Array.isArray(actions))
20
20
  actions = [actions];
21
21
  // avoid adding the "test" action if grading is disabled
22
- if (actions.includes('test') && ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.disabledActions) === null || _b === void 0 ? void 0 : _b.includes('test'))) {
23
- actions = actions.filter((a) => a !== 'test');
22
+ if (actions.includes("test") && ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.disabledActions) === null || _b === void 0 ? void 0 : _b.includes("test"))) {
23
+ actions = actions.filter((a) => a !== "test");
24
24
  }
25
25
  this.allowedActions = [
26
26
  ...(this.allowedActions || []).filter((a) => !actions.includes(a)),
@@ -37,30 +37,39 @@ const SocketManager = {
37
37
  var _a, _b, _c, _d;
38
38
  this.config = config;
39
39
  this.isTestingEnvironment = isTestingEnvironment;
40
- this.socket = new socket_io_1.Server(server, { allowEIO3: true });
41
- this.allowedActions = ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.disabledActions) === null || _b === void 0 ? void 0 : _b.includes('test')) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.disableGrading) ? this.possibleActions.filter(a => { var _a, _b; return !((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.disabledActions) === null || _b === void 0 ? void 0 : _b.includes(a)) && a !== 'test'; }) : this.possibleActions.filter(a => { var _a; return !((_a = this.allowedActions) === null || _a === void 0 ? void 0 : _a.includes(a)); });
42
- if (((_d = this.config) === null || _d === void 0 ? void 0 : _d.grading) === 'incremental') {
43
- this.removeAllowed('reset');
40
+ this.socket = new socket_io_1.Server(server, {
41
+ allowEIO3: true,
42
+ cors: {
43
+ origin: "http://localhost:5173",
44
+ methods: ["GET", "POST"],
45
+ },
46
+ });
47
+ this.allowedActions =
48
+ ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.disabledActions) === null || _b === void 0 ? void 0 : _b.includes("test")) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.disableGrading) ?
49
+ this.possibleActions.filter(a => { var _a, _b; return !((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.disabledActions) === null || _b === void 0 ? void 0 : _b.includes(a)) && a !== "test"; }) :
50
+ this.possibleActions.filter(a => { var _a; return !((_a = this.allowedActions) === null || _a === void 0 ? void 0 : _a.includes(a)); });
51
+ if (((_d = this.config) === null || _d === void 0 ? void 0 : _d.grading) === "incremental") {
52
+ this.removeAllowed("reset");
44
53
  }
45
54
  if (this.socket) {
46
- this.socket.on('connection', (socket) => {
47
- console_1.default.debug('Connection with client successfully established', this.allowedActions);
55
+ this.socket.on("connection", (socket) => {
56
+ console_1.default.debug("Connection with client successfully established", this.allowedActions);
48
57
  if (!this.isTestingEnvironment) {
49
- this.log('ready', ['Ready to compile or test...']);
58
+ this.log("ready", ["Ready to compile or test..."]);
50
59
  }
51
- socket.on('compiler', ({ action, data }) => {
52
- this.emit('clean', 'pending', ['Working...']);
53
- if (typeof data.exerciseSlug === 'undefined') {
54
- this.log('internal-error', ['No exercise slug specified']);
55
- console_1.default.error('No exercise slug especified');
60
+ socket.on("compiler", ({ action, data }) => {
61
+ this.emit("clean", "pending", ["Working..."]);
62
+ if (typeof data.exerciseSlug === "undefined") {
63
+ this.log("internal-error", ["No exercise slug specified"]);
64
+ console_1.default.error("No exercise slug especified");
56
65
  return;
57
66
  }
58
67
  if (this.actionCallBacks &&
59
- typeof this.actionCallBacks[action] === 'function') {
68
+ typeof this.actionCallBacks[action] === "function") {
60
69
  this.actionCallBacks[action](data);
61
70
  }
62
71
  else {
63
- this.log('internal-error', ['Uknown action ' + action]);
72
+ this.log("internal-error", ["Uknown action " + action]);
64
73
  }
65
74
  });
66
75
  });
@@ -71,14 +80,16 @@ const SocketManager = {
71
80
  this.actionCallBacks[action] = callBack;
72
81
  }
73
82
  },
74
- clean: function (_ = 'pending', logs = []) {
75
- this.emit('clean', 'pending', logs);
83
+ clean: function (_ = "pending", logs = []) {
84
+ this.emit("clean", "pending", logs);
76
85
  },
77
86
  ask: function (questions = []) {
78
87
  return new Promise((resolve, _) => {
79
- this.emit('ask', 'pending', ['Waiting for input...'], questions);
80
- this.on('input', ({ inputs }) => {
88
+ this.emit("ask", "pending", ["Waiting for input..."], questions);
89
+ console.log("Setting up listeners");
90
+ this.on("input", ({ inputs }) => {
81
91
  // Workaround to fix issue because null inputs
92
+ console.log("inputs", inputs);
82
93
  let isNull = false;
83
94
  // eslint-disable-next-line
84
95
  inputs.forEach((input) => {
@@ -93,31 +104,31 @@ const SocketManager = {
93
104
  });
94
105
  },
95
106
  reload: function (files = null, exercises = null) {
96
- this.emit('reload', (files === null || files === void 0 ? void 0 : files.join('')) || '' /* TODO: Check it out this */, exercises);
107
+ this.emit("reload", (files === null || files === void 0 ? void 0 : files.join("")) || "" /* TODO: Check it out this */, exercises);
97
108
  },
98
- openWindow: function (url = '') {
109
+ openWindow: function (url = "") {
99
110
  fileQueue_1.default.dispatcher().enqueue(fileQueue_1.default.events.OPEN_WINDOW, url);
100
- this.emit(fileQueue_1.default.events.OPEN_WINDOW, 'ready', [`Opening ${url}`], [], [], url);
111
+ this.emit(fileQueue_1.default.events.OPEN_WINDOW, "ready", [`Opening ${url}`], [], [], url);
101
112
  },
102
113
  log: function (status, messages = [], report = [], data = null) {
103
- this.emit('log', status, messages, [], report, data);
114
+ this.emit("log", status, messages, [], report, data);
104
115
  console_1.default.log(messages);
105
116
  },
106
- emit: function (action, status = 'ready', logs = [], inputs = [], report = [], data = null) {
117
+ emit: function (action, status = "ready", logs = [], inputs = [], report = [], data = null) {
107
118
  var _a, _b, _c, _d, _e, _f;
108
119
  if (((_a = this.config) === null || _a === void 0 ? void 0 : _a.compiler) &&
109
- ['webpack', 'vanillajs', 'vue', 'react', 'css', 'html'].includes((_b = this.config) === null || _b === void 0 ? void 0 : _b.compiler)) {
110
- if (['compiler-success', 'compiler-warning'].includes(status))
111
- this.addAllowed('preview');
112
- if (['compiler-error'].includes(status) || action === 'ready')
113
- this.removeAllowed('preview');
120
+ ["webpack", "vanillajs", "vue", "react", "css", "html"].includes((_b = this.config) === null || _b === void 0 ? void 0 : _b.compiler)) {
121
+ if (["compiler-success", "compiler-warning"].includes(status))
122
+ this.addAllowed("preview");
123
+ if (["compiler-error"].includes(status) || action === "ready")
124
+ this.removeAllowed("preview");
114
125
  }
115
- if (((_c = this.config) === null || _c === void 0 ? void 0 : _c.grading) === 'incremental') {
116
- this.removeAllowed('reset');
126
+ if (((_c = this.config) === null || _c === void 0 ? void 0 : _c.grading) === "incremental") {
127
+ this.removeAllowed("reset");
117
128
  }
118
129
  // eslint-disable-next-line
119
130
  (_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.disabledActions) === null || _e === void 0 ? void 0 : _e.forEach((a) => this.removeAllowed(a));
120
- (_f = this.socket) === null || _f === void 0 ? void 0 : _f.emit('compiler', {
131
+ (_f = this.socket) === null || _f === void 0 ? void 0 : _f.emit("compiler", {
121
132
  action,
122
133
  status,
123
134
  logs,
@@ -128,30 +139,33 @@ const SocketManager = {
128
139
  });
129
140
  },
130
141
  ready: function (message) {
131
- this.log('ready', [message]);
142
+ this.log("ready", [message]);
132
143
  },
133
144
  success: function (type, stdout) {
134
- const types = ['compiler', 'testing'];
145
+ const types = ["compiler", "testing"];
135
146
  if (!types.includes(type))
136
147
  this.fatal(`Invalid socket success type "${type}" on socket`);
137
- else if (stdout === '')
138
- this.log((type + '-success'), [
139
- 'No stdout to display on the console',
148
+ else if (stdout === "")
149
+ this.log((type + "-success"), [
150
+ "No stdout to display on the console",
140
151
  ]);
141
152
  else
142
- this.log((type + '-success'), [stdout]);
153
+ this.log((type + "-success"), [stdout]);
143
154
  },
144
155
  error: function (type, stdout) {
145
- console.error('Socket error: ' + type, stdout);
156
+ console.error("Socket error: " + type, stdout);
146
157
  this.log(type, [stdout]);
147
158
  if (this.isTestingEnvironment) {
148
159
  this.onTestingFinished({
149
- result: 'failed',
160
+ result: "failed",
150
161
  });
151
162
  }
152
163
  },
164
+ complete: function () {
165
+ console.log("complete");
166
+ },
153
167
  fatal: function (msg) {
154
- this.log('internal-error', [msg]);
168
+ this.log("internal-error", [msg]);
155
169
  throw msg;
156
170
  },
157
171
  onTestingFinished: function (result) {
@@ -1,2 +1,2 @@
1
- export declare type TAction = 'test' | 'log' | 'reload' | 'ready' | 'clean' | 'ask';
1
+ export declare type TAction = "test" | "log" | "reload" | "ready" | "clean" | "ask" | "generation";
2
2
  export declare type ICallback = (...agrs: any[]) => any;
@@ -1,7 +1,7 @@
1
1
  import { IExercise } from "./exercise-obj";
2
2
  export declare type TGrading = "isolated" | "incremental" | "no-grading";
3
3
  export declare type TMode = "preview" | "standalone";
4
- export declare type TConfigAction = "test" | "build" | "tutorial" | "reset";
4
+ export declare type TConfigAction = "test" | "build" | "tutorial" | "reset" | "generate";
5
5
  export declare type TConfigObjAttributes = "config" | "exercises" | "grading";
6
6
  export declare type TCompiler = "webpack" | "vanillajs" | "vue" | "react" | "css" | "html";
7
7
  export interface IConfigPath {
@@ -22,6 +22,9 @@ export interface IExercise {
22
22
  test?: (sessionConfig: any, config: IConfig, socket: ISocket) => void;
23
23
  }
24
24
  export interface IExerciseData {
25
+ lastMessages?: any;
26
+ userMessage?: string;
25
27
  exerciseSlug: string;
28
+ entryPoint?: string;
26
29
  files: string[];
27
30
  }
@@ -1,4 +1,4 @@
1
- import { IConfig, IConfigObj } from './config';
1
+ import { IConfig, IConfigObj } from "./config";
2
2
  export interface IPayload {
3
3
  email: string;
4
4
  }
@@ -12,11 +12,14 @@ export interface ISession {
12
12
  config: IConfig | null;
13
13
  currentCohort: null;
14
14
  initialize: () => Promise<boolean>;
15
+ getOpenAIToken: () => Promise<string | null>;
16
+ setOpenAIToken: (token: string) => Promise<boolean>;
15
17
  setPayload: (value: IPayload) => Promise<boolean>;
16
18
  getPayload: () => Promise<any>;
17
19
  isActive: () => boolean;
18
20
  get: (config?: IConfigObj) => Promise<any>;
19
21
  login: () => Promise<void>;
22
+ loginWeb: (email: string, password: string) => Promise<void>;
20
23
  sync: () => Promise<void>;
21
24
  start: ({ token, payload }: IStartProps) => Promise<void>;
22
25
  destroy: () => Promise<void>;