aboutsummaryrefslogtreecommitdiffstats
path: root/src/api
diff options
context:
space:
mode:
authorLibravatar Markus Hatvan <markus_hatvan@aon.at>2021-07-30 10:54:54 +0200
committerLibravatar GitHub <noreply@github.com>2021-07-30 14:24:54 +0530
commitf4b4416ea52d564bc2dbe543a82084ed98843ccc (patch)
tree7ca6b23571c86458a6b799746c91a7191de02715 /src/api
parent5.6.1-nightly.8 [skip ci] (diff)
downloadferdium-app-f4b4416ea52d564bc2dbe543a82084ed98843ccc.tar.gz
ferdium-app-f4b4416ea52d564bc2dbe543a82084ed98843ccc.tar.zst
ferdium-app-f4b4416ea52d564bc2dbe543a82084ed98843ccc.zip
chore: migrate from tslint to @typescript-eslint (#1706)
- update .eslintrc to work for .js and .ts - update devDependencies - lint properly both root /src and nested /packages - update webhint recommended setting for tsconfig.json to shrink output - Manage all eslint rules from the repo root - escape single quotes in scripts to please windows build Co-authored-by: Vijay A <avijayr@protonmail.com>
Diffstat (limited to 'src/api')
-rw-r--r--src/api/server/LocalApi.js20
-rw-r--r--src/api/server/ServerApi.js288
2 files changed, 190 insertions, 118 deletions
diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js
index 4b1f03f22..2d5bd8b80 100644
--- a/src/api/server/LocalApi.js
+++ b/src/api/server/LocalApi.js
@@ -2,7 +2,7 @@ import { ipcRenderer } from 'electron';
2import { session } from '@electron/remote'; 2import { session } from '@electron/remote';
3import du from 'du'; 3import du from 'du';
4 4
5import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js'; 5import { getServicePartitionsDirectory } from '../../helpers/service-helpers';
6 6
7const debug = require('debug')('Ferdi:LocalApi'); 7const debug = require('debug')('Ferdi:LocalApi');
8 8
@@ -41,11 +41,23 @@ export default class LocalApi {
41 } 41 }
42 42
43 async clearCache(serviceId = null) { 43 async clearCache(serviceId = null) {
44 const s = serviceId ? session.fromPartition(`persist:service-${serviceId}`) : session.defaultSession; 44 const s = serviceId
45 ? session.fromPartition(`persist:service-${serviceId}`)
46 : session.defaultSession;
45 47
46 debug('LocalApi::clearCache resolves', (serviceId || 'clearAppCache')); 48 debug('LocalApi::clearCache resolves', serviceId || 'clearAppCache');
47 await s.clearStorageData({ 49 await s.clearStorageData({
48 storages: ['appcache', 'cookies', 'filesystem', 'indexdb', 'localstorage', 'shadercache', 'websql', 'serviceworkers', 'cachestorage'], 50 storages: [
51 'appcache',
52 'cookies',
53 'filesystem',
54 'indexdb',
55 'localstorage',
56 'shadercache',
57 'websql',
58 'serviceworkers',
59 'cachestorage',
60 ],
49 quotas: ['temporary', 'persistent', 'syncable'], 61 quotas: ['temporary', 'persistent', 'syncable'],
50 }); 62 });
51 return s.clearCache(); 63 return s.clearCache();
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js
index 78a98e544..bc1d665b1 100644
--- a/src/api/server/ServerApi.js
+++ b/src/api/server/ServerApi.js
@@ -23,16 +23,11 @@ import {
23 loadRecipeConfig, 23 loadRecipeConfig,
24} from '../../helpers/recipe-helpers'; 24} from '../../helpers/recipe-helpers';
25 25
26import { 26import { removeServicePartitionDirectory } from '../../helpers/service-helpers';
27 removeServicePartitionDirectory,
28} from '../../helpers/service-helpers.js';
29 27
30const debug = require('debug')('Ferdi:ServerApi'); 28const debug = require('debug')('Ferdi:ServerApi');
31 29
32module.paths.unshift( 30module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory());
33 getDevRecipeDirectory(),
34 getRecipeDirectory(),
35);
36 31
37const { default: fetch } = remoteRequire('electron-fetch'); 32const { default: fetch } = remoteRequire('electron-fetch');
38 33
@@ -43,12 +38,16 @@ export default class ServerApi {
43 38
44 // User 39 // User
45 async login(email, passwordHash) { 40 async login(email, passwordHash) {
46 const request = await sendAuthRequest(`${apiBase()}/auth/login`, { 41 const request = await sendAuthRequest(
47 method: 'POST', 42 `${apiBase()}/auth/login`,
48 headers: { 43 {
49 Authorization: `Basic ${window.btoa(`${email}:${passwordHash}`)}`, 44 method: 'POST',
45 headers: {
46 Authorization: `Basic ${window.btoa(`${email}:${passwordHash}`)}`,
47 },
50 }, 48 },
51 }, false); 49 false,
50 );
52 if (!request.ok) { 51 if (!request.ok) {
53 throw request; 52 throw request;
54 } 53 }
@@ -59,10 +58,14 @@ export default class ServerApi {
59 } 58 }
60 59
61 async signup(data) { 60 async signup(data) {
62 const request = await sendAuthRequest(`${apiBase()}/auth/signup`, { 61 const request = await sendAuthRequest(
63 method: 'POST', 62 `${apiBase()}/auth/signup`,
64 body: JSON.stringify(data), 63 {
65 }, false); 64 method: 'POST',
65 body: JSON.stringify(data),
66 },
67 false,
68 );
66 if (!request.ok) { 69 if (!request.ok) {
67 throw request; 70 throw request;
68 } 71 }
@@ -86,12 +89,16 @@ export default class ServerApi {
86 } 89 }
87 90
88 async retrievePassword(email) { 91 async retrievePassword(email) {
89 const request = await sendAuthRequest(`${apiBase()}/auth/password`, { 92 const request = await sendAuthRequest(
90 method: 'POST', 93 `${apiBase()}/auth/password`,
91 body: JSON.stringify({ 94 {
92 email, 95 method: 'POST',
93 }), 96 body: JSON.stringify({
94 }, false); 97 email,
98 }),
99 },
100 false,
101 );
95 if (!request.ok) { 102 if (!request.ok) {
96 throw request; 103 throw request;
97 } 104 }
@@ -128,7 +135,9 @@ export default class ServerApi {
128 } 135 }
129 const updatedData = await request.json(); 136 const updatedData = await request.json();
130 137
131 const user = Object.assign(updatedData, { data: new UserModel(updatedData.data) }); 138 const user = Object.assign(updatedData, {
139 data: new UserModel(updatedData.data),
140 });
132 debug('ServerApi::updateUserInfo resolves', user); 141 debug('ServerApi::updateUserInfo resolves', user);
133 return user; 142 return user;
134 } 143 }
@@ -159,7 +168,7 @@ export default class ServerApi {
159 const data = await request.json(); 168 const data = await request.json();
160 169
161 let services = await this._mapServiceModels(data); 170 let services = await this._mapServiceModels(data);
162 services = services.filter(service => service !== null); 171 services = services.filter((service) => service !== null);
163 debug('ServerApi::getServices resolves', services); 172 debug('ServerApi::getServices resolves', services);
164 return services; 173 return services;
165 } 174 }
@@ -175,12 +184,17 @@ export default class ServerApi {
175 const serviceData = await request.json(); 184 const serviceData = await request.json();
176 185
177 if (data.iconFile) { 186 if (data.iconFile) {
178 const iconData = await this.uploadServiceIcon(serviceData.data.id, data.iconFile); 187 const iconData = await this.uploadServiceIcon(
188 serviceData.data.id,
189 data.iconFile,
190 );
179 191
180 serviceData.data = iconData; 192 serviceData.data = iconData;
181 } 193 }
182 194
183 const service = Object.assign(serviceData, { data: await this._prepareServiceModel(serviceData.data) }); 195 const service = Object.assign(serviceData, {
196 data: await this._prepareServiceModel(serviceData.data),
197 });
184 198
185 debug('ServerApi::createService resolves', service); 199 debug('ServerApi::createService resolves', service);
186 return service; 200 return service;
@@ -204,7 +218,9 @@ export default class ServerApi {
204 218
205 const serviceData = await request.json(); 219 const serviceData = await request.json();
206 220
207 const service = Object.assign(serviceData, { data: await this._prepareServiceModel(serviceData.data) }); 221 const service = Object.assign(serviceData, {
222 data: await this._prepareServiceModel(serviceData.data),
223 });
208 224
209 debug('ServerApi::updateService resolves', service); 225 debug('ServerApi::updateService resolves', service);
210 return service; 226 return service;
@@ -221,7 +237,10 @@ export default class ServerApi {
221 237
222 delete requestData.headers['Content-Type']; 238 delete requestData.headers['Content-Type'];
223 239
224 const request = await window.fetch(`${apiBase()}/service/${serviceId}`, requestData); 240 const request = await window.fetch(
241 `${apiBase()}/service/${serviceId}`,
242 requestData,
243 );
225 244
226 if (!request.ok) { 245 if (!request.ok) {
227 throw request; 246 throw request;
@@ -292,18 +311,21 @@ export default class ServerApi {
292 // Recipes 311 // Recipes
293 async getInstalledRecipes() { 312 async getInstalledRecipes() {
294 const recipesDirectory = getRecipeDirectory(); 313 const recipesDirectory = getRecipeDirectory();
295 const paths = fs.readdirSync(recipesDirectory) 314 const paths = fs
296 .filter(file => ( 315 .readdirSync(recipesDirectory)
297 fs.statSync(path.join(recipesDirectory, file)).isDirectory() 316 .filter(
298 && file !== 'temp' 317 (file) => fs.statSync(path.join(recipesDirectory, file)).isDirectory()
299 && file !== 'dev' 318 && file !== 'temp'
300 )); 319 && file !== 'dev',
301 320 );
302 this.recipes = paths.map((id) => { 321
303 // eslint-disable-next-line 322 this.recipes = paths
304 const Recipe = require(id)(RecipeModel); 323 .map((id) => {
305 return new Recipe(loadRecipeConfig(id)); 324 // eslint-disable-next-line
306 }).filter(recipe => recipe.id); 325 const Recipe = require(id)(RecipeModel);
326 return new Recipe(loadRecipeConfig(id));
327 })
328 .filter((recipe) => recipe.id);
307 329
308 this.recipes = this.recipes.concat(this._getDevRecipes()); 330 this.recipes = this.recipes.concat(this._getDevRecipes());
309 331
@@ -373,7 +395,9 @@ export default class ServerApi {
373 console.log('[ServerApi::getRecipePackage] Using internal recipe file'); 395 console.log('[ServerApi::getRecipePackage] Using internal recipe file');
374 archivePath = internalRecipeFile; 396 archivePath = internalRecipeFile;
375 } else { 397 } else {
376 console.log('[ServerApi::getRecipePackage] Downloading recipe from server'); 398 console.log(
399 '[ServerApi::getRecipePackage] Downloading recipe from server',
400 );
377 archivePath = tempArchivePath; 401 archivePath = tempArchivePath;
378 402
379 const packageUrl = `${apiBase()}/recipes/download/${recipeId}`; 403 const packageUrl = `${apiBase()}/recipes/download/${recipeId}`;
@@ -393,12 +417,14 @@ export default class ServerApi {
393 preservePaths: true, 417 preservePaths: true,
394 unlink: true, 418 unlink: true,
395 preserveOwner: false, 419 preserveOwner: false,
396 onwarn: x => console.log('warn', recipeId, x), 420 onwarn: (x) => console.log('warn', recipeId, x),
397 }); 421 });
398 422
399 await sleep(10); 423 await sleep(10);
400 424
401 const { id } = fs.readJsonSync(path.join(recipeTempDirectory, 'package.json')); 425 const { id } = fs.readJsonSync(
426 path.join(recipeTempDirectory, 'package.json'),
427 );
402 const recipeDirectory = path.join(recipesDirectory, id); 428 const recipeDirectory = path.join(recipesDirectory, id);
403 fs.copySync(recipeTempDirectory, recipeDirectory); 429 fs.copySync(recipeTempDirectory, recipeDirectory);
404 fs.remove(recipeTempDirectory); 430 fs.remove(recipeTempDirectory);
@@ -414,7 +440,9 @@ export default class ServerApi {
414 440
415 // News 441 // News
416 async getLatestNews() { 442 async getLatestNews() {
417 const url = `${apiBase(true)}/news?platform=${osPlatform}&arch=${osArch}&version=${app.getVersion()}`; 443 const url = `${apiBase(
444 true,
445 )}/news?platform=${osPlatform}&arch=${osArch}&version=${app.getVersion()}`;
418 const request = await sendAuthRequest(url); 446 const request = await sendAuthRequest(url);
419 if (!request.ok) throw request; 447 if (!request.ok) throw request;
420 const data = await request.json(); 448 const data = await request.json();
@@ -435,9 +463,13 @@ export default class ServerApi {
435 throw new Error('Server not loaded'); 463 throw new Error('Server not loaded');
436 } 464 }
437 465
438 const request = await sendAuthRequest(`${apiBase(false)}/health`, { 466 const request = await sendAuthRequest(
439 method: 'GET', 467 `${apiBase(false)}/health`,
440 }, false); 468 {
469 method: 'GET',
470 },
471 false,
472 );
441 if (!request.ok) { 473 if (!request.ok) {
442 throw request; 474 throw request;
443 } 475 }
@@ -445,23 +477,31 @@ export default class ServerApi {
445 } 477 }
446 478
447 async getLegacyServices() { 479 async getLegacyServices() {
448 const file = path.join(app.getPath('userData'), 'settings', 'services.json'); 480 const file = path.join(
481 app.getPath('userData'),
482 'settings',
483 'services.json',
484 );
449 485
450 try { 486 try {
451 const config = fs.readJsonSync(file); 487 const config = fs.readJsonSync(file);
452 488
453 if (Object.prototype.hasOwnProperty.call(config, 'services')) { 489 if (Object.prototype.hasOwnProperty.call(config, 'services')) {
454 const services = await Promise.all(config.services.map(async (s) => { 490 const services = await Promise.all(
455 const service = s; 491 config.services.map(async (s) => {
456 const request = await sendAuthRequest(`${apiBase()}/recipes/${s.service}`); 492 const service = s;
457 493 const request = await sendAuthRequest(
458 if (request.status === 200) { 494 `${apiBase()}/recipes/${s.service}`,
459 const data = await request.json(); 495 );
460 service.recipe = new RecipePreviewModel(data); 496
461 } 497 if (request.status === 200) {
462 498 const data = await request.json();
463 return service; 499 service.recipe = new RecipePreviewModel(data);
464 })); 500 }
501
502 return service;
503 }),
504 );
465 505
466 debug('ServerApi::getLegacyServices resolves', services); 506 debug('ServerApi::getLegacyServices resolves', services);
467 return services; 507 return services;
@@ -475,17 +515,19 @@ export default class ServerApi {
475 515
476 // Helper 516 // Helper
477 async _mapServiceModels(services) { 517 async _mapServiceModels(services) {
478 const recipes = services.map(s => s.recipeId); 518 const recipes = services.map((s) => s.recipeId);
479 await this._bulkRecipeCheck(recipes); 519 await this._bulkRecipeCheck(recipes);
480 /* eslint-disable no-return-await */ 520 /* eslint-disable no-return-await */
481 return Promise.all(services.map(async service => await this._prepareServiceModel(service))); 521 return Promise.all(
522 services.map(async (service) => await this._prepareServiceModel(service)),
523 );
482 /* eslint-enable no-return-await */ 524 /* eslint-enable no-return-await */
483 } 525 }
484 526
485 async _prepareServiceModel(service) { 527 async _prepareServiceModel(service) {
486 let recipe; 528 let recipe;
487 try { 529 try {
488 recipe = this.recipes.find(r => r.id === service.recipeId); 530 recipe = this.recipes.find((r) => r.id === service.recipeId);
489 531
490 if (!recipe) { 532 if (!recipe) {
491 console.warn(`Recipe ${service.recipeId} not loaded`); 533 console.warn(`Recipe ${service.recipeId} not loaded`);
@@ -501,21 +543,25 @@ export default class ServerApi {
501 543
502 async _bulkRecipeCheck(unfilteredRecipes) { 544 async _bulkRecipeCheck(unfilteredRecipes) {
503 // Filter recipe duplicates as we don't need to download 3 Slack recipes 545 // Filter recipe duplicates as we don't need to download 3 Slack recipes
504 const recipes = unfilteredRecipes.filter((elem, pos, arr) => arr.indexOf(elem) === pos); 546 const recipes = unfilteredRecipes.filter(
547 (elem, pos, arr) => arr.indexOf(elem) === pos,
548 );
505 549
506 return Promise.all(recipes 550 return Promise.all(
507 .map(async (recipeId) => { 551 recipes.map(async (recipeId) => {
508 let recipe = this.recipes.find(r => r.id === recipeId); 552 let recipe = this.recipes.find((r) => r.id === recipeId);
509 553
510 if (!recipe) { 554 if (!recipe) {
511 console.warn(`Recipe '${recipeId}' not installed, trying to fetch from server`); 555 console.warn(
556 `Recipe '${recipeId}' not installed, trying to fetch from server`,
557 );
512 558
513 await this.getRecipePackage(recipeId); 559 await this.getRecipePackage(recipeId);
514 560
515 debug('Rerun ServerAPI::getInstalledRecipes'); 561 debug('Rerun ServerAPI::getInstalledRecipes');
516 await this.getInstalledRecipes(); 562 await this.getInstalledRecipes();
517 563
518 recipe = this.recipes.find(r => r.id === recipeId); 564 recipe = this.recipes.find((r) => r.id === recipeId);
519 565
520 if (!recipe) { 566 if (!recipe) {
521 console.warn(`Could not load recipe ${recipeId}`); 567 console.warn(`Could not load recipe ${recipeId}`);
@@ -524,69 +570,83 @@ export default class ServerApi {
524 } 570 }
525 571
526 return recipe; 572 return recipe;
527 })).catch(err => console.error('Can\'t load recipe', err)); 573 }),
574 ).catch((err) => console.error("Can't load recipe", err));
528 } 575 }
529 576
530 _mapRecipePreviewModel(recipes) { 577 _mapRecipePreviewModel(recipes) {
531 return recipes.map((recipe) => { 578 return recipes
532 try { 579 .map((recipe) => {
533 return new RecipePreviewModel(recipe); 580 try {
534 } catch (e) { 581 return new RecipePreviewModel(recipe);
535 console.error(e); 582 } catch (e) {
536 return null; 583 console.error(e);
537 } 584 return null;
538 }).filter(recipe => recipe !== null); 585 }
586 })
587 .filter((recipe) => recipe !== null);
539 } 588 }
540 589
541 _mapNewsModels(news) { 590 _mapNewsModels(news) {
542 return news.map((newsItem) => { 591 return news
543 try { 592 .map((newsItem) => {
544 return new NewsModel(newsItem); 593 try {
545 } catch (e) { 594 return new NewsModel(newsItem);
546 console.error(e); 595 } catch (e) {
547 return null; 596 console.error(e);
548 } 597 return null;
549 }).filter(newsItem => newsItem !== null); 598 }
599 })
600 .filter((newsItem) => newsItem !== null);
550 } 601 }
551 602
552 _mapOrderModels(orders) { 603 _mapOrderModels(orders) {
553 return orders.map((orderItem) => { 604 return orders
554 try { 605 .map((orderItem) => {
555 return new OrderModel(orderItem); 606 try {
556 } catch (e) { 607 return new OrderModel(orderItem);
557 console.error(e); 608 } catch (e) {
558 return null; 609 console.error(e);
559 } 610 return null;
560 }).filter(orderItem => orderItem !== null); 611 }
612 })
613 .filter((orderItem) => orderItem !== null);
561 } 614 }
562 615
563 _getDevRecipes() { 616 _getDevRecipes() {
564 const recipesDirectory = getDevRecipeDirectory(); 617 const recipesDirectory = getDevRecipeDirectory();
565 try { 618 try {
566 const paths = fs.readdirSync(recipesDirectory) 619 const paths = fs
567 .filter(file => fs.statSync(path.join(recipesDirectory, file)).isDirectory() && file !== 'temp'); 620 .readdirSync(recipesDirectory)
568 621 .filter(
569 const recipes = paths.map((id) => { 622 (file) => fs.statSync(path.join(recipesDirectory, file)).isDirectory()
570 let Recipe; 623 && file !== 'temp',
571 try { 624 );
572 // eslint-disable-next-line 625
573 Recipe = require(id)(RecipeModel); 626 const recipes = paths
574 return new Recipe(loadRecipeConfig(id)); 627 .map((id) => {
575 } catch (err) { 628 let Recipe;
576 console.error(err); 629 try {
577 } 630 // eslint-disable-next-line
631 Recipe = require(id)(RecipeModel);
632 return new Recipe(loadRecipeConfig(id));
633 } catch (err) {
634 console.error(err);
635 }
578 636
579 return false; 637 return false;
580 }).filter(recipe => recipe.id).map((data) => { 638 })
581 const recipe = data; 639 .filter((recipe) => recipe.id)
640 .map((data) => {
641 const recipe = data;
582 642
583 recipe.icons = { 643 recipe.icons = {
584 svg: `${recipe.path}/icon.svg`, 644 svg: `${recipe.path}/icon.svg`,
585 }; 645 };
586 recipe.local = true; 646 recipe.local = true;
587 647
588 return data; 648 return data;
589 }); 649 });
590 650
591 return recipes; 651 return recipes;
592 } catch (err) { 652 } catch (err) {