@learnpack/learnpack 5.0.26 → 5.0.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.
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.26 win32-x64 node-v20.16.0
24
+ @learnpack/learnpack/5.0.28 win32-x64 node-v20.16.0
25
25
  $ learnpack --help [COMMAND]
26
26
  USAGE
27
27
  $ learnpack COMMAND
@@ -33,6 +33,7 @@ USAGE
33
33
 
34
34
  <!-- commands -->
35
35
  * [`learnpack audit`](#learnpack-audit)
36
+ * [`learnpack breakToken`](#learnpack-breaktoken)
36
37
  * [`learnpack clean`](#learnpack-clean)
37
38
  * [`learnpack download [PACKAGE]`](#learnpack-download-package)
38
39
  * [`learnpack help [COMMAND]`](#learnpack-help-command)
@@ -75,7 +76,22 @@ DESCRIPTION
75
76
  12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
76
77
  ```
77
78
 
78
- _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\audit.ts)_
79
+ _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\audit.ts)_
80
+
81
+ ## `learnpack breakToken`
82
+
83
+ Break the token
84
+
85
+ ```
86
+ USAGE
87
+ $ learnpack breakToken
88
+
89
+ OPTIONS
90
+ -h, --grading show CLI help
91
+ -y, --yes Skip all prompts and initialize an empty project
92
+ ```
93
+
94
+ _See code: [src\commands\breakToken.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\breakToken.ts)_
79
95
 
80
96
  ## `learnpack clean`
81
97
 
@@ -90,7 +106,7 @@ DESCRIPTION
90
106
  Extra documentation goes here
91
107
  ```
92
108
 
93
- _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\clean.ts)_
109
+ _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\clean.ts)_
94
110
 
95
111
  ## `learnpack download [PACKAGE]`
96
112
 
@@ -108,7 +124,7 @@ DESCRIPTION
108
124
  Extra documentation goes here
109
125
  ```
110
126
 
111
- _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\download.ts)_
127
+ _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\download.ts)_
112
128
 
113
129
  ## `learnpack help [COMMAND]`
114
130
 
@@ -140,7 +156,7 @@ OPTIONS
140
156
  -y, --yes Skip all prompts and initialize an empty project
141
157
  ```
142
158
 
143
- _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\init.ts)_
159
+ _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\init.ts)_
144
160
 
145
161
  ## `learnpack login [PACKAGE]`
146
162
 
@@ -158,7 +174,7 @@ DESCRIPTION
158
174
  Extra documentation goes here
159
175
  ```
160
176
 
161
- _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\login.ts)_
177
+ _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\login.ts)_
162
178
 
163
179
  ## `learnpack logout [PACKAGE]`
164
180
 
@@ -176,7 +192,7 @@ DESCRIPTION
176
192
  Extra documentation goes here
177
193
  ```
178
194
 
179
- _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\logout.ts)_
195
+ _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\logout.ts)_
180
196
 
181
197
  ## `learnpack plugins`
182
198
 
@@ -307,7 +323,7 @@ OPTIONS
307
323
  -h, --help show CLI help
308
324
  ```
309
325
 
310
- _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\publish.ts)_
326
+ _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\publish.ts)_
311
327
 
312
328
  ## `learnpack start`
313
329
 
@@ -329,7 +345,7 @@ OPTIONS
329
345
  -y, --yes Skip all prompts and initialize an empty project
330
346
  ```
331
347
 
332
- _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\start.ts)_
348
+ _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\start.ts)_
333
349
 
334
350
  ## `learnpack test [EXERCISESLUG]`
335
351
 
@@ -346,7 +362,7 @@ OPTIONS
346
362
  -y, --yes Skip all prompts and initialize an empty project
347
363
  ```
348
364
 
349
- _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\test.ts)_
365
+ _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\test.ts)_
350
366
 
351
367
  ## `learnpack translate`
352
368
 
@@ -360,7 +376,7 @@ OPTIONS
360
376
  -y, --yes Skip all prompts and initialize an empty project
361
377
  ```
362
378
 
363
- _See code: [src\commands\translate.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.26/src\commands\translate.ts)_
379
+ _See code: [src\commands\translate.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.28/src\commands\translate.ts)_
364
380
  <!-- commandsstop -->
365
381
 
