@learnpack/learnpack 2.0.13 → 2.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. package/README.md +10 -10
  2. package/lib/commands/audit.d.ts +6 -0
  3. package/lib/commands/audit.js +369 -0
  4. package/lib/commands/clean.d.ts +8 -0
  5. package/lib/commands/clean.js +25 -0
  6. package/lib/commands/download.d.ts +13 -0
  7. package/lib/commands/download.js +55 -0
  8. package/lib/commands/init.d.ts +9 -0
  9. package/lib/commands/init.js +117 -0
  10. package/lib/commands/login.d.ts +14 -0
  11. package/lib/commands/login.js +37 -0
  12. package/lib/commands/logout.d.ts +14 -0
  13. package/lib/commands/logout.js +37 -0
  14. package/lib/commands/publish.d.ts +14 -0
  15. package/lib/commands/publish.js +82 -0
  16. package/lib/commands/start.d.ts +7 -0
  17. package/lib/commands/start.js +165 -0
  18. package/lib/commands/test.d.ts +6 -0
  19. package/lib/commands/test.js +62 -0
  20. package/lib/index.d.ts +1 -0
  21. package/lib/managers/config/allowed_files.d.ts +5 -0
  22. package/lib/managers/config/allowed_files.js +30 -0
  23. package/lib/managers/config/defaults.d.ts +34 -0
  24. package/lib/managers/config/defaults.js +35 -0
  25. package/lib/managers/config/exercise.d.ts +36 -0
  26. package/lib/managers/config/exercise.js +230 -0
  27. package/lib/managers/config/index.d.ts +3 -0
  28. package/lib/managers/config/index.js +307 -0
  29. package/lib/managers/file.d.ts +13 -0
  30. package/lib/managers/file.js +134 -0
  31. package/lib/managers/gitpod.d.ts +3 -0
  32. package/lib/managers/gitpod.js +67 -0
  33. package/lib/managers/server/index.d.ts +6 -0
  34. package/lib/managers/server/index.js +51 -0
  35. package/lib/managers/server/routes.d.ts +4 -0
  36. package/lib/managers/server/routes.js +160 -0
  37. package/lib/managers/session.d.ts +3 -0
  38. package/lib/managers/session.js +104 -0
  39. package/lib/managers/socket.d.ts +3 -0
  40. package/lib/managers/socket.js +164 -0
  41. package/lib/managers/test.d.ts +0 -0
  42. package/lib/managers/test.js +84 -0
  43. package/lib/models/action.d.ts +2 -0
  44. package/lib/models/action.js +2 -0
  45. package/lib/models/audit-errors.d.ts +4 -0
  46. package/lib/models/audit-errors.js +2 -0
  47. package/lib/models/config-manager.d.ts +21 -0
  48. package/lib/models/config-manager.js +2 -0
  49. package/lib/models/config.d.ts +57 -0
  50. package/lib/models/config.js +2 -0
  51. package/lib/models/counter.d.ts +11 -0
  52. package/lib/models/counter.js +2 -0
  53. package/lib/models/errors.d.ts +15 -0
  54. package/lib/models/errors.js +2 -0
  55. package/lib/models/exercise-obj.d.ts +27 -0
  56. package/lib/models/exercise-obj.js +2 -0
  57. package/lib/models/file.d.ts +5 -0
  58. package/lib/models/file.js +2 -0
  59. package/lib/models/findings.d.ts +17 -0
  60. package/lib/models/findings.js +2 -0
  61. package/lib/models/flags.d.ts +10 -0
  62. package/lib/models/flags.js +2 -0
  63. package/lib/models/front-matter.d.ts +11 -0
  64. package/lib/models/front-matter.js +2 -0
  65. package/lib/models/gitpod-data.d.ts +16 -0
  66. package/lib/models/gitpod-data.js +2 -0
  67. package/lib/models/language.d.ts +4 -0
  68. package/lib/models/language.js +2 -0
  69. package/lib/models/package.d.ts +7 -0
  70. package/lib/models/package.js +2 -0
  71. package/lib/models/plugin-config.d.ts +16 -0
  72. package/lib/models/plugin-config.js +2 -0
  73. package/lib/models/session.d.ts +23 -0
  74. package/lib/models/session.js +2 -0
  75. package/lib/models/socket.d.ts +31 -0
  76. package/lib/models/socket.js +2 -0
  77. package/lib/models/status.d.ts +1 -0
  78. package/lib/models/status.js +2 -0
  79. package/lib/models/success-types.d.ts +1 -0
  80. package/lib/models/success-types.js +2 -0
  81. package/lib/plugin/command/compile.d.ts +6 -0
  82. package/lib/plugin/command/compile.js +18 -0
  83. package/lib/plugin/command/test.d.ts +6 -0
  84. package/lib/plugin/command/test.js +25 -0
  85. package/lib/plugin/index.d.ts +27 -0
  86. package/lib/plugin/index.js +7 -0
  87. package/lib/plugin/plugin.d.ts +8 -0
  88. package/lib/plugin/plugin.js +68 -0
  89. package/lib/plugin/utils.d.ts +16 -0
  90. package/lib/plugin/utils.js +58 -0
  91. package/lib/ui/download.d.ts +5 -0
  92. package/lib/ui/download.js +61 -0
  93. package/lib/utils/BaseCommand.d.ts +8 -0
  94. package/lib/utils/BaseCommand.js +41 -0
  95. package/lib/utils/SessionCommand.d.ts +10 -0
  96. package/lib/utils/SessionCommand.js +47 -0
  97. package/lib/utils/api.d.ts +12 -0
  98. package/lib/utils/api.js +173 -0
  99. package/lib/utils/audit.d.ts +13 -0
  100. package/lib/utils/audit.js +129 -0
  101. package/lib/utils/console.d.ts +12 -0
  102. package/lib/utils/console.js +19 -0
  103. package/lib/utils/errors.d.ts +17 -0
  104. package/lib/utils/errors.js +100 -0
  105. package/lib/utils/exercisesQueue.d.ts +9 -0
  106. package/lib/utils/exercisesQueue.js +38 -0
  107. package/lib/utils/fileQueue.d.ts +40 -0
  108. package/lib/utils/fileQueue.js +168 -0
  109. package/lib/utils/misc.d.ts +1 -0
  110. package/lib/utils/misc.js +23 -0
  111. package/lib/utils/validators.d.ts +5 -0
  112. package/lib/utils/validators.js +17 -0
  113. package/lib/utils/watcher.d.ts +2 -0
  114. package/lib/utils/watcher.js +24 -0
  115. package/oclif.manifest.json +1 -1
  116. package/package.json +3 -2
