@learnpack/learnpack 2.0.0 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
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/2.0.0 win32-x64 node-v16.14.0
24
+ @learnpack/learnpack/2.0.4 win32-x64 node-v16.14.0
25
25
  $ learnpack --help [COMMAND]
26
26
  USAGE
27
27
  $ learnpack COMMAND
@@ -74,7 +74,7 @@ DESCRIPTION
74
74
  12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
75
75
  ```
76
76
 
77
- _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\audit.ts)_
77
+ _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\audit.ts)_
78
78
 
79
79
  ## `learnpack clean`
80
80
 
@@ -89,7 +89,7 @@ DESCRIPTION
89
89
  Extra documentation goes here
90
90
  ```
91
91
 
92
- _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\clean.ts)_
92
+ _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\clean.ts)_
93
93
 
94
94
  ## `learnpack download [PACKAGE]`
95
95
 
@@ -107,7 +107,7 @@ DESCRIPTION
107
107
  Extra documentation goes here
108
108
  ```
109
109
 
110
- _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\download.ts)_
110
+ _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\download.ts)_
111
111
 
112
112
  ## `learnpack help [COMMAND]`
113
113
 
@@ -138,7 +138,7 @@ OPTIONS
138
138
  -h, --grading show CLI help
139
139
  ```
140
140
 
141
- _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\init.ts)_
141
+ _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\init.ts)_
142
142
 
143
143
  ## `learnpack login [PACKAGE]`
144
144
 
@@ -156,7 +156,7 @@ DESCRIPTION
156
156
  Extra documentation goes here
157
157
  ```
158
158
 
159
- _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\login.ts)_
159
+ _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\login.ts)_
160
160
 
161
161
  ## `learnpack logout [PACKAGE]`
162
162
 
@@ -174,7 +174,7 @@ DESCRIPTION
174
174
  Extra documentation goes here
175
175
  ```
176
176
 
177
- _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\logout.ts)_
177
+ _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\logout.ts)_
178
178
 
179
179
  ## `learnpack plugins`
180
180
 
@@ -309,7 +309,7 @@ DESCRIPTION
309
309
  Extra documentation goes here
310
310
  ```
311
311
 
312
- _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\publish.ts)_
312
+ _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\publish.ts)_
313
313
 
314
314
  ## `learnpack start`
315
315
 
@@ -330,7 +330,7 @@ OPTIONS
330
330
  -w, --watch Watch for file changes
331
331
  ```
332
332
 
333
- _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\start.ts)_
333
+ _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\start.ts)_
334
334
 
335
335
  ## `learnpack test [EXERCISESLUG]`
336
336
 
@@ -344,5 +344,5 @@ ARGUMENTS
344
344
  EXERCISESLUG The name of the exercise to test
345
345
  ```
346
346
 
347
- _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.0/src\commands\test.ts)_
347
+ _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.0.4/src\commands\test.ts)_
348
348
  <!-- commandsstop -->
@@ -1 +1 @@
1
- {"version":"2.0.0","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":[]},"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":{"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":"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}]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"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":"[standalone, gitpod]","options":["standalone","gitpod"]},"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":{},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]}}}
1
+ {"version":"2.0.4","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":[]},"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":{"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":"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}]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"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":"[standalone, gitpod]","options":["standalone","gitpod"]},"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":{},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]}}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@learnpack/learnpack",
3
3
  "description": "Create, sell or download and take learning amazing learning packages",
4
- "version": "2.0.0",
4
+ "version": "2.0.4",
5
5
  "author": "Alejandro Sanchez @alesanchezr",
6
6
  "bin": {
7
7
  "learnpack": "bin/run"
@@ -90,7 +90,8 @@
90
90
  "oclif"
91
91
  ],
92
92
  "license": "UNLICENSED",
93
- "main": "src/index.js",
93
+ "main": "../bin/index.js",
94
+ "types": "../bin/index.d.ts",
94
95
  "oclif": {
95
96
  "commands": "./src/commands",
96
97
  "bin": "learnpack",
@@ -1,62 +1,62 @@
1
- import {Command /* , flags */} from '@oclif/command'
1
+ import { Command /* , flags */ } from "@oclif/command";
2
2
  // import fetch from 'node-fetch'
3
- import {clone} from '../managers/file'
4
- import Console from '../utils/console'
5
- import api from '../utils/api'
6
- import {askPackage} from '../ui/download'
3
+ import { clone } from "../managers/file";
4
+ import Console from "../utils/console";
5
+ import api from "../utils/api";
6
+ import { askPackage } from "../ui/download";
7
7
  // const BaseCommand = require('../utils/BaseCommand');
8
8
 
9
9
  class DownloadCommand extends Command {
10
-
11
10
  static description = `Describe the command here
