@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,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const CompilationError = (messages) => {
|
|
5
|
+
const _err = new Error(messages);
|
|
6
|
+
_err.status = 400;
|
|
7
|
+
_err.stdout = messages;
|
|
8
|
+
_err.type = "compiler-error";
|
|
9
|
+
return _err;
|
|
10
|
+
};
|
|
11
|
+
exports.default = {
|
|
12
|
+
CompilationError,
|
|
13
|
+
default: async (_a) => {
|
|
14
|
+
var { action } = _a, rest = tslib_1.__rest(_a, ["action"]);
|
|
15
|
+
const stdout = await action.run(rest);
|
|
16
|
+
return stdout;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const TestingError = (messages) => {
|
|
5
|
+
const _err = new Error(messages);
|
|
6
|
+
_err.status = 400;
|
|
7
|
+
_err.stdout = messages;
|
|
8
|
+
_err.type = "testing-error";
|
|
9
|
+
return _err;
|
|
10
|
+
};
|
|
11
|
+
exports.default = {
|
|
12
|
+
TestingError,
|
|
13
|
+
default: async function (args) {
|
|
14
|
+
const { action, configuration, socket, exercise } = args;
|
|
15
|
+
if (!fs.existsSync(`${configuration.dirPath}/reports`)) {
|
|
16
|
+
// reports directory
|
|
17
|
+
fs.mkdirSync(`${configuration.dirPath}/reports`);
|
|
18
|
+
}
|
|
19
|
+
// compile
|
|
20
|
+
const stdout = await action.run(args);
|
|
21
|
+
// mark exercise as done
|
|
22
|
+
exercise.done = true;
|
|
23
|
+
return stdout;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
CompilationError: {
|
|
3
|
+
CompilationError: (messages: string) => import("../models/errors").IError;
|
|
4
|
+
default: ({ action, ...rest }: any) => Promise<any>;
|
|
5
|
+
};
|
|
6
|
+
TestingError: {
|
|
7
|
+
TestingError: (messages: string) => import("../models/errors").IError;
|
|
8
|
+
default: (args: any) => Promise<any>;
|
|
9
|
+
};
|
|
10
|
+
Utils: {
|
|
11
|
+
getMatches: (reg: RegExp, content: string) => (string | null)[];
|
|
12
|
+
cleanStdout: (buffer: string, inputs: string[]) => string;
|
|
13
|
+
indent: (string: string, options: any, count?: number) => string;
|
|
14
|
+
Console: {
|
|
15
|
+
_debug: boolean;
|
|
16
|
+
startDebug: () => void;
|
|
17
|
+
log: (msg: string, ...args: any[]) => void;
|
|
18
|
+
error: (msg: string, ...args: any[]) => void;
|
|
19
|
+
success: (msg: string, ...args: any[]) => void;
|
|
20
|
+
info: (msg: string, ...args: any[]) => void;
|
|
21
|
+
help: (msg: string) => void;
|
|
22
|
+
debug(...args: any[]): void;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
plugin: (pluginConfig: import("../models/plugin-config").IPluginConfig) => (args: any) => Promise<any>;
|
|
26
|
+
};
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const compile_1 = require("./command/compile");
|
|
4
|
+
const test_1 = require("./command/test");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
const plugin_1 = require("./plugin");
|
|
7
|
+
exports.default = { CompilationError: compile_1.default, TestingError: test_1.default, Utils: utils_1.default, plugin: plugin_1.default };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IPluginConfig } from "../models/plugin-config";
|
|
2
|
+
declare const _default: (pluginConfig: IPluginConfig) => (args: any) => Promise<any>;
|
|
3
|
+
/**
|
|
4
|
+
* Main Plugin Runner, it defines the behavior of a learnpack plugin
|
|
5
|
+
* dividing it in "actions" like: Compile, test, etc.
|
|
6
|
+
* @param {object} pluginConfig Configuration object that must defined language and each possible action.
|
|
7
|
+
*/
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const shell = require("shelljs");
|
|
4
|
+
/**
|
|
5
|
+
* Main Plugin Runner, it defines the behavior of a learnpack plugin
|
|
6
|
+
* dividing it in "actions" like: Compile, test, etc.
|
|
7
|
+
* @param {object} pluginConfig Configuration object that must defined language and each possible action.
|
|
8
|
+
*/
|
|
9
|
+
exports.default = (pluginConfig) => {
|
|
10
|
+
return async (args) => {
|
|
11
|
+
const { action, exercise, socket, configuration } = args;
|
|
12
|
+
if (pluginConfig.language === undefined)
|
|
13
|
+
throw new Error(`Missing language on the plugin configuration object`);
|
|
14
|
+
if (typeof action !== "string") {
|
|
15
|
+
throw new TypeError("Missing action property on hook details");
|
|
16
|
+
}
|
|
17
|
+
if (!exercise || exercise === undefined) {
|
|
18
|
+
throw new Error("Missing exercise information");
|
|
19
|
+
}
|
|
20
|
+
// if the action does not exist I don't do anything
|
|
21
|
+
if (pluginConfig[action] === undefined) {
|
|
22
|
+
console.log(`Ignoring ${action}`);
|
|
23
|
+
return () => null;
|
|
24
|
+
}
|
|
25
|
+
// ignore if the plugin language its not the same as the exercise language
|
|
26
|
+
if (exercise.language !== pluginConfig.language) {
|
|
27
|
+
return () => null;
|
|
28
|
+
}
|
|
29
|
+
if (!exercise.files || exercise.files.length === 0) {
|
|
30
|
+
throw new Error(`No files to process`);
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const _action = pluginConfig[action];
|
|
34
|
+
if (_action === null || typeof _action !== "object")
|
|
35
|
+
throw new Error(`The ${pluginConfig.language} ${action} module must export an object configuration`);
|
|
36
|
+
if (_action.validate === undefined)
|
|
37
|
+
throw new Error(`Missing validate method for ${pluginConfig.language} ${action}`);
|
|
38
|
+
if (_action.run === undefined)
|
|
39
|
+
throw new Error(`Missing run method for ${pluginConfig.language} ${action}`);
|
|
40
|
+
if (_action.dependencies !== undefined) {
|
|
41
|
+
if (!Array.isArray(_action.dependencies))
|
|
42
|
+
throw new Error(`${action}.dependencies must be an array of package names`);
|
|
43
|
+
for (const packageName of _action.dependencies) {
|
|
44
|
+
if (!shell.which(packageName)) {
|
|
45
|
+
throw new Error(`🚫 You need to have ${packageName} installed to run test the exercises`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const valid = await _action.validate({ exercise, configuration });
|
|
50
|
+
if (valid) {
|
|
51
|
+
// look for the command standard implementation and execute it
|
|
52
|
+
const execute = require("./command/" + action + ".js").default;
|
|
53
|
+
// no matter the command, the response must always be a stdout
|
|
54
|
+
const stdout = await execute(Object.assign(Object.assign({}, args), { action: _action, configuration }));
|
|
55
|
+
// Map the action names to socket messaging standards
|
|
56
|
+
const actionToSuccessMapper = { compile: "compiler", test: "testing" };
|
|
57
|
+
socket.success(actionToSuccessMapper[action], stdout);
|
|
58
|
+
return stdout;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error.type === undefined)
|
|
63
|
+
socket.fatal(error);
|
|
64
|
+
else
|
|
65
|
+
socket.error(error.type, error.stdout);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
getMatches: (reg: RegExp, content: string) => (string | null)[];
|
|
3
|
+
cleanStdout: (buffer: string, inputs: string[]) => string;
|
|
4
|
+
indent: (string: string, options: any, count?: number) => string;
|
|
5
|
+
Console: {
|
|
6
|
+
_debug: boolean;
|
|
7
|
+
startDebug: () => void;
|
|
8
|
+
log: (msg: string, ...args: any[]) => void;
|
|
9
|
+
error: (msg: string, ...args: any[]) => void;
|
|
10
|
+
success: (msg: string, ...args: any[]) => void;
|
|
11
|
+
info: (msg: string, ...args: any[]) => void;
|
|
12
|
+
help: (msg: string) => void;
|
|
13
|
+
debug(...args: any[]): void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const getMatches = (reg, content) => {
|
|
5
|
+
const inputs = [];
|
|
6
|
+
let m;
|
|
7
|
+
while ((m = reg.exec(content)) !== null) {
|
|
8
|
+
// This is necessary to avoid infinite loops with zero-width matches
|
|
9
|
+
if (m.index === reg.lastIndex)
|
|
10
|
+
reg.lastIndex++;
|
|
11
|
+
// The result can be accessed through the `m`-variable.
|
|
12
|
+
inputs.push(m[1] || null);
|
|
13
|
+
}
|
|
14
|
+
return inputs;
|
|
15
|
+
};
|
|
16
|
+
const cleanStdout = (buffer, inputs) => {
|
|
17
|
+
if (Array.isArray(inputs))
|
|
18
|
+
for (let i = 0; i < inputs.length; i++)
|
|
19
|
+
if (inputs[i])
|
|
20
|
+
buffer = buffer.replace(inputs[i], "");
|
|
21
|
+
return buffer;
|
|
22
|
+
};
|
|
23
|
+
const indent = (string, options, count = 1) => {
|
|
24
|
+
options = Object.assign({ indent: " ", includeEmptyLines: false }, options);
|
|
25
|
+
if (typeof string !== "string") {
|
|
26
|
+
throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);
|
|
27
|
+
}
|
|
28
|
+
if (typeof count !== "number") {
|
|
29
|
+
throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
|
|
30
|
+
}
|
|
31
|
+
if (count < 0) {
|
|
32
|
+
throw new RangeError(`Expected \`count\` to be at least 0, got \`${count}\``);
|
|
33
|
+
}
|
|
34
|
+
if (typeof options.indent !== "string") {
|
|
35
|
+
throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``);
|
|
36
|
+
}
|
|
37
|
+
if (count === 0) {
|
|
38
|
+
return string;
|
|
39
|
+
}
|
|
40
|
+
const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
|
|
41
|
+
return string.replace(regex, options.indent.repeat(count));
|
|
42
|
+
};
|
|
43
|
+
const Console = {
|
|
44
|
+
// _debug: true,
|
|
45
|
+
_debug: process.env.DEBUG === "true",
|
|
46
|
+
startDebug: function () {
|
|
47
|
+
this._debug = true;
|
|
48
|
+
},
|
|
49
|
+
log: (msg, ...args) => console.log(chalk.gray(msg), ...args),
|
|
50
|
+
error: (msg, ...args) => console.log(chalk.red("⨉ " + msg), ...args),
|
|
51
|
+
success: (msg, ...args) => console.log(chalk.green("✓ " + msg), ...args),
|
|
52
|
+
info: (msg, ...args) => console.log(chalk.blue("ⓘ " + msg), ...args),
|
|
53
|
+
help: (msg) => console.log(`${chalk.white.bold("⚠ help:")} ${chalk.white(msg)}`),
|
|
54
|
+
debug(...args) {
|
|
55
|
+
this._debug && console.log(chalk.magentaBright(`⚠ debug: `), args);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
exports.default = { getMatches, cleanStdout, indent, Console };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.askPackage = void 0;
|
|
4
|
+
const enquirer_1 = require("enquirer");
|
|
5
|
+
const console_1 = require("../utils/console");
|
|
6
|
+
const api_1 = require("../utils/api");
|
|
7
|
+
exports.askPackage = async () => {
|
|
8
|
+
console_1.default.info('No package was specified');
|
|
9
|
+
const languages = await api_1.default.getLangs();
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
if (languages.length === 0) {
|
|
12
|
+
// reject(new Error('No categories available'))
|
|
13
|
+
reject('No categories available');
|
|
14
|
+
// return null;
|
|
15
|
+
}
|
|
16
|
+
// let packages = []
|
|
17
|
+
enquirer_1.prompt([
|
|
18
|
+
{
|
|
19
|
+
type: 'select',
|
|
20
|
+
name: 'lang',
|
|
21
|
+
message: 'What language do you want to practice?',
|
|
22
|
+
choices: languages.map((l) => ({
|
|
23
|
+
message: l.title,
|
|
24
|
+
name: l.slug,
|
|
25
|
+
})),
|
|
26
|
+
},
|
|
27
|
+
])
|
|
28
|
+
.then(({ lang }) => {
|
|
29
|
+
return (async () => {
|
|
30
|
+
const response = await api_1.default.getAllPackages({ lang });
|
|
31
|
+
const packages = response.results;
|
|
32
|
+
if (packages.length === 0) {
|
|
33
|
+
const error = new Error(`No packages found for language ${lang}`);
|
|
34
|
+
console_1.default.error(error.message); // TODO: Look this
|
|
35
|
+
return error;
|
|
36
|
+
}
|
|
37
|
+
return enquirer_1.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'select',
|
|
40
|
+
name: 'pack',
|
|
41
|
+
message: 'Choose one of the packages available',
|
|
42
|
+
choices: packages.map((l) => ({
|
|
43
|
+
message: `${l.title}, difficulty: ${l.difficulty}, downloads: ${l.downloads} ${l.skills.length > 0 ? `(Skills: ${l.skills.join(',')})` : ''}`,
|
|
44
|
+
name: l.slug,
|
|
45
|
+
})),
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
48
|
+
})();
|
|
49
|
+
})
|
|
50
|
+
.then((resp) => {
|
|
51
|
+
if (!resp)
|
|
52
|
+
reject(resp.message || resp);
|
|
53
|
+
else
|
|
54
|
+
resolve(resp.pack);
|
|
55
|
+
})
|
|
56
|
+
.catch(error => {
|
|
57
|
+
console_1.default.error(error.message || error);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
exports.default = { askPackage: exports.askPackage };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const console_1 = require("./console");
|
|
5
|
+
const readline_1 = require("readline");
|
|
6
|
+
// import SessionManager from '../managers/session'
|
|
7
|
+
class BaseCommand extends command_1.Command {
|
|
8
|
+
async catch(err) {
|
|
9
|
+
console_1.default.debug("COMMAND CATCH", err);
|
|
10
|
+
throw err;
|
|
11
|
+
}
|
|
12
|
+
async init() {
|
|
13
|
+
const { flags, args } = this.parse(BaseCommand);
|
|
14
|
+
console_1.default.debug("COMMAND INIT");
|
|
15
|
+
console_1.default.debug("These are your flags: ", flags);
|
|
16
|
+
console_1.default.debug("These are your args: ", args);
|
|
17
|
+
// quick fix for listening to the process termination on windows
|
|
18
|
+
if (process.platform === "win32") {
|
|
19
|
+
const rl = readline_1.createInterface({
|
|
20
|
+
input: process.stdin,
|
|
21
|
+
output: process.stdout,
|
|
22
|
+
});
|
|
23
|
+
rl.on("SIGINT", function () {
|
|
24
|
+
// process.emit('SIGINT')
|
|
25
|
+
// process.emit('SIGINT')
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
process.on("SIGINT", function () {
|
|
29
|
+
console_1.default.debug("Terminated (SIGINT)");
|
|
30
|
+
process.exit();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async finally() {
|
|
34
|
+
console_1.default.debug("COMMAND FINALLY");
|
|
35
|
+
// called after run and catch regardless of whether or not the command errored
|
|
36
|
+
}
|
|
37
|
+
async run() {
|
|
38
|
+
// console.log('running my command')
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.default = BaseCommand;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import BaseCommand from './BaseCommand';
|
|
2
|
+
import { IConfigManager } from '../models/config-manager';
|
|
3
|
+
export default class SessionCommand extends BaseCommand {
|
|
4
|
+
session: any;
|
|
5
|
+
configManager: IConfigManager | null;
|
|
6
|
+
static flags: any;
|
|
7
|
+
initSession(flags: any, _private?: boolean): Promise<void>;
|
|
8
|
+
buildConfig(flags: any): Promise<void>;
|
|
9
|
+
catch(err: any): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// import { flags } from "@oclif/command";
|
|
4
|
+
const BaseCommand_1 = require("./BaseCommand");
|
|
5
|
+
const console_1 = require("./console");
|
|
6
|
+
const session_1 = require("../managers/session");
|
|
7
|
+
const index_1 = require("../managers/config/index");
|
|
8
|
+
const errors_1 = require("./errors");
|
|
9
|
+
class SessionCommand extends BaseCommand_1.default {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.session = null;
|
|
13
|
+
this.configManager = null;
|
|
14
|
+
}
|
|
15
|
+
async initSession(flags, _private = false) {
|
|
16
|
+
var _a;
|
|
17
|
+
try {
|
|
18
|
+
if (!this.configManager) {
|
|
19
|
+
await this.buildConfig(flags);
|
|
20
|
+
}
|
|
21
|
+
this.session = await session_1.default.get((_a = this.configManager) === null || _a === void 0 ? void 0 : _a.get());
|
|
22
|
+
if (this.session) {
|
|
23
|
+
console_1.default.debug(`Session open for ${this.session.payload.email}.`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (_private)
|
|
27
|
+
throw errors_1.AuthError('You need to log in, run the following command to continue: $ learnpack login');
|
|
28
|
+
console_1.default.debug('No active session available', _private);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console_1.default.error(error.message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async buildConfig(flags) {
|
|
36
|
+
this.configManager = await index_1.default(flags);
|
|
37
|
+
}
|
|
38
|
+
async catch(err) {
|
|
39
|
+
console_1.default.debug('COMMAND CATCH', err);
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.default = SessionCommand;
|
|
44
|
+
// SessionCommand.description = `Describe the command here
|
|
45
|
+
// ...
|
|
46
|
+
// Extra documentation goes here
|
|
47
|
+
// `
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
login: (identification: string, password: string) => Promise<any>;
|
|
3
|
+
publish: (config: any) => Promise<any>;
|
|
4
|
+
update: (config: any) => Promise<any>;
|
|
5
|
+
getPackage: (slug: string) => Promise<any>;
|
|
6
|
+
getLangs: () => Promise<any>;
|
|
7
|
+
getAllPackages: ({ lang, slug, }: {
|
|
8
|
+
lang?: string | undefined;
|
|
9
|
+
slug?: string | undefined;
|
|
10
|
+
}) => Promise<any>;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
package/lib/utils/api.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const console_1 = require("../utils/console");
|
|
4
|
+
const storage = require("node-persist");
|
|
5
|
+
const cli_ux_1 = require("cli-ux");
|
|
6
|
+
const HOST = "https://learnpack.herokuapp.com";
|
|
7
|
+
// eslint-disable-next-line
|
|
8
|
+
const _fetch = require("node-fetch");
|
|
9
|
+
const fetch = async (url, options = {}) => {
|
|
10
|
+
const headers = { "Content-Type": "application/json" };
|
|
11
|
+
let session = null;
|
|
12
|
+
try {
|
|
13
|
+
session = await storage.getItem("bc-payload");
|
|
14
|
+
if (session.token && session.token !== "" && !url.includes("/token"))
|
|
15
|
+
headers.Authorization = "Token " + session.token;
|
|
16
|
+
}
|
|
17
|
+
catch (_a) { }
|
|
18
|
+
try {
|
|
19
|
+
const resp = await _fetch(url, Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, headers), options.headers) }));
|
|
20
|
+
if (resp.status >= 200 && resp.status < 300)
|
|
21
|
+
return await resp.json();
|
|
22
|
+
if (resp.status === 401)
|
|
23
|
+
throw APIError("Invalid authentication credentials", 401);
|
|
24
|
+
else if (resp.status === 404)
|
|
25
|
+
throw APIError("Package not found", 404);
|
|
26
|
+
else if (resp.status >= 500)
|
|
27
|
+
throw APIError("Impossible to connect with the server", 500);
|
|
28
|
+
else if (resp.status >= 400) {
|
|
29
|
+
const error = await resp.json();
|
|
30
|
+
if (error.detail || error.error) {
|
|
31
|
+
throw APIError(error.detail || error.error);
|
|
32
|
+
}
|
|
33
|
+
else if (error.nonFieldErrors) {
|
|
34
|
+
throw APIError(error.nonFieldErrors[0], error);
|
|
35
|
+
}
|
|
36
|
+
else if (typeof error === "object") {
|
|
37
|
+
if (Object.keys(error).length > 0) {
|
|
38
|
+
const key = error[Object.keys(error)[0]];
|
|
39
|
+
throw APIError(`${key}: ${error[key][0]}`, error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw APIError("Uknown error");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
throw APIError("Uknown error");
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console_1.default.error(error.message);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const login = async (identification, password) => {
|
|
55
|
+
try {
|
|
56
|
+
cli_ux_1.default.action.start("Looking for credentials...");
|
|
57
|
+
await cli_ux_1.default.wait(1000);
|
|
58
|
+
const data = await fetch(`${HOST}/v1/auth/token/`, {
|
|
59
|
+
body: JSON.stringify({ identification, password }),
|
|
60
|
+
method: "post",
|
|
61
|
+
});
|
|
62
|
+
cli_ux_1.default.action.stop("ready");
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
console_1.default.error(error.message);
|
|
67
|
+
console_1.default.debug(error);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const publish = async (config) => {
|
|
71
|
+
const keys = [
|
|
72
|
+
"difficulty",
|
|
73
|
+
"language",
|
|
74
|
+
"skills",
|
|
75
|
+
"technologies",
|
|
76
|
+
"slug",
|
|
77
|
+
"repository",
|
|
78
|
+
"author",
|
|
79
|
+
"title",
|
|
80
|
+
];
|
|
81
|
+
const payload = {};
|
|
82
|
+
for (const k of keys)
|
|
83
|
+
config[k] ? (payload[k] = config[k]) : null;
|
|
84
|
+
try {
|
|
85
|
+
console.log("Package to publish:", payload);
|
|
86
|
+
cli_ux_1.default.action.start("Updating package information...");
|
|
87
|
+
await cli_ux_1.default.wait(1000);
|
|
88
|
+
const data = await fetch(`${HOST}/v1/package/${config.slug}`, {
|
|
89
|
+
method: "PUT",
|
|
90
|
+
body: JSON.stringify(payload),
|
|
91
|
+
});
|
|
92
|
+
cli_ux_1.default.action.stop("ready");
|
|
93
|
+
return data;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.log("payload", payload);
|
|
97
|
+
console_1.default.error(error.message);
|
|
98
|
+
console_1.default.debug(error);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const update = async (config) => {
|
|
103
|
+
try {
|
|
104
|
+
cli_ux_1.default.action.start("Updating package information...");
|
|
105
|
+
await cli_ux_1.default.wait(1000);
|
|
106
|
+
const data = await fetch(`${HOST}/v1/package/`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
body: JSON.stringify(config),
|
|
109
|
+
});
|
|
110
|
+
cli_ux_1.default.action.stop("ready");
|
|
111
|
+
return data;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console_1.default.error(error.message);
|
|
115
|
+
console_1.default.debug(error);
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const getPackage = async (slug) => {
|
|
120
|
+
try {
|
|
121
|
+
cli_ux_1.default.action.start("Downloading package information...");
|
|
122
|
+
await cli_ux_1.default.wait(1000);
|
|
123
|
+
const data = await fetch(`${HOST}/v1/package/${slug}`);
|
|
124
|
+
cli_ux_1.default.action.stop("ready");
|
|
125
|
+
return data;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (error.status === 404)
|
|
129
|
+
console_1.default.error(`Package ${slug} does not exist`);
|
|
130
|
+
else
|
|
131
|
+
console_1.default.error(`Package ${slug} does not exist`);
|
|
132
|
+
console_1.default.debug(error);
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const getLangs = async () => {
|
|
137
|
+
try {
|
|
138
|
+
cli_ux_1.default.action.start("Downloading language options...");
|
|
139
|
+
await cli_ux_1.default.wait(1000);
|
|
140
|
+
const data = await fetch(`${HOST}/v1/package/language`);
|
|
141
|
+
cli_ux_1.default.action.stop("ready");
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (error.status === 404)
|
|
146
|
+
console_1.default.error("Package slug does not exist");
|
|
147
|
+
else
|
|
148
|
+
console_1.default.error("Package slug does not exist");
|
|
149
|
+
console_1.default.debug(error);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const getAllPackages = async ({ lang = "", slug = "", }) => {
|
|
154
|
+
try {
|
|
155
|
+
cli_ux_1.default.action.start("Downloading packages...");
|
|
156
|
+
await cli_ux_1.default.wait(1000);
|
|
157
|
+
const data = await fetch(`${HOST}/v1/package/all?limit=100&language=${lang}&slug=${slug}`);
|
|
158
|
+
cli_ux_1.default.action.stop("ready");
|
|
159
|
+
return data;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console_1.default.error(`Package ${slug} does not exist`);
|
|
163
|
+
console_1.default.debug(error);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const APIError = (error, code) => {
|
|
168
|
+
const message = error.message || error;
|
|
169
|
+
const _err = new Error(message);
|
|
170
|
+
_err.status = code || 400;
|
|
171
|
+
return _err;
|
|
172
|
+
};
|
|
173
|
+
exports.default = { login, publish, update, getPackage, getLangs, getAllPackages };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IAuditErrors } from '../models/audit-errors';
|
|
2
|
+
import { IConfigObj } from '../models/config';
|
|
3
|
+
import { ICounter } from '../models/counter';
|
|
4
|
+
import { IFindings } from '../models/findings';
|
|
5
|
+
declare const _default: {
|
|
6
|
+
isUrl: (url: string, errors: IAuditErrors[], counter: ICounter) => Promise<boolean>;
|
|
7
|
+
checkForEmptySpaces: (str: string) => boolean;
|
|
8
|
+
checkLearnpackClean: (configObj: IConfigObj, errors: IAuditErrors[]) => void;
|
|
9
|
+
findInFile: (types: string[], content: string) => IFindings;
|
|
10
|
+
showErrors: (errors: IAuditErrors[], counter: ICounter) => Promise<unknown>;
|
|
11
|
+
showWarnings: (warnings: IAuditErrors[]) => Promise<unknown>;
|
|
12
|
+
};
|
|
13
|
+
export default _default;
|