@learnpack/learnpack 2.1.26 → 2.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>;