@learnpack/learnpack 5.0.31 → 5.0.33
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/commands/start.js +3 -27
- package/lib/managers/server/routes.js +9 -10
- package/lib/managers/session.js +0 -6
- package/lib/managers/telemetry.d.ts +8 -25
- package/lib/managers/telemetry.js +16 -207
- package/lib/models/action.d.ts +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/src/commands/start.ts +2 -33
- package/src/managers/server/routes.ts +10 -11
- package/src/managers/session.ts +0 -5
- package/src/managers/socket.ts +274 -274
- package/src/managers/telemetry.ts +31 -271
- package/src/models/action.ts +1 -0
- package/src/models/status.ts +1 -1
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/5.0.
|
24
|
+
@learnpack/learnpack/5.0.33 win32-x64 node-v22.14.0
|
25
25
|
$ learnpack --help [COMMAND]
|
26
26
|
USAGE
|
27
27
|
$ learnpack COMMAND
|
@@ -76,7 +76,7 @@ DESCRIPTION
|
|
76
76
|
12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
|
77
77
|
```
|
78
78
|
|
79
|
-
_See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
79
|
+
_See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\audit.ts)_
|
80
80
|
|
81
81
|
## `learnpack breakToken`
|
82
82
|
|
@@ -91,7 +91,7 @@ OPTIONS
|
|
91
91
|
-y, --yes Skip all prompts and initialize an empty project
|
92
92
|
```
|
93
93
|
|
94
|
-
_See code: [src\commands\breakToken.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
94
|
+
_See code: [src\commands\breakToken.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\breakToken.ts)_
|
95
95
|
|
96
96
|
## `learnpack clean`
|
97
97
|
|
@@ -106,7 +106,7 @@ DESCRIPTION
|
|
106
106
|
Extra documentation goes here
|
107
107
|
```
|
108
108
|
|
109
|
-
_See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
109
|
+
_See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\clean.ts)_
|
110
110
|
|
111
111
|
## `learnpack download [PACKAGE]`
|
112
112
|
|
@@ -124,7 +124,7 @@ DESCRIPTION
|
|
124
124
|
Extra documentation goes here
|
125
125
|
```
|
126
126
|
|
127
|
-
_See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
127
|
+
_See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\download.ts)_
|
128
128
|
|
129
129
|
## `learnpack help [COMMAND]`
|
130
130
|
|
@@ -156,7 +156,7 @@ OPTIONS
|
|
156
156
|
-y, --yes Skip all prompts and initialize an empty project
|
157
157
|
```
|
158
158
|
|
159
|
-
_See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
159
|
+
_See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\init.ts)_
|
160
160
|
|
161
161
|
## `learnpack login [PACKAGE]`
|
162
162
|
|
@@ -174,7 +174,7 @@ DESCRIPTION
|
|
174
174
|
Extra documentation goes here
|
175
175
|
```
|
176
176
|
|
177
|
-
_See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
177
|
+
_See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\login.ts)_
|
178
178
|
|
179
179
|
## `learnpack logout [PACKAGE]`
|
180
180
|
|
@@ -192,7 +192,7 @@ DESCRIPTION
|
|
192
192
|
Extra documentation goes here
|
193
193
|
```
|
194
194
|
|
195
|
-
_See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
195
|
+
_See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\logout.ts)_
|
196
196
|
|
197
197
|
## `learnpack plugins`
|
198
198
|
|
@@ -323,7 +323,7 @@ OPTIONS
|
|
323
323
|
-h, --help show CLI help
|
324
324
|
```
|
325
325
|
|
326
|
-
_See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
326
|
+
_See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\publish.ts)_
|
327
327
|
|
328
328
|
## `learnpack start`
|
329
329
|
|
@@ -345,7 +345,7 @@ OPTIONS
|
|
345
345
|
-y, --yes Skip all prompts and initialize an empty project
|
346
346
|
```
|
347
347
|
|
348
|
-
_See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
348
|
+
_See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\start.ts)_
|
349
349
|
|
350
350
|
## `learnpack test [EXERCISESLUG]`
|
351
351
|
|
@@ -362,7 +362,7 @@ OPTIONS
|
|
362
362
|
-y, --yes Skip all prompts and initialize an empty project
|
363
363
|
```
|
364
364
|
|
365
|
-
_See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
365
|
+
_See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\test.ts)_
|
366
366
|
|
367
367
|
## `learnpack translate`
|
368
368
|
|
@@ -376,7 +376,7 @@ OPTIONS
|
|
376
376
|
-y, --yes Skip all prompts and initialize an empty project
|
377
377
|
```
|
378
378
|
|
379
|
-
_See code: [src\commands\translate.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.
|
379
|
+
_See code: [src\commands\translate.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.33/src\commands\translate.ts)_
|
380
380
|
<!-- commandsstop -->
|
381
381
|
|
382
382
|
> > > > > > > 0cb3e56d84c197f9d008836bb573eade212b7e57
|
package/lib/commands/start.js
CHANGED
@@ -22,7 +22,7 @@ class StartCommand extends SessionCommand_1.default {
|
|
22
22
|
await this.initSession(flags);
|
23
23
|
}
|
24
24
|
async run() {
|
25
|
-
var _a, _b, _c, _d
|
25
|
+
var _a, _b, _c, _d;
|
26
26
|
// get configuration object
|
27
27
|
const configObject = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.get();
|
28
28
|
const hasXDG = await osOperations_1.eventManager.checkXDGInstalled();
|
@@ -57,28 +57,9 @@ class StartCommand extends SessionCommand_1.default {
|
|
57
57
|
create: true,
|
58
58
|
path: `${config.dirPath}/vscode_queue.json`,
|
59
59
|
});
|
60
|
-
if (configObject.exercises) {
|
61
|
-
const agent = ((_d = configObject.config) === null || _d === void 0 ? void 0 : _d.editor.agent) || "";
|
62
|
-
const path = ((_e = configObject.config) === null || _e === void 0 ? void 0 : _e.dirPath) || "";
|
63
|
-
const tutorialSlug = ((_f = configObject.config) === null || _f === void 0 ? void 0 : _f.slug) || "";
|
64
|
-
const steps = configObject.exercises.map((e, index) => ({
|
65
|
-
slug: e.slug,
|
66
|
-
position: e.position || index,
|
67
|
-
files: e.files,
|
68
|
-
ai_interactions: [],
|
69
|
-
compilations: [],
|
70
|
-
tests: [],
|
71
|
-
quiz_submissions: [],
|
72
|
-
is_testeable: e.graded || false,
|
73
|
-
}));
|
74
|
-
if (path && steps.length > 0) {
|
75
|
-
telemetry_1.default.start(agent, steps, path, tutorialSlug);
|
76
|
-
}
|
77
|
-
if (config.telemetry) {
|
78
|
-
telemetry_1.default.urls = config.telemetry;
|
79
|
-
}
|
80
|
-
}
|
81
60
|
socket_1.default.start(config, server, false);
|
61
|
+
const telemetryPath = ((_d = configObject.config) === null || _d === void 0 ? void 0 : _d.dirPath) || "";
|
62
|
+
telemetry_1.default.start(telemetryPath, socket_1.default);
|
82
63
|
socket_1.default.on("open", (data) => {
|
83
64
|
console_1.default.debug("Opening these files: ", data);
|
84
65
|
const files = (0, misc_1.prioritizeHTMLFile)(data.files);
|
@@ -144,10 +125,6 @@ class StartCommand extends SessionCommand_1.default {
|
|
144
125
|
telemetry: telemetry_1.default,
|
145
126
|
});
|
146
127
|
});
|
147
|
-
socket_1.default.on("telemetry_event", (data) => {
|
148
|
-
const { stepPosition, event, eventData } = data;
|
149
|
-
telemetry_1.default.registerStepEvent(stepPosition, event, eventData);
|
150
|
-
});
|
151
128
|
socket_1.default.on("test", async (data) => {
|
152
129
|
var _a, _b;
|
153
130
|
const exercise = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.getExercise(data.exerciseSlug);
|
@@ -203,7 +180,6 @@ class StartCommand extends SessionCommand_1.default {
|
|
203
180
|
const terminate = async () => {
|
204
181
|
var _a;
|
205
182
|
console_1.default.error("Terminating Learnpack...");
|
206
|
-
await telemetry_1.default.submit();
|
207
183
|
(_a = this.configManager) === null || _a === void 0 ? void 0 : _a.noCurrentExercise();
|
208
184
|
dispatcher.enqueue(dispatcher.events.END);
|
209
185
|
process.exit();
|
@@ -43,7 +43,7 @@ async function default_1(app, configObject, configManager) {
|
|
43
43
|
res.json(confObject);
|
44
44
|
}));
|
45
45
|
// Added this line to parse the json body
|
46
|
-
const jsonBodyParser = bodyParser.json();
|
46
|
+
const jsonBodyParser = bodyParser.json({ limit: "10mb" });
|
47
47
|
// Trying to log in from frontend
|
48
48
|
app.post("/login", jsonBodyParser, withHandler(async (req, res) => {
|
49
49
|
const email = req.body.email;
|
@@ -132,20 +132,19 @@ async function default_1(app, configObject, configManager) {
|
|
132
132
|
res.status(500).json({ error: "Internal server error" });
|
133
133
|
}
|
134
134
|
}));
|
135
|
-
app.get("/telemetry
|
136
|
-
const
|
137
|
-
|
138
|
-
|
135
|
+
app.get("/telemetry", async (req, res) => {
|
136
|
+
const telemetry = await telemetry_1.default.retrieve();
|
137
|
+
res.json(telemetry);
|
138
|
+
});
|
139
|
+
app.post("/telemetry", jsonBodyParser, async (req, res) => {
|
140
|
+
const telemetry = req.body;
|
141
|
+
await telemetry_1.default.save(telemetry);
|
142
|
+
res.json({ message: "Telemetry saved successfully" });
|
139
143
|
});
|
140
144
|
app.get("/check/rigo/status", withHandler(async (_, res) => {
|
141
145
|
const payload = await session_1.default.getPayload();
|
142
146
|
if (payload && payload.rigobot && payload.rigobot.key) {
|
143
147
|
res.json({ rigoToken: payload.rigobot.key, payload: payload });
|
144
|
-
telemetry_1.default.setStudent({
|
145
|
-
user_id: payload.user_id,
|
146
|
-
email: payload.email,
|
147
|
-
token: payload.token,
|
148
|
-
});
|
149
148
|
}
|
150
149
|
else {
|
151
150
|
res
|
package/lib/managers/session.js
CHANGED
@@ -7,7 +7,6 @@ const errors_1 = require("../utils/errors");
|
|
7
7
|
const fs = require("fs");
|
8
8
|
const cli_ux_1 = require("cli-ux");
|
9
9
|
const storage = require("node-persist");
|
10
|
-
const telemetry_1 = require("./telemetry");
|
11
10
|
const path = require("path");
|
12
11
|
const os = require("os");
|
13
12
|
const GLOBAL_SESSION_PATH = path.join(os.homedir(), ".learnpack-session");
|
@@ -110,11 +109,6 @@ const Session = {
|
|
110
109
|
const data = await api_1.default.login(email, password);
|
111
110
|
if (data) {
|
112
111
|
this.start({ token: data.token, payload: data });
|
113
|
-
telemetry_1.default.setStudent({
|
114
|
-
user_id: data.user_id,
|
115
|
-
email: data.email,
|
116
|
-
token: data.token,
|
117
|
-
});
|
118
112
|
return data;
|
119
113
|
}
|
120
114
|
},
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { IFile } from "../models/file";
|
2
|
+
import { ISocket } from "../models/socket";
|
2
3
|
type TCompilationAttempt = {
|
3
4
|
source_code: string;
|
4
5
|
stdout: string;
|
@@ -46,13 +47,9 @@ type TWorkoutSession = {
|
|
46
47
|
started_at: number;
|
47
48
|
ended_at?: number;
|
48
49
|
};
|
49
|
-
type TStudent = {
|
50
|
-
token: string;
|
51
|
-
user_id: string;
|
52
|
-
email: string;
|
53
|
-
};
|
54
50
|
export interface ITelemetryJSONSchema {
|
55
51
|
telemetry_id?: string;
|
52
|
+
version: string;
|
56
53
|
user_id?: number | string;
|
57
54
|
slug: string;
|
58
55
|
agent?: string;
|
@@ -66,28 +63,14 @@ export type TTelemetryUrls = {
|
|
66
63
|
streaming?: string;
|
67
64
|
batch?: string;
|
68
65
|
};
|
69
|
-
|
70
|
-
token: string;
|
71
|
-
id: string;
|
72
|
-
email: string;
|
73
|
-
};
|
74
|
-
interface ITelemetryManager {
|
75
|
-
current: ITelemetryJSONSchema | null;
|
66
|
+
interface ITelemetryManagerCLI {
|
76
67
|
configPath: string | null;
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
salute: (message: string) => void;
|
81
|
-
start: (agent: string, steps: TStep[], path: string, tutorialSlug: string) => void;
|
82
|
-
prevStep?: number;
|
68
|
+
socket: ISocket | null;
|
69
|
+
version: string;
|
70
|
+
start: (path: string, socket: ISocket) => void;
|
83
71
|
registerStepEvent: (stepPosition: number, event: TStepEvent, data: any) => void;
|
84
|
-
|
85
|
-
submit: () => Promise<void>;
|
86
|
-
finishWorkoutSession: () => void;
|
87
|
-
setStudent: (student: TStudent) => void;
|
88
|
-
save: () => void;
|
72
|
+
save: (telemetry: ITelemetryJSONSchema) => void;
|
89
73
|
retrieve: () => Promise<ITelemetryJSONSchema | null>;
|
90
|
-
getStep: (stepPosition: number) => TStep | null;
|
91
74
|
}
|
92
|
-
declare const TelemetryManager:
|
75
|
+
declare const TelemetryManager: ITelemetryManagerCLI;
|
93
76
|
export default TelemetryManager;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
const
|
3
|
+
const packageInfo = require("../../package.json");
|
4
4
|
const console_1 = require("../utils/console");
|
5
5
|
const fs = require("fs");
|
6
6
|
function createUUID() {
|
@@ -11,169 +11,21 @@ function stringToBase64(input) {
|
|
11
11
|
return Buffer.from(input).toString("base64");
|
12
12
|
}
|
13
13
|
const TelemetryManager = {
|
14
|
-
|
15
|
-
|
16
|
-
user: {
|
17
|
-
token: "",
|
18
|
-
id: "",
|
19
|
-
email: "",
|
20
|
-
},
|
14
|
+
version: packageInfo.version,
|
15
|
+
socket: null,
|
21
16
|
configPath: "",
|
22
|
-
|
23
|
-
salute: message => {
|
24
|
-
console_1.default.info(message);
|
25
|
-
},
|
26
|
-
start: function (agent, steps, path, tutorialSlug) {
|
17
|
+
start: function (path, socket) {
|
27
18
|
this.configPath = path;
|
28
|
-
|
29
|
-
this.retrieve()
|
30
|
-
.then(data => {
|
31
|
-
const prevTelemetry = data;
|
32
|
-
if (prevTelemetry) {
|
33
|
-
this.current = prevTelemetry;
|
34
|
-
this.finishWorkoutSession();
|
35
|
-
}
|
36
|
-
else {
|
37
|
-
this.current = {
|
38
|
-
telemetry_id: createUUID(),
|
39
|
-
slug: tutorialSlug,
|
40
|
-
agent,
|
41
|
-
tutorial_started_at: Date.now(),
|
42
|
-
last_interaction_at: Date.now(),
|
43
|
-
steps,
|
44
|
-
workout_session: [
|
45
|
-
{
|
46
|
-
started_at: Date.now(),
|
47
|
-
},
|
48
|
-
],
|
49
|
-
};
|
50
|
-
}
|
51
|
-
if (this.current.user_id) {
|
52
|
-
this.user.id = this.current.user_id.toString();
|
53
|
-
}
|
54
|
-
this.save();
|
55
|
-
this.started = true;
|
56
|
-
console_1.default.debug("Telemetry started successfully!");
|
57
|
-
if (!this.user.id) {
|
58
|
-
console_1.default.debug("No user ID found, impossible to submit telemetry at start");
|
59
|
-
return;
|
60
|
-
}
|
61
|
-
this.submit();
|
62
|
-
})
|
63
|
-
.catch(error => {
|
64
|
-
console_1.default.debug(error);
|
65
|
-
// Delete the telemetry.json if it exists
|
66
|
-
fs.unlinkSync(`${this.configPath}/telemetry.json`);
|
67
|
-
throw new Error("There was a problem starting, reload LearnPack\nRun\n$ learnpack start");
|
68
|
-
});
|
69
|
-
}
|
70
|
-
},
|
71
|
-
setStudent: function (student) {
|
72
|
-
if (!this.current) {
|
73
|
-
console_1.default.debug("Telemetry has not been started");
|
74
|
-
return;
|
75
|
-
}
|
76
|
-
console_1.default.debug("Setting student", student);
|
77
|
-
this.current.user_id = student.user_id;
|
78
|
-
this.user.id = student.user_id;
|
79
|
-
this.user.token = student.token;
|
80
|
-
this.user.email = student.email;
|
81
|
-
this.save();
|
82
|
-
this.submit();
|
83
|
-
},
|
84
|
-
finishWorkoutSession: function () {
|
85
|
-
var _a, _b;
|
86
|
-
if (!this.current) {
|
87
|
-
return;
|
88
|
-
}
|
89
|
-
const lastSession = (_a = this.current) === null || _a === void 0 ? void 0 : _a.workout_session[this.current.workout_session.length - 1];
|
90
|
-
if (lastSession &&
|
91
|
-
!lastSession.ended_at &&
|
92
|
-
((_b = this.current) === null || _b === void 0 ? void 0 : _b.last_interaction_at)) {
|
93
|
-
lastSession.ended_at = this.current.last_interaction_at;
|
94
|
-
this.current.workout_session.push({
|
95
|
-
started_at: Date.now(),
|
96
|
-
});
|
97
|
-
}
|
19
|
+
this.socket = socket;
|
98
20
|
},
|
99
21
|
registerStepEvent: function (stepPosition, event, data) {
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
return;
|
108
|
-
}
|
109
|
-
if (data.source_code) {
|
110
|
-
data.source_code = stringToBase64(data.source_code);
|
111
|
-
}
|
112
|
-
if (data.stdout) {
|
113
|
-
data.stdout = stringToBase64(data.stdout);
|
114
|
-
}
|
115
|
-
if (data.stderr) {
|
116
|
-
data.stderr = stringToBase64(data.stderr);
|
117
|
-
}
|
118
|
-
if (Object.prototype.hasOwnProperty.call(data, "exitCode")) {
|
119
|
-
data.exit_code = data.exitCode;
|
120
|
-
data.exitCode = undefined;
|
121
|
-
}
|
122
|
-
switch (event) {
|
123
|
-
case "compile":
|
124
|
-
if (!step.compilations) {
|
125
|
-
step.compilations = [];
|
126
|
-
}
|
127
|
-
step.compilations.push(data);
|
128
|
-
this.current.steps[stepPosition] = step;
|
129
|
-
break;
|
130
|
-
case "test":
|
131
|
-
if (!step.tests) {
|
132
|
-
step.tests = [];
|
133
|
-
}
|
134
|
-
// data.stdout =
|
135
|
-
step.tests.push(data);
|
136
|
-
if (data.exit_code === 0) {
|
137
|
-
step.completed_at = Date.now();
|
138
|
-
}
|
139
|
-
this.current.steps[stepPosition] = step;
|
140
|
-
break;
|
141
|
-
case "ai_interaction":
|
142
|
-
if (!step.ai_interactions) {
|
143
|
-
step.ai_interactions = [];
|
144
|
-
}
|
145
|
-
step.ai_interactions.push(data);
|
146
|
-
break;
|
147
|
-
case "quiz_submission": {
|
148
|
-
if (!step.quiz_submissions) {
|
149
|
-
step.quiz_submissions = [];
|
150
|
-
}
|
151
|
-
step.quiz_submissions.push(data);
|
152
|
-
break;
|
153
|
-
}
|
154
|
-
case "open_step": {
|
155
|
-
const now = Date.now();
|
156
|
-
if (!step.opened_at) {
|
157
|
-
step.opened_at = now;
|
158
|
-
this.current.steps[stepPosition] = step;
|
159
|
-
}
|
160
|
-
if (this.prevStep || this.prevStep === 0) {
|
161
|
-
const prevStep = this.current.steps[this.prevStep];
|
162
|
-
if (!prevStep.is_testeable && !prevStep.completed_at) {
|
163
|
-
prevStep.completed_at = now;
|
164
|
-
this.current.steps[this.prevStep] = prevStep;
|
165
|
-
}
|
166
|
-
}
|
167
|
-
this.prevStep = stepPosition;
|
168
|
-
this.submit();
|
169
|
-
break;
|
170
|
-
}
|
171
|
-
default:
|
172
|
-
throw new Error(`Event type ${event} is not supported`);
|
173
|
-
}
|
174
|
-
this.current.last_interaction_at = Date.now();
|
175
|
-
this.streamEvent(stepPosition, event, data);
|
176
|
-
this.save();
|
22
|
+
var _a;
|
23
|
+
console_1.default.debug(`Registering Telemetry Event ${event}`);
|
24
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.emit("telemetry_event", "ready", [`Registering telemetry event ${event}`], [], [], {
|
25
|
+
stepPosition,
|
26
|
+
event,
|
27
|
+
data,
|
28
|
+
});
|
177
29
|
},
|
178
30
|
retrieve: function () {
|
179
31
|
return new Promise((resolve, reject) => {
|
@@ -191,61 +43,18 @@ const TelemetryManager = {
|
|
191
43
|
try {
|
192
44
|
resolve(JSON.parse(data));
|
193
45
|
}
|
194
|
-
catch (
|
195
|
-
|
46
|
+
catch (_a) {
|
47
|
+
resolve(null);
|
196
48
|
}
|
197
49
|
}
|
198
50
|
});
|
199
51
|
});
|
200
52
|
},
|
201
|
-
|
202
|
-
|
203
|
-
return ((_a = this.current) === null || _a === void 0 ? void 0 : _a.steps[stepPosition]) || null;
|
204
|
-
},
|
205
|
-
submit: async function () {
|
206
|
-
console_1.default.debug("Submitting telemetry...");
|
207
|
-
if (!this.current) {
|
208
|
-
console_1.default.debug("Telemetry has not been started");
|
209
|
-
return Promise.resolve();
|
210
|
-
}
|
211
|
-
if (!this.user.id) {
|
212
|
-
console_1.default.debug("User ID not found, skipping batch telemetry delivery");
|
213
|
-
return Promise.resolve();
|
214
|
-
}
|
215
|
-
const url = this.urls.batch;
|
216
|
-
if (!url) {
|
217
|
-
console_1.default.debug("Batch URL not found, skipping batch telemetry delivery");
|
218
|
-
return Promise.resolve();
|
219
|
-
}
|
220
|
-
const body = this.current;
|
221
|
-
if (!body.user_id) {
|
222
|
-
body.user_id = this.user.id;
|
223
|
-
}
|
224
|
-
api_1.default.sendBatchTelemetry(url, body);
|
225
|
-
},
|
226
|
-
save: function () {
|
227
|
-
fs.writeFile(`${this.configPath}/telemetry.json`, JSON.stringify(this.current), (err) => {
|
53
|
+
save: function (telemetry) {
|
54
|
+
fs.writeFile(`${this.configPath}/telemetry.json`, JSON.stringify(telemetry), (err) => {
|
228
55
|
if (err)
|
229
56
|
throw err;
|
230
57
|
});
|
231
58
|
},
|
232
|
-
streamEvent: async function (stepPosition, event, data) {
|
233
|
-
if (!this.current)
|
234
|
-
return;
|
235
|
-
const url = this.urls.streaming;
|
236
|
-
if (!url) {
|
237
|
-
return;
|
238
|
-
}
|
239
|
-
const stepSlug = this.current.steps[stepPosition].slug;
|
240
|
-
const body = {
|
241
|
-
slug: stepSlug,
|
242
|
-
telemetry_id: this.current.telemetry_id,
|
243
|
-
user_id: this.current.user_id,
|
244
|
-
step_position: stepPosition,
|
245
|
-
event,
|
246
|
-
data,
|
247
|
-
};
|
248
|
-
api_1.default.sendStreamTelemetry(url, body);
|
249
|
-
},
|
250
59
|
};
|
251
60
|
exports.default = TelemetryManager;
|
package/lib/models/action.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export type TAction = "test" | "log" | "reload" | "ready" | "clean" | "ask" | "file_change" | "dialog" | "session-refreshed";
|
1
|
+
export type TAction = "test" | "log" | "reload" | "ready" | "clean" | "ask" | "file_change" | "dialog" | "session-refreshed" | "telemetry_event";
|
2
2
|
export type ICallback = (...agrs: any[]) => any;
|
package/oclif.manifest.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":"5.0.
|
1
|
+
{"version":"5.0.33","commands":{"audit":{"id":"audit","description":"learnpack audit is the command in charge of creating an auditory of the repository\n...\nlearnpack audit checks for the following information in a repository:\n 1. The configuration object has slug, repository and description. (Error)\n 2. The command learnpack clean has been run. (Error)\n 3. If a markdown or test file doesn't have any content. (Error)\n 4. The links are accessing to valid servers. (Error)\n 5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)\n 6. The external images are working (If they are pointing to a valid server). (Error)\n 7. The exercises directory names are valid. (Error)\n 8. If an exercise doesn't have a README file. (Error)\n 9. The exercises array (Of the config file) has content. (Error)\n 10. The exercses have the same translations. (Warning)\n 11. The .gitignore file exists. (Warning)\n 12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"breakToken":{"id":"breakToken","description":"Break the token","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"clean":{"id":"clean","description":"Clean the configuration object\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"download":{"id":"download","description":"Describe the command here\n...\nExtra documentation goes here\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"init":{"id":"init","description":"Create a new learning package: Book, Tutorial or Exercise","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"login":{"id":"login","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"logout":{"id":"logout","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"publish":{"id":"publish","description":"Builds the project by copying necessary files and directories into a zip file","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"disableGrading":{"name":"disableGrading","type":"boolean","char":"D","description":"disble grading functionality","allowNo":false},"watch":{"name":"watch","type":"boolean","char":"w","description":"Watch for file changes","allowNo":false},"editor":{"name":"editor","type":"option","char":"e","description":"[preview, extension]","options":["extension","preview"]},"version":{"name":"version","type":"option","char":"v","description":"E.g: 1.0.1"},"grading":{"name":"grading","type":"option","char":"g","description":"[isolated, incremental]","options":["isolated","incremental"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"test":{"id":"test","description":"Test exercises","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false}},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]},"translate":{"id":"translate","description":"List all the lessons, the user is able of select many of them to translate to the given languages","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Skip all prompts and initialize an empty project","allowNo":false}},"args":[]}}}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@learnpack/learnpack",
|
3
3
|
"description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
|
4
|
-
"version": "5.0.
|
4
|
+
"version": "5.0.33",
|
5
5
|
"author": "Alejandro Sanchez @alesanchezr",
|
6
6
|
"contributors": [
|
7
7
|
{
|
package/src/commands/start.ts
CHANGED
@@ -143,33 +143,9 @@ export default class StartCommand extends SessionCommand {
|
|
143
143
|
path: `${config.dirPath}/vscode_queue.json`,
|
144
144
|
})
|
145
145
|
|
146
|
-
if (configObject.exercises) {
|
147
|
-
const agent = configObject.config?.editor.agent || ""
|
148
|
-
const path = configObject.config?.dirPath || ""
|
149
|
-
const tutorialSlug = configObject.config?.slug || ""
|
150
|
-
|
151
|
-
const steps: TStep[] = configObject.exercises.map(
|
152
|
-
(e: IExercise, index): TStep => ({
|
153
|
-
slug: e.slug,
|
154
|
-
position: e.position || index,
|
155
|
-
files: e.files,
|
156
|
-
ai_interactions: [],
|
157
|
-
compilations: [],
|
158
|
-
tests: [],
|
159
|
-
quiz_submissions: [],
|
160
|
-
is_testeable: e.graded || false,
|
161
|
-
})
|
162
|
-
)
|
163
|
-
if (path && steps.length > 0) {
|
164
|
-
TelemetryManager.start(agent, steps, path, tutorialSlug)
|
165
|
-
}
|
166
|
-
|
167
|
-
if (config.telemetry) {
|
168
|
-
TelemetryManager.urls = config.telemetry
|
169
|
-
}
|
170
|
-
}
|
171
|
-
|
172
146
|
socket.start(config, server, false)
|
147
|
+
const telemetryPath = configObject.config?.dirPath || ""
|
148
|
+
TelemetryManager.start(telemetryPath, socket)
|
173
149
|
|
174
150
|
socket.on("open", (data: IGitpodData) => {
|
175
151
|
Console.debug("Opening these files: ", data)
|
@@ -252,12 +228,6 @@ export default class StartCommand extends SessionCommand {
|
|
252
228
|
})
|
253
229
|
})
|
254
230
|
|
255
|
-
socket.on("telemetry_event", (data: any) => {
|
256
|
-
const { stepPosition, event, eventData } = data
|
257
|
-
|
258
|
-
TelemetryManager.registerStepEvent(stepPosition, event, eventData)
|
259
|
-
})
|
260
|
-
|
261
231
|
socket.on("test", async (data: IExerciseData) => {
|
262
232
|
const exercise = this.configManager?.getExercise(data.exerciseSlug)
|
263
233
|
|
@@ -335,7 +305,6 @@ export default class StartCommand extends SessionCommand {
|
|
335
305
|
|
336
306
|
const terminate = async () => {
|
337
307
|
Console.error("Terminating Learnpack...")
|
338
|
-
await TelemetryManager.submit()
|
339
308
|
this.configManager?.noCurrentExercise()
|
340
309
|
dispatcher.enqueue(dispatcher.events.END)
|
341
310
|
process.exit()
|