aboutsummaryrefslogtreecommitdiffstats
path: root/src/api
diff options
context:
space:
mode:
authorLibravatar Markus Hatvan <markus_hatvan@aon.at>2021-11-18 17:37:45 +0100
committerLibravatar GitHub <noreply@github.com>2021-11-18 22:07:45 +0530
commitb37a6b07b39c8c7827052dc6fb97f490f1e0f514 (patch)
tree0276e7c51f5ebfa14c566def7aac39f014c2291d /src/api
parentUpdate github issues template [skip ci] (diff)
downloadferdium-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')
-rw-r--r--src/api/server/ServerApi.ts (renamed from src/api/server/ServerApi.js)98
-rw-r--r--src/api/utils/auth.ts2
2 files changed, 53 insertions, 47 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';
15import fetch from 'electron-fetch'; 16import fetch from 'electron-fetch';
16 17
@@ -40,12 +41,12 @@ const debug = require('debug')('Ferdi:ServerApi');
40module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory()); 41module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory());
41 42
42export default class ServerApi { 43export 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 {
diff --git a/src/api/utils/auth.ts b/src/api/utils/auth.ts
index 98295d1a4..899881e88 100644
--- a/src/api/utils/auth.ts
+++ b/src/api/utils/auth.ts
@@ -31,7 +31,7 @@ export const prepareAuthRequest = (
31 31
32export const sendAuthRequest = ( 32export const sendAuthRequest = (
33 url: RequestInfo, 33 url: RequestInfo,
34 options: { method: string } | undefined, 34 options?: { method: string; headers?: any; body?: any },
35 auth?: boolean, 35 auth?: boolean,
36) => 36) =>
37 // @ts-expect-error Argument of type '{ method: string; } & { mode: string; headers: any; }' is not assignable to parameter of type 'RequestInit | undefined'. 37 // @ts-expect-error Argument of type '{ method: string; } & { mode: string; headers: any; }' is not assignable to parameter of type 'RequestInit | undefined'.