12
11
  ...
13
12
  Extra documentation goes here
14
- `
13
+ `;
15
14
 
16
- static flags:any = {
15
+ static flags: any = {
17
16
  // name: flags.string({char: 'n', description: 'name to print'}),
18
- }
17
+ };
19
18
 
20
19
  static args = [
21
20
  {
22
- name: 'package', // name of arg to show in help and reference with args[name]
21
+ name: "package", // name of arg to show in help and reference with args[name]
23
22
  required: false, // make the arg required with `required: true`
24
- description: 'The unique string that identifies this package on learnpack', // help description
23
+ description:
24
+ "The unique string that identifies this package on learnpack", // help description
25
25
  hidden: false, // hide this arg from help
26
26
  },
27
- ]
27
+ ];
28
28
  // async init() {
29
29
  // const {flags} = this.parse(DownloadCommand)
30
30
  // await this.initSession(flags)
31
31
  // }
32
32
 
33
33
  async run() {
34
- const {/* flags, */ args} = this.parse(DownloadCommand)
34
+ const { /* flags, */ args } = this.parse(DownloadCommand);
35
35
  // start watching for file changes
36
- let _package: string = args.package
36
+ let _package: string = args.package;
37
37
  if (!_package) {
38
- _package = (await askPackage()) as string
38
+ _package = (await askPackage()) as string;
39
39
  }
40
40
 
41
41
  if (!_package) {
42
- return null
42
+ return null;
43
43
  }
44
44
 
45
45
  try {
46
- const packageInfo = await api.getAllPackages({slug: _package})
46
+ const packageInfo = await api.getAllPackages({ slug: _package });
47
47
  if (packageInfo.results.length === 0)
48
- Console.error(`Package ${_package} not found`)
48
+ Console.error(`Package ${_package} not found`);
49
49
  else
50
50
  clone(packageInfo.results[0].repository)
51
- .then(_result => {
52
- Console.success('Successfully downloaded')
53
- Console.info(
54
- `You can now CD into the folder like this: $ cd ${_package}`,
55
- )
56
- })
57
- .catch(error => Console.error(error.message || error))
51
+ .then(_result => {
52
+ Console.success("Successfully downloaded");
53
+ Console.info(
54
+ `You can now CD into the folder like this: $ cd ${_package}`
55
+ );
56
+ })
57
+ .catch(error => Console.error(error.message || error));
58
58
  } catch {}
59
59
  }
60
60
  }
61
61
 
62
- export default DownloadCommand
62
+ export default DownloadCommand;
@@ -92,7 +92,10 @@ class InitComand extends BaseCommand {
92
92
  duration: parseInt(choices.duration),
93
93
  description: choices.description,
94
94
  title: choices.title,
95
- slug: choices.title.toLowerCase().replace(/ /g, "-").replace(/[^\w-]+/g, ""),
95
+ slug: choices.title
96
+ .toLowerCase()
97
+ .replace(/ /g, "-")
98
+ .replace(/[^\w-]+/g, ""),
96
99
  };
97
100
 
98
101
  cli.action.start("Initializing package");
@@ -1,8 +1,8 @@
1
1
  // import {Command, flags} from '@oclif/command'
2
2
  // import { prompt } from "enquirer"
3
3
  // import fetch from 'node-fetch'
