@learnpack/learnpack 5.0.158 → 5.0.162

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.158 win32-x64 node-v22.15.0
24
+ @learnpack/learnpack/5.0.162 win32-x64 node-v22.15.0
25
25
  $ learnpack --help [COMMAND]
26
26
  USAGE
27
27
  $ learnpack COMMAND
@@ -80,7 +80,7 @@ DESCRIPTION
80
80
  12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
81
81
  ```
82
82
 
83
- _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\audit.ts)_
83
+ _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\audit.ts)_
84
84
 
85
85
  ## `learnpack breakToken`
86
86
 
@@ -95,7 +95,7 @@ OPTIONS
95
95
  -y, --yes Skip all prompts and initialize an empty project
96
96
  ```
97
97
 
98
- _See code: [src\commands\breakToken.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\breakToken.ts)_
98
+ _See code: [src\commands\breakToken.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\breakToken.ts)_
99
99
 
100
100
  ## `learnpack clean`
101
101
 
@@ -110,7 +110,7 @@ DESCRIPTION
110
110
  Extra documentation goes here
111
111
  ```
112
112
 
113
- _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\clean.ts)_
113
+ _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\clean.ts)_
114
114
 
115
115
  ## `learnpack download [PACKAGE]`
116
116
 
@@ -128,7 +128,7 @@ DESCRIPTION
128
128
  Extra documentation goes here
129
129
  ```
130
130
 
131
- _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\download.ts)_
131
+ _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\download.ts)_
132
132
 
133
133
  ## `learnpack help [COMMAND]`
134
134
 
@@ -160,7 +160,7 @@ OPTIONS
160
160
  -y, --yes Skip all prompts and initialize an empty project
161
161
  ```
162
162
 
163
- _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\init.ts)_
163
+ _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\init.ts)_
164
164
 
165
165
  ## `learnpack login [PACKAGE]`
166
166
 
@@ -178,7 +178,7 @@ DESCRIPTION
178
178
  Extra documentation goes here
179
179
  ```
180
180
 
181
- _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\login.ts)_
181
+ _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\login.ts)_
182
182
 
183
183
  ## `learnpack logout [PACKAGE]`
184
184
 
@@ -196,7 +196,7 @@ DESCRIPTION
196
196
  Extra documentation goes here
197
197
  ```
198
198
 
199
- _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\logout.ts)_
199
+ _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\logout.ts)_
200
200
 
201
201
  ## `learnpack plugins`
202
202
 
@@ -328,7 +328,7 @@ OPTIONS
328
328
  -s, --strict strict mode
329
329
  ```
330
330
 
331
- _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\publish.ts)_
331
+ _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\publish.ts)_
332
332
 
333
333
  ## `learnpack serve`
334
334
 
@@ -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\serve.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\serve.ts)_
348
+ _See code: [src\commands\serve.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\serve.ts)_
349
349
 
350
350
  ## `learnpack start`
351
351
 
@@ -367,7 +367,7 @@ OPTIONS
367
367
  -y, --yes Skip all prompts and initialize an empty project
368
368
  ```
369
369
 
370
- _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\start.ts)_
370
+ _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\start.ts)_
371
371
 
372
372
  ## `learnpack test [EXERCISESLUG]`
373
373
 
@@ -384,7 +384,7 @@ OPTIONS
384
384
  -y, --yes Skip all prompts and initialize an empty project
385
385
  ```
386
386
 
387
- _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\test.ts)_
387
+ _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\test.ts)_
388
388
 
389
389
  ## `learnpack translate`
390
390
 
@@ -398,7 +398,7 @@ OPTIONS
398
398
  -y, --yes Skip all prompts and initialize an empty project
