@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
@@ -1,20 +1,20 @@
1
- import {Socket, Server} from 'socket.io'
2
- import Console from '../utils/console'
3
- import queue from '../utils/fileQueue'
4
-
5
- import {ISocket, TPossibleActions} from '../models/socket'
6
- import {IConfig} from '../models/config'
7
- import {ICallback, TAction} from '../models/action'
8
- import {IExercise, IExerciseData} from '../models/exercise-obj'
9
- import {TStatus} from '../models/status'
10
- import {TSuccessType} from '../models/success-types'
11
- import * as http from 'http'
1
+ import { Socket, Server } from "socket.io"
2
+ import Console from "../utils/console"
3
+ import queue from "../utils/fileQueue"
4
+
5
+ import { ISocket, TPossibleActions } from "../models/socket"
6
+ import { IConfig } from "../models/config"
7
+ import { ICallback, TAction } from "../models/action"
8
+ import { IExercise, IExerciseData } from "../models/exercise-obj"
9
+ import { TStatus } from "../models/status"
10
+ import { TSuccessType } from "../models/success-types"
11
+ import * as http from "http"
12
12
 
13
13
  const SocketManager: ISocket = {
14
14
  socket: null,
15
15
  config: null,
16
16
  allowedActions: [],
17
- possibleActions: ['build', 'reset', 'test', 'tutorial'],
17
+ possibleActions: ["build", "reset", "test", "tutorial"],
18
18
  isTestingEnvironment: false,
19
19
  actionCallBacks: {
20
20
  clean: (_, s: { logs: Array<string> }) => {
@@ -22,86 +22,91 @@ const SocketManager: ISocket = {
22
22
  },
23
23
  },
24
24
  addAllowed: function (actions: Array<TPossibleActions> | TPossibleActions) {
25
- if (!Array.isArray(actions))
26
- actions = [actions]
25
+ if (!Array.isArray(actions))
26
+ actions = [actions]
27
27
 
28
28
  // avoid adding the "test" action if grading is disabled
29
29
  if (
30
- actions.includes('test') &&
31
- this.config?.disabledActions?.includes('test')
30
+ actions.includes("test") &&
31
+ this.config?.disabledActions?.includes("test")
32
32
  ) {
33
- actions = actions.filter((a: TPossibleActions) => a !== 'test')
33
+ actions = actions.filter((a: TPossibleActions) => a !== "test")
34
34
  }
35
35
 
36
36
  this.allowedActions = [
37
37
  ...(this.allowedActions || []).filter(
38
- (a: TPossibleActions) => !actions.includes(a),
38
+ (a: TPossibleActions) => !actions.includes(a)
39
39
  ),
40
40
  ...actions,
41
41
  ]
42
42
  },
43
43
  removeAllowed: function (
44
- actions: Array<TPossibleActions> | TPossibleActions,
44
+ actions: Array<TPossibleActions> | TPossibleActions
45
45
  ) {
46
46
  if (!Array.isArray(actions)) {
47
47
  actions = [actions]
48
48
  }
49
49
 
50
50
  this.allowedActions = (this.allowedActions || []).filter(
51
- (a: TPossibleActions) => !actions.includes(a),
51
+ (a: TPossibleActions) => !actions.includes(a)
52
52
  )
53
53
  },
54
54
  start: function (
55
55
  config: IConfig,
56
56
  server: http.Server,
57
- isTestingEnvironment = false,
57
+ isTestingEnvironment = false
58
58
  ) {
59
59
  this.config = config
60
60
  this.isTestingEnvironment = isTestingEnvironment
61
+ this.socket = new Server(server, {
62
+ allowEIO3: true,
63
+ cors: {
64
+ origin: "http://localhost:5173",
65
+ methods: ["GET", "POST"],
66
+ },
67
+ })
61
68
 
62
- this.socket = new Server(server, {allowEIO3: true})
69
+ this.allowedActions =
70
+ this.config?.disabledActions?.includes("test") ||
71
+ this.config?.disableGrading ?
72
+ this.possibleActions.filter(
73
+ a => !this.config?.disabledActions?.includes(a) && a !== "test"
74
+ ) :
75
+ this.possibleActions.filter(a => !this.allowedActions?.includes(a))
63
76
 
64
- this.allowedActions = this.config?.disabledActions?.includes('test') ||
65
- this.config?.disableGrading ? this.possibleActions.filter(
66
- a => !this.config?.disabledActions?.includes(a) && a !== 'test',
67
- ) : this.possibleActions.filter(
68
- a => !this.allowedActions?.includes(a),
69
- )
70
-
71
- if (this.config?.grading === 'incremental') {
72
- this.removeAllowed('reset')
77
+ if (this.config?.grading === "incremental") {
78
+ this.removeAllowed("reset")
73
79
  }
74
80
 
75
81
  if (this.socket) {
76
- this.socket.on('connection', (socket: Socket) => {
82
+ this.socket.on("connection", (socket: Socket) => {
77
83
  Console.debug(
78
- 'Connection with client successfully established',
79
- this.allowedActions,
84
+ "Connection with client successfully established",
85
+ this.allowedActions
80
86
  )
81
87
  if (!this.isTestingEnvironment) {
82
- this.log('ready', ['Ready to compile or test...'])
88
+ this.log("ready", ["Ready to compile or test..."])
83
89
  }
84
90
 
85
91
  socket.on(
86
- 'compiler',
87
- ({action, data}: { action: string; data: IExerciseData }) => {
88
- this.emit('clean', 'pending', ['Working...'])
89
-
90
- if (typeof data.exerciseSlug === 'undefined') {
91
- this.log('internal-error', ['No exercise slug specified'])
92
- Console.error('No exercise slug especified')
92
+ "compiler",
93
+ ({ action, data }: { action: string; data: IExerciseData }) => {
94
+ this.emit("clean", "pending", ["Working..."])
95
+ if (typeof data.exerciseSlug === "undefined") {
96
+ this.log("internal-error", ["No exercise slug specified"])
97
+ Console.error("No exercise slug especified")
93
98
  return
94
99
  }
95
100
 
96
101
  if (
97
102
  this.actionCallBacks &&
98
- typeof this.actionCallBacks[action] === 'function'
103
+ typeof this.actionCallBacks[action] === "function"
99
104
  ) {
100
105
  this.actionCallBacks[action](data)
101
106
  } else {
102
- this.log('internal-error', ['Uknown action ' + action])
107
+ this.log("internal-error", ["Uknown action " + action])
103
108
  }
104
- },
109
+ }
105
110
  )
106
111
  })
107
112
  }
@@ -111,14 +116,18 @@ const SocketManager: ISocket = {
111
116
  this.actionCallBacks[action] = callBack
112
117
  }
113
118
  },
114
- clean: function (_ = 'pending', logs = []) {
115
- this.emit('clean', 'pending', logs)
119
+ clean: function (_ = "pending", logs = []) {
120
+ this.emit("clean", "pending", logs)
116
121
  },
117
122
  ask: function (questions = []) {
118
123
  return new Promise((resolve, _) => {
119
- this.emit('ask', 'pending', ['Waiting for input...'], questions)
120
- this.on('input', ({inputs}: any) => {
124
+ this.emit("ask", "pending", ["Waiting for input..."], questions)
125
+ console.log("Setting up listeners")
126
+ this.on("input", ({ inputs }: any) => {
121
127
  // Workaround to fix issue because null inputs
128
+
129
+ console.log("inputs", inputs)
130
+
122
131
  let isNull = false
123
132
  // eslint-disable-next-line
124
133
  inputs.forEach((input: any) => {
@@ -135,62 +144,62 @@ const SocketManager: ISocket = {
135
144
  },
136
145
  reload: function (
137
146
  files: Array<string> | null = null,
138
- exercises: Array<string> | null = null,
147
+ exercises: Array<string> | null = null
139
148
  ) {
140
149
  this.emit(
141
- 'reload',
142
- files?.join('') || '' /* TODO: Check it out this */,
143
- exercises!,
150
+ "reload",
151
+ files?.join("") || "" /* TODO: Check it out this */,
152
+ exercises!
144
153
  )
145
154
  },
146
- openWindow: function (url = '') {
155
+ openWindow: function (url = "") {
147
156
  queue.dispatcher().enqueue(queue.events.OPEN_WINDOW, url)
148
157
  this.emit(
149
158
  queue.events.OPEN_WINDOW as TAction,
150
- 'ready',
159
+ "ready",
151
160
  [`Opening ${url}`],
152
161
  [],
153
162
  [],
154
- url,
163
+ url
155
164
  )
156
165
  },
157
166
  log: function (
158
167
  status: TStatus,
159
168
  messages: string | Array<string> = [],
160
169
  report: Array<string> = [],
161
- data: any = null,
170
+ data: any = null
162
171
  ) {
163
- this.emit('log', status, messages, [], report, data)
172
+ this.emit("log", status, messages, [], report, data)
164
173
  Console.log(messages)
165
174
  },
166
175
  emit: function (
167
176
  action: TAction,
168
- status: TStatus | string = 'ready',
177
+ status: TStatus | string = "ready",
169
178
  logs: string | Array<string> = [],
170
179
  inputs: Array<string> = [],
171
180
  report: Array<string> = [],
172
- data: any = null,
181
+ data: any = null
173
182
  ) {
174
183
  if (
175
184
  this.config?.compiler &&
176
- ['webpack', 'vanillajs', 'vue', 'react', 'css', 'html'].includes(
177
- this.config?.compiler,
185
+ ["webpack", "vanillajs", "vue", "react", "css", "html"].includes(
186
+ this.config?.compiler
178
187
  )
179
188
  ) {
180
- if (['compiler-success', 'compiler-warning'].includes(status))
181
- this.addAllowed('preview')
182
- if (['compiler-error'].includes(status) || action === 'ready')
183
- this.removeAllowed('preview')
189
+ if (["compiler-success", "compiler-warning"].includes(status))
190
+ this.addAllowed("preview")
191
+ if (["compiler-error"].includes(status) || action === "ready")
192
+ this.removeAllowed("preview")
184
193
  }
185
194
 
186
- if (this.config?.grading === 'incremental') {
187
- this.removeAllowed('reset')
195
+ if (this.config?.grading === "incremental") {
196
+ this.removeAllowed("reset")
188
197
  }
189
198
 
190
199
  // eslint-disable-next-line
191
200
  this.config?.disabledActions?.forEach((a) => this.removeAllowed(a));
192
201
 
193
- this.socket?.emit('compiler', {
202
+ this.socket?.emit("compiler", {
194
203
  action,
195
204
  status,
196
205
  logs,
@@ -202,31 +211,35 @@ const SocketManager: ISocket = {
202
211
  },
203
212
 
204
213
  ready: function (message: string) {
205
- this.log('ready', [message])
214
+ this.log("ready", [message])
206
215
  },
207
216
  success: function (type: TSuccessType, stdout: string) {
208
- const types = ['compiler', 'testing']
217
+ const types = ["compiler", "testing"]
209
218
  if (!types.includes(type))
210
219
  this.fatal(`Invalid socket success type "${type}" on socket`)
211
- else if (stdout === '')
212
- this.log((type + '-success') as TSuccessType, [
213
- 'No stdout to display on the console',
220
+ else if (stdout === "")
221
+ this.log((type + "-success") as TSuccessType, [
222
+ "No stdout to display on the console",
214
223
  ])
215
- else
216
- this.log((type + '-success') as TSuccessType, [stdout])
224
+ else
225
+ this.log((type + "-success") as TSuccessType, [stdout])
217
226
  },
218
227
  error: function (type: TStatus, stdout: string) {
219
- console.error('Socket error: ' + type, stdout)
228
+ console.error("Socket error: " + type, stdout)
220
229
  this.log(type, [stdout])
221
230
 
222
231
  if (this.isTestingEnvironment) {
223
232
  this.onTestingFinished({
224
- result: 'failed',
233
+ result: "failed",
225
234
  })
226
235
  }
227
236
  },
237
+ complete: function () {
238
+ console.log("complete")
239
+ },
240
+
228
241
  fatal: function (msg: string) {
229
- this.log('internal-error', [msg])
242
+ this.log("internal-error", [msg])
230
243
  throw msg
231
244
  },
232
245
  onTestingFinished: function (result: any) {
@@ -1,3 +1,10 @@
1
- export type TAction = 'test' | 'log' | 'reload' | 'ready' | 'clean' | 'ask';
1
+ export type TAction =
2
+ | "test"
3
+ | "log"
4
+ | "reload"
5
+ | "ready"
6
+ | "clean"
7
+ | "ask"
8
+ | "generation";
2
9
 
3
10
  export type ICallback = (...agrs: any[]) => any;
@@ -1,5 +1,5 @@
1
- import { IConfigObj, TGrading } from "./config";
2
- import { IExercise } from "./exercise-obj";
1
+ import { IConfigObj, TGrading } from "./config"
2
+ import { IExercise } from "./exercise-obj"
3
3
 
4
4
  export interface IConfigManagerAttributes {
5
5
  grading: TGrading;
@@ -1,10 +1,15 @@
1
- import { IExercise } from "./exercise-obj";
1
+ import { IExercise } from "./exercise-obj"
2
2
 
3
3
  export type TGrading = "isolated" | "incremental" | "no-grading";
4
4
 
5
5
  export type TMode = "preview" | "standalone";
6
6
 
7
- export type TConfigAction = "test" | "build" | "tutorial" | "reset";
7
+ export type TConfigAction =
8
+ | "test"
9
+ | "build"
10
+ | "tutorial"
11
+ | "reset"
12
+ | "generate";
8
13
 
9
14
  export type TConfigObjAttributes = "config" | "exercises" | "grading";
10
15
 
@@ -1,6 +1,6 @@
1
- import { IFile } from "./file";
2
- import { IConfig } from "./config";
3
- import { ISocket } from "./socket";
1
+ import { IFile } from "./file"
2
+ import { IConfig } from "./config"
3
+ import { ISocket } from "./socket"
4
4
 
5
5
  export interface IExercise {
6
6
  position?: number;
@@ -21,6 +21,9 @@ export interface IExercise {
21
21
  }
22
22
 
23
23
  export interface IExerciseData {
24
+ lastMessages?: any;
25
+ userMessage?: string;
24
26
  exerciseSlug: string;
27
+ entryPoint?: string;
25
28
  files: string[];
26
29
  }
@@ -1,5 +1,5 @@
1
- import { IConfig } from "./config";
2
- import { IExercise } from "./exercise-obj";
1
+ import { IConfig } from "./config"
2
+ import { IExercise } from "./exercise-obj"
3
3
 
4
4
  export interface IPluginConfig {
5
5
  language: string;
@@ -1,4 +1,4 @@
1
- import {IConfig, IConfigObj} from './config'
1
+ import { IConfig, IConfigObj } from "./config"
2
2
 
3
3
  export interface IPayload {
4
4
  email: string;
@@ -15,12 +15,15 @@ export interface ISession {
15
15
  config: IConfig | null;
16
16
  currentCohort: null;
17
17
  initialize: () => Promise<boolean>;
18
+ getOpenAIToken: () => Promise<string | null>;
19
+ setOpenAIToken: (token: string) => Promise<boolean>;
18
20
  setPayload: (value: IPayload) => Promise<boolean>;
19
21
  getPayload: () => Promise<any>;
20
22
  isActive: () => boolean;
21
23
  get: (config?: IConfigObj) => Promise<any>;
22
24
  login: () => Promise<void>;
25
+ loginWeb: (email: string, password: string) => Promise<void>;
23
26
  sync: () => Promise<void>;
24
- start: ({token, payload}: IStartProps) => Promise<void>;
27
+ start: ({ token, payload }: IStartProps) => Promise<void>;
25
28
  destroy: () => Promise<void>;
26
29
  }
@@ -1,10 +1,15 @@
1
- import {IConfig} from './config'
2
- import {Server} from 'socket.io'
3
- import {DefaultEventsMap} from 'socket.io/dist/typed-events'
4
- import {TAction, ICallback} from './action'
5
- import {TStatus} from './status'
1
+ import { IConfig } from "./config"
2
+ import { Server } from "socket.io"
3
+ import { DefaultEventsMap } from "socket.io/dist/typed-events"
4
+ import { TAction, ICallback } from "./action"
5
+ import { TStatus } from "./status"
6
6
 
7
- export type TPossibleActions = 'build' | 'test' | 'reset' | 'tutorial';
7
+ export type TPossibleActions =
8
+ | "build"
9
+ | "test"
10
+ | "reset"
11
+ | "tutorial"
12
+ | "generate";
8
13
 
9
14
  export interface ISocket {
10
15
  socket: Server<
@@ -23,6 +28,7 @@ export interface ISocket {
23
28
  start: (config: IConfig, server: any, isTestingEnvironment: boolean) => void;
24
29
  on: (action: any, callBack: any) => void;
25
30
  clean: (_: string, logs: Array<any>) => void;
31
+ complete: () => void;
26
32
  ask: (questions: Array<string>) => void;
27
33
  reload: (files: Array<string> | null, exercises: Array<string>) => void;
28
34
  openWindow: (id: string) => void;
@@ -1,15 +1,16 @@
1
1
  export type TStatus =
2
- | 'ready'
3
- | 'internal-error'
4
- | 'compiler-success'
5
- | 'testing-success'
6
- | 'compiling'
7
- | 'testing'
8
- | 'start_exercise'
9
- | 'initializing'
10
- | 'configuration_loaded'
11
- | 'connection_ended'
12
- | 'reset_exercise'
13
- | 'open_files'
14
- | 'open_window'
15
- | 'instructions_closed';
2
+ | "ready"
3
+ | "internal-error"
4
+ | "compiler-success"
5
+ | "testing-success"
6
+ | "compiling"
7
+ | "testing"
8
+ | "start_exercise"
9
+ | "initializing"
10
+ | "configuration_loaded"
11
+ | "connection_ended"
12
+ | "reset_exercise"
13
+ | "open_files"
14
+ | "open_window"
15
+ | "instructions_closed"
16
+ | "completed";
@@ -1,17 +1,17 @@
1
- import { IError } from "../../models/errors";
1
+ import { IError } from "../../models/errors"
2
2
 
3
3
  const CompilationError = (messages: string) => {
4
- const _err: IError = new Error(messages);
5
- _err.status = 400;
6
- _err.stdout = messages;
7
- _err.type = "compiler-error";
8
- return _err;
9
- };
4
+ const _err: IError = new Error(messages)
5
+ _err.status = 400
6
+ _err.stdout = messages
7
+ _err.type = "compiler-error"
8
+ return _err
9
+ }
10
10
 
11
11
  export default {
12
12
  CompilationError,
13
13
  default: async ({ action, ...rest }: any) => {
14
- const stdout = await action.run(rest);
15
- return stdout;
14
+ const stdout = await action.run(rest)
15
+ return stdout
16
16
  },
17
- };
17
+ }
@@ -1,30 +1,30 @@
1
- import * as fs from "fs";
2
- import { IError } from "../../models/errors";
1
+ import * as fs from "fs"
2
+ import { IError } from "../../models/errors"
3
3
 
4
4
  const TestingError = (messages: string) => {
5
- const _err: IError = new Error(messages);
6
- _err.status = 400;
7
- _err.stdout = messages;
8
- _err.type = "testing-error";
9
- return _err;
10
- };
5
+ const _err: IError = new Error(messages)
6
+ _err.status = 400
7
+ _err.stdout = messages
8
+ _err.type = "testing-error"
9
+ return _err
10
+ }
11
11
 
12
12
  export default {
13
13
  TestingError,
14
14
  default: async function (args: any) {
15
- const { action, configuration, socket, exercise } = args;
15
+ const { action, configuration, socket, exercise } = args
16
16
 
17
17
  if (!fs.existsSync(`${configuration.dirPath}/reports`)) {
18
18
  // reports directory
19
- fs.mkdirSync(`${configuration.dirPath}/reports`);
19
+ fs.mkdirSync(`${configuration.dirPath}/reports`)
20
20
  }
21
21
 
22
22
  // compile
23
- const stdout = await action.run(args);
23
+ const stdout = await action.run(args)
24
24
 
25
25
  // mark exercise as done
26
- exercise.done = true;
26
+ exercise.done = true
27
27
 
28
- return stdout;
28
+ return stdout
29
29
  },
30
- };
30
+ }
@@ -1,6 +1,6 @@
1
- import CompilationError from "./command/compile";
2
- import TestingError from "./command/test";
3
- import utils from "./utils";
4
- import plugin from "./plugin";
1
+ import CompilationError from "./command/compile"
2
+ import TestingError from "./command/test"
3
+ import utils from "./utils"
4
+ import plugin from "./plugin"
5
5
 
6
- export default { CompilationError, TestingError, Utils: utils, plugin };
6
+ export default { CompilationError, TestingError, Utils: utils, plugin }