@learnpack/learnpack 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. package/README.md +51 -398
  2. package/bin/run +14 -2
  3. package/oclif.manifest.json +1 -1
  4. package/package.json +135 -111
  5. package/src/commands/audit.ts +462 -0
  6. package/src/commands/clean.ts +29 -0
  7. package/src/commands/download.ts +62 -0
  8. package/src/commands/init.ts +169 -0
  9. package/src/commands/login.ts +42 -0
  10. package/src/commands/logout.ts +43 -0
  11. package/src/commands/publish.ts +107 -0
  12. package/src/commands/start.ts +229 -0
  13. package/src/commands/{test.js → test.ts} +19 -21
  14. package/src/index.ts +1 -0
  15. package/src/managers/config/allowed_files.ts +29 -0
  16. package/src/managers/config/defaults.ts +33 -0
  17. package/src/managers/config/exercise.ts +295 -0
  18. package/src/managers/config/index.ts +411 -0
  19. package/src/managers/file.ts +169 -0
  20. package/src/managers/gitpod.ts +84 -0
  21. package/src/managers/server/{index.js → index.ts} +26 -19
  22. package/src/managers/server/routes.ts +250 -0
  23. package/src/managers/session.ts +118 -0
  24. package/src/managers/socket.ts +239 -0
  25. package/src/managers/test.ts +83 -0
  26. package/src/models/action.ts +3 -0
  27. package/src/models/audit-errors.ts +4 -0
  28. package/src/models/config-manager.ts +23 -0
  29. package/src/models/config.ts +74 -0
  30. package/src/models/counter.ts +11 -0
  31. package/src/models/errors.ts +22 -0
  32. package/src/models/exercise-obj.ts +26 -0
  33. package/src/models/file.ts +5 -0
  34. package/src/models/findings.ts +18 -0
  35. package/src/models/flags.ts +10 -0
  36. package/src/models/front-matter.ts +11 -0
  37. package/src/models/gitpod-data.ts +19 -0
  38. package/src/models/language.ts +4 -0
  39. package/src/models/package.ts +7 -0
  40. package/src/models/plugin-config.ts +17 -0
  41. package/src/models/session.ts +26 -0
  42. package/src/models/socket.ts +48 -0
  43. package/src/models/status.ts +15 -0
  44. package/src/models/success-types.ts +1 -0
  45. package/src/plugin/command/compile.ts +17 -0
  46. package/src/plugin/command/test.ts +30 -0
  47. package/src/plugin/index.ts +6 -0
  48. package/src/plugin/plugin.ts +94 -0
  49. package/src/plugin/utils.ts +87 -0
  50. package/src/types/node-fetch.d.ts +1 -0
  51. package/src/ui/download.ts +71 -0
  52. package/src/utils/BaseCommand.ts +48 -0
  53. package/src/utils/SessionCommand.ts +48 -0
  54. package/src/utils/api.ts +194 -0
  55. package/src/utils/audit.ts +162 -0
  56. package/src/utils/console.ts +24 -0
  57. package/src/utils/errors.ts +117 -0
  58. package/src/utils/{exercisesQueue.js → exercisesQueue.ts} +12 -6
  59. package/src/utils/fileQueue.ts +198 -0
  60. package/src/utils/misc.ts +23 -0
  61. package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.es.md +2 -4
  62. package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.md +1 -2
  63. package/src/utils/templates/isolated/01-hello-world/README.es.md +1 -2
  64. package/src/utils/templates/isolated/01-hello-world/README.md +1 -2
  65. package/src/utils/templates/isolated/README.ejs +1 -1
  66. package/src/utils/templates/isolated/README.es.ejs +1 -1
  67. package/src/utils/validators.ts +18 -0
  68. package/src/utils/watcher.ts +27 -0
  69. package/plugin/command/compile.js +0 -17
  70. package/plugin/command/test.js +0 -29
  71. package/plugin/index.js +0 -6
  72. package/plugin/plugin.js +0 -71
  73. package/plugin/utils.js +0 -78
  74. package/src/commands/audit.js +0 -243
  75. package/src/commands/clean.js +0 -27
  76. package/src/commands/download.js +0 -52
  77. package/src/commands/hello.js +0 -20
  78. package/src/commands/init.js +0 -133
  79. package/src/commands/login.js +0 -45
  80. package/src/commands/logout.js +0 -39
  81. package/src/commands/publish.js +0 -78
  82. package/src/commands/start.js +0 -169
  83. package/src/index.js +0 -1
  84. package/src/managers/config/allowed_files.js +0 -12
  85. package/src/managers/config/defaults.js +0 -32
  86. package/src/managers/config/exercise.js +0 -212
  87. package/src/managers/config/index.js +0 -342
  88. package/src/managers/file.js +0 -137
  89. package/src/managers/server/routes.js +0 -151
  90. package/src/managers/session.js +0 -83
  91. package/src/managers/socket.js +0 -185
  92. package/src/managers/test.js +0 -77
  93. package/src/ui/download.js +0 -48
  94. package/src/utils/BaseCommand.js +0 -34
  95. package/src/utils/SessionCommand.js +0 -46
  96. package/src/utils/api.js +0 -164
  97. package/src/utils/audit.js +0 -114
  98. package/src/utils/console.js +0 -16
  99. package/src/utils/errors.js +0 -90
  100. package/src/utils/fileQueue.js +0 -194
  101. package/src/utils/misc.js +0 -26
  102. package/src/utils/validators.js +0 -15
  103. package/src/utils/watcher.js +0 -24