4
- import SessionCommand from '../utils/SessionCommand'
5
- import SessionManager from '../managers/session'
4
+ import SessionCommand from "../utils/SessionCommand";
5
+ import SessionManager from "../managers/session";
6
6
  // import Console from '../utils/console'
7
7
  // import { replace } from 'node-emoji'
8
8
  // import { validURL } from "../utils/validators"
@@ -12,32 +12,32 @@ class LogoutCommand extends SessionCommand {
12
12
  static description = `Describe the command here
13
13
  ...
14
14
  Extra documentation goes here
15
- `
15
+ `;
16
16
 
17
17
  static flags: any = {
18
18
  // name: flags.string({char: 'n', description: 'name to print'}),
19
- }
19
+ };
20
20
 
21
21
  static args = [
22
22
  {
23
- name: 'package', // name of arg to show in help and reference with args[name]
23
+ name: "package", // name of arg to show in help and reference with args[name]
24
24
  required: false, // make the arg required with `required: true`
25
25
  description:
26
- 'The unique string that identifies this package on learnpack', // help description
26
+ "The unique string that identifies this package on learnpack", // help description
27
27
  hidden: false, // hide this arg from help
28
28
  },
29
- ]
29
+ ];
30
30
 
31
31
  async init() {
32
- const {flags} = this.parse(LogoutCommand)
33
- await this.initSession(flags)
32
+ const { flags } = this.parse(LogoutCommand);
33
+ await this.initSession(flags);
34
34
  }
35
35
 
36
36
  async run() {
37
37
  // const {flags, args} = this.parse(LogoutCommand)
38
38
 
39
- SessionManager.destroy()
39
+ SessionManager.destroy();
40
40
  }
41
41
  }
42
42
 
43
- export default LogoutCommand
43
+ export default LogoutCommand;
@@ -74,7 +74,9 @@ export default class StartCommand extends SessionCommand {
74
74
  `Grading: ${config?.grading} ${
75
75
  config?.disabledActions?.includes("test") ? "(disabled)" : ""
76
76
  }, editor: ${config?.editor.mode} ${config?.editor.version}, for ${
77
- Array.isArray(configObject?.exercises) ? configObject?.exercises.length : 0
77
+ Array.isArray(configObject?.exercises) ?
78
+ configObject?.exercises.length :
79
+ 0
78
80
  } exercises found`
79
81
  );
80
82
 
@@ -221,8 +223,11 @@ export default class StartCommand extends SessionCommand {
221
223
  setTimeout(() => dispatcher.enqueue(dispatcher.events.RUNNING), 1000);
222
224
 
223
225
  // start watching for file changes
224
- // eslint-disable-next-line
225
- if (StartCommand.flags.watch) this.configManager.watchIndex(_exercises => socket.reload(null, _exercises));
226
+
227
+ if (StartCommand.flags.watch)
228
+ this.configManager.watchIndex(_exercises =>
229
+ socket.reload(null, _exercises)
230
+ );
226
231
  }
227
232
  }
228
233
  }
@@ -11,7 +11,7 @@ class TestCommand extends SessionCommand {
11
11
  const { flags } = this.parse(TestCommand);
12
12
  await this.initSession(flags);
13
13
  }
14
-
14
+
15
15
  async run() {
16
16
  const {
17
17
  args: { exerciseSlug },
@@ -23,7 +23,9 @@ class TestCommand extends SessionCommand {
23
23
  let exercises: IExercise[] | undefined = [];
24
24
 
25
25
  // test all exercises
26
- !exerciseSlug ? exercises = this.configManager?.getAllExercises() : exercises = [this.configManager!.getExercise(exerciseSlug)];
26
+ !exerciseSlug ?
27
+ (exercises = this.configManager?.getAllExercises()) :
28
+ (exercises = [this.configManager!.getExercise(exerciseSlug)]);
27
29
 
28
30
  const exercisesQueue = new ExercisesQueue(exercises);
29
31
 
@@ -42,14 +42,14 @@ export const exercise = (
42
42
  const parts = file.split(".");
43
43
 
44
44
  if (parts.length === 3)
45
- translations[parts[1]] = file;
45
+ translations[parts[1]] = file;
46
46
  else
47
- translations.us = file;
47
+ translations.us = file;
48
48
  }
49
49
 
50
50
  // if the slug is a dot, it means there is not "exercises" folder, and its just a single README.md
51
51
  if (slug === ".")
52
- slug = "default-index";
52
+ slug = "default-index";
53
53
 
54
54
  const detected = detect(configObject, files);
55
55
 
@@ -61,24 +61,31 @@ export const exercise = (
61
61
  language: detected?.language,
62
62
  entry: detected?.entry ? path + "/" + detected.entry : null, // full path to the exercise entry
63
63
  title: slug || "Exercise",
64
- graded: files.some(file => file.toLowerCase().startsWith("test.") || file.toLowerCase().startsWith("tests.")),
64
+ graded: files.some(
65
+ file =>
66
+ file.toLowerCase().startsWith("test.") ||
67
+ file.toLowerCase().startsWith("tests.")
68
+ ),
65
69
  files: filterFiles(files, path),
66
70
  // if the exercises was on the config before I may keep the status done
67
71
  done:
68
72
  Array.isArray(exercises) &&
69
73
  typeof exercises[position] !== "undefined" &&
70
- path.slice(Math.max(0, path.indexOf("exercises/") + 10)) === exercises[position].slug ? exercises[position].done : false,
74
+ path.slice(Math.max(0, path.indexOf("exercises/") + 10)) ===
75
+ exercises[position].slug ?
76
+ exercises[position].done :
77
+ false,
71
78
  getReadme: function (lang = null) {
72
79
  if (lang === "us")
73
- lang = null; // <-- english is default, no need to append it to the file name
74
-
80
+ lang = null; // <-- english is default, no need to append it to the file name
81
+
75
82
  if (!fs.existsSync(`${this.path}/README${lang ? "." + lang : ""}.md`)) {
76
83
  Console.error(
77
84
  `Language ${lang} not found for exercise ${slug}, switching to default language`
78
85
  );
79
86
 
80
87
  if (lang)
81
- lang = null;
88
+ lang = null;
82
89
 
83
90
  if (!fs.existsSync(`${this.path}/README${lang ? "." + lang : ""}.md`))
84
91
  throw new Error(
@@ -141,7 +148,7 @@ export const exercise = (
141
148
  const _path = `${configObject?.confPath?.base}/reports/${this.slug}.json`;
142
149
 
143
150
  if (!fs.existsSync(_path))
144
- return {};
151
+ return {};
145
152
 
146
153
  const content = fs.readFileSync(_path);
147
154
  const data = JSON.parse(`${content}`);
@@ -154,7 +161,7 @@ export const exercise = (
154
161
 
155
162
  export const validateExerciseDirectoryName = (str: string) => {
156
163
  if (str === "./")
157
- return true;
164
+ return true;
158
165
  // TODO: Add nameValidationREgex from the config
159
166
  const regex = /^(\d{2,3}(\.\d{1,2})?-([\dA-Za-z]+(-|_)?)+)$/;
160
167
  return regex.test(str);
@@ -124,7 +124,9 @@ export default async ({
124
124
 
125
125
  Console.debug("This is your configuration object: ", {
126
126
  ...configObj,
127
- exercises: configObj.exercises ? configObj.exercises.map(e => e.slug) : [],
127
+ exercises: configObj.exercises ?
128
+ configObj.exercises.map(e => e.slug) :
129
+ [],
128
130
  });
129
131
 
130
132
  // auto detect agent (if possible)
@@ -151,8 +153,7 @@ export default async ({
151
153
  configObj.config.editor.agent === "localhost" ? "standalone" : "preview";
152
154
 
153
155
  if (version && configObj.config)
154
- configObj.config.editor.version = version;
155
-
156
+ configObj.config.editor.version = version;
156
157
  else if (configObj.config && configObj.config.editor.version === null) {
157
158
  Console.debug("Config version not found, downloading default.");
158
159
  const resp = await fetch(
@@ -177,7 +178,7 @@ export default async ({
177
178
  python3: "python",
178
179
  };
179
180
  if (map[_l])
180
- return map[_l];
181
+ return map[_l];
181
182
  return _l;
182
183
  };
183
184
 
@@ -185,7 +186,7 @@ export default async ({
185
186
  language = alias(language);
186
187
 
187
188
  if (this.validLanguages[language])
188
- return true;
189
+ return true;
189
190
 
190
191
  Console.debug(`Validating engine for ${language} compilation`);
191
192
  let result = shell.exec("learnpack plugins", { silent: true });
@@ -249,7 +250,7 @@ export default async ({
249
250
  const exercise = (configObj.exercises || []).find(
250
251
  ex => ex.slug === slug
251
252
  );
252
- if (!exercise)
253
+ if (!exercise)
253
254
  throw ValidationError(`Exercise ${slug} not found`);
254
255
 
255
256
  return exercise;
@@ -269,7 +270,7 @@ throw ValidationError(`Exercise ${slug} not found`);
269
270
  exercise.files.forEach((f: IFile) => {
270
271
  if (configObj.config) {
271
272
  const _path = configObj.config.outputPath + "/" + f.name;
272
- if (f.hidden === false && fs.existsSync(_path))
273
+ if (f.hidden === false && fs.existsSync(_path))
273
274
  fs.unlinkSync(_path);
274
275
  }
275
276
  });
@@ -314,7 +315,7 @@ fs.unlinkSync(_path);
314
315
  if (name === path.basename(configObj?.config?.dirPath || ""))
315
316
  return false;
316
317
  // ignore folders that start with a dot
317
- if (name.charAt(0) === "." || name.charAt(0) === "_")
318
+ if (name.charAt(0) === "." || name.charAt(0) === "_")
318
319
  return false;
319
320
 
320
321
  return fs.lstatSync(source).isDirectory();
@@ -326,7 +327,7 @@ return false;
326
327
  .map(name => path.join(source, name))
327
328
  .filter(isDirectory);
328
329
  // add the .learn folder
329
- if (!fs.existsSync(confPath.base))
330
+ if (!fs.existsSync(confPath.base))
330
331
  fs.mkdirSync(confPath.base);
331
332
  // add the outout folder where webpack will publish the the html/css/js files
332
333
  if (
@@ -359,7 +360,7 @@ fs.mkdirSync(confPath.base);
359
360
  .then((/* eventname, filename */) => {
360
361
  Console.debug("Changes detected on your exercises");
361
362
  this.buildIndex();
362
- if (onChange)
363
+ if (onChange)
363
364
  onChange();
364
365
  })
365
366
  .catch(error => {
@@ -385,7 +386,7 @@ onChange();
385
386
  } as IConfigManager;
386
387
  };
387
388
 
388
- function deepMerge(...sources: any): any {
389
+ function deepMerge(...sources: any): any {
389
390
  let acc: any = {};
390
391
  for (const source of sources) {
391
392
  if (Array.isArray(source)) {
@@ -401,7 +402,7 @@ function deepMerge(...sources: any): any {
401
402
  value = deepMerge(acc[key], value);
402
403
  }
403
404
 
404
- if (value !== undefined)
405
+ if (value !== undefined)
405
406
  acc = { ...acc, [key]: value };
406
407
  }
407
408
  }
@@ -67,8 +67,8 @@ export default async function (
67
67
  // symbolic link to maintain path compatiblity
68
68
  const fetchStaticAsset = withHandler((req, res) => {
69
69
  const filePath = `${config?.dirPath}/assets/${req.params.filePath}`;
70
- if (!fs.existsSync(filePath))
71
- throw new Error("File not found: " + filePath);
70
+ if (!fs.existsSync(filePath))
71
+ throw new Error("File not found: " + filePath);
72
72
  const content = fs.readFileSync(filePath);
73
73
  res.write(content);
74
74
  res.end();
@@ -138,18 +138,23 @@ throw new Error("File not found: " + filePath);
138
138
  dispatcher.enqueue(dispatcher.events.START_EXERCISE, req.params.slug);
139
139
 
140
140
  type TEntry = "python3" | "html" | "node" | "react" | "java";
141
+
142
+ const entries = new Set(
143
+ Object.keys(config?.entries!).map(
144
+ lang => config?.entries[lang as TEntry]
145
+ )
146
+ );
141
147
 
142
- // eslint-disable-next-line
143
- const entries = new Set(Object.keys(config?.entries!).map(
144
- lang => config?.entries[lang as TEntry]
145
- ));
146
148
  // if we are in incremental grading, the entry file can by dinamically detected
147
149
  // based on the changes the student is making during the exercise
148
150
  if (config?.grading === "incremental") {
149
151
  const scanedFiles = fs.readdirSync("./");
150
152
 
151
153
  // update the file hierarchy with updates
152
- exercise.files = [...exercise.files.filter(f => f.name.includes("test.")), ...filterFiles(scanedFiles)];
154
+ exercise.files = [
155
+ ...exercise.files.filter(f => f.name.includes("test.")),
156
+ ...filterFiles(scanedFiles),
157
+ ];
153
158
  Console.debug(`Exercise updated files: `, exercise.files);
154
159
  }
155
160
 
@@ -27,7 +27,7 @@ class BaseCommand extends Command {
27
27
  // process.emit('SIGINT')
28
28
  // process.emit('SIGINT')
29
29
  });
30
- }
30
+ }
31
31
 
32
32
  process.on("SIGINT", function () {
33
33
  Console.debug("Terminated (SIGINT)");
package/src/utils/api.ts CHANGED
@@ -32,11 +32,11 @@ const fetch = async (url: string, options: IOptions = {}) => {
32
32
  headers: { ...headers, ...options.headers },
33
33
  } as any);
34
34
 
35
- if (resp.status >= 200 && resp.status < 300)
35
+ if (resp.status >= 200 && resp.status < 300)
36
36
  return await resp.json();
37
37
  if (resp.status === 401)
38
38
  throw APIError("Invalid authentication credentials", 401);
39
- else if (resp.status === 404)
39
+ else if (resp.status === 404)
40
40
  throw APIError("Package not found", 404);
41
41
  else if (resp.status >= 500)
42
42
  throw APIError("Impossible to connect with the server", 500);
@@ -54,7 +54,7 @@ throw APIError("Package not found", 404);
54
54
  } else {
55
55
  throw APIError("Uknown error");
56
56
  }
57
- } else
57
+ } else
58
58
  throw APIError("Uknown error");
59
59
  } catch (error) {
60
60
  Console.error((error as TypeError).message);
@@ -91,7 +91,7 @@ const publish = async (config: any) => {
91
91
  ];
92
92
 
93
93
  const payload: { [key: string]: string } = {};
94
- for (const k of keys)
94
+ for (const k of keys)
95
95
  config[k] ? (payload[k] = config[k]) : null;
96
96
  try {
97
97
  console.log("Package to publish:", payload);
@@ -138,7 +138,7 @@ const getPackage = async (slug: string) => {
138
138
  } catch (error) {
139
139
  if ((error as any).status === 404)
140
140
  Console.error(`Package ${slug} does not exist`);
141
- else
141
+ else
142
142
  Console.error(`Package ${slug} does not exist`);
143
143
  Console.debug(error);
144
144
  throw error;
@@ -155,7 +155,7 @@ const getLangs = async () => {
155
155
  } catch (error) {
156
156
  if ((error as any).status === 404)
157
157
  Console.error("Package slug does not exist");
158
- else
158
+ else
159
159
  Console.error("Package slug does not exist");
160
160
  Console.debug(error);
161
161
  throw error;
@@ -30,7 +30,7 @@ const loadDispatcher = (opts: any) => {
30
30
  let exists = fs.existsSync(opts.path);
31
31
  if (opts.create) {
32
32
  if (exists)
33
- actions.push({ name: "reset", time: now() });
33
+ actions.push({ name: "reset", time: now() });
34
34
  fs.writeFileSync(opts.path, JSON.stringify(actions), { flag: "w" });
35
35
  exists = true;
36
36
  }