366
382
  > > > > > > > 0cb3e56d84c197f9d008836bb573eade212b7e57
@@ -0,0 +1,10 @@
1
+ import BaseCommand from "../utils/BaseCommand";
2
+ declare class BreakTokenCommand extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ grading: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
6
+ yes: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ export default BreakTokenCommand;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const command_1 = require("@oclif/command");
4
+ const BaseCommand_1 = require("../utils/BaseCommand");
5
+ const session_1 = require("../managers/session");
6
+ class BreakTokenCommand extends BaseCommand_1.default {
7
+ async run() {
8
+ const { flags } = this.parse(BreakTokenCommand);
9
+ await session_1.default.breakToken();
10
+ process.exit(0);
11
+ }
12
+ }
13
+ BreakTokenCommand.description = "Break the token";
14
+ BreakTokenCommand.flags = Object.assign(Object.assign({}, BaseCommand_1.default.flags), { grading: command_1.flags.help({ char: "h" }) });
15
+ exports.default = BreakTokenCommand;
@@ -13,86 +13,34 @@ const errors_1 = require("../utils/errors");
13
13
  const path = require("path");
14
14
  const rigoActions_1 = require("../utils/rigoActions");
15
15
  const api_2 = require("../utils/api");
16
- const slugify = (text) => {
17
- return text
18
- .toString()
19
- .normalize("NFD")
20
- .replace(/[\u0300-\u036F]/g, "")
21
- .toLowerCase()
22
- .trim()
23
- .replace(/\s+/g, "-")
24
- .replace(/[^\w-]+/g, "");
25
- };
26
- const getExInfo = (title) => {
27
- // Example title: '1.0 - Introduction to AI [READ: Small introduction to important concepts such as AI, machine learning, and their applications]'
28
- let [exNumber, exTitle] = title.split(" - ");
29
- // Extract kind and description
30
- const kindMatch = exTitle.match(/\[(.*?):(.*?)]/);
31
- const kind = kindMatch ? kindMatch[1].trim().toLowerCase() : "read";
32
- const description = kindMatch ? kindMatch[2].trim() : "";
33
- exNumber = exNumber.trim();
34
- // Clean title
35
- exTitle = exTitle.replace((kindMatch === null || kindMatch === void 0 ? void 0 : kindMatch[0]) || "", "").trim();
36
- exTitle = slugify(exTitle);
37
- return {
38
- exNumber,
39
- kind,
40
- description,
41
- exTitle,
42
- };
43
- };
44
- function extractImagesFromMarkdown(markdown) {
45
- const imageRegex = /!\[([^\]]*)]\(([^)]+)\)/g;
46
- const images = [];
47
- let match;
48
- while ((match = imageRegex.exec(markdown)) !== null) {
49
- const altText = match[1];
50
- const url = match[2];
51
- images.push({ alt: altText, url: url });
52
- }
53
- return images;
54
- }
55
- function getFilenameFromUrl(url) {
56
- return path.basename(url);
57
- }
58
- const makePackageInfo = (choices) => {
59
- const packageInfo = {
60
- grading: choices.grading,
61
- difficulty: choices.difficulty,
62
- duration: parseInt(choices.duration),
63
- description: {
64
- us: choices.description,
65
- },
66
- title: {
67
- us: choices.title,
68
- },
69
- slug: choices.title
70
- .toLowerCase()
71
- .replace(/ /g, "-")
72
- .replace(/[^\w-]+/g, ""),
73
- };
74
- return packageInfo;
75
- };
76
- async function createPreviewReadme(tutorialDir, packageInfo, rigoToken, readmeContents) {
77
- const readmeFilename = `README.md`;
78
- const readmeContent = await (0, rigoActions_1.generateCourseIntroduction)(rigoToken, {
79
- course_title: packageInfo.title.us,
80
- lessons_context: readmeContents.join("\n"),
81
- });
82
- fs.writeFileSync(path.join(tutorialDir, readmeFilename), readmeContent.answer);
83
- }
16
+ const creatorUtilities_1 = require("../utils/creatorUtilities");
17
+ const session_1 = require("../managers/session");
84
18
  const initializeInteractiveCreation = async (rigoToken, courseInfo) => {
85
19
  let prevInteractions = "";
86
20
  let isReady = false;
87
21
  let currentSteps = [];
22
+ let currentTitle = "";
23
+ let currentDescription = "";
88
24
  while (!isReady) {
25
+ let wholeInfo = courseInfo;
26
+ wholeInfo += `
27
+ Current title: ${currentTitle}
28
+ Current description: ${currentDescription}
29
+ `;
89
30
  // eslint-disable-next-line
90
31
  const res = await (0, rigoActions_1.interactiveCreation)(rigoToken, {
91
- courseInfo: courseInfo,
32
+ courseInfo: wholeInfo,
92
33
  prevInteractions: prevInteractions,
93
34
  });
94
35
  currentSteps = res.parsed.listOfSteps;
95
36
  isReady = res.parsed.ready;
37
+ if (res.parsed.title && currentTitle !== res.parsed.title) {
38
+ currentTitle = res.parsed.title;
39
+ }
40
+ if (res.parsed.description &&
41
+ currentDescription !== res.parsed.description) {
42
+ currentDescription = res.parsed.description;
43
+ }
96
44
  if (!isReady) {
97
45
  console.log(currentSteps);
98
46
  console_1.default.info(`AI: ${res.parsed.aiMessage}`);
@@ -109,45 +57,32 @@ const initializeInteractiveCreation = async (rigoToken, courseInfo) => {
109
57
  }
110
58
  }
111
59
  return {
112
- currentSteps,
113
- prevInteractions,
60
+ steps: currentSteps,
61
+ title: currentTitle,
62
+ description: currentDescription,
63
+ interactions: prevInteractions,
114
64
  };
115
65
  };
116
66
  const handleAILogic = async (tutorialDir, packageInfo) => {
117
- console_1.default.info("Almost there! First you need to login with 4Geeks.com to use AI Generation tool for creators. You can create a new account here: https://4geeks.com/creators");
118
67
  fs.removeSync(path.join(tutorialDir, "exercises", "01-hello-world"));
119
- const loginPrompts = await prompts([
120
- {
121
- type: "text",
122
- name: "email",
123
- message: "What's your email?",
124
- validate: (value) => {
125
- return value.length > 0 && value.includes("@");
126
- },
127
- },
128
- {
129
- type: "password",
130
- name: "password",
131
- message: "What's your password?",
132
- validate: (value) => {
133
- return value.length > 0;
134
- },
135
- },
136
- ]);
137
- let sessionPayload;
138
- try {
139
- sessionPayload = await api_1.default.login(loginPrompts.email, loginPrompts.password);
140
- }
141
- catch (error) {
142
- console_1.default.error("Error trying to authenticate");
143
- console_1.default.error(error.message || error);
144
- return;
68
+ let sessionPayload = await session_1.default.getPayload();
69
+ if (!sessionPayload ||
70
+ !sessionPayload.rigobot ||
71
+ (sessionPayload.token && !(await api_1.default.validateToken(sessionPayload.token)))) {
72
+ console_1.default.info("Almost there! First you need to login with 4Geeks.com to use AI Generation tool for creators. You can create a new account here: https://4geeks.com/creators");
73
+ try {
74
+ sessionPayload = await session_1.default.login();
75
+ }
76
+ catch (error) {
77
+ console_1.default.error("Error trying to authenticate");
78
+ console_1.default.error(error.message || error);
79
+ }
145
80
  }
146
81
  const rigoToken = sessionPayload.rigobot.key;
147
- const consumables = await (0, api_2.getConsumables)(sessionPayload.token, "ai-generation");
148
- if (consumables.ai_generation === 0) {
149
- console_1.default.error("It seems you cannot generate tutorials with AI. Make sure you creator subscription is up to date here: https://4geeks.com/profile/subscriptions? . If you believe there is an issue you can always contact support@4geeks.com");
150
- process.exit(1);
82
+ const consumable = await (0, api_2.getConsumable)(sessionPayload.token, "ai-generation");
83
+ if (consumable.count === 0) {
84
+ console_1.default.error("It seems you cannot generate tutorials with AI. Make sure you creator subscription is up to date here: https://4geeks.com/profile/subscriptions. If you believe there is an issue you can always contact support@4geeks.com");
85
+ // process.exit(1)
151
86
  }
152
87
  const isCreator = await (0, rigoActions_1.hasCreatorPermission)(rigoToken);
153
88
  if (!isCreator) {
@@ -155,42 +90,53 @@ const handleAILogic = async (tutorialDir, packageInfo) => {
155
90
  process.exit(1);
156
91
  }
157
92
  console_1.default.success("🎉 Let's begin this learning journey!");
158
- const packageContext = `
93
+ let packageContext = `
159
94
  \n
160
- The following information comes from user inputs
161
95
  Title: ${packageInfo.title.us}
162
96
  Description: ${packageInfo.description.us}
163
- Grading: ${packageInfo.grading}
164
97
  Difficulty: ${packageInfo.difficulty}
165
98
  Duration: ${packageInfo.duration}
166
-
167
- Use it to generate more relevant exercises
168
99
  `;
169
- const { currentSteps } = await initializeInteractiveCreation(rigoToken, packageContext);
100
+ const { steps, title, description } = await initializeInteractiveCreation(rigoToken, packageContext);
101
+ packageInfo.title.us = title;
102
+ packageInfo.description.us = description;
103
+ packageContext = `
104
+ Title: ${title}
105
+ Description: ${description}
106
+ Difficulty: ${packageInfo.difficulty}
107
+ Estimated duration: ${packageInfo.duration}
108
+ List of exercises: ${steps.join(", ")}
109
+ `;
170
110
  const exercisesDir = path.join(tutorialDir, "exercises");
171
111
  fs.ensureDirSync(exercisesDir);
172
112
  console_1.default.info("Creating lessons...");
173
- for (const [index, exercise] of currentSteps.entries()) {
174
- const { exNumber, exTitle } = getExInfo(exercise);
113
+ for (const [index, exercise] of steps.entries()) {
114
+ const { exNumber, exTitle } = (0, creatorUtilities_1.getExInfo)(exercise);
175
115
  const exerciseDir = path.join(exercisesDir, `${exNumber}-${exTitle}`);
176
116
  fs.ensureDirSync(exerciseDir);
177
117
  }
178
- const exercisePromises = currentSteps.map(async (exercise, index) => {
179
- const { exNumber, exTitle, kind, description } = getExInfo(exercise);
118
+ const exercisePromises = steps.map(async (exercise, index) => {
119
+ const { exNumber, exTitle, kind, description } = (0, creatorUtilities_1.getExInfo)(exercise);
180
120
  const exerciseDir = path.join(exercisesDir, `${exNumber}-${exTitle}`);
181
121
  const readme = await (0, rigoActions_1.readmeCreator)(rigoToken, {
182
122
  title: `${exNumber} - ${exTitle}`,
183
123
  output_lang: "en",
184
- list_of_exercises: currentSteps.join(","),
124
+ list_of_exercises: steps.join(","),
185
125
  tutorial_description: packageContext,
186
126
  lesson_description: description,
187
127
  kind: kind.toLowerCase(),
188
128
  });
129
+ const { exceedsThreshold, newMarkdown } = (0, creatorUtilities_1.checkReadingTime)(readme.parsed.content, 200);
130
+ if (exceedsThreshold) {
131
+ console_1.default.error("The reading time exceeds the threshold");
132
+ console_1.default.info(`Please reduce the reading time of the lesson, current reading time is ${exceedsThreshold} minutes`);
133
+ }
189
134
  const readmeFilename = "README.md";
190
- fs.writeFileSync(path.join(exerciseDir, readmeFilename), readme.parsed.content);
135
+ fs.writeFileSync(path.join(exerciseDir, readmeFilename), newMarkdown);
191
136
  if (kind.toLowerCase() === "code") {
192
137
  const codeFile = await (0, rigoActions_1.createCodeFile)(rigoToken, {
193
138
  readme: readme.parsed.content,
139
+ tutorial_info: packageContext,
194
140
  });
195
141
  fs.writeFileSync(path.join(exerciseDir, `app.${codeFile.parsed.extension.replace(".", "")}`), codeFile.parsed.content);
196
142
  }
@@ -201,11 +147,11 @@ const handleAILogic = async (tutorialDir, packageInfo) => {
201
147
  console_1.default.success("Lessons created! 🎉");
202
148
  console_1.default.info("Generating images for the lessons...");
203
149
  for (const content of readmeContents) {
204
- imagesArray = [...imagesArray, ...extractImagesFromMarkdown(content)];
150
+ imagesArray = [...imagesArray, ...(0, creatorUtilities_1.extractImagesFromMarkdown)(content)];
205
151
  }
206
152
  const imagePromises = imagesArray.map(async (image) => {
207
153
  try {
208
- const filename = getFilenameFromUrl(image.url);
154
+ const filename = (0, creatorUtilities_1.getFilenameFromUrl)(image.url);
209
155
  const imagePath = path.join(tutorialDir, ".learn", "assets", filename);
210
156
  const res = await (0, rigoActions_1.generateImage)(rigoToken, { prompt: image.alt });
211
157
  await (0, rigoActions_1.downloadImage)(res.image_url, imagePath);
@@ -219,7 +165,7 @@ const handleAILogic = async (tutorialDir, packageInfo) => {
219
165
  await Promise.all(imagePromises);
220
166
  console_1.default.info("Images generated successfully! 🎉 Your tutorial will be ready soon!");
221
167
  console_1.default.info("Creating preview readme...");
222
- await createPreviewReadme(tutorialDir, packageInfo, rigoToken, readmeContents);
168
+ await (0, rigoActions_1.createPreviewReadme)(tutorialDir, packageInfo, rigoToken, readmeContents);
223
169
  return true;
224
170
  };
225
171
  const getChoices = async (empty) => {
@@ -307,7 +253,7 @@ class InitComand extends BaseCommand_1.default {
307
253
  const { flags } = this.parse(InitComand);
308
254
  await alreadyInitialized();
309
255
  const choices = await getChoices(flags.yes);
310
- const packageInfo = makePackageInfo(choices);
256
+ const packageInfo = (0, creatorUtilities_1.makePackageInfo)(choices);
311
257
  const tutorialDir = `./${packageInfo.slug}`;
312
258
  fs.ensureDirSync(tutorialDir);
313
259
  const templatesDir = path.resolve(__dirname, "../../src/utils/templates/" + (choices.grading || "no-grading"));
@@ -13,6 +13,8 @@ const axios_1 = require("axios");
13
13
  const FormData = require("form-data");
14
14
  const console_1 = require("../utils/console");
15
15
  const file_1 = require("../managers/file");
16
+ const api_1 = require("../utils/api");
17
+ const prompts = require("prompts");
16
18
  const RIGOBOT_HOST = "https://rigobot.herokuapp.com";
17
19
  // const RIGOBOT_HOST =
18
20
  // "https://8000-charlytoc-rigobot-bmwdeam7cev.ws-us116.gitpod.io"
@@ -37,6 +39,26 @@ const runAudit = () => {
37
39
  // Continuar con el proceso de build solo si `learnpack publish` fue exitoso
38
40
  console_1.default.info("Learnpack publish completed successfully. Proceeding with build...");
39
41
  };
42
+ const selectAcademy = async (academies) => {
43
+ if (academies.length === 0) {
44
+ return null;
45
+ }
46
+ if (academies.length === 1) {
47
+ return academies[0];
48
+ }
49
+ // prompts the user to select an academy to upload the assets
50
+ console_1.default.info("In which academy do you want to publish the asset?");
51
+ const response = await prompts({
52
+ type: "select",
53
+ name: "academy",
54
+ message: "Select an academy",
55
+ choices: academies.map((academy) => ({
56
+ title: academy.name,
57
+ value: academy,
58
+ })),
59
+ });
60
+ return response.academy;
61
+ };
40
62
  class BuildCommand extends SessionCommand_1.default {
41
63
  async init() {
42
64
  const { flags } = this.parse(BuildCommand);
@@ -48,7 +70,9 @@ class BuildCommand extends SessionCommand_1.default {
48
70
  // this.configManager?.clean()
49
71
  const configObject = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.get();
50
72
  let sessionPayload = await session_1.default.getPayload();
51
- if (!sessionPayload || !sessionPayload.rigobot) {
73
+ if (!sessionPayload ||
74
+ !sessionPayload.rigobot ||
75
+ (sessionPayload.token && !(await api_1.default.validateToken(sessionPayload.token)))) {
52
76
  console_1.default.error("You must be logged in to upload a LearnPack package");
53
77
  try {
54
78
  sessionPayload = await session_1.default.login();
@@ -67,7 +91,10 @@ class BuildCommand extends SessionCommand_1.default {
67
91
  console_1.default.debug("Building exercises");
68
92
  (_c = this.configManager) === null || _c === void 0 ? void 0 : _c.buildIndex();
69
93
  }
70
- // const rigoToken = "417d612d226a1606ad3a4e94b1881a9f0124b667"
94
+ // const academies = await api.listUserAcademies(sessionPayload.token)
95
+ // console.log(academies, "academies")
96
+ // const academy = await selectAcademy(academies)
97
+ // console.log(academy, "academy")
71
98
  // Read learn.json to get the slug
72
99
  const learnJsonPath = path.join(process.cwd(), "learn.json");
73
100
  if (!fs.existsSync(learnJsonPath)) {
@@ -138,5 +138,13 @@ const Session = {
138
138
  this.token = null;
139
139
  console_1.default.success("You have logged out");
140
140
  },
141
+ breakToken: async function () {
142
+ const payload = await this.getPayload();
143
+ if (payload) {
144
+ this.token = "asdasdasdasd";
145
+ await storage.setItem("bc-payload", Object.assign(Object.assign({}, payload), { token: "asdasdsad" }));
146
+ console_1.default.success("Token broken successfully");
147
+ }
148
+ },
141
149
  };
142
150
  exports.default = Session;
@@ -31,5 +31,6 @@ export interface ISession {
31
31
  sync: () => Promise<void>;
32
32
  start: ({ token, payload }: IStartProps) => Promise<void>;
33
33
  destroy: () => Promise<void>;
34
+ breakToken: () => Promise<void>;
34
35
  }
35
36
  export {};
@@ -1,6 +1,14 @@
1
1
  type TConsumableSlug = "ai-conversation-message" | "ai-compilation" | "ai-tutorial-generation" | "ai-generation";
2
2
  export declare const countConsumables: (consumables: any, consumableSlug?: TConsumableSlug) => any;
3
- export declare const getConsumables: (token: string, consumableSlug?: TConsumableSlug) => Promise<any>;
3
+ export declare const getConsumable: (token: string, consumableSlug?: TConsumableSlug) => Promise<any>;
4
+ export interface TAcademy {
5
+ id: number;
6
+ name: string;
7
+ slug: string;
8
+ timezone: string;
9
+ }
10
+ export declare const listUserAcademies: (breathecodeToken: string) => Promise<TAcademy[]>;
11
+ export declare const validateToken: (token: string) => Promise<any>;
4
12
  declare const _default: {
5
13
  login: (identification: string, password: string) => Promise<any>;
6
14
  publish: (config: any) => Promise<any>;
@@ -13,5 +21,7 @@ declare const _default: {
13
21
  }) => Promise<any>;
14
22
  sendBatchTelemetry: (url: string, body: any) => Promise<void>;
15
23
  sendStreamTelemetry: (url: string, body: object) => Promise<void>;
24
+ listUserAcademies: (breathecodeToken: string) => Promise<TAcademy[]>;
25
+ validateToken: (token: string) => Promise<any>;
16
26
  };
17
27
  export default _default;
package/lib/utils/api.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getConsumables = exports.countConsumables = void 0;
3
+ exports.validateToken = exports.listUserAcademies = exports.getConsumable = exports.countConsumables = void 0;
4
4
  const console_1 = require("../utils/console");
5
5
  const storage = require("node-persist");
6
6
  const cli_ux_1 = require("cli-ux");
@@ -63,13 +63,11 @@ const login = async (identification, password) => {
63
63
  cli_ux_1.default.action.start(`Looking for credentials with ${identification}`);
64
64
  await cli_ux_1.default.wait(1000);
65
65
  const url = `${HOST}/v1/auth/login/`;
66
- const data = await fetch(url, {
67
- body: JSON.stringify({
68
- email: identification,
69
- password: password,
70
- }),
71
- method: "post",
66
+ const res = await axios_1.default.post(url, {
67
+ email: identification,
68
+ password: password,
72
69
  });
70
+ const data = res.data;
73
71
  cli_ux_1.default.action.stop("ready");
74
72
  let rigoPayload = null;
75
73
  try {
@@ -258,22 +256,60 @@ const countConsumables = (consumables, consumableSlug = "ai-tutorial-generation"
258
256
  return consumable ? consumable.balance.unit : 0;
259
257
  };
260
258
  exports.countConsumables = countConsumables;
261
- const getConsumables = async (token, consumableSlug = "ai-generation") => {
259
+ const getConsumable = async (token, consumableSlug = "ai-generation") => {
262
260
  const url = `${HOST}/v1/payments/me/service/consumable?virtual=true`;
263
261
  const headers = {
264
262
  Authorization: `Token ${token}`,
265
263
  };
266
264
  try {
267
265
  const response = await axios_1.default.get(url, { headers });
268
- const ai_tutorial_generation = (0, exports.countConsumables)(response.data, consumableSlug);
269
- return { ai_tutorial_generation };
266
+ const count = (0, exports.countConsumables)(response.data, consumableSlug);
267
+ return { count };
270
268
  }
271
269
  catch (error) {
272
270
  console.error("Error fetching consumables:", error);
273
271
  throw error;
274
272
  }
275
273
  };
276
- exports.getConsumables = getConsumables;
274
+ exports.getConsumable = getConsumable;
275
+ const listUserAcademies = async (breathecodeToken) => {
276
+ const url = "https://breathecode.herokuapp.com/v1/auth/user/me";
277
+ try {
278
+ const response = await axios_1.default.get(url, {
279
+ headers: {
280
+ Authorization: `Token ${breathecodeToken}`,
281
+ },
282
+ });
283
+ const data = response.data;
284
+ const academiesMap = new Map();
285
+ for (const role of data.roles) {
286
+ const academy = role.academy;
287
+ if (!academiesMap.has(academy.id)) {
288
+ academiesMap.set(academy.id, academy);
289
+ }
290
+ }
291
+ return [...academiesMap.values()];
292
+ }
293
+ catch (error) {
294
+ console.error("Failed to fetch user academies:", error);
295
+ return [];
296
+ }
297
+ };
298
+ exports.listUserAcademies = listUserAcademies;
299
+ const validateToken = async (token) => {
300
+ const url = "https://breathecode.herokuapp.com/v1/auth/user/me";
301
+ const headers = {
302
+ Authorization: `Token ${token}`,
303
+ };
304
+ try {
305
+ const response = await axios_1.default.get(url, { headers });
306
+ return response.data;
307
+ }
308
+ catch (_a) {
309
+ return false;
310
+ }
311
+ };
312
+ exports.validateToken = validateToken;
277
313
  exports.default = {
278
314
  login,
279
315
  publish,
@@ -283,4 +319,6 @@ exports.default = {
283
319
  getAllPackages,
284
320
  sendBatchTelemetry,
285
321
  sendStreamTelemetry,
322
+ listUserAcademies: exports.listUserAcademies,
323
+ validateToken: exports.validateToken,
286
324
  };
@@ -0,0 +1,44 @@
1
+ type TEstimateReadingTimeReturns = {
2
+ minutes: number;
3
+ words: number;
4
+ };
5
+ export declare const estimateReadingTime: (text: string, wordsPerMinute?: number) => TEstimateReadingTimeReturns;
6
+ export type PackageInfo = {
7
+ grading: string;
8
+ difficulty: string;
9
+ duration: number;
10
+ description: {
11
+ us: string;
12
+ };
13
+ title: {
14
+ us: string;
15
+ };
16
+ };
17
+ export declare function checkReadingTime(markdown: string, wordsPerMinute?: number): {
18
+ newMarkdown: string;
19
+ exceedsThreshold: boolean;
20
+ };
21
+ export declare const getExInfo: (title: string) => {
22
+ exNumber: string;
23
+ kind: string;
24
+ description: string;
25
+ exTitle: string;
26
+ };
27
+ export declare function extractImagesFromMarkdown(markdown: string): {
28
+ alt: string;
29
+ url: string;
30
+ }[];
31
+ export declare function getFilenameFromUrl(url: string): string;
32
+ export declare const makePackageInfo: (choices: any) => {
33
+ grading: any;
34
+ difficulty: any;
35
+ duration: number;
36
+ description: {
37
+ us: any;
38
+ };
39
+ title: {
40
+ us: any;
41
+ };
42
+ slug: any;
43
+ };
44
+ export {};