399
399
  ```
400
400
 
401
- _See code: [src\commands\translate.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.158/src\commands\translate.ts)_
401
+ _See code: [src\commands\translate.ts](https://github.com/learnpack/learnpack-cli/blob/v5.0.162/src\commands\translate.ts)_
402
402
  <!-- commandsstop -->
403
403
 
404
404
  > > > > > > > 0cb3e56d84c197f9d008836bb573eade212b7e57
@@ -1,6 +1,8 @@
1
1
  import SessionCommand from "../utils/SessionCommand";
2
- import { TAcademy } from "../utils/api";
3
- export declare const handleAssetCreation: (sessionPayload: any, academy: TAcademy, learnJson: any, learnpackDeployUrl: string, category: number) => Promise<void>;
2
+ export declare const handleAssetCreation: (sessionPayload: {
3
+ token: string;
4
+ rigobotToken: string;
5
+ }, learnJson: any, learnpackDeployUrl: string) => Promise<void>;
4
6
  declare class BuildCommand extends SessionCommand {
5
7
  static description: string;
6
8
  static flags: {
@@ -19,32 +19,36 @@ const prompts = require("prompts");
19
19
  const rigoActions_1 = require("../utils/rigoActions");
20
20
  const misc_1 = require("../utils/misc");
21
21
  const uploadZipEndpont = api_1.RIGOBOT_HOST + "/v1/learnpack/upload";
22
- const handleAssetCreation = async (sessionPayload, academy, learnJson, learnpackDeployUrl, category) => {
22
+ const handleAssetCreation = async (sessionPayload, learnJson, learnpackDeployUrl) => {
23
23
  try {
24
- const { exists, academyId } = await api_1.default.doesAssetExists(sessionPayload.token, learnJson.slug);
24
+ const user = await api_1.default.validateToken(sessionPayload.token);
25
+ const { exists } = await api_1.default.doesAssetExists(sessionPayload.token, learnJson.slug);
25
26
  if (!exists) {
26
27
  console_1.default.info("Asset does not exist in this academy, creating it");
27
- const asset = await api_1.default.createAsset(sessionPayload.token, academy.id, {
28
+ const asset = await api_1.default.createAsset(sessionPayload.token, {
28
29
  slug: learnJson.slug,
29
30
  title: learnJson.title.us,
30
31
  lang: "us",
31
32
  description: learnJson.description.us,
32
33
  learnpack_deploy_url: learnpackDeployUrl,
33
34
  technologies: ["node", "bash"],
34
- url: "https://4geeksacademy.com",
35
- category: category,
36
- owner: sessionPayload.id,
37
- author: sessionPayload.id,
35
+ url: learnpackDeployUrl,
36
+ category: 51,
37
+ owner: user.id,
38
+ author: user.id,
39
+ preview: learnJson.preview,
38
40
  });
41
+ await api_1.default.updateRigoAssetID(sessionPayload.token, learnJson.slug, asset.id);
39
42
  console_1.default.info("Asset created with id", asset.id);
40
43
  }
41
44
  else {
42
45
  console_1.default.info("Asset exists, updating it");
43
- const asset = await api_1.default.updateAsset(sessionPayload.token, academyId, learnJson.slug, {
46
+ const asset = await api_1.default.updateAsset(sessionPayload.token, learnJson.slug, {
44
47
  learnpack_deploy_url: learnpackDeployUrl,
45
48
  title: learnJson.title.us,
46
49
  description: learnJson.description.us,
47
50
  });
51
+ await api_1.default.updateRigoAssetID(sessionPayload.rigobotToken, learnJson.slug, asset.id);
48
52
  console_1.default.info("Asset updated with id", asset.id);
49
53
  }
50
54
  }
@@ -283,9 +287,7 @@ class BuildCommand extends SessionCommand_1.default {
283
287
  console.log(res.data);
284
288
  fs.unlinkSync(zipFilePath);
285
289
  this.removeDirectory(buildDir);
286
- if (academy) {
287
- await (0, exports.handleAssetCreation)(sessionPayload, academy, learnJson, res.data.url, category);
288
- }
290
+ await (0, exports.handleAssetCreation)(sessionPayload, learnJson, res.data.url);
289
291
  }
290
292
  catch (error) {
291
293
  if (axios_1.default.isAxiosError(error)) {
@@ -31,6 +31,7 @@ const misc_1 = require("../utils/misc");
31
31
  const configBuilder_1 = require("../utils/configBuilder");
32
32
  const creatorUtilities_2 = require("../utils/creatorUtilities");
33
33
  const sidebarGenerator_1 = require("../utils/sidebarGenerator");
34
+ const publish_1 = require("./publish");
34
35
  const frontMatter = require("front-matter");
35
36
  dotenv.config();
36
37
  const createLearnJson = (courseInfo) => {
@@ -310,6 +311,44 @@ class ServeCommand extends SessionCommand_1.default {
310
311
  res.status(500).json({ error: error.message });
311
312
  }
312
313
  });
314
+ app.put("/upload/preview-image/:slug", (0, misc_1.createUploadMiddleware)().single("file"), async (req, res) => {
315
+ const { slug } = req.params;
316
+ const rigoToken = req.header("x-rigo-token");
317
+ if (!rigoToken) {
318
+ return res.status(400).json({
319
+ error: "Rigo token is required. x-rigo-token header is missing",
320
+ });
321
+ }
322
+ const { isAuthor } = await (0, rigoActions_1.isPackageAuthor)(rigoToken, slug);
323
+ if (!isAuthor) {
324
+ return res.status(403).json({
325
+ error: "You are not authorized to upload a preview image",
326
+ });
327
+ }
328
+ // eslint-disable-next-line
329
+ // @ts-ignore
330
+ if (!slug || !req.file) {
331
+ return res.status(400).json({ error: "Slug and file are required" });
332
+ }
333
+ try {
334
+ const filePath = `courses/${slug}/preview.png`;
335
+ const file = bucket.file(filePath);
336
+ // eslint-disable-next-line
337
+ // @ts-ignore
338
+ await file.save(req.file.buffer, {
339
+ resumable: false,
340
+ // eslint-disable-next-line
341
+ // @ts-ignore
342
+ contentType: req.file.mimetype,
343
+ });
344
+ console.log(`✅ Preview image uploaded to ${filePath}`);
345
+ return res.json({ message: "Preview uploaded", path: filePath });
346
+ }
347
+ catch (error) {
348
+ console.error("❌ Error uploading preview image:", error);
349
+ return res.status(500).json({ error: error.message });
350
+ }
351
+ });
313
352
  app.get("/check-preview-image/:slug", async (req, res) => {
314
353
  const { slug } = req.params;
315
354
  const file = bucket.file(`courses/${slug}/preview.png`);
@@ -690,14 +729,7 @@ class ServeCommand extends SessionCommand_1.default {
690
729
  const rigoRes = await axios_1.default.post(`${api_1.RIGOBOT_HOST}/v1/learnpack/upload`, form, {
691
730
  headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: `Token ${rigoToken}` }),
692
731
  });
693
- // 11) Crear/actualizar asset en Breathecode
694
- // await handleAssetCreation(
695
- // { token: bcToken, rigobot: { key: rigoToken }, id: 0 },
696
- // { id: academyId } as any,
697
- // config,
698
- // rigoRes.data.url,
699
- // categoryId
700
- // )
732
+ await (0, publish_1.handleAssetCreation)({ token: bcToken, rigobotToken: rigoToken }, config, rigoRes.data.url);
701
733
  rimraf.sync(tmpRoot);
702
734
  console.log("RIGO RES", rigoRes.data);
703
735
  return res.json({ url: rigoRes.data.url });
@@ -21,8 +21,9 @@ type TAssetMissing = {
21
21
  category: number;
22
22
  owner: number;
23
23
  author: number;
24
+ preview: string;
24
25
  };
25
- export declare const createAsset: (token: string, academyId: number, asset: TAssetMissing) => Promise<any>;
26
+ export declare const createAsset: (token: string, asset: TAssetMissing) => Promise<any>;
26
27
  export declare const doesAssetExists: (token: string, assetSlug: string) => Promise<{
27
28
  exists: boolean;
28
29
  academyId?: number;
@@ -41,12 +42,13 @@ declare const _default: {
41
42
  sendStreamTelemetry: (url: string, body: object) => Promise<void>;
42
43
  listUserAcademies: (breathecodeToken: string) => Promise<TAcademy[]>;
43
44
  validateToken: (token: string) => Promise<any>;
44
- createAsset: (token: string, academyId: number, asset: TAssetMissing) => Promise<any>;
45
+ createAsset: (token: string, asset: TAssetMissing) => Promise<any>;
45
46
  doesAssetExists: (token: string, assetSlug: string) => Promise<{
46
47
  exists: boolean;
47
48
  academyId?: number;
48
49
  }>;
49
- updateAsset: (token: string, academyId: number, assetSlug: string, asset: Partial<TAssetMissing>) => Promise<any>;
50
+ updateAsset: (token: string, assetSlug: string, asset: Partial<TAssetMissing>) => Promise<any>;
50
51
  getCategories: (token: string) => Promise<any>;
52
+ updateRigoAssetID: (token: string, slug: string, asset_id: number) => Promise<any>;
51
53
  };
52
54
  export default _default;
package/lib/utils/api.js CHANGED
@@ -324,7 +324,7 @@ const validateToken = async (token) => {
324
324
  }
325
325
  };
326
326
  exports.validateToken = validateToken;
327
- const createAsset = async (token, academyId, asset) => {
327
+ const createAsset = async (token, asset) => {
328
328
  const body = {
329
329
  slug: asset.slug,
330
330
  title: asset.title,
@@ -332,7 +332,7 @@ const createAsset = async (token, academyId, asset) => {
332
332
  asset_type: "EXERCISE",
333
333
  visibility: "PUBLIC",
334
334
  status: "DRAFT",
335
- url: "https://4geeksacademy.com",
335
+ url: asset.url,
336
336
  readme_url: null,
337
337
  difficulty: null,
338
338
  duration: null,
@@ -341,7 +341,7 @@ const createAsset = async (token, academyId, asset) => {
341
341
  category: asset.category,
342
342
  owner: asset.owner,
343
343
  author: asset.author,
344
- preview: null,
344
+ preview: asset.preview,
345
345
  description: asset.description,
346
346
  external: false,
347
347
  interactive: true,
@@ -351,17 +351,16 @@ const createAsset = async (token, academyId, asset) => {
351
351
  learnpack_deploy_url: asset.learnpack_deploy_url,
352
352
  technologies: asset.technologies,
353
353
  };
354
- const url = `https://breathecode.herokuapp.com/v1/registry/academy/asset`;
354
+ const url = `https://breathecode.herokuapp.com/v1/registry/asset/me`;
355
355
  const headers = {
356
356
  Authorization: `Token ${token}`,
357
- Academy: academyId,
358
357
  };
