@learnpack/learnpack 2.0.19 → 2.0.21
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 +10 -10
- package/lib/commands/audit.d.ts +6 -0
- package/lib/commands/audit.js +369 -0
- package/lib/commands/clean.d.ts +8 -0
- package/lib/commands/clean.js +25 -0
- package/lib/commands/download.d.ts +13 -0
- package/lib/commands/download.js +55 -0
- package/lib/commands/init.d.ts +9 -0
- package/lib/commands/init.js +117 -0
- package/lib/commands/login.d.ts +14 -0
- package/lib/commands/login.js +37 -0
- package/lib/commands/logout.d.ts +14 -0
- package/lib/commands/logout.js +37 -0
- package/lib/commands/publish.d.ts +14 -0
- package/lib/commands/publish.js +82 -0
- package/lib/commands/start.d.ts +7 -0
- package/lib/commands/start.js +165 -0
- package/lib/commands/test.d.ts +6 -0
- package/lib/commands/test.js +62 -0
- package/lib/managers/config/allowed_files.d.ts +5 -0
- package/lib/managers/config/allowed_files.js +30 -0
- package/lib/managers/config/defaults.d.ts +34 -0
- package/lib/managers/config/defaults.js +35 -0
- package/lib/managers/config/exercise.d.ts +36 -0
- package/lib/managers/config/exercise.js +230 -0
- package/lib/managers/config/index.d.ts +3 -0
- package/lib/managers/config/index.js +307 -0
- package/lib/managers/file.d.ts +13 -0
- package/lib/managers/file.js +134 -0
- package/lib/managers/gitpod.d.ts +3 -0
- package/lib/managers/gitpod.js +67 -0
- package/lib/managers/server/index.d.ts +6 -0
- package/lib/managers/server/index.js +51 -0
- package/lib/managers/server/routes.d.ts +4 -0
- package/lib/managers/server/routes.js +160 -0
- package/lib/managers/session.d.ts +3 -0
- package/lib/managers/session.js +104 -0
- package/lib/managers/socket.d.ts +3 -0
- package/lib/managers/socket.js +164 -0
- package/lib/managers/test.d.ts +0 -0
- package/lib/managers/test.js +84 -0
- package/lib/models/action.d.ts +2 -0
- package/lib/models/action.js +2 -0
- package/lib/models/audit-errors.d.ts +4 -0
- package/lib/models/audit-errors.js +2 -0
- package/lib/models/config-manager.d.ts +21 -0
- package/lib/models/config-manager.js +2 -0
- package/lib/models/config.d.ts +57 -0
- package/lib/models/config.js +2 -0
- package/lib/models/counter.d.ts +11 -0
- package/lib/models/counter.js +2 -0
- package/lib/models/errors.d.ts +15 -0
- package/lib/models/errors.js +2 -0
- package/lib/models/exercise-obj.d.ts +27 -0
- package/lib/models/exercise-obj.js +2 -0
- package/lib/models/file.d.ts +5 -0
- package/lib/models/file.js +2 -0
- package/lib/models/findings.d.ts +17 -0
- package/lib/models/findings.js +2 -0
- package/lib/models/flags.d.ts +10 -0
- package/lib/models/flags.js +2 -0
- package/lib/models/front-matter.d.ts +11 -0
- package/lib/models/front-matter.js +2 -0
- package/lib/models/gitpod-data.d.ts +16 -0
- package/lib/models/gitpod-data.js +2 -0
- package/lib/models/language.d.ts +4 -0
- package/lib/models/language.js +2 -0
- package/lib/models/package.d.ts +7 -0
- package/lib/models/package.js +2 -0
- package/lib/models/plugin-config.d.ts +16 -0
- package/lib/models/plugin-config.js +2 -0
- package/lib/models/session.d.ts +23 -0
- package/lib/models/session.js +2 -0
- package/lib/models/socket.d.ts +31 -0
- package/lib/models/socket.js +2 -0
- package/lib/models/status.d.ts +1 -0
- package/lib/models/status.js +2 -0
- package/lib/models/success-types.d.ts +1 -0
- package/lib/models/success-types.js +2 -0
- package/lib/plugin/command/compile.d.ts +6 -0
- package/lib/plugin/command/compile.js +18 -0
- package/lib/plugin/command/test.d.ts +6 -0
- package/lib/plugin/command/test.js +25 -0
- package/lib/plugin/index.d.ts +27 -0
- package/lib/plugin/index.js +7 -0
- package/lib/plugin/plugin.d.ts +8 -0
- package/lib/plugin/plugin.js +68 -0
- package/lib/plugin/utils.d.ts +16 -0
- package/lib/plugin/utils.js +58 -0
- package/lib/ui/download.d.ts +5 -0
- package/lib/ui/download.js +61 -0
- package/lib/utils/BaseCommand.d.ts +8 -0
- package/lib/utils/BaseCommand.js +41 -0
- package/lib/utils/SessionCommand.d.ts +10 -0
- package/lib/utils/SessionCommand.js +47 -0
- package/lib/utils/api.d.ts +12 -0
- package/lib/utils/api.js +173 -0
- package/lib/utils/audit.d.ts +13 -0
- package/lib/utils/audit.js +129 -0
- package/lib/utils/console.d.ts +12 -0
- package/lib/utils/console.js +19 -0
- package/lib/utils/errors.d.ts +17 -0
- package/lib/utils/errors.js +100 -0
- package/lib/utils/exercisesQueue.d.ts +9 -0
- package/lib/utils/exercisesQueue.js +38 -0
- package/lib/utils/fileQueue.d.ts +40 -0
- package/lib/utils/fileQueue.js +168 -0
- package/lib/utils/misc.d.ts +1 -0
- package/lib/utils/misc.js +23 -0
- package/lib/utils/validators.d.ts +5 -0
- package/lib/utils/validators.js +17 -0
- package/lib/utils/watcher.d.ts +2 -0
- package/lib/utils/watcher.js +24 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
|
@@ -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,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,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;
|
|
@@ -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;
|