@learnpack/learnpack 2.1.25 → 2.1.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. package/README.md +16 -16
  2. package/bin/run +17 -17
  3. package/bin/run.cmd +3 -3
  4. package/oclif.manifest.json +1 -1
  5. package/package.json +139 -138
  6. package/src/commands/audit.ts +134 -109
  7. package/src/commands/clean.ts +29 -29
  8. package/src/commands/download.ts +62 -62
  9. package/src/commands/init.ts +39 -39
  10. package/src/commands/login.ts +42 -42
  11. package/src/commands/logout.ts +43 -43
  12. package/src/commands/publish.ts +107 -107
  13. package/src/commands/start.ts +264 -234
  14. package/src/commands/test.ts +85 -85
  15. package/src/index.ts +1 -1
  16. package/src/managers/config/allowed_files.ts +29 -29
  17. package/src/managers/config/defaults.ts +4 -2
  18. package/src/managers/config/exercise.ts +309 -302
  19. package/src/managers/config/index.ts +159 -138
  20. package/src/managers/file.ts +178 -169
  21. package/src/managers/gitpod.ts +84 -84
  22. package/src/managers/server/index.ts +78 -69
  23. package/src/managers/server/routes.ts +139 -90
  24. package/src/managers/session.ts +147 -118
  25. package/src/managers/socket.ts +252 -239
  26. package/src/managers/test.ts +83 -83
  27. package/src/models/action.ts +10 -3
  28. package/src/models/config-manager.ts +23 -23
  29. package/src/models/config.ts +9 -2
  30. package/src/models/counter.ts +11 -11
  31. package/src/models/errors.ts +22 -22
  32. package/src/models/exercise-obj.ts +6 -3
  33. package/src/models/file.ts +5 -5
  34. package/src/models/findings.ts +18 -18
  35. package/src/models/flags.ts +10 -10
  36. package/src/models/front-matter.ts +11 -11
  37. package/src/models/gitpod-data.ts +19 -19
  38. package/src/models/language.ts +4 -4
  39. package/src/models/package.ts +7 -7
  40. package/src/models/plugin-config.ts +17 -17
  41. package/src/models/session.ts +29 -26
  42. package/src/models/socket.ts +54 -48
  43. package/src/models/status.ts +16 -15
  44. package/src/models/success-types.ts +1 -1
  45. package/src/plugin/command/compile.ts +17 -17
  46. package/src/plugin/command/test.ts +30 -30
  47. package/src/plugin/index.ts +6 -6
  48. package/src/plugin/plugin.ts +94 -94
  49. package/src/plugin/utils.ts +87 -87
  50. package/src/types/node-fetch.d.ts +1 -1
  51. package/src/ui/download.ts +71 -71
  52. package/src/utils/BaseCommand.ts +48 -48
  53. package/src/utils/SessionCommand.ts +48 -48
  54. package/src/utils/api.ts +246 -194
  55. package/src/utils/audit.ts +392 -395
  56. package/src/utils/console.ts +24 -24
  57. package/src/utils/errors.ts +117 -117
  58. package/src/utils/exercisesQueue.ts +51 -51
  59. package/src/utils/fileQueue.ts +198 -198
  60. package/src/utils/misc.ts +23 -23
  61. package/src/utils/templates/gitignore.txt +19 -19
  62. package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.es.md +24 -24
  63. package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.md +24 -24
  64. package/src/utils/templates/incremental/README.ejs +4 -4
  65. package/src/utils/templates/incremental/README.es.ejs +4 -4
  66. package/src/utils/templates/isolated/01-hello-world/README.es.md +26 -26
  67. package/src/utils/templates/isolated/01-hello-world/README.md +26 -26
  68. package/src/utils/templates/isolated/README.ejs +4 -4
  69. package/src/utils/templates/isolated/README.es.ejs +4 -4
  70. package/src/utils/templates/no-grading/README.ejs +4 -4
  71. package/src/utils/templates/no-grading/README.es.ejs +4 -4
  72. package/src/utils/validators.ts +18 -18
  73. package/src/utils/watcher.ts +14 -14
  74. package/lib/commands/audit.d.ts +0 -6
  75. package/lib/commands/audit.js +0 -317
  76. package/lib/commands/clean.d.ts +0 -8
  77. package/lib/commands/clean.js +0 -25
  78. package/lib/commands/download.d.ts +0 -13
  79. package/lib/commands/download.js +0 -55
  80. package/lib/commands/init.d.ts +0 -9
  81. package/lib/commands/init.js +0 -123
  82. package/lib/commands/login.d.ts +0 -14
  83. package/lib/commands/login.js +0 -37
  84. package/lib/commands/logout.d.ts +0 -14
  85. package/lib/commands/logout.js +0 -37
  86. package/lib/commands/publish.d.ts +0 -14
  87. package/lib/commands/publish.js +0 -82
  88. package/lib/commands/start.d.ts +0 -7
  89. package/lib/commands/start.js +0 -165
  90. package/lib/commands/test.d.ts +0 -6
  91. package/lib/commands/test.js +0 -62
  92. package/lib/index.d.ts +0 -1
  93. package/lib/index.js +0 -4
  94. package/lib/managers/config/allowed_files.d.ts +0 -5
  95. package/lib/managers/config/allowed_files.js +0 -30
  96. package/lib/managers/config/defaults.d.ts +0 -37
  97. package/lib/managers/config/defaults.js +0 -38
  98. package/lib/managers/config/exercise.d.ts +0 -36
  99. package/lib/managers/config/exercise.js +0 -230
  100. package/lib/managers/config/index.d.ts +0 -3
  101. package/lib/managers/config/index.js +0 -302
  102. package/lib/managers/file.d.ts +0 -13
  103. package/lib/managers/file.js +0 -134
  104. package/lib/managers/gitpod.d.ts +0 -3
  105. package/lib/managers/gitpod.js +0 -67
  106. package/lib/managers/server/index.d.ts +0 -6
  107. package/lib/managers/server/index.js +0 -51
  108. package/lib/managers/server/routes.d.ts +0 -4
  109. package/lib/managers/server/routes.js +0 -167
  110. package/lib/managers/session.d.ts +0 -3
  111. package/lib/managers/session.js +0 -104
  112. package/lib/managers/socket.d.ts +0 -3
  113. package/lib/managers/socket.js +0 -164
  114. package/lib/managers/test.d.ts +0 -0
  115. package/lib/managers/test.js +0 -84
  116. package/lib/models/action.d.ts +0 -2
  117. package/lib/models/action.js +0 -2
  118. package/lib/models/audit.d.ts +0 -15
  119. package/lib/models/audit.js +0 -2
  120. package/lib/models/config-manager.d.ts +0 -21
  121. package/lib/models/config-manager.js +0 -2
  122. package/lib/models/config.d.ts +0 -60
  123. package/lib/models/config.js +0 -2
  124. package/lib/models/counter.d.ts +0 -11
  125. package/lib/models/counter.js +0 -2
  126. package/lib/models/errors.d.ts +0 -15
  127. package/lib/models/errors.js +0 -2
  128. package/lib/models/exercise-obj.d.ts +0 -27
  129. package/lib/models/exercise-obj.js +0 -2
  130. package/lib/models/file.d.ts +0 -5
  131. package/lib/models/file.js +0 -2
  132. package/lib/models/findings.d.ts +0 -17
  133. package/lib/models/findings.js +0 -2
  134. package/lib/models/flags.d.ts +0 -10
  135. package/lib/models/flags.js +0 -2
  136. package/lib/models/front-matter.d.ts +0 -11
  137. package/lib/models/front-matter.js +0 -2
  138. package/lib/models/gitpod-data.d.ts +0 -16
  139. package/lib/models/gitpod-data.js +0 -2
  140. package/lib/models/language.d.ts +0 -4
  141. package/lib/models/language.js +0 -2
  142. package/lib/models/package.d.ts +0 -7
  143. package/lib/models/package.js +0 -2
  144. package/lib/models/plugin-config.d.ts +0 -16
  145. package/lib/models/plugin-config.js +0 -2
  146. package/lib/models/session.d.ts +0 -23
  147. package/lib/models/session.js +0 -2
  148. package/lib/models/socket.d.ts +0 -31
  149. package/lib/models/socket.js +0 -2
  150. package/lib/models/status.d.ts +0 -1
  151. package/lib/models/status.js +0 -2
  152. package/lib/models/success-types.d.ts +0 -1
  153. package/lib/models/success-types.js +0 -2
  154. package/lib/plugin/command/compile.d.ts +0 -6
  155. package/lib/plugin/command/compile.js +0 -18
  156. package/lib/plugin/command/test.d.ts +0 -6
  157. package/lib/plugin/command/test.js +0 -25
  158. package/lib/plugin/index.d.ts +0 -27
  159. package/lib/plugin/index.js +0 -7
  160. package/lib/plugin/plugin.d.ts +0 -8
  161. package/lib/plugin/plugin.js +0 -68
  162. package/lib/plugin/utils.d.ts +0 -16
  163. package/lib/plugin/utils.js +0 -58
  164. package/lib/ui/download.d.ts +0 -5
  165. package/lib/ui/download.js +0 -61
  166. package/lib/utils/BaseCommand.d.ts +0 -8
  167. package/lib/utils/BaseCommand.js +0 -41
  168. package/lib/utils/SessionCommand.d.ts +0 -10
  169. package/lib/utils/SessionCommand.js +0 -47
  170. package/lib/utils/api.d.ts +0 -12
  171. package/lib/utils/api.js +0 -173
  172. package/lib/utils/audit.d.ts +0 -16
  173. package/lib/utils/audit.js +0 -302
  174. package/lib/utils/console.d.ts +0 -12
  175. package/lib/utils/console.js +0 -19
  176. package/lib/utils/errors.d.ts +0 -17
  177. package/lib/utils/errors.js +0 -100
  178. package/lib/utils/exercisesQueue.d.ts +0 -9
  179. package/lib/utils/exercisesQueue.js +0 -38
  180. package/lib/utils/fileQueue.d.ts +0 -40
  181. package/lib/utils/fileQueue.js +0 -168
  182. package/lib/utils/misc.d.ts +0 -1
  183. package/lib/utils/misc.js +0 -23
  184. package/lib/utils/validators.d.ts +0 -5
  185. package/lib/utils/validators.js +0 -17
  186. package/lib/utils/watcher.d.ts +0 -2
  187. package/lib/utils/watcher.js +0 -23