@@ -0,0 +1,117 @@
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
+ // eslint-disable-next-line
6
+ const fs = require("fs-extra");
7
+ const prompts = require("prompts");
8
+ const cli_ux_1 = require("cli-ux");
9
+ const eta = require("eta");
10
+ const console_1 = require("../utils/console");
11
+ const errors_1 = require("../utils/errors");
12
+ const defaults_1 = require("../managers/config/defaults");
13
+ const path = require("path");
14
+ class InitComand extends BaseCommand_1.default {
15
+ async run() {
16
+ const { flags } = this.parse(InitComand);
17
+ // if the folder/file .learn or .breathecode aleady exists
18
+ await alreadyInitialized();
19
+ const choices = await prompts([
20
+ {
21
+ type: "select",
22
+ name: "grading",
23
+ message: "Is the auto-grading going to be isolated or incremental?",
24
+ choices: [
25
+ {
26
+ title: "Incremental: Build on top of each other like a tutorial",
27
+ value: "incremental",
28
+ },
29
+ { title: "Isolated: Small separated exercises", value: "isolated" },
30
+ {
31
+ title: "No grading: No feedback or testing whatsoever",
32
+ value: null,
33
+ },
34
+ ],
35
+ },
36
+ {
37
+ type: "text",
38
+ name: "title",
39
+ initial: "My Interactive Tutorial",
40
+ message: "Title for your tutorial? Press enter to leave as it is",
41
+ },
42
+ {
43
+ type: "text",
44
+ name: "description",
45
+ initial: "",
46
+ message: "Description for your tutorial? Press enter to leave blank",
47
+ },
48
+ {
49
+ type: "select",
50
+ name: "difficulty",
51
+ message: "How difficulty will be to complete the tutorial?",
52
+ choices: [
53
+ { title: "Begginer (no previous experience)", value: "beginner" },
54
+ { title: "Easy (just a bit of experience required)", value: "easy" },
55
+ {
56
+ title: "Intermediate (you need experience)",
57
+ value: "intermediate",
58
+ },
59
+ { title: "Hard (master the topic)", value: "hard" },
60
+ ],
61
+ },
62
+ {
63
+ type: "text",
64
+ name: "duration",
65
+ initial: "1",
66
+ message: "How many hours avg it takes to complete (number)?",
67
+ validate: (value) => {
68
+ const n = Math.floor(Number(value));
69
+ return (n !== Number.POSITIVE_INFINITY && String(n) === value && n >= 0);
70
+ },
71
+ },
72
+ ]);
73
+ const packageInfo = Object.assign(Object.assign({}, defaults_1.default.config), { grading: choices.grading, difficulty: choices.difficulty, duration: parseInt(choices.duration), description: choices.description, title: choices.title, slug: choices.title
74
+ .toLowerCase()
75
+ .replace(/ /g, "-")
76
+ .replace(/[^\w-]+/g, "") });
77
+ cli_ux_1.default.action.start("Initializing package");
78
+ const languages = ["en", "es"];
79
+ const templatesDir = path.resolve(__dirname, "../utils/templates/" + choices.grading || "no-grading");
80
+ if (!fs.existsSync(templatesDir))
81
+ throw errors_1.ValidationError(`Template ${templatesDir} does not exists`);
82
+ await fs.copySync(templatesDir, "./");
83
+ // Creating README files
84
+ // eslint-disable-next-line
85
+ languages.forEach((language) => {
86
+ const readmeFilename = `README${language !== "en" ? `.${language}` : ""}`;
87
+ fs.writeFileSync(`./${readmeFilename}.md`, eta.render(fs.readFileSync(path.resolve(__dirname, `${templatesDir}/${readmeFilename}.ejs`), "utf-8"), packageInfo));
88
+ if (fs.existsSync(`./${readmeFilename}.ejs`))
89
+ fs.removeSync(`./${readmeFilename}.ejs`);
90
+ });
91
+ if (!fs.existsSync("./.gitignore"))
92
+ fs.copyFile(path.resolve(__dirname, "../utils/templates/gitignore.txt"), "./.gitignore");
93
+ fs.writeFileSync("./learn.json", JSON.stringify(packageInfo, null, 2));
94
+ cli_ux_1.default.action.stop();
95
+ console_1.default.success(`😋 Package initialized successfully`);
96
+ console_1.default.help(`Start the exercises by running the following command on your terminal: $ learnpack start`);
97
+ }
98
+ }
99
+ InitComand.description = "Create a new learning package: Book, Tutorial or Exercise";
100
+ InitComand.flags = Object.assign(Object.assign({}, BaseCommand_1.default.flags), { grading: command_1.flags.help({ char: "h" }) });
101
+ const alreadyInitialized = () => new Promise((resolve, reject) => {
102
+ fs.readdir("./", function (err, files) {
103
+ files = files.filter((f) => [".learn", "learn.json", "bc.json", ".breathecode"].includes(f));
104
+ if (err) {
105
+ reject(errors_1.ValidationError(err.message));
106
+ throw errors_1.ValidationError(err.message);
107
+ }
108
+ else if (files.length > 0) {
109
+ reject(errors_1.ValidationError("It seems the package is already initialized because we've found the following files: " +
110
+ files.join(",")));
111
+ throw errors_1.ValidationError("It seems the package is already initialized because we've found the following files: " +
112
+ files.join(","));
113
+ }
114
+ resolve(false);
115
+ });
116
+ });
117
+ exports.default = InitComand;
@@ -0,0 +1,14 @@
1
+ import SessionCommand from "../utils/SessionCommand";
2
+ declare class LoginCommand extends SessionCommand {
3
+ static description: string;
4
+ static flags: any;
5
+ static args: {
6
+ name: string;
7
+ required: boolean;
8
+ description: string;
9
+ hidden: boolean;
10
+ }[];
11
+ init(): Promise<void>;
12
+ run(): Promise<void>;
13
+ }
14
+ export default LoginCommand;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const SessionCommand_1 = require("../utils/SessionCommand");
4
+ const session_1 = require("../managers/session");
5
+ const console_1 = require("../utils/console");
6
+ class LoginCommand extends SessionCommand_1.default {
7
+ async init() {
8
+ const { flags } = this.parse(LoginCommand);
9
+ await this.initSession(flags);
10
+ }
11
+ async run() {
12
+ /* const {flags, args} = */ this.parse(LoginCommand);
13
+ try {
14
+ await session_1.default.login();
15
+ }
16
+ catch (error) {
17
+ console_1.default.error("Error trying to authenticate");
18
+ console_1.default.error(error.message || error);
19
+ }
20
+ }
21
+ }
22
+ LoginCommand.description = `Describe the command here
23
+ ...
24
+ Extra documentation goes here
25
+ `;
26
+ LoginCommand.flags = {
27
+ // name: flags.string({char: 'n', description: 'name to print'}),
28
+ };
29
+ LoginCommand.args = [
30
+ {
31
+ name: "package",
32
+ required: false,
33
+ description: "The unique string that identifies this package on learnpack",
34
+ hidden: false,
35
+ },
36
+ ];
37
+ exports.default = LoginCommand;
@@ -0,0 +1,14 @@
1
+ import SessionCommand from "../utils/SessionCommand";
2
+ declare class LogoutCommand extends SessionCommand {
3
+ static description: string;
4
+ static flags: any;
5
+ static args: {
6
+ name: string;
7
+ required: boolean;
8
+ description: string;
9
+ hidden: boolean;
10
+ }[];
11
+ init(): Promise<void>;
12
+ run(): Promise<void>;
13
+ }
14
+ export default LogoutCommand;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // import {Command, flags} from '@oclif/command'
4
+ // import { prompt } from "enquirer"
5
+ // import fetch from 'node-fetch'
6
+ const SessionCommand_1 = require("../utils/SessionCommand");
7
+ const session_1 = require("../managers/session");
8
+ // import Console from '../utils/console'
9
+ // import { replace } from 'node-emoji'
10
+ // import { validURL } from "../utils/validators"
11
+ // const BaseCommand from '../utils/BaseCommand');
12
+ class LogoutCommand extends SessionCommand_1.default {
13
+ async init() {
14
+ const { flags } = this.parse(LogoutCommand);
15
+ await this.initSession(flags);
16
+ }
17
+ async run() {
18
+ // const {flags, args} = this.parse(LogoutCommand)
19
+ session_1.default.destroy();
20
+ }
21
+ }
22
+ LogoutCommand.description = `Describe the command here
23
+ ...
24
+ Extra documentation goes here
25
+ `;
26
+ LogoutCommand.flags = {
27
+ // name: flags.string({char: 'n', description: 'name to print'}),
28
+ };
29
+ LogoutCommand.args = [
30
+ {
31
+ name: "package",
32
+ required: false,
33
+ description: "The unique string that identifies this package on learnpack",
34
+ hidden: false,
35
+ },
36
+ ];
37
+ exports.default = LogoutCommand;
@@ -0,0 +1,14 @@
1
+ import SessionCommand from "../utils/SessionCommand";
2
+ declare class PublishCommand extends SessionCommand {
3
+ static description: string;
4
+ static flags: any;
5
+ static args: {
6
+ name: string;
7
+ required: boolean;
8
+ description: string;
9
+ hidden: boolean;
10
+ }[];
11
+ init(): Promise<void>;
12
+ run(): Promise<void>;
13
+ }
14
+ export default PublishCommand;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const enquirer_1 = require("enquirer");
4
+ const SessionCommand_1 = require("../utils/SessionCommand");
5
+ const console_1 = require("../utils/console");
6
+ const api_1 = require("../utils/api");
7
+ const validators_1 = require("../utils/validators");
8
+ // eslint-disable-next-line
9
+ const fetch = require("node-fetch");
10
+ class PublishCommand extends SessionCommand_1.default {
11
+ async init() {
12
+ const { flags } = this.parse(PublishCommand);
13
+ await this.initSession(flags, true);
14
+ }
15
+ async run() {
16
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
17
+ const { flags, args } = this.parse(PublishCommand);
18
+ // avoid annonymus sessions
19
+ // eslint-disable-next-line
20
+ if (!this.session)
21
+ return;
22
+ console_1.default.info(`Session found for ${this.session.payload.email}, publishing the package...`);
23
+ const configObject = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.get();
24
+ if (((_b = configObject === null || configObject === void 0 ? void 0 : configObject.config) === null || _b === void 0 ? void 0 : _b.slug) === undefined ||
25
+ !((_c = configObject.config) === null || _c === void 0 ? void 0 : _c.slug)) {
26
+ throw new Error("The package is missing a slug (unique name identifier), please check your learn.json file and make sure it has a 'slug'");
27
+ }
28
+ if (!validators_1.validURL((_e = (_d = configObject === null || configObject === void 0 ? void 0 : configObject.config) === null || _d === void 0 ? void 0 : _d.repository) !== null && _e !== void 0 ? _e : "")) {
29
+ throw new Error("The package has a missing or invalid 'repository' on the configuration file, it needs to be a Github URL");
30
+ }
31
+ else {
32
+ const validateResp = await fetch((_f = configObject.config) === null || _f === void 0 ? void 0 : _f.repository, {
33
+ method: "HEAD",
34
+ });
35
+ if (!validateResp.ok || validateResp.status !== 200) {
36
+ throw new Error(`The specified repository URL on the configuration file does not exist or its private, only public repositories are allowed at the moment: ${(_g = configObject.config) === null || _g === void 0 ? void 0 : _g.repository}`);
37
+ }
38
+ }
39
+ // start watching for file changes
40
+ try {
41
+ await api_1.default.publish(Object.assign(Object.assign({}, configObject), { author: this.session.payload.user_id }));
42
+ console_1.default.success(`Package updated and published successfully: ${(_h = configObject.config) === null || _h === void 0 ? void 0 : _h.slug}`);
43
+ }
44
+ catch (error) {
45
+ if (error.status === 404) {
46
+ const answer = await enquirer_1.prompt([
47
+ {
48
+ type: "confirm",
49
+ name: "create",
50
+ message: `Package with slug ${(_j = configObject.config) === null || _j === void 0 ? void 0 : _j.slug} does not exist, do you want to create it?`,
51
+ },
52
+ ]);
53
+ if (answer) {
54
+ await api_1.default.update(Object.assign(Object.assign({}, configObject), { author: this.session.payload.user_id }));
55
+ console_1.default.success(`Package created and published successfully: ${(_k = configObject.config) === null || _k === void 0 ? void 0 : _k.slug}`);
56
+ }
57
+ else {
58
+ console_1.default.error("No answer from server");
59
+ }
60
+ }
61
+ else {
62
+ console_1.default.error(error.message);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ PublishCommand.description = `Describe the command here
68
+ ...
69
+ Extra documentation goes here
70
+ `;
71
+ PublishCommand.flags = {
72
+ // name: flags.string({char: 'n', description: 'name to print'}),
73
+ };
74
+ PublishCommand.args = [
75
+ {
76
+ name: "package",
77
+ required: false,
78
+ description: "The unique string that identifies this package on learnpack",
79
+ hidden: false,
80
+ },
81
+ ];
82
+ exports.default = PublishCommand;
@@ -0,0 +1,7 @@
1
+ import SessionCommand from "../utils/SessionCommand";
2
+ export default class StartCommand extends SessionCommand {
3
+ static description: string;
4
+ static flags: any;
5
+ init(): Promise<void>;
6
+ run(): Promise<void>;
7
+ }
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // import path from "path";
4
+ const command_1 = require("@oclif/command");
5
+ const SessionCommand_1 = require("../utils/SessionCommand");
6
+ const console_1 = require("../utils/console");
7
+ const socket_1 = require("../managers/socket");
8
+ const fileQueue_1 = require("../utils/fileQueue");
9
+ const file_1 = require("../managers/file");
10
+ const misc_1 = require("../utils/misc");
11
+ const server_1 = require("../managers/server");
12
+ class StartCommand extends SessionCommand_1.default {
13
+ // 🛑 IMPORTANT
14
+ // Every command that will use the configManager needs this init method
15
+ async init() {
16
+ const { flags } = this.parse(StartCommand);
17
+ await this.initSession(flags);
18
+ }
19
+ async run() {
20
+ var _a, _b, _c;
21
+ // get configuration object
22
+ const configObject = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.get();
23
+ const config = configObject === null || configObject === void 0 ? void 0 : configObject.config;
24
+ if (configObject) {
25
+ const { config } = configObject;
26
+ // build exerises
27
+ (_b = this.configManager) === null || _b === void 0 ? void 0 : _b.buildIndex();
28
+ console_1.default.debug(`Grading: ${config === null || config === void 0 ? void 0 : config.grading} ${((_c = config === null || config === void 0 ? void 0 : config.disabledActions) === null || _c === void 0 ? void 0 : _c.includes("test")) ? "(disabled)" : ""}, editor: ${config === null || config === void 0 ? void 0 : config.editor.mode} ${config === null || config === void 0 ? void 0 : config.editor.version}, for ${Array.isArray(configObject === null || configObject === void 0 ? void 0 : configObject.exercises) ? configObject === null || configObject === void 0 ? void 0 : configObject.exercises.length :
29
+ 0} exercises found`);
30
+ // download app and decompress
31
+ await file_1.downloadEditor(config === null || config === void 0 ? void 0 : config.editor.version, `${config === null || config === void 0 ? void 0 : config.dirPath}/app.tar.gz`);
32
+ console_1.default.info("Decompressing LearnPack UI, this may take a minute...");
33
+ await file_1.decompress(`${config === null || config === void 0 ? void 0 : config.dirPath}/app.tar.gz`, `${config === null || config === void 0 ? void 0 : config.dirPath}/_app/`);
34
+ // listen to socket commands
35
+ if (config && this.configManager) {
36
+ const server = await server_1.default(configObject, this.configManager);
37
+ const dispatcher = fileQueue_1.default.dispatcher({
38
+ create: true,
39
+ path: `${config.dirPath}/vscode_queue.json`,
40
+ });
41
+ socket_1.default.start(config, server, false);
42
+ socket_1.default.on("open", (data) => {
43
+ console_1.default.debug("Opening these files: ", data);
44
+ const files = misc_1.prioritizeHTMLFile(data.files);
45
+ dispatcher.enqueue(dispatcher.events.OPEN_FILES, files);
46
+ socket_1.default.ready("Ready to compile...");
47
+ });
48
+ socket_1.default.on("open_window", (data) => {
49
+ console_1.default.debug("Opening window: ", data);
50
+ dispatcher.enqueue(dispatcher.events.OPEN_WINDOW, data);
51
+ socket_1.default.ready("Ready to compile...");
52
+ });
53
+ socket_1.default.on("reset", (exercise) => {
54
+ var _a;
55
+ try {
56
+ (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.reset(exercise.exerciseSlug);
57
+ dispatcher.enqueue(dispatcher.events.RESET_EXERCISE, exercise.exerciseSlug);
58
+ socket_1.default.ready("Ready to compile...");
59
+ }
60
+ catch (error) {
61
+ socket_1.default.error("compiler-error", error.message ||
62
+ "There was an error reseting the exercise");
63
+ setTimeout(() => socket_1.default.ready("Ready to compile..."), 2000);
64
+ }
65
+ });
66
+ // socket.on("preview", (data) => {
67
+ // Console.debug("Preview triggered, removing the 'preview' action ")
68
+ // socket.removeAllowed("preview")
69
+ // socket.log('ready',['Ready to compile...'])
70
+ // })
71
+ socket_1.default.on("build", async (data) => {
72
+ var _a;
73
+ const exercise = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.getExercise(data.exerciseSlug);
74
+ if (!(exercise === null || exercise === void 0 ? void 0 : exercise.language)) {
75
+ socket_1.default.error("compiler-error", "Impossible to detect language to build for " +
76
+ data.exerciseSlug +
77
+ "...");
78
+ return;
79
+ }
80
+ socket_1.default.log("compiling", "Building exercise " +
81
+ data.exerciseSlug +
82
+ " with " +
83
+ exercise.language +
84
+ "...");
85
+ await this.config.runHook("action", {
86
+ action: "compile",
87
+ socket: socket_1.default,
88
+ configuration: config,
89
+ exercise,
90
+ });
91
+ });
92
+ socket_1.default.on("test", async (data) => {
93
+ var _a, _b;
94
+ const exercise = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.getExercise(data.exerciseSlug);
95
+ if (!(exercise === null || exercise === void 0 ? void 0 : exercise.language)) {
96
+ socket_1.default.error("compiler-error", "Impossible to detect engine language for testing for " +
97
+ data.exerciseSlug +
98
+ "...");
99
+ return;
100
+ }
101
+ if ((config === null || config === void 0 ? void 0 : config.disabledActions.includes("test")) || (config === null || config === void 0 ? void 0 : config.disableGrading)) {
102
+ socket_1.default.ready("Grading is disabled on configuration");
103
+ return true;
104
+ }
105
+ socket_1.default.log("testing", "Testing your exercise using the " + exercise.language + " engine.");
106
+ await this.config.runHook("action", {
107
+ action: "test",
108
+ socket: socket_1.default,
109
+ configuration: config,
110
+ exercise,
111
+ });
112
+ (_b = this.configManager) === null || _b === void 0 ? void 0 : _b.save();
113
+ return true;
114
+ });
115
+ const terminate = () => {
116
+ console_1.default.debug("Terminating Learnpack...");
117
+ server.terminate(() => {
118
+ var _a;
119
+ (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.noCurrentExercise();
120
+ dispatcher.enqueue(dispatcher.events.END);
121
+ process.exit();
122
+ });
123
+ };
124
+ server.on("close", terminate);
125
+ process.on("SIGINT", terminate);
126
+ process.on("SIGTERM", terminate);
127
+ process.on("SIGHUP", terminate);
128
+ // finish the server startup
129
+ setTimeout(() => dispatcher.enqueue(dispatcher.events.RUNNING), 1000);
130
+ // start watching for file changes
131
+ if (StartCommand.flags.watch)
132
+ this.configManager.watchIndex(_exercises => socket_1.default.reload(null, _exercises));
133
+ }
134
+ }
135
+ }
136
+ }
137
+ exports.default = StartCommand;
138
+ StartCommand.description = "Runs a small server with all the exercise instructions";
139
+ StartCommand.flags = Object.assign(Object.assign({}, SessionCommand_1.default.flags), { port: command_1.flags.string({ char: "p", description: "server port" }), host: command_1.flags.string({ char: "h", description: "server host" }), disableGrading: command_1.flags.boolean({
140
+ char: "D",
141
+ description: "disble grading functionality",
142
+ default: false,
143
+ }),
144
+ // disableGrading: flags.boolean({char: 'dg', description: 'disble grading functionality', default: false }),
145
+ watch: command_1.flags.boolean({
146
+ char: "w",
147
+ description: "Watch for file changes",
148
+ default: false,
149
+ }), editor: command_1.flags.string({
150
+ char: "e",
151
+ description: "[standalone, gitpod]",
152
+ options: ["standalone", "gitpod"],
153
+ }), version: command_1.flags.string({
154
+ char: "v",
155
+ description: "E.g: 1.0.1",
156
+ default: undefined,
157
+ }), grading: command_1.flags.string({
158
+ char: "g",
159
+ description: "[isolated, incremental]",
160
+ options: ["isolated", "incremental"],
161
+ }), debug: command_1.flags.boolean({
162
+ char: "d",
163
+ description: "debugger mode for more verbage",
164
+ default: false,
165
+ }) });
@@ -0,0 +1,6 @@
1
+ import SessionCommand from "../utils/SessionCommand";
2
+ declare class TestCommand extends SessionCommand {
3
+ init(): Promise<void>;
4
+ run(): Promise<void>;
5
+ }
6
+ export default TestCommand;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const console_1 = require("../utils/console");
4
+ const SessionCommand_1 = require("../utils/SessionCommand");
5
+ const socket_1 = require("../managers/socket");
6
+ const server_1 = require("../managers/server");
7
+ const exercisesQueue_1 = require("../utils/exercisesQueue");
8
+ class TestCommand extends SessionCommand_1.default {
9
+ async init() {
10
+ const { flags } = this.parse(TestCommand);
11
+ await this.initSession(flags);
12
+ }
13
+ async run() {
14
+ var _a, _b, _c;
15
+ const { args: { exerciseSlug }, } = this.parse(TestCommand);
16
+ // Build exercises index
17
+ (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.buildIndex();
18
+ let exercises = [];
19
+ // test all exercises
20
+ !exerciseSlug ?
21
+ (exercises = (_b = this.configManager) === null || _b === void 0 ? void 0 : _b.getAllExercises()) :
22
+ (exercises = [this.configManager.getExercise(exerciseSlug)]);
23
+ const exercisesQueue = new exercisesQueue_1.default(exercises);
24
+ const configObject = (_c = this.configManager) === null || _c === void 0 ? void 0 : _c.get();
25
+ let hasFailed = false;
26
+ let failedTestsCount = 0;
27
+ let successTestsCount = 0;
28
+ const testsToRunCount = exercisesQueue.size();
29
+ configObject.config.testingFinishedCallback = ({ result }) => {
30
+ if (result === "failed") {
31
+ hasFailed = true;
32
+ failedTestsCount++;
33
+ }
34
+ else {
35
+ successTestsCount++;
36
+ }
37
+ if (exercisesQueue.isEmpty()) {
38
+ console_1.default.info(`${testsToRunCount} test${testsToRunCount > 1 ? "s" : ""} runned`);
39
+ console_1.default.success(`${successTestsCount} test${successTestsCount > 1 ? "s" : ""} passed`);
40
+ console_1.default.error(`${failedTestsCount} test${failedTestsCount > 1 ? "s" : ""} failed`);
41
+ process.exit(hasFailed ? 1 : 0);
42
+ }
43
+ else {
44
+ exercisesQueue.pop().test(this.config, config, socket_1.default);
45
+ }
46
+ };
47
+ const config = configObject === null || configObject === void 0 ? void 0 : configObject.config;
48
+ const server = await server_1.default(configObject, this.configManager, true);
49
+ socket_1.default.start(config, server, true);
50
+ exercisesQueue.pop().test(this.config, config, socket_1.default);
51
+ }
52
+ }
53
+ TestCommand.description = `Test exercises`;
54
+ TestCommand.args = [
55
+ {
56
+ name: "exerciseSlug",
57
+ required: false,
58
+ description: "The name of the exercise to test",
59
+ hidden: false,
60
+ },
61
+ ];
62
+ exports.default = TestCommand;
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from '@oclif/command';
@@ -0,0 +1,5 @@
1
+ declare const extensions: {
2
+ extensions: string[];
3
+ names: string[];
4
+ };
5
+ export default extensions;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const extensions = {
4
+ extensions: [
5
+ "py",
6
+ "java",
7
+ "py",
8
+ "ruby",
9
+ "html",
10
+ "css",
11
+ "htm",
12
+ "php",
13
+ "js",
14
+ "jsx",
15
+ "ts",
16
+ "sh",
17
+ "bash",
18
+ "json",
19
+ "yml",
20
+ "yaml",
21
+ "csv",
22
+ "xml",
23
+ "txt",
24
+ "text",
25
+ "markdown",
26
+ "readme",
27
+ ],
28
+ names: ["package.json", "package-lock.json"],
29
+ };
30
+ exports.default = extensions;
@@ -0,0 +1,34 @@
1
+ declare const _default: {
2
+ config: {
3
+ port: number;
4
+ editor: {
5
+ mode: null;
6
+ agent: null;
7
+ version: null;
8
+ };
9
+ dirPath: string;
10
+ configPath: string;
11
+ outputPath: string;
12
+ publicPath: string;
13
+ publicUrl: null;
14
+ language: string;
15
+ grading: string;
16
+ exercisesPath: string;
17
+ webpackTemplate: null;
18
+ disableGrading: boolean;
19
+ disabledActions: never[];
20
+ actions: never[];
21
+ entries: {
22
+ html: string;
23
+ vanillajs: string;
24
+ react: string;
25
+ node: string;
26
+ python3: string;
27
+ java: string;
28
+ };
29
+ };
30
+ address: string;
31
+ currentExercise: null;
32
+ exercises: never[];
33
+ };
34
+ export default _default;