diff --git a/desktop/app/src/ui/components/Glyph.tsx b/desktop/app/src/ui/components/Glyph.tsx index 543ae3ea2..6b7525e78 100644 --- a/desktop/app/src/ui/components/Glyph.tsx +++ b/desktop/app/src/ui/components/Glyph.tsx @@ -9,7 +9,7 @@ import React from 'react'; import styled from '@emotion/styled'; -import {getIconURL} from '../../utils/icons'; +import {getIconURLSync} from '../../utils/icons'; export type IconSize = 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32; @@ -121,7 +121,7 @@ export default class Glyph extends React.PureComponent<{ color={color} size={size} title={title} - src={getIconURL( + src={getIconURLSync( variant === 'outline' ? `${name}-outline` : name, size, typeof window !== 'undefined' ? window.devicePixelRatio : 1, diff --git a/desktop/app/src/utils/__tests__/icons.node.tsx b/desktop/app/src/utils/__tests__/icons.node.tsx index eb52b7d50..6a9ec644e 100644 --- a/desktop/app/src/utils/__tests__/icons.node.tsx +++ b/desktop/app/src/utils/__tests__/icons.node.tsx @@ -7,7 +7,7 @@ * @format */ -import {buildLocalIconPath, buildIconURL} from '../icons'; +import {buildLocalIconPath, buildIconURLSync} from '../icons'; import * as path from 'path'; test('filled icons get correct local path', () => { @@ -21,14 +21,14 @@ test('outline icons get correct local path', () => { }); test('filled icons get correct URL', () => { - const iconUrl = buildIconURL('star', 12, 2); + const iconUrl = buildIconURLSync('star', 12, 2); expect(iconUrl).toBe( 'https://facebook.com/assets/?name=star&variant=filled&size=12&set=facebook_icons&density=2x', ); }); test('outline icons get correct URL', () => { - const iconUrl = buildIconURL('star-outline', 12, 2); + const iconUrl = buildIconURLSync('star-outline', 12, 2); expect(iconUrl).toBe( 'https://facebook.com/assets/?name=star&variant=outline&size=12&set=facebook_icons&density=2x', ); diff --git a/desktop/app/src/utils/exportData.tsx b/desktop/app/src/utils/exportData.tsx index 5a5cc812f..406fba042 100644 --- a/desktop/app/src/utils/exportData.tsx +++ b/desktop/app/src/utils/exportData.tsx @@ -589,7 +589,10 @@ export function importDataToStore(source: string, data: string, store: Store) { export const importFileToStore = (file: string, store: Store) => { fs.readFile(file, 'utf8', (err, data) => { if (err) { - console.error(`[exportData] Failed to write to file ${file}: `, err); + console.error( + `[exportData] importFileToStore for file ${file} failed:`, + err, + ); return; } importDataToStore(file, data, store); diff --git a/desktop/app/src/utils/icons.ts b/desktop/app/src/utils/icons.ts index 5e9e058f8..24b5cdadd 100644 --- a/desktop/app/src/utils/icons.ts +++ b/desktop/app/src/utils/icons.ts @@ -7,6 +7,10 @@ * @format */ +// We should get rid of sync use entirely but until then the +// methods are marked as such. +/* eslint-disable node/no-sync */ + import fs from 'fs'; import path from 'path'; // eslint-disable-next-line flipper/no-electron-remote-imports @@ -26,7 +30,7 @@ export type Icons = { let _icons: Icons | undefined; -export function getIcons(): Icons { +export function getIconsSync(): Icons { return ( _icons! ?? (_icons = JSON.parse(fs.readFileSync(getIconsPath(), {encoding: 'utf8'}))) @@ -67,7 +71,7 @@ export function buildLocalIconURL(name: string, size: number, density: number) { return `icons/${getIconFileName(icon, size, density)}`; } -export function buildIconURL(name: string, size: number, density: number) { +export function buildIconURLSync(name: string, size: number, density: number) { const icon = getIconPartsFromName(name); // eslint-disable-next-line prettier/prettier const url = `https://facebook.com/assets/?name=${ @@ -77,7 +81,7 @@ export function buildIconURL(name: string, size: number, density: number) { }&size=${size}&set=facebook_icons&density=${density}x`; if ( typeof window !== 'undefined' && - (!getIcons()[name] || !getIcons()[name].includes(size)) + (!getIconsSync()[name] || !getIconsSync()[name].includes(size)) ) { // From utils/isProduction const isProduction = !/node_modules[\\/]electron[\\/]/.test( @@ -85,7 +89,7 @@ export function buildIconURL(name: string, size: number, density: number) { ); if (!isProduction) { - const existing = getIcons()[name] || (getIcons()[name] = []); + const existing = getIconsSync()[name] || (getIconsSync()[name] = []); if (!existing.includes(size)) { // Check if that icon actually exists! fetch(url) @@ -96,7 +100,7 @@ export function buildIconURL(name: string, size: number, density: number) { existing.sort(); fs.writeFileSync( getIconsPath(), - JSON.stringify(getIcons(), null, 2), + JSON.stringify(getIconsSync(), null, 2), 'utf8', ); console.warn( @@ -122,7 +126,7 @@ export function buildIconURL(name: string, size: number, density: number) { return url; } -export function getIconURL(name: string, size: number, density: number) { +export function getIconURLSync(name: string, size: number, density: number) { if (name.indexOf('/') > -1) { return name; } @@ -168,5 +172,5 @@ export function getIconURL(name: string, size: number, density: number) { ) { return buildLocalIconURL(name, size, density); } - return buildIconURL(name, requestedSize, density); + return buildIconURLSync(name, requestedSize, density); } diff --git a/desktop/app/src/utils/info.tsx b/desktop/app/src/utils/info.tsx index fbbb3e87e..779f800e8 100644 --- a/desktop/app/src/utils/info.tsx +++ b/desktop/app/src/utils/info.tsx @@ -7,6 +7,9 @@ * @format */ +// Use of sync methods is cached. +/* eslint-disable node/no-sync */ + import os from 'os'; import isProduction from './isProduction'; import fs from 'fs-extra'; diff --git a/desktop/app/src/utils/jsonFileReduxPersistStorage.tsx b/desktop/app/src/utils/jsonFileReduxPersistStorage.tsx index 8185816f9..ded99fdbd 100644 --- a/desktop/app/src/utils/jsonFileReduxPersistStorage.tsx +++ b/desktop/app/src/utils/jsonFileReduxPersistStorage.tsx @@ -29,11 +29,12 @@ export default class JsonFileStorage { return readFile(this.filepath) .then((buffer) => buffer.toString()) .then(this.deserializeValue) - .catch((e) => { + .catch(async (e) => { console.warn( `Failed to read settings file: "${this.filepath}". ${e}. Replacing file with default settings.`, ); - return this.writeContents(prettyStringify({})).then(() => ({})); + await this.writeContents(prettyStringify({})); + return {}; }); } diff --git a/desktop/app/src/utils/launcherSettingsStorage.tsx b/desktop/app/src/utils/launcherSettingsStorage.tsx index bf2d05b4c..314c6ee45 100644 --- a/desktop/app/src/utils/launcherSettingsStorage.tsx +++ b/desktop/app/src/utils/launcherSettingsStorage.tsx @@ -7,7 +7,7 @@ * @format */ -import fs from 'fs'; +import fs from 'fs-extra'; import path from 'path'; import TOML, {JsonMap} from '@iarna/toml'; import {Storage} from 'redux-persist/es/types'; @@ -36,7 +36,7 @@ export default class LauncherSettingsStorage implements Storage { private async parseFile(): Promise { try { - const content = fs.readFileSync(this.filepath).toString(); + const content = fs.readFile(this.filepath).toString(); return deserialize(content); } catch (e) { console.warn( @@ -50,12 +50,15 @@ export default class LauncherSettingsStorage implements Storage { private async writeFile(value: LauncherSettings): Promise { this.ensureDirExists(); const content = serialize(value); - fs.writeFileSync(this.filepath, content); + return fs.writeFile(this.filepath, content); } - private ensureDirExists(): void { + private async ensureDirExists(): Promise { const dir = path.dirname(this.filepath); - fs.existsSync(dir) || fs.mkdirSync(dir, {recursive: true}); + const exists = await fs.pathExists(dir); + if (!exists) { + await fs.mkdir(dir, {recursive: true}); + } } } diff --git a/desktop/app/src/utils/processConfig.tsx b/desktop/app/src/utils/processConfig.tsx index 32a728493..7cf0f9f03 100644 --- a/desktop/app/src/utils/processConfig.tsx +++ b/desktop/app/src/utils/processConfig.tsx @@ -7,6 +7,7 @@ * @format */ +// eslint-disable-next-line flipper/no-electron-remote-imports import {remote} from 'electron'; export type ProcessConfig = { diff --git a/desktop/app/src/utils/restartFlipper.tsx b/desktop/app/src/utils/restartFlipper.tsx index 241960477..324efd6f9 100644 --- a/desktop/app/src/utils/restartFlipper.tsx +++ b/desktop/app/src/utils/restartFlipper.tsx @@ -7,6 +7,7 @@ * @format */ +// eslint-disable-next-line flipper/no-electron-remote-imports import {remote} from 'electron'; import isProduction from './isProduction'; diff --git a/desktop/app/src/utils/screenshot.tsx b/desktop/app/src/utils/screenshot.tsx index c3588d08c..ad9a19e55 100644 --- a/desktop/app/src/utils/screenshot.tsx +++ b/desktop/app/src/utils/screenshot.tsx @@ -12,6 +12,7 @@ import path from 'path'; import BaseDevice from '../devices/BaseDevice'; import {reportPlatformFailures} from 'flipper-common'; import expandTilde from 'expand-tilde'; +// eslint-disable-next-line flipper/no-electron-remote-imports import {remote} from 'electron'; import config from '../utils/processConfig'; diff --git a/desktop/app/src/utils/vscodeUtils.tsx b/desktop/app/src/utils/vscodeUtils.tsx index 5f9893b20..620c215ab 100644 --- a/desktop/app/src/utils/vscodeUtils.tsx +++ b/desktop/app/src/utils/vscodeUtils.tsx @@ -13,7 +13,7 @@ import {getPreferredEditorUriScheme} from '../fb-stubs/user'; let preferredEditorUriScheme: string | undefined = undefined; export function callVSCode(plugin: string, command: string, params?: string) { - getVSCodeUrl(plugin, command, params).then((url) => + return getVSCodeUrl(plugin, command, params).then((url) => getFlipperLib().openLink(url), ); } diff --git a/desktop/scripts/build-release.ts b/desktop/scripts/build-release.ts index d7d06bbdb..6f30e0490 100755 --- a/desktop/scripts/build-release.ts +++ b/desktop/scripts/build-release.ts @@ -29,7 +29,11 @@ import { moveSourceMaps, } from './build-utils'; import fetch from '@adobe/node-fetch-retry'; -import {getIcons, buildLocalIconPath, getIconURL} from '../app/src/utils/icons'; +import { + getIconsSync, + buildLocalIconPath, + getIconURLSync, +} from '../app/src/utils/icons'; import isFB from './isFB'; import copyPackageWithDependencies from './copy-package-with-dependencies'; import {staticDir, distDir} from './paths'; @@ -305,7 +309,7 @@ async function copyStaticFolder(buildFolder: string) { } function downloadIcons(buildFolder: string) { - const iconURLs = Object.entries(getIcons()).reduce< + const iconURLs = Object.entries(getIconsSync()).reduce< { name: string; size: number; @@ -322,7 +326,7 @@ function downloadIcons(buildFolder: string) { return Promise.all( iconURLs.map(({name, size, density}) => { - const url = getIconURL(name, size, density); + const url = getIconURLSync(name, size, density); return fetch(url, { retryOptions: { // Be default, only 5xx are retried but we're getting the odd 404