@learnpack/learnpack 4.0.12 → 4.0.14

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/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
- }