diff options
author | Markus Hatvan <markus_hatvan@aon.at> | 2021-11-18 17:37:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-18 22:07:45 +0530 |
commit | b37a6b07b39c8c7827052dc6fb97f490f1e0f514 (patch) | |
tree | 0276e7c51f5ebfa14c566def7aac39f014c2291d /src/api/server | |
parent | Update github issues template [skip ci] (diff) | |
download | ferdium-app-b37a6b07b39c8c7827052dc6fb97f490f1e0f514.tar.gz ferdium-app-b37a6b07b39c8c7827052dc6fb97f490f1e0f514.tar.zst ferdium-app-b37a6b07b39c8c7827052dc6fb97f490f1e0f514.zip |
chore: convert various files to TS (#2246)
* convert various files to TS
* removed outdated docs/example-feature folder
* turn off unicorn/no-empty-file
* update eslint config
Diffstat (limited to 'src/api/server')
-rw-r--r-- | src/api/server/ServerApi.ts (renamed from src/api/server/ServerApi.js) | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.ts index bcc72ffdc..2fd1a8d0d 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.ts | |||
@@ -11,6 +11,7 @@ import { | |||
11 | pathExistsSync, | 11 | pathExistsSync, |
12 | readJsonSync, | 12 | readJsonSync, |
13 | removeSync, | 13 | removeSync, |
14 | PathOrFileDescriptor, | ||
14 | } from 'fs-extra'; | 15 | } from 'fs-extra'; |
15 | import fetch from 'electron-fetch'; | 16 | import fetch from 'electron-fetch'; |
16 | 17 | ||
@@ -40,12 +41,12 @@ const debug = require('debug')('Ferdi:ServerApi'); | |||
40 | module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory()); | 41 | module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory()); |
41 | 42 | ||
42 | export default class ServerApi { | 43 | export default class ServerApi { |
43 | recipePreviews = []; | 44 | recipePreviews: any[] = []; |
44 | 45 | ||
45 | recipes = []; | 46 | recipes: any[] = []; |
46 | 47 | ||
47 | // User | 48 | // User |
48 | async login(email, passwordHash) { | 49 | async login(email: string, passwordHash: string) { |
49 | const request = await sendAuthRequest( | 50 | const request = await sendAuthRequest( |
50 | `${apiBase()}/auth/login`, | 51 | `${apiBase()}/auth/login`, |
51 | { | 52 | { |
@@ -57,7 +58,7 @@ export default class ServerApi { | |||
57 | false, | 58 | false, |
58 | ); | 59 | ); |
59 | if (!request.ok) { | 60 | if (!request.ok) { |
60 | throw request; | 61 | throw new Error(request.statusText); |
61 | } | 62 | } |
62 | const u = await request.json(); | 63 | const u = await request.json(); |
63 | 64 | ||
@@ -65,7 +66,7 @@ export default class ServerApi { | |||
65 | return u.token; | 66 | return u.token; |
66 | } | 67 | } |
67 | 68 | ||
68 | async signup(data) { | 69 | async signup(data: any) { |
69 | const request = await sendAuthRequest( | 70 | const request = await sendAuthRequest( |
70 | `${apiBase()}/auth/signup`, | 71 | `${apiBase()}/auth/signup`, |
71 | { | 72 | { |
@@ -75,7 +76,7 @@ export default class ServerApi { | |||
75 | false, | 76 | false, |
76 | ); | 77 | ); |
77 | if (!request.ok) { | 78 | if (!request.ok) { |
78 | throw request; | 79 | throw new Error(request.statusText); |
79 | } | 80 | } |
80 | const u = await request.json(); | 81 | const u = await request.json(); |
81 | 82 | ||
@@ -83,20 +84,20 @@ export default class ServerApi { | |||
83 | return u.token; | 84 | return u.token; |
84 | } | 85 | } |
85 | 86 | ||
86 | async inviteUser(data) { | 87 | async inviteUser(data: any) { |
87 | const request = await sendAuthRequest(`${apiBase()}/invite`, { | 88 | const request = await sendAuthRequest(`${apiBase()}/invite`, { |
88 | method: 'POST', | 89 | method: 'POST', |
89 | body: JSON.stringify(data), | 90 | body: JSON.stringify(data), |
90 | }); | 91 | }); |
91 | if (!request.ok) { | 92 | if (!request.ok) { |
92 | throw request; | 93 | throw new Error(request.statusText); |
93 | } | 94 | } |
94 | 95 | ||
95 | debug('ServerApi::inviteUser'); | 96 | debug('ServerApi::inviteUser'); |
96 | return true; | 97 | return true; |
97 | } | 98 | } |
98 | 99 | ||
99 | async retrievePassword(email) { | 100 | async retrievePassword(email: string) { |
100 | const request = await sendAuthRequest( | 101 | const request = await sendAuthRequest( |
101 | `${apiBase()}/auth/password`, | 102 | `${apiBase()}/auth/password`, |
102 | { | 103 | { |
@@ -108,7 +109,7 @@ export default class ServerApi { | |||
108 | false, | 109 | false, |
109 | ); | 110 | ); |
110 | if (!request.ok) { | 111 | if (!request.ok) { |
111 | throw request; | 112 | throw new Error(request.statusText); |
112 | } | 113 | } |
113 | const r = await request.json(); | 114 | const r = await request.json(); |
114 | 115 | ||
@@ -123,7 +124,7 @@ export default class ServerApi { | |||
123 | 124 | ||
124 | const request = await sendAuthRequest(`${apiBase()}/me`); | 125 | const request = await sendAuthRequest(`${apiBase()}/me`); |
125 | if (!request.ok) { | 126 | if (!request.ok) { |
126 | throw request; | 127 | throw new Error(request.statusText); |
127 | } | 128 | } |
128 | const data = await request.json(); | 129 | const data = await request.json(); |
129 | 130 | ||
@@ -133,13 +134,13 @@ export default class ServerApi { | |||
133 | return user; | 134 | return user; |
134 | } | 135 | } |
135 | 136 | ||
136 | async updateUserInfo(data) { | 137 | async updateUserInfo(data: any) { |
137 | const request = await sendAuthRequest(`${apiBase()}/me`, { | 138 | const request = await sendAuthRequest(`${apiBase()}/me`, { |
138 | method: 'PUT', | 139 | method: 'PUT', |
139 | body: JSON.stringify(data), | 140 | body: JSON.stringify(data), |
140 | }); | 141 | }); |
141 | if (!request.ok) { | 142 | if (!request.ok) { |
142 | throw request; | 143 | throw new Error(request.statusText); |
143 | } | 144 | } |
144 | const updatedData = await request.json(); | 145 | const updatedData = await request.json(); |
145 | 146 | ||
@@ -155,7 +156,7 @@ export default class ServerApi { | |||
155 | method: 'DELETE', | 156 | method: 'DELETE', |
156 | }); | 157 | }); |
157 | if (!request.ok) { | 158 | if (!request.ok) { |
158 | throw request; | 159 | throw new Error(request.statusText); |
159 | } | 160 | } |
160 | const data = await request.json(); | 161 | const data = await request.json(); |
161 | 162 | ||
@@ -171,7 +172,7 @@ export default class ServerApi { | |||
171 | 172 | ||
172 | const request = await sendAuthRequest(`${apiBase()}/me/services`); | 173 | const request = await sendAuthRequest(`${apiBase()}/me/services`); |
173 | if (!request.ok) { | 174 | if (!request.ok) { |
174 | throw request; | 175 | throw new Error(request.statusText); |
175 | } | 176 | } |
176 | const data = await request.json(); | 177 | const data = await request.json(); |
177 | 178 | ||
@@ -181,13 +182,13 @@ export default class ServerApi { | |||
181 | return filteredServices; | 182 | return filteredServices; |
182 | } | 183 | } |
183 | 184 | ||
184 | async createService(recipeId, data) { | 185 | async createService(recipeId: string, data: { iconFile: any }) { |
185 | const request = await sendAuthRequest(`${apiBase()}/service`, { | 186 | const request = await sendAuthRequest(`${apiBase()}/service`, { |
186 | method: 'POST', | 187 | method: 'POST', |
187 | body: JSON.stringify({ recipeId, ...data }), | 188 | body: JSON.stringify({ recipeId, ...data }), |
188 | }); | 189 | }); |
189 | if (!request.ok) { | 190 | if (!request.ok) { |
190 | throw request; | 191 | throw new Error(request.statusText); |
191 | } | 192 | } |
192 | const serviceData = await request.json(); | 193 | const serviceData = await request.json(); |
193 | 194 | ||
@@ -208,7 +209,7 @@ export default class ServerApi { | |||
208 | return service; | 209 | return service; |
209 | } | 210 | } |
210 | 211 | ||
211 | async updateService(serviceId, rawData) { | 212 | async updateService(serviceId: string, rawData: any) { |
212 | const data = rawData; | 213 | const data = rawData; |
213 | 214 | ||
214 | if (data.iconFile) { | 215 | if (data.iconFile) { |
@@ -221,7 +222,7 @@ export default class ServerApi { | |||
221 | }); | 222 | }); |
222 | 223 | ||
223 | if (!request.ok) { | 224 | if (!request.ok) { |
224 | throw request; | 225 | throw new Error(request.statusText); |
225 | } | 226 | } |
226 | 227 | ||
227 | const serviceData = await request.json(); | 228 | const serviceData = await request.json(); |
@@ -234,12 +235,13 @@ export default class ServerApi { | |||
234 | return service; | 235 | return service; |
235 | } | 236 | } |
236 | 237 | ||
237 | async uploadServiceIcon(serviceId, icon) { | 238 | async uploadServiceIcon(serviceId: string, icon: string | Blob) { |
238 | const formData = new FormData(); | 239 | const formData = new FormData(); |
239 | formData.append('icon', icon); | 240 | formData.append('icon', icon); |
240 | 241 | ||
241 | const requestData = prepareAuthRequest({ | 242 | const requestData = prepareAuthRequest({ |
242 | method: 'PUT', | 243 | method: 'PUT', |
244 | // @ts-expect-error Argument of type '{ method: string; body: FormData; }' is not assignable to parameter of type '{ method: string; }'. | ||
243 | body: formData, | 245 | body: formData, |
244 | }); | 246 | }); |
245 | 247 | ||
@@ -247,11 +249,12 @@ export default class ServerApi { | |||
247 | 249 | ||
248 | const request = await window.fetch( | 250 | const request = await window.fetch( |
249 | `${apiBase()}/service/${serviceId}`, | 251 | `${apiBase()}/service/${serviceId}`, |
252 | // @ts-expect-error Argument of type '{ method: string; } & { mode: string; headers: any; }' is not assignable to parameter of type 'RequestInit | undefined'. | ||
250 | requestData, | 253 | requestData, |
251 | ); | 254 | ); |
252 | 255 | ||
253 | if (!request.ok) { | 256 | if (!request.ok) { |
254 | throw request; | 257 | throw new Error(request.statusText); |
255 | } | 258 | } |
256 | 259 | ||
257 | const serviceData = await request.json(); | 260 | const serviceData = await request.json(); |
@@ -259,25 +262,25 @@ export default class ServerApi { | |||
259 | return serviceData.data; | 262 | return serviceData.data; |
260 | } | 263 | } |
261 | 264 | ||
262 | async reorderService(data) { | 265 | async reorderService(data: any) { |
263 | const request = await sendAuthRequest(`${apiBase()}/service/reorder`, { | 266 | const request = await sendAuthRequest(`${apiBase()}/service/reorder`, { |
264 | method: 'PUT', | 267 | method: 'PUT', |
265 | body: JSON.stringify(data), | 268 | body: JSON.stringify(data), |
266 | }); | 269 | }); |
267 | if (!request.ok) { | 270 | if (!request.ok) { |
268 | throw request; | 271 | throw new Error(request.statusText); |
269 | } | 272 | } |
270 | const serviceData = await request.json(); | 273 | const serviceData = await request.json(); |
271 | debug('ServerApi::reorderService resolves', serviceData); | 274 | debug('ServerApi::reorderService resolves', serviceData); |
272 | return serviceData; | 275 | return serviceData; |
273 | } | 276 | } |
274 | 277 | ||
275 | async deleteService(id) { | 278 | async deleteService(id: string) { |
276 | const request = await sendAuthRequest(`${apiBase()}/service/${id}`, { | 279 | const request = await sendAuthRequest(`${apiBase()}/service/${id}`, { |
277 | method: 'DELETE', | 280 | method: 'DELETE', |
278 | }); | 281 | }); |
279 | if (!request.ok) { | 282 | if (!request.ok) { |
280 | throw request; | 283 | throw new Error(request.statusText); |
281 | } | 284 | } |
282 | const data = await request.json(); | 285 | const data = await request.json(); |
283 | 286 | ||
@@ -291,7 +294,7 @@ export default class ServerApi { | |||
291 | async getDefaultFeatures() { | 294 | async getDefaultFeatures() { |
292 | const request = await sendAuthRequest(`${apiBase()}/features/default`); | 295 | const request = await sendAuthRequest(`${apiBase()}/features/default`); |
293 | if (!request.ok) { | 296 | if (!request.ok) { |
294 | throw request; | 297 | throw new Error(request.statusText); |
295 | } | 298 | } |
296 | const data = await request.json(); | 299 | const data = await request.json(); |
297 | 300 | ||
@@ -307,7 +310,7 @@ export default class ServerApi { | |||
307 | 310 | ||
308 | const request = await sendAuthRequest(`${apiBase()}/features`); | 311 | const request = await sendAuthRequest(`${apiBase()}/features`); |
309 | if (!request.ok) { | 312 | if (!request.ok) { |
310 | throw request; | 313 | throw new Error(request.statusText); |
311 | } | 314 | } |
312 | const data = await request.json(); | 315 | const data = await request.json(); |
313 | 316 | ||
@@ -341,13 +344,13 @@ export default class ServerApi { | |||
341 | return this.recipes; | 344 | return this.recipes; |
342 | } | 345 | } |
343 | 346 | ||
344 | async getRecipeUpdates(recipeVersions) { | 347 | async getRecipeUpdates(recipeVersions: any) { |
345 | const request = await sendAuthRequest(`${apiBase()}/recipes/update`, { | 348 | const request = await sendAuthRequest(`${apiBase()}/recipes/update`, { |
346 | method: 'POST', | 349 | method: 'POST', |
347 | body: JSON.stringify(recipeVersions), | 350 | body: JSON.stringify(recipeVersions), |
348 | }); | 351 | }); |
349 | if (!request.ok) { | 352 | if (!request.ok) { |
350 | throw request; | 353 | throw new Error(request.statusText); |
351 | } | 354 | } |
352 | const recipes = await request.json(); | 355 | const recipes = await request.json(); |
353 | debug('ServerApi::getRecipeUpdates resolves', recipes); | 356 | debug('ServerApi::getRecipeUpdates resolves', recipes); |
@@ -357,7 +360,7 @@ export default class ServerApi { | |||
357 | // Recipes Previews | 360 | // Recipes Previews |
358 | async getRecipePreviews() { | 361 | async getRecipePreviews() { |
359 | const request = await sendAuthRequest(`${apiBase()}/recipes`); | 362 | const request = await sendAuthRequest(`${apiBase()}/recipes`); |
360 | if (!request.ok) throw request; | 363 | if (!request.ok) throw new Error(request.statusText); |
361 | const data = await request.json(); | 364 | const data = await request.json(); |
362 | const recipePreviews = this._mapRecipePreviewModel(data); | 365 | const recipePreviews = this._mapRecipePreviewModel(data); |
363 | debug('ServerApi::getRecipes resolves', recipePreviews); | 366 | debug('ServerApi::getRecipes resolves', recipePreviews); |
@@ -367,7 +370,7 @@ export default class ServerApi { | |||
367 | async getFeaturedRecipePreviews() { | 370 | async getFeaturedRecipePreviews() { |
368 | // TODO: If we are hitting the internal-server, we need to return an empty list, else we can hit the remote server and get the data | 371 | // TODO: If we are hitting the internal-server, we need to return an empty list, else we can hit the remote server and get the data |
369 | const request = await sendAuthRequest(`${apiBase()}/recipes/popular`); | 372 | const request = await sendAuthRequest(`${apiBase()}/recipes/popular`); |
370 | if (!request.ok) throw request; | 373 | if (!request.ok) throw new Error(request.statusText); |
371 | 374 | ||
372 | const data = await request.json(); | 375 | const data = await request.json(); |
373 | const recipePreviews = this._mapRecipePreviewModel(data); | 376 | const recipePreviews = this._mapRecipePreviewModel(data); |
@@ -375,10 +378,10 @@ export default class ServerApi { | |||
375 | return recipePreviews; | 378 | return recipePreviews; |
376 | } | 379 | } |
377 | 380 | ||
378 | async searchRecipePreviews(needle) { | 381 | async searchRecipePreviews(needle: string) { |
379 | const url = `${apiBase()}/recipes/search?needle=${needle}`; | 382 | const url = `${apiBase()}/recipes/search?needle=${needle}`; |
380 | const request = await sendAuthRequest(url); | 383 | const request = await sendAuthRequest(url); |
381 | if (!request.ok) throw request; | 384 | if (!request.ok) throw new Error(request.statusText); |
382 | 385 | ||
383 | const data = await request.json(); | 386 | const data = await request.json(); |
384 | const recipePreviews = this._mapRecipePreviewModel(data); | 387 | const recipePreviews = this._mapRecipePreviewModel(data); |
@@ -386,7 +389,7 @@ export default class ServerApi { | |||
386 | return recipePreviews; | 389 | return recipePreviews; |
387 | } | 390 | } |
388 | 391 | ||
389 | async getRecipePackage(recipeId) { | 392 | async getRecipePackage(recipeId: string) { |
390 | try { | 393 | try { |
391 | const recipesDirectory = userDataRecipesPath(); | 394 | const recipesDirectory = userDataRecipesPath(); |
392 | const recipeTempDirectory = join(recipesDirectory, 'temp', recipeId); | 395 | const recipeTempDirectory = join(recipesDirectory, 'temp', recipeId); |
@@ -396,7 +399,7 @@ export default class ServerApi { | |||
396 | 399 | ||
397 | ensureDirSync(recipeTempDirectory); | 400 | ensureDirSync(recipeTempDirectory); |
398 | 401 | ||
399 | let archivePath; | 402 | let archivePath: PathOrFileDescriptor; |
400 | 403 | ||
401 | if (pathExistsSync(internalRecipeFile)) { | 404 | if (pathExistsSync(internalRecipeFile)) { |
402 | debug('[ServerApi::getRecipePackage] Using internal recipe file'); | 405 | debug('[ServerApi::getRecipePackage] Using internal recipe file'); |
@@ -416,6 +419,7 @@ export default class ServerApi { | |||
416 | 419 | ||
417 | await sleep(10); | 420 | await sleep(10); |
418 | 421 | ||
422 | // @ts-expect-error No overload matches this call. | ||
419 | await tar.x({ | 423 | await tar.x({ |
420 | file: archivePath, | 424 | file: archivePath, |
421 | cwd: recipeTempDirectory, | 425 | cwd: recipeTempDirectory, |
@@ -455,7 +459,7 @@ export default class ServerApi { | |||
455 | false, | 459 | false, |
456 | ); | 460 | ); |
457 | if (!request.ok) { | 461 | if (!request.ok) { |
458 | throw request; | 462 | throw new Error(request.statusText); |
459 | } | 463 | } |
460 | debug('ServerApi::healthCheck resolves'); | 464 | debug('ServerApi::healthCheck resolves'); |
461 | } | 465 | } |
@@ -468,7 +472,7 @@ export default class ServerApi { | |||
468 | 472 | ||
469 | if (Object.prototype.hasOwnProperty.call(config, 'services')) { | 473 | if (Object.prototype.hasOwnProperty.call(config, 'services')) { |
470 | const services = await Promise.all( | 474 | const services = await Promise.all( |
471 | config.services.map(async s => { | 475 | config.services.map(async (s: { service: any }) => { |
472 | const service = s; | 476 | const service = s; |
473 | const request = await sendAuthRequest( | 477 | const request = await sendAuthRequest( |
474 | `${apiBase()}/recipes/${s.service}`, | 478 | `${apiBase()}/recipes/${s.service}`, |
@@ -476,6 +480,7 @@ export default class ServerApi { | |||
476 | 480 | ||
477 | if (request.status === 200) { | 481 | if (request.status === 200) { |
478 | const data = await request.json(); | 482 | const data = await request.json(); |
483 | // @ts-expect-error Property 'recipe' does not exist on type '{ service: any; }'. | ||
479 | service.recipe = new RecipePreviewModel(data); | 484 | service.recipe = new RecipePreviewModel(data); |
480 | } | 485 | } |
481 | 486 | ||
@@ -494,18 +499,18 @@ export default class ServerApi { | |||
494 | } | 499 | } |
495 | 500 | ||
496 | // Helper | 501 | // Helper |
497 | async _mapServiceModels(services) { | 502 | async _mapServiceModels(services: any[]) { |
498 | const recipes = services.map(s => s.recipeId); | 503 | const recipes = services.map((s: { recipeId: string }) => s.recipeId); |
499 | await this._bulkRecipeCheck(recipes); | 504 | await this._bulkRecipeCheck(recipes); |
500 | /* eslint-disable no-return-await */ | 505 | /* eslint-disable no-return-await */ |
501 | return Promise.all( | 506 | return Promise.all( |
502 | services.map(async service => await this._prepareServiceModel(service)), | 507 | services.map(async (service: any) => this._prepareServiceModel(service)), |
503 | ); | 508 | ); |
504 | /* eslint-enable no-return-await */ | 509 | /* eslint-enable no-return-await */ |
505 | } | 510 | } |
506 | 511 | ||
507 | async _prepareServiceModel(service) { | 512 | async _prepareServiceModel(service: { recipeId: string }) { |
508 | let recipe; | 513 | let recipe: undefined; |
509 | try { | 514 | try { |
510 | recipe = this.recipes.find(r => r.id === service.recipeId); | 515 | recipe = this.recipes.find(r => r.id === service.recipeId); |
511 | 516 | ||
@@ -521,14 +526,15 @@ export default class ServerApi { | |||
521 | } | 526 | } |
522 | } | 527 | } |
523 | 528 | ||
524 | async _bulkRecipeCheck(unfilteredRecipes) { | 529 | async _bulkRecipeCheck(unfilteredRecipes: any[]) { |
525 | // Filter recipe duplicates as we don't need to download 3 Slack recipes | 530 | // Filter recipe duplicates as we don't need to download 3 Slack recipes |
526 | const recipes = unfilteredRecipes.filter( | 531 | const recipes = unfilteredRecipes.filter( |
527 | (elem, pos, arr) => arr.indexOf(elem) === pos, | 532 | (elem: any, pos: number, arr: string | any[]) => |
533 | arr.indexOf(elem) === pos, | ||
528 | ); | 534 | ); |
529 | 535 | ||
530 | return Promise.all( | 536 | return Promise.all( |
531 | recipes.map(async recipeId => { | 537 | recipes.map(async (recipeId: string) => { |
532 | let recipe = this.recipes.find(r => r.id === recipeId); | 538 | let recipe = this.recipes.find(r => r.id === recipeId); |
533 | 539 | ||
534 | if (!recipe) { | 540 | if (!recipe) { |
@@ -554,7 +560,7 @@ export default class ServerApi { | |||
554 | ).catch(error => console.error("Can't load recipe", error)); | 560 | ).catch(error => console.error("Can't load recipe", error)); |
555 | } | 561 | } |
556 | 562 | ||
557 | _mapRecipePreviewModel(recipes) { | 563 | _mapRecipePreviewModel(recipes: any[]) { |
558 | return recipes | 564 | return recipes |
559 | .map(recipe => { | 565 | .map(recipe => { |
560 | try { | 566 | try { |