@learnpack/learnpack 5.0.31 → 5.0.32
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.
- package/README.md +12 -12
- package/lib/managers/telemetry.d.ts +2 -0
- package/lib/managers/telemetry.js +7 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/src/commands/start.ts +361 -361
- package/src/managers/socket.ts +274 -274
- package/src/managers/telemetry.ts +10 -0
- package/src/models/action.ts +12 -12
package/src/managers/socket.ts
CHANGED
@@ -1,274 +1,274 @@
|
|
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
|
-
|
13
|
-
const languageToMessage: Record<string, string> = {
|
14
|
-
python3:
|
15
|
-
"Your code executed without erros, but no output is shown on the terminal. Maybe you forgot to include a print statement in your code?",
|
16
|
-
node: "Your code executed without erros, but no output is shown on the terminal. Maybe you forgot to include a console.log statement in your code?",
|
17
|
-
}
|
18
|
-
|
19
|
-
const SocketManager: ISocket = {
|
20
|
-
socket: null,
|
21
|
-
config: null,
|
22
|
-
allowedActions: [],
|
23
|
-
possibleActions: ["build", "reset", "test", "tutorial"],
|
24
|
-
isTestingEnvironment: false,
|
25
|
-
actionCallBacks: {
|
26
|
-
clean: (_, s: { logs: Array<string> }) => {
|
27
|
-
s.logs = []
|
28
|
-
},
|
29
|
-
},
|
30
|
-
addAllowed: function (actions: Array<TPossibleActions> | TPossibleActions) {
|
31
|
-
if (!Array.isArray(actions))
|
32
|
-
actions = [actions]
|
33
|
-
|
34
|
-
// avoid adding the "test" action if grading is disabled
|
35
|
-
if (
|
36
|
-
actions.includes("test") &&
|
37
|
-
this.config?.disabledActions?.includes("test")
|
38
|
-
) {
|
39
|
-
actions = actions.filter((a: TPossibleActions) => a !== "test")
|
40
|
-
}
|
41
|
-
|
42
|
-
this.allowedActions = [
|
43
|
-
...(this.allowedActions || []).filter(
|
44
|
-
(a: TPossibleActions) => !actions.includes(a)
|
45
|
-
),
|
46
|
-
...actions,
|
47
|
-
]
|
48
|
-
},
|
49
|
-
removeAllowed: function (
|
50
|
-
actions: Array<TPossibleActions> | TPossibleActions
|
51
|
-
) {
|
52
|
-
if (!Array.isArray(actions)) {
|
53
|
-
actions = [actions]
|
54
|
-
}
|
55
|
-
|
56
|
-
this.allowedActions = (this.allowedActions || []).filter(
|
57
|
-
(a: TPossibleActions) => !actions.includes(a)
|
58
|
-
)
|
59
|
-
},
|
60
|
-
start: function (
|
61
|
-
config: IConfig,
|
62
|
-
server: http.Server,
|
63
|
-
isTestingEnvironment = false
|
64
|
-
) {
|
65
|
-
this.config = config
|
66
|
-
this.isTestingEnvironment = isTestingEnvironment
|
67
|
-
this.socket = new Server(server, {
|
68
|
-
allowEIO3: true,
|
69
|
-
cors: {
|
70
|
-
origin: "http://localhost:5173",
|
71
|
-
methods: ["GET", "POST"],
|
72
|
-
},
|
73
|
-
})
|
74
|
-
|
75
|
-
this.allowedActions =
|
76
|
-
this.config?.disabledActions?.includes("test") ||
|
77
|
-
this.config?.disableGrading ?
|
78
|
-
this.possibleActions.filter(
|
79
|
-
a => !this.config?.disabledActions?.includes(a) && a !== "test"
|
80
|
-
) :
|
81
|
-
this.possibleActions.filter(a => !this.allowedActions?.includes(a))
|
82
|
-
|
83
|
-
if (this.config?.grading === "incremental") {
|
84
|
-
this.removeAllowed("reset")
|
85
|
-
}
|
86
|
-
|
87
|
-
if (this.socket) {
|
88
|
-
this.socket.on("connection", (socket: Socket) => {
|
89
|
-
Console.debug(
|
90
|
-
"Connection with client successfully established",
|
91
|
-
this.allowedActions
|
92
|
-
)
|
93
|
-
if (!this.isTestingEnvironment) {
|
94
|
-
this.log("ready", ["Ready to compile or test..."])
|
95
|
-
}
|
96
|
-
|
97
|
-
socket.on(
|
98
|
-
"compiler",
|
99
|
-
({ action, data }: { action: string; data: IExerciseData }) => {
|
100
|
-
this.emit("clean", "pending", ["Working..."])
|
101
|
-
if (typeof data.exerciseSlug === "undefined") {
|
102
|
-
this.log("internal-error", ["No exercise slug specified"])
|
103
|
-
Console.error("No exercise slug especified")
|
104
|
-
return
|
105
|
-
}
|
106
|
-
|
107
|
-
if (
|
108
|
-
this.actionCallBacks &&
|
109
|
-
typeof this.actionCallBacks[action] === "function"
|
110
|
-
) {
|
111
|
-
this.actionCallBacks[action](data)
|
112
|
-
} else {
|
113
|
-
this.log("internal-error", ["Uknown action " + action])
|
114
|
-
}
|
115
|
-
}
|
116
|
-
)
|
117
|
-
})
|
118
|
-
}
|
119
|
-
},
|
120
|
-
on: function (action: TAction, callBack: ICallback) {
|
121
|
-
if (this.actionCallBacks) {
|
122
|
-
this.actionCallBacks[action] = callBack
|
123
|
-
}
|
124
|
-
},
|
125
|
-
clean: function (_ = "pending", logs = []) {
|
126
|
-
this.emit("clean", "pending", logs)
|
127
|
-
},
|
128
|
-
ask: function (questions = []) {
|
129
|
-
return new Promise((resolve, _) => {
|
130
|
-
this.emit("ask", "pending", ["Waiting for input..."], questions)
|
131
|
-
|
132
|
-
this.on("input", ({ inputs }: any) => {
|
133
|
-
// Workaround to fix issue because null inputs
|
134
|
-
|
135
|
-
let isNull = false
|
136
|
-
// eslint-disable-next-line
|
137
|
-
inputs.forEach((input: any) => {
|
138
|
-
if (input === null) {
|
139
|
-
isNull = true
|
140
|
-
}
|
141
|
-
})
|
142
|
-
|
143
|
-
if (!isNull) {
|
144
|
-
resolve(inputs)
|
145
|
-
}
|
146
|
-
})
|
147
|
-
})
|
148
|
-
},
|
149
|
-
sessionRefreshed: function (data) {
|
150
|
-
this.emit("session-refreshed", "", [data])
|
151
|
-
},
|
152
|
-
|
153
|
-
reload: function (
|
154
|
-
files: Array<string> | null = null,
|
155
|
-
exercises: Array<string> | null = null
|
156
|
-
) {
|
157
|
-
this.emit("reload", files?.join("") || "", exercises!)
|
158
|
-
},
|
159
|
-
openWindow: function (url = "") {
|
160
|
-
queue.dispatcher().enqueue(queue.events.OPEN_WINDOW, url)
|
161
|
-
this.emit(
|
162
|
-
queue.events.OPEN_WINDOW as TAction,
|
163
|
-
"ready",
|
164
|
-
[`Opening ${url}`],
|
165
|
-
[],
|
166
|
-
[],
|
167
|
-
url
|
168
|
-
)
|
169
|
-
},
|
170
|
-
log: function (
|
171
|
-
status: TStatus,
|
172
|
-
messages: string | Array<string> = [],
|
173
|
-
report: Array<string> = [],
|
174
|
-
data: any = null
|
175
|
-
) {
|
176
|
-
this.emit("log", status, messages, [], report, data)
|
177
|
-
Console.log(messages)
|
178
|
-
},
|
179
|
-
emit: function (
|
180
|
-
action: TAction,
|
181
|
-
status: TStatus | string = "ready",
|
182
|
-
logs: string | Array<string> = [],
|
183
|
-
inputs: Array<string> = [],
|
184
|
-
report: Array<string> = [],
|
185
|
-
data: any = null
|
186
|
-
) {
|
187
|
-
if (
|
188
|
-
this.config?.compiler &&
|
189
|
-
["webpack", "vanillajs", "vue", "react", "css", "html"].includes(
|
190
|
-
this.config?.compiler
|
191
|
-
)
|
192
|
-
) {
|
193
|
-
if (["compiler-success", "compiler-warning"].includes(status))
|
194
|
-
this.addAllowed("preview")
|
195
|
-
if (["compiler-error"].includes(status) || action === "ready")
|
196
|
-
this.removeAllowed("preview")
|
197
|
-
}
|
198
|
-
|
199
|
-
if (this.config?.grading === "incremental") {
|
200
|
-
this.removeAllowed("reset")
|
201
|
-
}
|
202
|
-
|
203
|
-
// eslint-disable-next-line
|
204
|
-
this.config?.disabledActions?.forEach((a) => this.removeAllowed(a))
|
205
|
-
|
206
|
-
this.socket?.emit("compiler", {
|
207
|
-
action,
|
208
|
-
status,
|
209
|
-
logs,
|
210
|
-
allowed: this.allowedActions,
|
211
|
-
inputs,
|
212
|
-
report,
|
213
|
-
data,
|
214
|
-
})
|
215
|
-
},
|
216
|
-
|
217
|
-
ready: function (message: string) {
|
218
|
-
this.log("ready", [message])
|
219
|
-
},
|
220
|
-
success: function (type: TSuccessType, stdout: string, lang) {
|
221
|
-
const types = ["compiler", "testing"]
|
222
|
-
|
223
|
-
if (!types.includes(type))
|
224
|
-
this.fatal(`Invalid socket success type "${type}" on socket`)
|
225
|
-
else if (
|
226
|
-
stdout === "" &&
|
227
|
-
lang &&
|
228
|
-
Object.keys(languageToMessage).includes(lang)
|
229
|
-
) {
|
230
|
-
this.log((type + "-success") as TSuccessType, [languageToMessage[lang]])
|
231
|
-
} else if (stdout === "") {
|
232
|
-
this.log((type + "-success") as TSuccessType, [
|
233
|
-
"No stdout to display on the console",
|
234
|
-
])
|
235
|
-
} else
|
236
|
-
this.log((type + "-success") as TSuccessType, [stdout])
|
237
|
-
},
|
238
|
-
error: function (type: TStatus, stdout: string) {
|
239
|
-
if (!this.config?.editor.hideTerminal) {
|
240
|
-
queue.dispatcher().enqueue(queue.events.OPEN_TERMINAL, "")
|
241
|
-
}
|
242
|
-
|
243
|
-
this.log(type, [stdout])
|
244
|
-
|
245
|
-
if (this.isTestingEnvironment) {
|
246
|
-
this.onTestingFinished({
|
247
|
-
result: "failed",
|
248
|
-
})
|
249
|
-
}
|
250
|
-
},
|
251
|
-
complete: function () {
|
252
|
-
console.log("complete")
|
253
|
-
},
|
254
|
-
dialog: function (message: string, format = "md") {
|
255
|
-
if (!this.socket) {
|
256
|
-
this.fatal("Socket is not initialized")
|
257
|
-
return
|
258
|
-
}
|
259
|
-
|
260
|
-
this.emit("dialog", "talk", [], undefined, undefined, { message, format })
|
261
|
-
},
|
262
|
-
|
263
|
-
fatal: function (msg: string) {
|
264
|
-
this.log("internal-error", [msg])
|
265
|
-
throw msg
|
266
|
-
},
|
267
|
-
onTestingFinished: function (result: any) {
|
268
|
-
if (this.config?.testingFinishedCallback) {
|
269
|
-
this.config.testingFinishedCallback(result)
|
270
|
-
}
|
271
|
-
},
|
272
|
-
}
|
273
|
-
|
274
|
-
export default SocketManager
|
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
|
+
|
13
|
+
const languageToMessage: Record<string, string> = {
|
14
|
+
python3:
|
15
|
+
"Your code executed without erros, but no output is shown on the terminal. Maybe you forgot to include a print statement in your code?",
|
16
|
+
node: "Your code executed without erros, but no output is shown on the terminal. Maybe you forgot to include a console.log statement in your code?",
|
17
|
+
}
|
18
|
+
|
19
|
+
const SocketManager: ISocket = {
|
20
|
+
socket: null,
|
21
|
+
config: null,
|
22
|
+
allowedActions: [],
|
23
|
+
possibleActions: ["build", "reset", "test", "tutorial"],
|
24
|
+
isTestingEnvironment: false,
|
25
|
+
actionCallBacks: {
|
26
|
+
clean: (_, s: { logs: Array<string> }) => {
|
27
|
+
s.logs = []
|
28
|
+
},
|
29
|
+
},
|
30
|
+
addAllowed: function (actions: Array<TPossibleActions> | TPossibleActions) {
|
31
|
+
if (!Array.isArray(actions))
|
32
|
+
actions = [actions]
|
33
|
+
|
34
|
+
// avoid adding the "test" action if grading is disabled
|
35
|
+
if (
|
36
|
+
actions.includes("test") &&
|
37
|
+
this.config?.disabledActions?.includes("test")
|
38
|
+
) {
|
39
|
+
actions = actions.filter((a: TPossibleActions) => a !== "test")
|
40
|
+
}
|
41
|
+
|
42
|
+
this.allowedActions = [
|
43
|
+
...(this.allowedActions || []).filter(
|
44
|
+
(a: TPossibleActions) => !actions.includes(a)
|
45
|
+
),
|
46
|
+
...actions,
|
47
|
+
]
|
48
|
+
},
|
49
|
+
removeAllowed: function (
|
50
|
+
actions: Array<TPossibleActions> | TPossibleActions
|
51
|
+
) {
|
52
|
+
if (!Array.isArray(actions)) {
|
53
|
+
actions = [actions]
|
54
|
+
}
|
55
|
+
|
56
|
+
this.allowedActions = (this.allowedActions || []).filter(
|
57
|
+
(a: TPossibleActions) => !actions.includes(a)
|
58
|
+
)
|
59
|
+
},
|
60
|
+
start: function (
|
61
|
+
config: IConfig,
|
62
|
+
server: http.Server,
|
63
|
+
isTestingEnvironment = false
|
64
|
+
) {
|
65
|
+
this.config = config
|
66
|
+
this.isTestingEnvironment = isTestingEnvironment
|
67
|
+
this.socket = new Server(server, {
|
68
|
+
allowEIO3: true,
|
69
|
+
cors: {
|
70
|
+
origin: "http://localhost:5173",
|
71
|
+
methods: ["GET", "POST"],
|
72
|
+
},
|
73
|
+
})
|
74
|
+
|
75
|
+
this.allowedActions =
|
76
|
+
this.config?.disabledActions?.includes("test") ||
|
77
|
+
this.config?.disableGrading ?
|
78
|
+
this.possibleActions.filter(
|
79
|
+
a => !this.config?.disabledActions?.includes(a) && a !== "test"
|
80
|
+
) :
|
81
|
+
this.possibleActions.filter(a => !this.allowedActions?.includes(a))
|
82
|
+
|
83
|
+
if (this.config?.grading === "incremental") {
|
84
|
+
this.removeAllowed("reset")
|
85
|
+
}
|
86
|
+
|
87
|
+
if (this.socket) {
|
88
|
+
this.socket.on("connection", (socket: Socket) => {
|
89
|
+
Console.debug(
|
90
|
+
"Connection with client successfully established",
|
91
|
+
this.allowedActions
|
92
|
+
)
|
93
|
+
if (!this.isTestingEnvironment) {
|
94
|
+
this.log("ready", ["Ready to compile or test..."])
|
95
|
+
}
|
96
|
+
|
97
|
+
socket.on(
|
98
|
+
"compiler",
|
99
|
+
({ action, data }: { action: string; data: IExerciseData }) => {
|
100
|
+
this.emit("clean", "pending", ["Working..."])
|
101
|
+
if (typeof data.exerciseSlug === "undefined") {
|
102
|
+
this.log("internal-error", ["No exercise slug specified"])
|
103
|
+
Console.error("No exercise slug especified")
|
104
|
+
return
|
105
|
+
}
|
106
|
+
|
107
|
+
if (
|
108
|
+
this.actionCallBacks &&
|
109
|
+
typeof this.actionCallBacks[action] === "function"
|
110
|
+
) {
|
111
|
+
this.actionCallBacks[action](data)
|
112
|
+
} else {
|
113
|
+
this.log("internal-error", ["Uknown action " + action])
|
114
|
+
}
|
115
|
+
}
|
116
|
+
)
|
117
|
+
})
|
118
|
+
}
|
119
|
+
},
|
120
|
+
on: function (action: TAction, callBack: ICallback) {
|
121
|
+
if (this.actionCallBacks) {
|
122
|
+
this.actionCallBacks[action] = callBack
|
123
|
+
}
|
124
|
+
},
|
125
|
+
clean: function (_ = "pending", logs = []) {
|
126
|
+
this.emit("clean", "pending", logs)
|
127
|
+
},
|
128
|
+
ask: function (questions = []) {
|
129
|
+
return new Promise((resolve, _) => {
|
130
|
+
this.emit("ask", "pending", ["Waiting for input..."], questions)
|
131
|
+
|
132
|
+
this.on("input", ({ inputs }: any) => {
|
133
|
+
// Workaround to fix issue because null inputs
|
134
|
+
|
135
|
+
let isNull = false
|
136
|
+
// eslint-disable-next-line
|
137
|
+
inputs.forEach((input: any) => {
|
138
|
+
if (input === null) {
|
139
|
+
isNull = true
|
140
|
+
}
|
141
|
+
})
|
142
|
+
|
143
|
+
if (!isNull) {
|
144
|
+
resolve(inputs)
|
145
|
+
}
|
146
|
+
})
|
147
|
+
})
|
148
|
+
},
|
149
|
+
sessionRefreshed: function (data) {
|
150
|
+
this.emit("session-refreshed", "", [data])
|
151
|
+
},
|
152
|
+
|
153
|
+
reload: function (
|
154
|
+
files: Array<string> | null = null,
|
155
|
+
exercises: Array<string> | null = null
|
156
|
+
) {
|
157
|
+
this.emit("reload", files?.join("") || "", exercises!)
|
158
|
+
},
|
159
|
+
openWindow: function (url = "") {
|
160
|
+
queue.dispatcher().enqueue(queue.events.OPEN_WINDOW, url)
|
161
|
+
this.emit(
|
162
|
+
queue.events.OPEN_WINDOW as TAction,
|
163
|
+
"ready",
|
164
|
+
[`Opening ${url}`],
|
165
|
+
[],
|
166
|
+
[],
|
167
|
+
url
|
168
|
+
)
|
169
|
+
},
|
170
|
+
log: function (
|
171
|
+
status: TStatus,
|
172
|
+
messages: string | Array<string> = [],
|
173
|
+
report: Array<string> = [],
|
174
|
+
data: any = null
|
175
|
+
) {
|
176
|
+
this.emit("log", status, messages, [], report, data)
|
177
|
+
Console.log(messages)
|
178
|
+
},
|
179
|
+
emit: function (
|
180
|
+
action: TAction,
|
181
|
+
status: TStatus | string = "ready",
|
182
|
+
logs: string | Array<string> = [],
|
183
|
+
inputs: Array<string> = [],
|
184
|
+
report: Array<string> = [],
|
185
|
+
data: any = null
|
186
|
+
) {
|
187
|
+
if (
|
188
|
+
this.config?.compiler &&
|
189
|
+
["webpack", "vanillajs", "vue", "react", "css", "html"].includes(
|
190
|
+
this.config?.compiler
|
191
|
+
)
|
192
|
+
) {
|
193
|
+
if (["compiler-success", "compiler-warning"].includes(status))
|
194
|
+
this.addAllowed("preview")
|
195
|
+
if (["compiler-error"].includes(status) || action === "ready")
|
196
|
+
this.removeAllowed("preview")
|
197
|
+
}
|
198
|
+
|
199
|
+
if (this.config?.grading === "incremental") {
|
200
|
+
this.removeAllowed("reset")
|
201
|
+
}
|
202
|
+
|
203
|
+
// eslint-disable-next-line
|
204
|
+
this.config?.disabledActions?.forEach((a) => this.removeAllowed(a))
|
205
|
+
|
206
|
+
this.socket?.emit("compiler", {
|
207
|
+
action,
|
208
|
+
status,
|
209
|
+
logs,
|
210
|
+
allowed: this.allowedActions,
|
211
|
+
inputs,
|
212
|
+
report,
|
213
|
+
data,
|
214
|
+
})
|
215
|
+
},
|
216
|
+
|
217
|
+
ready: function (message: string) {
|
218
|
+
this.log("ready", [message])
|
219
|
+
},
|
220
|
+
success: function (type: TSuccessType, stdout: string, lang) {
|
221
|
+
const types = ["compiler", "testing"]
|
222
|
+
|
223
|
+
if (!types.includes(type))
|
224
|
+
this.fatal(`Invalid socket success type "${type}" on socket`)
|
225
|
+
else if (
|
226
|
+
stdout === "" &&
|
227
|
+
lang &&
|
228
|
+
Object.keys(languageToMessage).includes(lang)
|
229
|
+
) {
|
230
|
+
this.log((type + "-success") as TSuccessType, [languageToMessage[lang]])
|
231
|
+
} else if (stdout === "") {
|
232
|
+
this.log((type + "-success") as TSuccessType, [
|
233
|
+
"No stdout to display on the console",
|
234
|
+
])
|
235
|
+
} else
|
236
|
+
this.log((type + "-success") as TSuccessType, [stdout])
|
237
|
+
},
|
238
|
+
error: function (type: TStatus, stdout: string) {
|
239
|
+
if (!this.config?.editor.hideTerminal) {
|
240
|
+
queue.dispatcher().enqueue(queue.events.OPEN_TERMINAL, "")
|
241
|
+
}
|
242
|
+
|
243
|
+
this.log(type, [stdout])
|
244
|
+
|
245
|
+
if (this.isTestingEnvironment) {
|
246
|
+
this.onTestingFinished({
|
247
|
+
result: "failed",
|
248
|
+
})
|
249
|
+
}
|
250
|
+
},
|
251
|
+
complete: function () {
|
252
|
+
console.log("complete")
|
253
|
+
},
|
254
|
+
dialog: function (message: string, format = "md") {
|
255
|
+
if (!this.socket) {
|
256
|
+
this.fatal("Socket is not initialized")
|
257
|
+
return
|
258
|
+
}
|
259
|
+
|
260
|
+
this.emit("dialog", "talk", [], undefined, undefined, { message, format })
|
261
|
+
},
|
262
|
+
|
263
|
+
fatal: function (msg: string) {
|
264
|
+
this.log("internal-error", [msg])
|
265
|
+
throw msg
|
266
|
+
},
|
267
|
+
onTestingFinished: function (result: any) {
|
268
|
+
if (this.config?.testingFinishedCallback) {
|
269
|
+
this.config.testingFinishedCallback(result)
|
270
|
+
}
|
271
|
+
},
|
272
|
+
}
|
273
|
+
|
274
|
+
export default SocketManager
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { IFile } from "../models/file"
|
2
2
|
import API from "../utils/api"
|
3
|
+
const packageInfo = require("../../package.json")
|
3
4
|
import Console from "../utils/console"
|
4
5
|
|
5
6
|
const fs = require("fs")
|
@@ -77,6 +78,7 @@ type TStudent = {
|
|
77
78
|
|
78
79
|
export interface ITelemetryJSONSchema {
|
79
80
|
telemetry_id?: string
|
81
|
+
version: string
|
80
82
|
user_id?: number | string
|
81
83
|
slug: string
|
82
84
|
agent?: string
|
@@ -111,6 +113,7 @@ interface ITelemetryManager {
|
|
111
113
|
user: TUser
|
112
114
|
urls: TTelemetryUrls
|
113
115
|
started: boolean
|
116
|
+
version: string
|
114
117
|
salute: (message: string) => void
|
115
118
|
start: (
|
116
119
|
agent: string,
|
@@ -136,6 +139,7 @@ interface ITelemetryManager {
|
|
136
139
|
const TelemetryManager: ITelemetryManager = {
|
137
140
|
current: null,
|
138
141
|
urls: {},
|
142
|
+
version: packageInfo.version,
|
139
143
|
user: {
|
140
144
|
token: "",
|
141
145
|
id: "",
|
@@ -160,6 +164,8 @@ const TelemetryManager: ITelemetryManager = {
|
|
160
164
|
this.current = {
|
161
165
|
telemetry_id: createUUID(),
|
162
166
|
slug: tutorialSlug,
|
167
|
+
version: `CLI:${this.version}`,
|
168
|
+
user_id: 0,
|
163
169
|
agent,
|
164
170
|
tutorial_started_at: Date.now(),
|
165
171
|
last_interaction_at: Date.now(),
|
@@ -176,6 +182,10 @@ const TelemetryManager: ITelemetryManager = {
|
|
176
182
|
this.user.id = this.current.user_id.toString()
|
177
183
|
}
|
178
184
|
|
185
|
+
if (!this.current.version) {
|
186
|
+
this.current.version = `CLI:${this.version}`
|
187
|
+
}
|
188
|
+
|
179
189
|
this.save()
|
180
190
|
|
181
191
|
this.started = true
|
package/src/models/action.ts
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
export type TAction =
|
2
|
-
| "test"
|
3
|
-
| "log"
|
4
|
-
| "reload"
|
5
|
-
| "ready"
|
6
|
-
| "clean"
|
7
|
-
| "ask"
|
8
|
-
| "file_change"
|
9
|
-
| "dialog"
|
10
|
-
| "session-refreshed"
|
11
|
-
|
12
|
-
export type ICallback = (...agrs: any[]) => any
|
1
|
+
export type TAction =
|
2
|
+
| "test"
|
3
|
+
| "log"
|
4
|
+
| "reload"
|
5
|
+
| "ready"
|
6
|
+
| "clean"
|
7
|
+
| "ask"
|
8
|
+
| "file_change"
|
9
|
+
| "dialog"
|
10
|
+
| "session-refreshed"
|
11
|
+
|
12
|
+
export type ICallback = (...agrs: any[]) => any
|