@learnpack/learnpack 4.0.12 → 4.0.14

Sign up to get free protection for your applications and to get access to all the features.
package/src/utils/api.ts CHANGED
@@ -1,303 +1,304 @@
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 (
22
- url: string,
23
- options: IOptions = {},
24
- returnAsJson = true
25
- ) => {
26
- const headers: IHeaders = { "Content-Type": "application/json" }
27
- Console.debug(`Fetching ${url}`)
28
- let session = null
29
- try {
30
- session = await storage.getItem("bc-payload")
31
- if (session.token && session.token !== "" && !url.includes("/token"))
32
- headers.Authorization = "Token " + session.token
33
- } catch {}
34
-
35
- try {
36
- const resp = await _fetch(url, {
37
- ...options,
38
- headers: { ...headers, ...options.headers },
39
- } as any)
40
-
41
- if (resp.status >= 200 && resp.status < 300) {
42
- return returnAsJson ? await resp.json() : await resp.text()
43
- }
44
-
45
- if (resp.status === 401)
46
- Console.debug("Invalid authentication credentials", `Code: 401`)
47
- // throw APIError("Invalid authentication credentials", 401)
48
- else if (resp.status === 404)
49
- throw APIError("Package not found", 404)
50
- else if (resp.status >= 500)
51
- throw APIError("Impossible to connect with the server", 500)
52
- else if (resp.status >= 400) {
53
- const error = await resp.json()
54
- if (error.detail || error.error) {
55
- throw APIError(error.detail || error.error)
56
- } else if (error.nonFieldErrors) {
57
- throw APIError(error.nonFieldErrors[0], error)
58
- } else if (typeof error === "object") {
59
- if (Object.keys(error).length > 0) {
60
- const key = error[Object.keys(error)[0]]
61
- throw APIError(`${key}: ${error[key][0]}`, error)
62
- }
63
- } else {
64
- throw APIError("Uknown error")
65
- }
66
- } else
67
- throw APIError("Uknown error")
68
- } catch (error) {
69
- Console.error((error as TypeError).message)
70
- throw error
71
- }
72
- }
73
-
74
- const login = async (identification: string, password: string) => {
75
- try {
76
- cli.action.start(`Looking for credentials with ${identification}`)
77
- await cli.wait(1000)
78
- const url = `${HOST}/v1/auth/login/`
79
-
80
- const data = await fetch(url, {
81
- body: JSON.stringify({
82
- email: identification,
83
- password: password,
84
- }),
85
- method: "post",
86
- })
87
- cli.action.stop("ready")
88
- let rigoPayload = null
89
- try {
90
- rigoPayload = await loginRigo(data.token)
91
- } catch {
92
- return { ...data, rigobot: null }
93
- }
94
-
95
- return { ...data, rigobot: rigoPayload }
96
- } catch (error) {
97
- cli.action.stop("error")
98
- Console.error((error as TypeError).message)
99
- Console.debug(error)
100
- }
101
- }
102
-
103
- const loginRigo = async (token: string) => {
104
- try {
105
- const rigoUrl = `${RIGOBOT_HOST}/v1/auth/me/token?breathecode_token=${token}`
106
- const rigoResp = await _fetch(rigoUrl)
107
- const rigobotJson = await rigoResp.json()
108
- return rigobotJson
109
- } catch (error) {
110
- // Handle the error as needed, for example log it or return a custom error message
111
- Console.error(
112
- "Error logging in to Rigo, did you already accepted Rigobot?:",
113
- error
114
- )
115
- throw new Error("Failed to log in to Rigo")
116
- }
117
- }
118
-
119
- const publish = async (config: any) => {
120
- const keys = [
121
- "difficulty",
122
- "language",
123
- "skills",
124
- "technologies",
125
- "slug",
126
- "repository",
127
- "author",
128
- "title",
129
- ]
130
-
131
- const payload: { [key: string]: string } = {}
132
- for (const k of keys)
133
- config[k] ? (payload[k] = config[k]) : null
134
- try {
135
- console.log("Package to publish:", payload)
136
- cli.action.start("Updating package information...")
137
- await cli.wait(1000)
138
- const data = await fetch(`${HOST}/v1/package/${config.slug}`, {
139
- method: "PUT",
140
- body: JSON.stringify(payload),
141
- })
142
- cli.action.stop("ready")
143
- return data
144
- } catch (error) {
145
- Console.error((error as TypeError).message)
146
- Console.debug(error)
147
- throw error
148
- }
149
- }
150
-
151
- const update = async (config: any) => {
152
- try {
153
- cli.action.start("Updating package information...")
154
- await cli.wait(1000)
155
- const data = await fetch(`${HOST}/v1/package/`, {
156
- method: "POST",
157
- body: JSON.stringify(config),
158
- })
159
- cli.action.stop("ready")
160
- return data
161
- } catch (error) {
162
- Console.error((error as any).message)
163
- Console.debug(error)
164
- throw error
165
- }
166
- }
167
-
168
- const getPackage = async (slug: string) => {
169
- try {
170
- cli.action.start("Downloading package information...")
171
- await cli.wait(1000)
172
- const data = await fetch(`${HOST}/v1/package/${slug}`)
173
- cli.action.stop("ready")
174
- return data
175
- } catch (error) {
176
- if ((error as any).status === 404)
177
- Console.error(`Package ${slug} does not exist`)
178
- else
179
- Console.error(`Package ${slug} does not exist`)
180
- Console.debug(error)
181
- throw error
182
- }
183
- }
184
-
185
- const getLangs = async () => {
186
- try {
187
- cli.action.start("Downloading language options...")
188
- await cli.wait(1000)
189
- const data = await fetch(`${HOST}/v1/package/language`)
190
- cli.action.stop("ready")
191
- return data
192
- } catch (error) {
193
- if ((error as any).status === 404)
194
- Console.error("Package slug does not exist")
195
- else
196
- Console.error("Package slug does not exist")
197
- Console.debug(error)
198
- throw error
199
- }
200
- }
201
-
202
- const getAllPackages = async ({
203
- lang = "",
204
- slug = "",
205
- }: {
206
- lang?: string;
207
- slug?: string;
208
- }) => {
209
- try {
210
- cli.action.start("Downloading packages...")
211
- await cli.wait(1000)
212
- const data = await fetch(
213
- `${HOST}/v1/package/all?limit=100&language=${lang}&slug=${slug}`
214
- )
215
- cli.action.stop("ready")
216
- return data
217
- } catch (error) {
218
- Console.error(`Package ${slug} does not exist`)
219
- Console.debug(error)
220
- throw error
221
- }
222
- }
223
-
224
- const APIError = (error: TypeError | string, code?: number) => {
225
- const message: string = (error as TypeError).message || (error as string)
226
- const _err = new Error(message) as any
227
- _err.status = code || 400
228
- return _err
229
- }
230
-
231
- const sendBatchTelemetry = async function (url: string, body: object) {
232
- if (!url) {
233
- return
234
- }
235
-
236
- const session = await storage.getItem("bc-payload")
237
- if (
238
- !session ||
239
- !Object.prototype.hasOwnProperty.call(session, "token") ||
240
- session.token === ""
241
- ) {
242
- Console.debug("No token found, skipping stream telemetry delivery")
243
- return
244
- }
245
-
246
- fetch(
247
- url,
248
- {
249
- method: "POST",
250
- body: JSON.stringify(body),
251
- },
252
- false
253
- )
254
- .then(response => {
255
- Console.debug("Telemetry sent successfully")
256
- return response.text()
257
- })
258
- .catch(error => {
259
- Console.debug("Error while sending batch Telemetry", error)
260
- })
261
- }
262
-
263
- const sendStreamTelemetry = async function (url: string, body: object) {
264
- if (!url) {
265
- return
266
- }
267
-
268
- const session = await storage.getItem("bc-payload")
269
- if (
270
- !session ||
271
- !Object.prototype.hasOwnProperty.call(session, "token") ||
272
- session.token === ""
273
- ) {
274
- Console.debug("No token found, skipping stream telemetry delivery")
275
- return
276
- }
277
-
278
- fetch(
279
- url,
280
- {
281
- method: "POST",
282
- body: JSON.stringify(body),
283
- },
284
- false
285
- )
286
- .then(response => {
287
- return response
288
- })
289
- .catch(error => {
290
- Console.debug("Error while sending stream Telemetry", error)
291
- })
292
- }
293
-
294
- export default {
295
- login,
296
- publish,
297
- update,
298
- getPackage,
299
- getLangs,
300
- getAllPackages,
301
- sendBatchTelemetry,
302
- sendStreamTelemetry,
303
- }
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
+ // const RIGOBOT_HOST = "https://8000-charlytoc-rigobot-bmwdeam7cev.ws-us116.gitpod.io"
7
+
8
+ // eslint-disable-next-line
9
+ const _fetch = require("node-fetch")
10
+
11
+ interface IHeaders {
12
+ "Content-Type"?: string
13
+ Authorization?: string
14
+ }
15
+
16
+ interface IOptions {
17
+ headers?: IHeaders
18
+ method?: string
19
+ body?: string
20
+ }
21
+
22
+ const fetch = async (
23
+ url: string,
24
+ options: IOptions = {},
25
+ returnAsJson = true
26
+ ) => {
27
+ const headers: IHeaders = { "Content-Type": "application/json" }
28
+ Console.debug(`Fetching ${url}`)
29
+ let session = null
30
+ try {
31
+ session = await storage.getItem("bc-payload")
32
+ if (session.token && session.token !== "" && !url.includes("/token"))
33
+ headers.Authorization = "Token " + session.token
34
+ } catch {}
35
+
36
+ try {
37
+ const resp = await _fetch(url, {
38
+ ...options,
39
+ headers: { ...headers, ...options.headers },
40
+ } as any)
41
+
42
+ if (resp.status >= 200 && resp.status < 300) {
43
+ return returnAsJson ? await resp.json() : await resp.text()
44
+ }
45
+
46
+ if (resp.status === 401)
47
+ Console.debug("Invalid authentication credentials", `Code: 401`)
48
+ // throw APIError("Invalid authentication credentials", 401)
49
+ else if (resp.status === 404)
50
+ throw APIError("Package not found", 404)
51
+ else if (resp.status >= 500)
52
+ throw APIError("Impossible to connect with the server", 500)
53
+ else if (resp.status >= 400) {
54
+ const error = await resp.json()
55
+ if (error.detail || error.error) {
56
+ throw APIError(error.detail || error.error)
57
+ } else if (error.nonFieldErrors) {
58
+ throw APIError(error.nonFieldErrors[0], error)
59
+ } else if (typeof error === "object") {
60
+ if (Object.keys(error).length > 0) {
61
+ const key = error[Object.keys(error)[0]]
62
+ throw APIError(`${key}: ${error[key][0]}`, error)
63
+ }
64
+ } else {
65
+ throw APIError("Uknown error")
66
+ }
67
+ } else
68
+ throw APIError("Uknown error")
69
+ } catch (error) {
70
+ Console.error((error as TypeError).message)
71
+ throw error
72
+ }
73
+ }
74
+
75
+ const login = async (identification: string, password: string) => {
76
+ try {
77
+ cli.action.start(`Looking for credentials with ${identification}`)
78
+ await cli.wait(1000)
79
+ const url = `${HOST}/v1/auth/login/`
80
+
81
+ const data = await fetch(url, {
82
+ body: JSON.stringify({
83
+ email: identification,
84
+ password: password,
85
+ }),
86
+ method: "post",
87
+ })
88
+ cli.action.stop("ready")
89
+ let rigoPayload = null
90
+ try {
91
+ rigoPayload = await loginRigo(data.token)
92
+ } catch {
93
+ return { ...data, rigobot: null }
94
+ }
95
+
96
+ return { ...data, rigobot: rigoPayload }
97
+ } catch (error) {
98
+ cli.action.stop("error")
99
+ Console.error((error as TypeError).message)
100
+ Console.debug(error)
101
+ }
102
+ }
103
+
104
+ const loginRigo = async (token: string) => {
105
+ try {
106
+ const rigoUrl = `${RIGOBOT_HOST}/v1/auth/me/token?breathecode_token=${token}`
107
+ const rigoResp = await _fetch(rigoUrl)
108
+ const rigobotJson = await rigoResp.json()
109
+ return rigobotJson
110
+ } catch (error) {
111
+ // Handle the error as needed, for example log it or return a custom error message
112
+ Console.error(
113
+ "Error logging in to Rigo, did you already accepted Rigobot?:",
114
+ error
115
+ )
116
+ throw new Error("Failed to log in to Rigo")
117
+ }
118
+ }
119
+
120
+ const publish = async (config: any) => {
121
+ const keys = [
122
+ "difficulty",
123
+ "language",
124
+ "skills",
125
+ "technologies",
126
+ "slug",
127
+ "repository",
128
+ "author",
129
+ "title",
130
+ ]
131
+
132
+ const payload: { [key: string]: string } = {}
133
+ for (const k of keys)
134
+ config[k] ? (payload[k] = config[k]) : null
135
+ try {
136
+ console.log("Package to publish:", payload)
137
+ cli.action.start("Updating package information...")
138
+ await cli.wait(1000)
139
+ const data = await fetch(`${HOST}/v1/package/${config.slug}`, {
140
+ method: "PUT",
141
+ body: JSON.stringify(payload),
142
+ })
143
+ cli.action.stop("ready")
144
+ return data
145
+ } catch (error) {
146
+ Console.error((error as TypeError).message)
147
+ Console.debug(error)
148
+ throw error
149
+ }
150
+ }
151
+
152
+ const update = async (config: any) => {
153
+ try {
154
+ cli.action.start("Updating package information...")
155
+ await cli.wait(1000)
156
+ const data = await fetch(`${HOST}/v1/package/`, {
157
+ method: "POST",
158
+ body: JSON.stringify(config),
159
+ })
160
+ cli.action.stop("ready")
161
+ return data
162
+ } catch (error) {
163
+ Console.error((error as any).message)
164
+ Console.debug(error)
165
+ throw error
166
+ }
167
+ }
168
+
169
+ const getPackage = async (slug: string) => {
170
+ try {
171
+ cli.action.start("Downloading package information...")
172
+ await cli.wait(1000)
173
+ const data = await fetch(`${HOST}/v1/package/${slug}`)
174
+ cli.action.stop("ready")
175
+ return data
176
+ } catch (error) {
177
+ if ((error as any).status === 404)
178
+ Console.error(`Package ${slug} does not exist`)
179
+ else
180
+ Console.error(`Package ${slug} does not exist`)
181
+ Console.debug(error)
182
+ throw error
183
+ }
184
+ }
185
+
186
+ const getLangs = async () => {
187
+ try {
188
+ cli.action.start("Downloading language options...")
189
+ await cli.wait(1000)
190
+ const data = await fetch(`${HOST}/v1/package/language`)
191
+ cli.action.stop("ready")
192
+ return data
193
+ } catch (error) {
194
+ if ((error as any).status === 404)
195
+ Console.error("Package slug does not exist")
196
+ else
197
+ Console.error("Package slug does not exist")
198
+ Console.debug(error)
199
+ throw error
200
+ }
201
+ }
202
+
203
+ const getAllPackages = async ({
204
+ lang = "",
205
+ slug = "",
206
+ }: {
207
+ lang?: string
208
+ slug?: string
209
+ }) => {
210
+ try {
211
+ cli.action.start("Downloading packages...")
212
+ await cli.wait(1000)
213
+ const data = await fetch(
214
+ `${HOST}/v1/package/all?limit=100&language=${lang}&slug=${slug}`
215
+ )
216
+ cli.action.stop("ready")
217
+ return data
218
+ } catch (error) {
219
+ Console.error(`Package ${slug} does not exist`)
220
+ Console.debug(error)
221
+ throw error
222
+ }
223
+ }
224
+
225
+ const APIError = (error: TypeError | string, code?: number) => {
226
+ const message: string = (error as TypeError).message || (error as string)
227
+ const _err = new Error(message) as any
228
+ _err.status = code || 400
229
+ return _err
230
+ }
231
+
232
+ const sendBatchTelemetry = async function (url: string, body: object) {
233
+ if (!url) {
234
+ return
235
+ }
236
+
237
+ const session = await storage.getItem("bc-payload")
238
+ if (
239
+ !session ||
240
+ !Object.prototype.hasOwnProperty.call(session, "token") ||
241
+ session.token === ""
242
+ ) {
243
+ Console.debug("No token found, skipping stream telemetry delivery")
244
+ return
245
+ }
246
+
247
+ fetch(
248
+ url,
249
+ {
250
+ method: "POST",
251
+ body: JSON.stringify(body),
252
+ },
253
+ false
254
+ )
255
+ .then(response => {
256
+ Console.debug("Telemetry sent successfully")
257
+ return response.text()
258
+ })
259
+ .catch(error => {
260
+ Console.debug("Error while sending batch Telemetry", error)
261
+ })
262
+ }
263
+
264
+ const sendStreamTelemetry = async function (url: string, body: object) {
265
+ if (!url) {
266
+ return
267
+ }
268
+
269
+ const session = await storage.getItem("bc-payload")
270
+ if (
271
+ !session ||
272
+ !Object.prototype.hasOwnProperty.call(session, "token") ||
273
+ session.token === ""
274
+ ) {
275
+ Console.debug("No token found, skipping stream telemetry delivery")
276
+ return
277
+ }
278
+
279
+ fetch(
280
+ url,
281
+ {
282
+ method: "POST",
283
+ body: JSON.stringify(body),
284
+ },
285
+ false
286
+ )
287
+ .then(response => {
288
+ return response
289
+ })
290
+ .catch(error => {
291
+ Console.debug("Error while sending stream Telemetry", error)
292
+ })
293
+ }
294
+
295
+ export default {
296
+ login,
297
+ publish,
298
+ update,
299
+ getPackage,
300
+ getLangs,
301
+ getAllPackages,
302
+ sendBatchTelemetry,
303
+ sendStreamTelemetry,
304
+ }
@@ -1,11 +0,0 @@
1
- import SessionCommand from "../utils/SessionCommand";
2
- export default class BuildCommand extends SessionCommand {
3
- static description: string;
4
- static flags: {
5
- help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
6
- };
7
- init(): Promise<void>;
8
- run(): Promise<void>;
9
- copyDirectory(src: string, dest: string): void;
10
- removeDirectory(dir: string): void;
11
- }