@@ -1,48 +1,48 @@
1
- import { Command } from "@oclif/command";
2
- import Console from "./console";
3
- import { createInterface } from "readline";
4
- // import SessionManager from '../managers/session'
5
-
6
- class BaseCommand extends Command {
7
- async catch(err: any) {
8
- Console.debug("COMMAND CATCH", err);
9
-
10
- throw err;
11
- }
12
-
13
- async init() {
14
- const { flags, args } = this.parse(BaseCommand);
15
- Console.debug("COMMAND INIT");
16
- Console.debug("These are your flags: ", flags);
17
- Console.debug("These are your args: ", args);
18
-
19
- // quick fix for listening to the process termination on windows
20
- if (process.platform === "win32") {
21
- const rl = createInterface({
22
- input: process.stdin,
23
- output: process.stdout,
24
- });
25
-
26
- rl.on("SIGINT", function () {
27
- // process.emit('SIGINT')
28
- // process.emit('SIGINT')
29
- });
30
- }
31
-
32
- process.on("SIGINT", function () {
33
- Console.debug("Terminated (SIGINT)");
34
- process.exit();
35
- });
36
- }
37
-
38
- async finally() {
39
- Console.debug("COMMAND FINALLY");
40
- // called after run and catch regardless of whether or not the command errored
41
- }
42
-
43
- async run() {
44
- // console.log('running my command')
45
- }
46
- }
47
-
48
- export default BaseCommand;
1
+ import { Command } from "@oclif/command"
2
+ import Console from "./console"
3
+ import { createInterface } from "readline"
4
+ // import SessionManager from '../managers/session'
5
+
6
+ class BaseCommand extends Command {
7
+ async catch(err: any) {
8
+ Console.debug("COMMAND CATCH", err)
9
+
10
+ throw err
11
+ }
12
+
13
+ async init() {
14
+ const { flags, args } = this.parse(BaseCommand)
15
+ Console.debug("COMMAND INIT")
16
+ Console.debug("These are your flags: ", flags)
17
+ Console.debug("These are your args: ", args)
18
+
19
+ // quick fix for listening to the process termination on windows
20
+ if (process.platform === "win32") {
21
+ const rl = createInterface({
22
+ input: process.stdin,
23
+ output: process.stdout,
24
+ })
25
+
26
+ rl.on("SIGINT", function () {
27
+ // process.emit('SIGINT')
28
+ // process.emit('SIGINT')
29
+ })
30
+ }
31
+
32
+ process.on("SIGINT", function () {
33
+ Console.debug("Terminated (SIGINT)")
34
+ process.exit()
35
+ })
36
+ }
37
+
38
+ async finally() {
39
+ Console.debug("COMMAND FINALLY")
40
+ // called after run and catch regardless of whether or not the command errored
41
+ }
42
+
43
+ async run() {
44
+ // console.log('running my command')
45
+ }
46
+ }
47
+
48
+ export default BaseCommand
@@ -1,48 +1,48 @@
1
- // import { flags } from "@oclif/command";
2
- import BaseCommand from './BaseCommand'
3
- import Console from './console'
4
- import SessionManager from '../managers/session'
5
- import configManager from '../managers/config/index'
6
- import {AuthError} from './errors'
7
- import {IConfigManager} from '../models/config-manager'
8
-
9
- export default class SessionCommand extends BaseCommand {
10
- session: any = null
11
- configManager: IConfigManager | null = null
12
- static flags: any
13
-
14
- async initSession(flags: any, _private = false) {
15
- try {
16
- if (!this.configManager) {
17
- await this.buildConfig(flags)
18
- }
19
-
20
- this.session = await SessionManager.get(this.configManager?.get())
21
- if (this.session) {
22
- Console.debug(`Session open for ${this.session.payload.email}.`)
23
- } else {
24
- if (_private)
25
- throw AuthError(
26
- 'You need to log in, run the following command to continue: $ learnpack login',
27
- )
28
- Console.debug('No active session available', _private)
29
- }
30
- } catch (error) {
31
- Console.error((error as TypeError).message)
32
- }
33
- }
34
-
35
- async buildConfig(flags: any) {
36
- this.configManager = await configManager(flags)
37
- }
38
-
39
- async catch(err: any) {
40
- Console.debug('COMMAND CATCH', err)
41
- throw err
42
- }
43
- }
44
-
45
- // SessionCommand.description = `Describe the command here
46
- // ...
47
- // Extra documentation goes here
48
- // `
1
+ // import { flags } from "@oclif/command";
2
+ import BaseCommand from './BaseCommand'
3
+ import Console from './console'
4
+ import SessionManager from '../managers/session'
5
+ import configManager from '../managers/config/index'
6
+ import {AuthError} from './errors'
7
+ import {IConfigManager} from '../models/config-manager'
8
+
9
+ export default class SessionCommand extends BaseCommand {
10
+ session: any = null
11
+ configManager: IConfigManager | null = null
12
+ static flags: any
13
+
14
+ async initSession(flags: any, _private = false) {
15
+ try {
16
+ if (!this.configManager) {
17
+ await this.buildConfig(flags)
18
+ }
19
+
20
+ this.session = await SessionManager.get(this.configManager?.get())
21
+ if (this.session) {
22
+ Console.debug(`Session open for ${this.session.payload.email}.`)
23
+ } else {
24
+ if (_private)
25
+ throw AuthError(
26
+ 'You need to log in, run the following command to continue: $ learnpack login',
27
+ )
28
+ Console.debug('No active session available', _private)
29
+ }
30
+ } catch (error) {
31
+ Console.error((error as TypeError).message)
32
+ }
33
+ }
34
+
35
+ async buildConfig(flags: any) {
36
+ this.configManager = await configManager(flags)
37
+ }
38
+
39
+ async catch(err: any) {
40
+ Console.debug('COMMAND CATCH', err)
41
+ throw err
42
+ }
43
+ }
44
+
45
+ // SessionCommand.description = `Describe the command here
46
+ // ...
47
+ // Extra documentation goes here
48
+ // `
package/src/utils/api.ts CHANGED
@@ -1,194 +1,246 @@
1
- import Console from "../utils/console";
2
- import * as storage from "node-persist";
3
- import cli from "cli-ux";
4
- const HOST = "https://learnpack.herokuapp.com";
5
-
6
- // eslint-disable-next-line
7
- const _fetch = require("node-fetch");
8
-
9
- interface IHeaders {
10
- "Content-Type"?: string;
11
- Authorization?: string;
12
- }
13
-
14
- interface IOptions {
15
- headers?: IHeaders;
16
- method?: string;
17
- body?: string;
18
- }
19
-
20
- const fetch = async (url: string, options: IOptions = {}) => {
21
- const headers: IHeaders = { "Content-Type": "application/json" };
22
- let session = null;
23
- try {
24
- session = await storage.getItem("bc-payload");
25
- if (session.token && session.token !== "" && !url.includes("/token"))
26
- headers.Authorization = "Token " + session.token;
27
- } catch {}
28
-
29
- try {
30
- const resp = await _fetch(url, {
31
- ...options,
32
- headers: { ...headers, ...options.headers },
33
- } as any);
34
-
35
- if (resp.status >= 200 && resp.status < 300)
36
- return await resp.json();
37
- if (resp.status === 401)
38
- throw APIError("Invalid authentication credentials", 401);
39
- else if (resp.status === 404)
40
- throw APIError("Package not found", 404);
41
- else if (resp.status >= 500)
42
- throw APIError("Impossible to connect with the server", 500);
43
- else if (resp.status >= 400) {
44
- const error = await resp.json();
45
- if (error.detail || error.error) {
46
- throw APIError(error.detail || error.error);
47
- } else if (error.nonFieldErrors) {
48
- throw APIError(error.nonFieldErrors[0], error);
49
- } else if (typeof error === "object") {
50
- if (Object.keys(error).length > 0) {
51
- const key = error[Object.keys(error)[0]];
52
- throw APIError(`${key}: ${error[key][0]}`, error);
53
- }
54
- } else {
55
- throw APIError("Uknown error");
56
- }
57
- } else
58
- throw APIError("Uknown error");
59
- } catch (error) {
60
- Console.error((error as TypeError).message);
61
- throw error;
62
- }
63
- };
64
-
65
- const login = async (identification: string, password: string) => {
66
- try {
67
- cli.action.start("Looking for credentials...");
68
- await cli.wait(1000);
69
- const data = await fetch(`${HOST}/v1/auth/token/`, {
70
- body: JSON.stringify({ identification, password }),
71
- method: "post",
72
- });
73
- cli.action.stop("ready");
74
- return data;
75
- } catch (error) {
76
- Console.error((error as TypeError).message);
77
- Console.debug(error);
78
- }
79
- };
80
-
81
- const publish = async (config: any) => {
82
- const keys = [
83
- "difficulty",
84
- "language",
85
- "skills",
86
- "technologies",
87
- "slug",
88
- "repository",
89
- "author",
90
- "title",
91
- ];
92
-
93
- const payload: { [key: string]: string } = {};
94
- for (const k of keys)
95
- config[k] ? (payload[k] = config[k]) : null;
96
- try {
97
- console.log("Package to publish:", payload);
98
- cli.action.start("Updating package information...");
99
- await cli.wait(1000);
100
- const data = await fetch(`${HOST}/v1/package/${config.slug}`, {
101
- method: "PUT",
102
- body: JSON.stringify(payload),
103
- });
104
- cli.action.stop("ready");
105
- return data;
106
- } catch (error) {
107
- console.log("payload", payload);
108
- Console.error((error as TypeError).message);
109
- Console.debug(error);
110
- throw error;
111
- }
112
- };
113
-
114
- const update = async (config: any) => {
115
- try {
116
- cli.action.start("Updating package information...");
117
- await cli.wait(1000);
118
- const data = await fetch(`${HOST}/v1/package/`, {
119
- method: "POST",
120
- body: JSON.stringify(config),
121
- });
122
- cli.action.stop("ready");
123
- return data;
124
- } catch (error) {
125
- Console.error((error as any).message);
126
- Console.debug(error);
127
- throw error;
128
- }
129
- };
130
-
131
- const getPackage = async (slug: string) => {
132
- try {
133
- cli.action.start("Downloading package information...");
134
- await cli.wait(1000);
135
- const data = await fetch(`${HOST}/v1/package/${slug}`);
136
- cli.action.stop("ready");
137
- return data;
138
- } catch (error) {
139
- if ((error as any).status === 404)
140
- Console.error(`Package ${slug} does not exist`);
141
- else
142
- Console.error(`Package ${slug} does not exist`);
143
- Console.debug(error);
144
- throw error;
145
- }
146
- };
147
-
148
- const getLangs = async () => {
149
- try {
150
- cli.action.start("Downloading language options...");
151
- await cli.wait(1000);
152
- const data = await fetch(`${HOST}/v1/package/language`);
153
- cli.action.stop("ready");
154
- return data;
155
- } catch (error) {
156
- if ((error as any).status === 404)
157
- Console.error("Package slug does not exist");
158
- else
159
- Console.error("Package slug does not exist");
160
- Console.debug(error);
161
- throw error;
162
- }
163
- };
164
-
165
- const getAllPackages = async ({
166
- lang = "",
167
- slug = "",
168
- }: {
169
- lang?: string;
170
- slug?: string;
171
- }) => {
172
- try {
173
- cli.action.start("Downloading packages...");
174
- await cli.wait(1000);
175
- const data = await fetch(
176
- `${HOST}/v1/package/all?limit=100&language=${lang}&slug=${slug}`
177
- );
178
- cli.action.stop("ready");
179
- return data;
180
- } catch (error) {
181
- Console.error(`Package ${slug} does not exist`);
182
- Console.debug(error);
183
- throw error;
184
- }
185
- };
186
-
187
- const APIError = (error: TypeError | string, code?: number) => {
188
- const message: string = (error as TypeError).message || (error as string);
189
- const _err = new Error(message) as any;
190
- _err.status = code || 400;
191
- return _err;
192
- };
193
-
194
- export default { login, publish, update, getPackage, getLangs, getAllPackages };
1
+ import Console from "../utils/console"
2
+ import * as storage from "node-persist"
3
+ import cli from "cli-ux"
4
+ const HOST = "https://breathecode.herokuapp.com"
5
+ const RIGOBOT_HOST = "https://rigobot.herokuapp.com"
6
+
7
+ // eslint-disable-next-line
8
+ const _fetch = require("node-fetch");
9
+
10
+ interface IHeaders {
11
+ "Content-Type"?: string;
12
+ Authorization?: string;
13
+ }
14
+
15
+ interface IOptions {
16
+ headers?: IHeaders;
17
+ method?: string;
18
+ body?: string;
19
+ }
20
+
21
+ const fetch = async (url: string, options: IOptions = {}) => {
22
+ const headers: IHeaders = { "Content-Type": "application/json" }
23
+ Console.log(`Fetching ${url}`)
24
+ let session = null
25
+ try {
26
+ session = await storage.getItem("bc-payload")
27
+ if (session.token && session.token !== "" && !url.includes("/token"))
28
+ headers.Authorization = "Token " + session.token
29
+ } catch {}
30
+
31
+ try {
32
+ const resp = await _fetch(url, {
33
+ ...options,
34
+ headers: { ...headers, ...options.headers },
35
+ } as any)
36
+
37
+ if (resp.status >= 200 && resp.status < 300)
38
+ return await resp.json()
39
+ if (resp.status === 401)
40
+ throw APIError("Invalid authentication credentials", 401)
41
+ else if (resp.status === 404)
42
+ throw APIError("Package not found", 404)
43
+ else if (resp.status >= 500)
44
+ throw APIError("Impossible to connect with the server", 500)
45
+ else if (resp.status >= 400) {
46
+ const error = await resp.json()
47
+ if (error.detail || error.error) {
48
+ throw APIError(error.detail || error.error)
49
+ } else if (error.nonFieldErrors) {
50
+ throw APIError(error.nonFieldErrors[0], error)
51
+ } else if (typeof error === "object") {
52
+ if (Object.keys(error).length > 0) {
53
+ const key = error[Object.keys(error)[0]]
54
+ throw APIError(`${key}: ${error[key][0]}`, error)
55
+ }
56
+ } else {
57
+ throw APIError("Uknown error")
58
+ }
59
+ } else
60
+ throw APIError("Uknown error")
61
+ } catch (error) {
62
+ Console.error((error as TypeError).message)
63
+ throw error
64
+ }
65
+ }
66
+
67
+ const login = async (identification: string, password: string) => {
68
+ try {
69
+ cli.action.start(`Looking for credentials with ${identification}`)
70
+ await cli.wait(1000)
71
+ const url = `${HOST}/v1/auth/login/`
72
+ // Console.log(url);
73
+ const data = await fetch(url, {
74
+ body: JSON.stringify({
75
+ email: identification,
76
+ password: password,
77
+ }),
78
+ method: "post",
79
+ })
80
+ cli.action.stop("ready")
81
+ const payload = await loginRigo(data.token)
82
+
83
+ return { ...data, rigobot: payload }
84
+ } catch (error) {
85
+ cli.action.stop("error")
86
+ Console.error((error as TypeError).message)
87
+ Console.debug(error)
88
+ }
89
+ }
90
+
91
+ const loginRigo = async (token: string) => {
92
+ const rigoUrl = `${RIGOBOT_HOST}/v1/auth/me/token?breathecode_token=${token}`
93
+ const rigoResp = await _fetch(rigoUrl)
94
+ const rigobotJson = await rigoResp.json()
95
+ return rigobotJson
96
+ }
97
+
98
+ const getOpenAIToken = async () => {
99
+ const token = await storage.getItem("openai-token")
100
+ return token
101
+ }
102
+
103
+ const getRigoFeedback = async (readme: string, currentCode: string) => {
104
+ const payload = {
105
+ current_code: Buffer.from(currentCode).toString("base64"), // Encode currentCode as base64
106
+ tutorial: Buffer.from(readme).toString("base64"), // Encode readme as base64
107
+ }
108
+
109
+ const session = await storage.getItem("bc-payload")
110
+
111
+ const response = await _fetch(`${RIGOBOT_HOST}/v1/conversation/feedback/`, {
112
+ method: "POST",
113
+ headers: {
114
+ "Content-Type": "application/json",
115
+ Authorization: `Token ${session.rigobot.key}`,
116
+ },
117
+ body: JSON.stringify(payload),
118
+ })
119
+
120
+ const responseData = await response.json()
121
+ return responseData.feedback
122
+ }
123
+
124
+ const publish = async (config: any) => {
125
+ const keys = [
126
+ "difficulty",
127
+ "language",
128
+ "skills",
129
+ "technologies",
130
+ "slug",
131
+ "repository",
132
+ "author",
133
+ "title",
134
+ ]
135
+
136
+ const payload: { [key: string]: string } = {}
137
+ for (const k of keys)
138
+ config[k] ? (payload[k] = config[k]) : null
139
+ try {
140
+ console.log("Package to publish:", payload)
141
+ cli.action.start("Updating package information...")
142
+ await cli.wait(1000)
143
+ const data = await fetch(`${HOST}/v1/package/${config.slug}`, {
144
+ method: "PUT",
145
+ body: JSON.stringify(payload),
146
+ })
147
+ cli.action.stop("ready")
148
+ return data
149
+ } catch (error) {
150
+ console.log("payload", payload)
151
+ Console.error((error as TypeError).message)
152
+ Console.debug(error)
153
+ throw error
154
+ }
155
+ }
156
+
157
+ const update = async (config: any) => {
158
+ try {
159
+ cli.action.start("Updating package information...")
160
+ await cli.wait(1000)
161
+ const data = await fetch(`${HOST}/v1/package/`, {
162
+ method: "POST",
163
+ body: JSON.stringify(config),
164
+ })
165
+ cli.action.stop("ready")
166
+ return data
167
+ } catch (error) {
168
+ Console.error((error as any).message)
169
+ Console.debug(error)
170
+ throw error
171
+ }
172
+ }
173
+
174
+ const getPackage = async (slug: string) => {
175
+ try {
176
+ cli.action.start("Downloading package information...")
177
+ await cli.wait(1000)
178
+ const data = await fetch(`${HOST}/v1/package/${slug}`)
179
+ cli.action.stop("ready")
180
+ return data
181
+ } catch (error) {
182
+ if ((error as any).status === 404)
183
+ Console.error(`Package ${slug} does not exist`)
184
+ else
185
+ Console.error(`Package ${slug} does not exist`)
186
+ Console.debug(error)
187
+ throw error
188
+ }
189
+ }
190
+
191
+ const getLangs = async () => {
192
+ try {
193
+ cli.action.start("Downloading language options...")
194
+ await cli.wait(1000)
195
+ const data = await fetch(`${HOST}/v1/package/language`)
196
+ cli.action.stop("ready")
197
+ return data
198
+ } catch (error) {
199
+ if ((error as any).status === 404)
200
+ Console.error("Package slug does not exist")
201
+ else
202
+ Console.error("Package slug does not exist")
203
+ Console.debug(error)
204
+ throw error
205
+ }
206
+ }
207
+
208
+ const getAllPackages = async ({
209
+ lang = "",
210
+ slug = "",
211
+ }: {
212
+ lang?: string;
213
+ slug?: string;
214
+ }) => {
215
+ try {
216
+ cli.action.start("Downloading packages...")
217
+ await cli.wait(1000)
218
+ const data = await fetch(
219
+ `${HOST}/v1/package/all?limit=100&language=${lang}&slug=${slug}`
220
+ )
221
+ cli.action.stop("ready")
222
+ return data
223
+ } catch (error) {
224
+ Console.error(`Package ${slug} does not exist`)
225
+ Console.debug(error)
226
+ throw error
227
+ }
228
+ }
229
+
230
+ const APIError = (error: TypeError | string, code?: number) => {
231
+ const message: string = (error as TypeError).message || (error as string)
232
+ const _err = new Error(message) as any
233
+ _err.status = code || 400
234
+ return _err
235
+ }
236
+
237
+ export default {
238
+ login,
239
+ publish,
240
+ update,
241
+ getPackage,
242
+ getLangs,
243
+ getAllPackages,
244
+ getRigoFeedback,
245
+ getOpenAIToken,
246
+ }