359
358
  try {
360
359
  const response = await axios_1.default.post(url, body, { headers });
361
360
  return response.data;
362
361
  }
363
362
  catch (error) {
364
- // console.error("Failed to create asset:", error)
363
+ console.error("Failed to create asset:", error);
365
364
  throw error.response.data;
366
365
  }
367
366
  };
@@ -374,9 +373,7 @@ const doesAssetExists = async (token, assetSlug) => {
374
373
  try {
375
374
  const response = await axios_1.default.get(url, { headers });
376
375
  if (response.status === 200) {
377
- const data = response.data;
378
- const academy = data.academy.id;
379
- return { exists: true, academyId: academy };
376
+ return { exists: true };
380
377
  }
381
378
  return { exists: false };
382
379
  }
@@ -386,18 +383,17 @@ const doesAssetExists = async (token, assetSlug) => {
386
383
  }
387
384
  };
388
385
  exports.doesAssetExists = doesAssetExists;
389
- const updateAsset = async (token, academyId, assetSlug, asset) => {
390
- const url = `https://breathecode.herokuapp.com/v1/registry/academy/asset/${assetSlug}`;
386
+ const updateAsset = async (token, assetSlug, asset) => {
387
+ const url = `https://breathecode.herokuapp.com/v1/registry/asset/me/${assetSlug}`;
391
388
  const headers = {
392
389
  Authorization: `Token ${token}`,
393
- Academy: academyId,
394
390
  };
395
391
  try {
396
392
  const response = await axios_1.default.put(url, asset, { headers });
397
393
  return response.data;
398
394
  }
399
395
  catch (error) {
400
- // console.error("Failed to update asset:", error)
396
+ console.error("Failed to update asset:", error);
401
397
  // Try to print the data
402
398
  // console.log(error.response.data)
403
399
  throw error.response.data;
@@ -417,6 +413,20 @@ const getCategories = async (token) => {
417
413
  throw error;
418
414
  }
419
415
  };
416
+ const updateRigoAssetID = async (token, slug, asset_id) => {
417
+ const url = `${exports.RIGOBOT_HOST}/v1/learnpack/package/${slug}/`;
418
+ const headers = {
419
+ Authorization: `Token ${token}`,
420
+ };
421
+ try {
422
+ const response = await axios_1.default.put(url, { asset_id }, { headers });
423
+ return response.data;
424
+ }
425
+ catch (error) {
426
+ console.error("Failed to update Rigo package:", error);
427
+ throw error;
428
+ }
429
+ };
420
430
  exports.default = {
421
431
  login,
422
432
  publish,
@@ -432,4 +442,5 @@ exports.default = {
432
442
  doesAssetExists: exports.doesAssetExists,
433
443
  updateAsset,
434
444
  getCategories,
445
+ updateRigoAssetID,
435
446
  };
@@ -71,4 +71,8 @@ type TFillSidebarJSONInputs = {
71
71
  sidebar_json: string;
72
72
  };
73
73
  export declare const fillSidebarJSON: (token: string, inputs: TFillSidebarJSONInputs) => Promise<any>;
74
+ export declare const isPackageAuthor: (token: string, packageSlug: string) => Promise<{
75
+ isAuthor: boolean;
76
+ status: number;
77
+ }>;
74
78
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fillSidebarJSON = exports.generateCourseShortName = exports.isValidRigoToken = exports.readmeCreator = exports.createCodingReadme = exports.createCodeFile = exports.interactiveCreation = exports.generateCourseIntroduction = exports.translateExercise = exports.generateImage = exports.hasCreatorPermission = exports.createReadme = void 0;
3
+ exports.isPackageAuthor = exports.fillSidebarJSON = exports.generateCourseShortName = exports.isValidRigoToken = exports.readmeCreator = exports.createCodingReadme = exports.createCodeFile = exports.interactiveCreation = exports.generateCourseIntroduction = exports.translateExercise = exports.generateImage = exports.hasCreatorPermission = exports.createReadme = void 0;
4
4
  exports.downloadImage = downloadImage;
5
5
  exports.createPreviewReadme = createPreviewReadme;
6
6
  exports.makeReadmeReadable = makeReadmeReadable;
@@ -218,3 +218,20 @@ const fillSidebarJSON = async (token, inputs) => {
218
218
  return response.data;
219
219
  };
220
220
  exports.fillSidebarJSON = fillSidebarJSON;
221
+ const isPackageAuthor = async (token, packageSlug) => {
222
+ var _a;
223
+ const url = `${api_1.RIGOBOT_HOST}/v1/learnpack/package/${packageSlug}/`;
224
+ const headers = {
225
+ Authorization: `Token ${token}`,
226
+ };
227
+ try {
228
+ const response = await axios_1.default.get(url, { headers });
229
+ return { isAuthor: response.status === 200, status: response.status };
230
+ }
231
+ catch (error) {
232
+ const status = ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) || 500;
233
+ console.error("Error fetching package:", error);
234
+ return { isAuthor: false, status };
235
+ }
236
+ };
237
+ exports.isPackageAuthor = isPackageAuthor;
@@ -1 +1 @@
1
- {"version":"5.0.158","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":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false}},"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":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"serve":{"id":"serve","description":"Runs a small server to build tutorials","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"},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","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":[]}}}
1
+ {"version":"5.0.162","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":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false}},"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":{"strict":{"name":"strict","type":"boolean","char":"s","description":"strict mode","allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"serve":{"id":"serve","description":"Runs a small server to build tutorials","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"},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","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.158",
4
+ "version": "5.0.162",
5
5
  "author": "Alejandro Sanchez @alesanchezr",
6
6
  "contributors": [
7
7
  {
@@ -51,6 +51,7 @@
51
51
  "markdown-it": "^14.1.0",
52
52
  "mkdirp": "^3.0.1",
53
53
  "moment": "^2.27.0",
54
+ "multer": "^2.0.0",
54
55
  "node-emoji": "^1.10.0",
55
56
  "node-fetch": "^2.7.0",
56
57
  "node-persist": "^3.1.0",