@@ -1,83 +0,0 @@
1
- const Console = require('../utils/console');
2
- const api = require('../utils/api');
3
-
4
- const v = require('validator');
5
- const { ValidationError, InternalError } = require('../utils/errors');
6
- const moment = require('moment');
7
- const fs = require('fs');
8
- const cli = require("cli-ux").default
9
- const storage = require('node-persist');
10
-
11
- module.exports = {
12
- sessionStarted: false,
13
- token: null,
14
- config: null,
15
- currentCohort: null,
16
- initialize: async function(){
17
- if(!this.sessionStarted){
18
-
19
- if(!this.config) throw InternalError('Configuration not found')
20
- if(!fs.existsSync(this.config.dirPath)) fs.mkdirSync(this.config.dirPath)
21
- await storage.init({ dir: `${this.config.dirPath}/.session` });
22
- this.sessionStarted = true;
23
- }
24
- return true
25
- },
26
- setPayload: async function(value){
27
- await this.initialize();
28
- await storage.setItem('bc-payload', { token: this.token, ...value });
29
- Console.debug("Payload successfuly found and set for "+value.email);
30
- return true;
31
- },
32
- getPayload: async function(){
33
- await this.initialize();
34
- let payload = null;
35
- try{
36
- payload = await storage.getItem('bc-payload');
37
- }
38
- catch(err){
39
- Console.debug("Error retriving session payload");
40
- }
41
- return payload;
42
- },
43
- isActive: function(){
44
- if(this.token) return true;
45
- else return false;
46
- },
47
- get: async function(configObj=null){
48
- if(configObj) this.config = configObj.config;
49
-
50
- await this.sync();
51
- if(!this.isActive()) return null;
52
-
53
- const payload = await this.getPayload();
54
- return {
55
- payload, token: this.token,
56
- };
57
- },
58
- login: async function(){
59
-
60
- var email = await cli.prompt('What is your email?')
61
- if(!v.isEmail(email)) throw ValidationError('Invalid email');
62
-
63
- var password = await cli.prompt('What is your password?', {type: 'hide'})
64
-
65
- const data = await api.login(email, password);
66
- if(data) this.start({ token: data.token, payload: data });
67
-
68
- },
69
- sync: async function(){
70
- const payload = await this.getPayload();
71
- if(payload) this.token = payload.token;
72
- },
73
- start: async function({ token, payload=null }){
74
- if(!token) throw new Error("A token and email is needed to start a session");
75
- this.token = token;
76
- if(payload) if(await this.setPayload(payload)) Console.success(`Successfully logged in as ${payload.email}`);
77
- },
78
- destroy: async function(){
79
- await storage.clear();
80
- this.token = null;
81
- Console.success('You have logged out');
82
- }
83
- };
@@ -1,185 +0,0 @@
1
- let connect = require("socket.io");
2
- let Console = require("../utils/console");
3
- const queue = require("../utils/fileQueue");
4
-
5
- module.exports = {
6
- socket: null,
7
- config: null,
8
- allowedActions: null,
9
- isTestingEnvironment: false,
10
- actionCallBacks: {
11
- clean: (data, s) => {
12
- s.logs = [];
13
- },
14
- },
15
- addAllowed: function (actions) {
16
- if (!Array.isArray(actions)) actions = [actions];
17
-
18
- //avoid adding the "test" action if grading is disabled
19
- if (actions.includes("test") && this.config.disable_grading)
20
- actions = actions.filter((a) => a != "test");
21
-
22
- //remove duplicates
23
- this.allowedActions = this.allowedActions
24
- .filter((a) => !actions.includes(a))
25
- .concat(actions);
26
- },
27
- removeAllowed: function (actions) {
28
- if (!Array.isArray(actions)) actions = [actions];
29
- this.allowedActions = this.allowedActions.filter(
30
- (a) => !actions.includes(a)
31
- );
32
- },
33
- start: function (config, server, isTestingEnvironment = false) {
34
- this.config = config;
35
- this.isTestingEnvironment = isTestingEnvironment;
36
-
37
- // remove test action if grading is disabled
38
- this.allowedActions = config.actions.filter((act) =>
39
- config.disable_grading ? act !== "test" : true
40
- );
41
-
42
- this.socket = connect(server);
43
- this.socket.on("connection", (socket) => {
44
- Console.debug(
45
- "Connection with client successfully established",
46
- this.allowedActions
47
- );
48
-
49
- if (!this.isTestingEnvironment) {
50
- this.log("ready", ["Ready to compile or test..."]);
51
- }
52
-
53
- socket.on("compiler", ({ action, data }) => {
54
- this.emit("clean", "pending", ["Working..."]);
55
-
56
- if (typeof data.exerciseSlug == "undefined") {
57
- this.log("internal-error", ["No exercise slug specified"]);
58
- Console.error("No exercise slug especified");
59
- return;
60
- }
61
-
62
- if (typeof this.actionCallBacks[action] == "function")
63
- this.actionCallBacks[action](data);
64
- else this.log("internal-error", ["Uknown action " + action]);
65
- });
66
- });
67
- },
68
- on: function (action, callBack) {
69
- this.actionCallBacks[action] = callBack;
70
- },
71
- clean: function (status = "pending", logs = []) {
72
- this.emit("clean", "pending", logs);
73
- },
74
- ask: function (questions = []) {
75
- return new Promise((resolve, reject) => {
76
- this.emit("ask", "pending", ["Waiting for input..."], questions);
77
- this.on("input", ({ inputs }) => {
78
- // Workaround to fix issue because null inputs
79
- let isNull = false;
80
- inputs.forEach((input) => {
81
- if (input === null) {
82
- isNull = true;
83
- }
84
- });
85
-
86
- if (!isNull) {
87
- resolve(inputs);
88
- }
89
- });
90
- });
91
- },
92
- reload: function (files = null, exercises = null) {
93
- this.emit("reload", files, exercises);
94
- },
95
- openWindow: function (url = "") {
96
- queue.dispatcher().enqueue(queue.events.OPEN_WINDOW, url);
97
- this.emit(
98
- queue.events.OPEN_WINDOW,
99
- (status = "ready"),
100
- (logs = [`Opening ${url}`]),
101
- (inputs = []),
102
- (report = []),
103
- (data = url)
104
- );
105
- },
106
- log: function (status, messages = [], report = [], data = null) {
107
- this.emit("log", status, messages, [], report, data);
108
- Console.log(messages);
109
- },
110
- emit: function (
111
- action,
112
- status = "ready",
113
- logs = [],
114
- inputs = [],
115
- report = [],
116
- data = null
117
- ) {
118
- if (
119
- ["webpack", "vanillajs", "vue", "react", "css", "html"].includes(
120
- this.config.compiler
121
- )
122
- ) {
123
- if (["compiler-success", "compiler-warning"].includes(status))
124
- this.addAllowed("preview");
125
- if (["compiler-error"].includes(status) || action == "ready")
126
- this.removeAllowed("preview");
127
- }
128
-
129
- if (this.config.grading === "incremental") {
130
- this.removeAllowed("reset");
131
- }
132
-
133
- Console.debug("dactions", this.config)
134
- this.config.disabledActions.forEach(a => this.removeAllowed(a))
135
-
136
- this.socket.emit("compiler", {
137
- action,
138
- status,
139
- logs,
140
- allowed: this.allowedActions,
141
- inputs,
142
- report,
143
- data,
144
- });
145
- },
146
-
147
- ready: function (message) {
148
- this.log("ready", [message]);
149
- },
150
- success: function (type, stdout = "") {
151
- const types = ["compiler", "testing"];
152
- if (!types.includes(type))
153
- this.fatal(`Invalid socket success type "${type}" on socket`);
154
- else {
155
- if (stdout === "")
156
- this.log(type + "-success", ["No stdout to display on the console"]);
157
- else this.log(type + "-success", [stdout]);
158
- }
159
-
160
- if (this.isTestingEnvironment) {
161
- this.onTestingFinised({
162
- result: "success",
163
- });
164
- }
165
- },
166
- error: function (type, stdout) {
167
- console.error("Socket error: " + type, stdout);
168
- this.log(type, [stdout]);
169
-
170
- if (this.isTestingEnvironment) {
171
- this.onTestingFinised({
172
- result: "failed",
173
- });
174
- }
175
- },
176
- fatal: function (msg) {
177
- this.log("internal-error", [msg]);
178
- throw msg;
179
- },
180
- onTestingFinised: function (result) {
181
- if (this.config.testingFinishedCallback) {
182
- this.config.testingFinishedCallback(result);
183
- }
184
- },
185
- };
@@ -1,77 +0,0 @@
1
- const path = require('path');
2
- let shell = require('shelljs');
3
- const fs = require('fs');
4
- let { TestingError } = require('./errors');
5
- let Console = require('../utils/console');
6
- const color = require('colors');
7
- const bcActivity = require('./bcActivity.js');
8
-
9
- module.exports = async function({ socket, files, config, slug }){
10
-
11
- const configPath = path.resolve(__dirname,`./config/tester/${config.tester}/${config.language}.config.js`);
12
- if (!fs.existsSync(configPath)) throw CompilerError(`Uknown testing engine for compiler: '${config.language}'`);
13
-
14
- const testingConfig = require(configPath)(files, config, slug);
15
- testingConfig.validate();
16
-
17
- if(config.ignoreTests) throw TestingError('Grading is disabled on learn.json file.');
18
-
19
- if (!fs.existsSync(`${config.dirPath}/reports`)){
20
- fs.mkdirSync(`${config.dirPath}/reports`);
21
- Console.debug(`Creating the ${config.dirPath}/reports directory`);
22
- }
23
-
24
- Console.info('Running tests...');
25
-
26
- const command = await testingConfig.getCommand(socket)
27
- const { stdout, stderr, code } = shell.exec(command);
28
-
29
- if(code != 0){
30
- const errors = typeof(testingConfig.getErrors === 'function') ? testingConfig.getErrors(stdout || stderr) : [];
31
- socket.log('testing-error', errors);
32
- console.log(errors.join('\n'))
33
-
34
- Console.error("There was an error while testing");
35
- bcActivity.error('exercise_error', {
36
- message: errors,
37
- name: `${config.tester}-error`,
38
- framework: config.tester,
39
- language: config.language,
40
- data: slug,
41
- compiler: config.compiler
42
- });
43
- }
44
- else{
45
- socket.log('testing-success',[ stdout || stderr ].concat(["😁Everything is amazing!"]));
46
- Console.success("Everything is amazing!");
47
-
48
-
49
- bcActivity.activity('exercise_success', {
50
- language: config.language,
51
- slug: slug,
52
- editor: config.editor,
53
- compiler: config.compiler
54
- });
55
- config.exercises = config.exercises.map(e => {
56
- if(e.slug === slug) e.done = true;
57
- return e;
58
- });
59
- }
60
-
61
-
62
- if(typeof testingConfig.cleanup !== "undefined"){
63
- if(typeof testingConfig.cleanup === 'function' || typeof testingConfig.cleanup === 'object'){
64
- const clean = await testingConfig.cleanup(socket);
65
- if(clean){
66
- const { stdout, stderr, code } = shell.exec(clean);
67
- if(code == 0){
68
- Console.debug("The cleanup command runned successfully");
69
- }
70
- else Console.warning("There is an error on the cleanup command for the test");
71
- }
72
-
73
- }
74
- }
75
-
76
- return true;
77
- };
@@ -1,48 +0,0 @@
1
- const { prompt } = require("enquirer")
2
- const Console = require('../utils/console')
3
- const api = require('../utils/api')
4
- const fetch = require('node-fetch')
5
-
6
- const askPackage = () => new Promise(async (resolve, reject) => {
7
- Console.info(`No package was specified`)
8
- const languages = await api.getLangs()
9
- if(languages.length === 0){
10
- reject(new Error("No categories available"))
11
- return null;
12
- }
13
- let packages = []
14
- prompt([{
15
- type: 'select',
16
- name: 'lang',
17
- message: 'What language do you want to practice?',
18
- choices: languages.map(l => ({ message: l.title, name: l.slug })),
19
- }])
20
- .then(({ lang }) => {
21
- return (async() => {
22
- const response = await api.getAllPackages({ lang })
23
- const packages = response.results
24
- if(packages.length === 0){
25
- const error = new Error(`No packages found for language ${lang}`)
26
- Console.error(error)
27
- return error
28
- }
29
- return await prompt([{
30
- type: 'select',
31
- name: 'pack',
32
- message: 'Choose one of the packages available',
33
- choices: packages.map(l => ({
34
- message: `${l.title}, difficulty: ${l.difficulty}, downloads: ${l.downloads} ${l.skills.length > 0 ? `(Skills: ${l.skills.join(",")})` : ""}`,
35
- value: l
36
- })),
37
- }])
38
- })()
39
- })
40
- .then(resp => {
41
- if(!resp) reject(resp.message || resp)
42
- else resolve(resp)
43
- })
44
- .catch(error => {
45
- Console.error(error.message || error)
46
- })
47
- })
48
- module.exports = { askPackage }
@@ -1,34 +0,0 @@
1
- const {Command, flags} = require('@oclif/command')
2
- const Console = require('./console')
3
- const SessionManager = require('../managers/session.js')
4
-
5
-
6
- class BaseCommand extends Command {
7
- constructor(...params){
8
- super(...params)
9
- }
10
- async catch(err) {
11
- Console.debug("COMMAND CATCH", err)
12
-
13
- throw err
14
- }
15
- async init() {
16
- const {flags, args} = this.parse(BaseCommand)
17
- Console.debug("COMMAND INIT")
18
- Console.debug("These are your flags: ",flags);
19
- Console.debug("These are your args: ",args);
20
-
21
- // quick fix for listening to the process termination on windows
22
- process.on('SIGINT', function() {
23
- Console.debug("Terminated (SIGINT)")
24
- process.exit();
25
- });
26
-
27
- }
28
- async finally() {
29
- Console.debug("COMMAND FINALLY")
30
- // called after run and catch regardless of whether or not the command errored
31
- }
32
- }
33
-
34
- module.exports = BaseCommand
@@ -1,46 +0,0 @@
1
- const {flags} = require('@oclif/command')
2
- const BaseCommand = require("./BaseCommand")
3
- const Console = require('./console')
4
- const SessionManager = require('../managers/session.js')
5
- const ConfigManager = require('../managers/config/index.js')
6
- const { AuthError } = require('./errors.js')
7
-
8
- class SessionCommand extends BaseCommand {
9
- constructor(...args){
10
- super(...args)
11
- this.configManager = null
12
- this.session = null
13
- }
14
-
15
- async initSession(flags, _private){
16
- try{
17
- if(!this.configManager) await this.buildConfig(flags)
18
-
19
- this.session = await SessionManager.get(this.configManager.get())
20
- if(this.session) Console.debug(`Session open for ${this.session.payload.email}.`)
21
- else{
22
- if(_private) throw AuthError("You need to log in, run the following command to continue: $ learnpack login");
23
- Console.debug("No active session available", _private)
24
- }
25
- }
26
- catch(error){
27
- Console.error(error.message)
28
- }
29
- }
30
- async buildConfig(flags){
31
- Console.debug("Building configuration for the first time")
32
- Console.debug("Flags", flags)
33
- this.configManager = await ConfigManager(flags)
34
- }
35
- async catch(err) {
36
- Console.debug("COMMAND CATCH", err)
37
- throw err
38
- }
39
- }
40
-
41
- // SessionCommand.description = `Describe the command here
42
- // ...
43
- // Extra documentation goes here
44
- // `
45
-
46
- module.exports = SessionCommand
package/src/utils/api.js DELETED
@@ -1,164 +0,0 @@
1
- const Console = require('../utils/console');
2
- const _fetch = require('node-fetch');
3
- const storage = require('node-persist');
4
- const cli = require("cli-ux").default
5
- const HOST = "https://learnpack.herokuapp.com";
6
-
7
- const fetch = async (url, options={}) => {
8
-
9
- let headers = { "Content-Type": "application/json" }
10
- let session = null;
11
- try{
12
- session = await storage.getItem('bc-payload');
13
- if(session.token && session.token != "" && !url.includes("/token")) headers["Authorization"] = "Token "+session.token;
14
- }
15
- catch(err){}
16
-
17
- try{
18
- const resp = await _fetch(url, {
19
- ...options,
20
- headers: { ...headers, ...options.headers }
21
- })
22
-
23
- if(resp.status >= 200 && resp.status < 300) return await resp.json()
24
- else if(resp.status === 401) throw APIError("Invalid authentication credentials", 401)
25
- else if(resp.status === 404) throw APIError("Package not found", 404)
26
- else if(resp.status >= 500) throw APIError("Impossible to connect with the server", 500)
27
- else if(resp.status >= 400){
28
- const error = await resp.json()
29
- if(error.detail || error.error){
30
- throw APIError(error.detail || error.error)
31
- }else if(error.non_field_errors){
32
- throw APIError(non_field_errors[0], error)
33
- }else if (typeof error === "object"){
34
- for(let key in error){
35
- throw APIError(`${key}: ${error[key][0]}`, error)
36
- }
37
- }else{
38
- throw APIError("Uknown error")
39
- }
40
- }
41
- else throw APIError("Uknown error")
42
- }
43
- catch(error){
44
- Console.error(error.message);
45
- throw error;
46
- }
47
- }
48
- const login = async (identification, password) => {
49
-
50
- try{
51
- cli.action.start('Looking for credentials...')
52
- await cli.wait(1000)
53
- const data = await fetch(`${HOST}/v1/auth/token/`, {
54
- body: JSON.stringify({ identification, password }),
55
- method: 'post'
56
- });
57
- cli.action.stop('ready')
58
- return data
59
- }
60
- catch(err){
61
- Console.error(err.message);
62
- Console.debug(err);
63
- }
64
- }
65
- const publish = async (config) => {
66
-
67
- const keys = ['difficulty', 'language', 'skills', 'technologies', 'slug', 'repository', 'author', 'title'];
68
-
69
- let payload = {}
70
- keys.forEach(k => config[k] ? payload[k] = config[k] : null);
71
- try{
72
- Console.log("Package to publish: ", payload)
73
- cli.action.start('Updating package information...')
74
- await cli.wait(1000)
75
- const data = await fetch(`${HOST}/v1/package/${config.slug}`,{
76
- method: 'PUT',
77
- body: JSON.stringify(payload)
78
- })
79
- cli.action.stop('ready')
80
- return data
81
- }
82
- catch(err){
83
- Console.log("payload", payload)
84
- Console.error(err.message);
85
- Console.debug(err);
86
- throw err;
87
- }
88
- }
89
-
90
- const update = async (config) => {
91
-
92
- try{
93
- cli.action.start('Updating package information...')
94
- await cli.wait(1000)
95
- const data = await fetch(`${HOST}/v1/package/`,{
96
- method: 'POST',
97
- body: JSON.stringify(config)
98
- })
99
- cli.action.stop('ready')
100
- return data
101
- }
102
- catch(err){
103
- Console.error(err.message);
104
- Console.debug(err);
105
- throw err;
106
- }
107
- }
108
-
109
- const getPackage = async (slug) => {
110
- try{
111
- cli.action.start('Downloading package information...')
112
- await cli.wait(1000)
113
- const data = await fetch(`${HOST}/v1/package/${slug}`)
114
- cli.action.stop('ready')
115
- return data
116
- }
117
- catch(err){
118
- if(err.status == 404) Console.error(`Package ${slug} does not exist`);
119
- else Console.error(`Package ${slug} does not exist`);
120
- Console.debug(err);
121
- throw err;
122
- }
123
- }
124
-
125
- const getLangs = async () => {
126
- try{
127
- cli.action.start('Downloading language options...')
128
- await cli.wait(1000)
129
- const data = await fetch(`${HOST}/v1/package/language`)
130
- cli.action.stop('ready')
131
- return data;
132
- }
133
- catch(err){
134
- if(err.status == 404) Console.error(`Package ${slug} does not exist`);
135
- else Console.error(`Package ${slug} does not exist`);
136
- Console.debug(err);
137
- throw err;
138
- }
139
- }
140
-
141
-
142
- const getAllPackages = async ({ lang='', slug='' }) => {
143
- try{
144
- cli.action.start('Downloading packages...')
145
- await cli.wait(1000)
146
- const data = await fetch(`${HOST}/v1/package/all?limit=100&language=${lang}&slug=${slug}`)
147
- cli.action.stop('ready')
148
- return data;
149
- }
150
- catch(err){
151
- Console.error(`Package ${slug} does not exist`);
152
- Console.debug(err);
153
- throw err;
154
- }
155
- }
156
-
157
- const APIError = (error, code) => {
158
- const message = error.message || error;
159
- const _err = new Error(message);
160
- _err.status = code || 400;
161
- return _err;
162
- }
163
-
164
- module.exports = {login, publish, update, getPackage, getLangs, getAllPackages }