From a279b9bc43d23f1c4bb46a924830e230749c11b2 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Thu, 18 Nov 2021 09:13:48 -0800 Subject: [PATCH] Remove fs.readFile from some plugins Summary: 1. Remove fs.readFile from some plugins 2. Add "importFile" to FlipperLib and RenderHost See D32492149 for context Followups: 1. Decapitate Stella's sendToPhone 2. Decapitate crash reporter 3. Figure out how to approach navigation 4. Figure out how to approach FileSelector Reviewed By: mweststrate Differential Revision: D32496775 fbshipit-source-id: e150aa56a2c2c1eb12a4c03c801f76cd76485a9d --- .../app/src/electron/initializeElectron.tsx | 20 ++++++++ .../flipper-plugin/src/__tests__/api.node.tsx | 1 + desktop/flipper-plugin/src/index.ts | 1 + .../flipper-plugin/src/plugin/FlipperLib.tsx | 19 ++++++++ .../src/test-utils/test-utils.tsx | 1 + desktop/flipper-ui-core/src/RenderHost.tsx | 8 ++++ .../src/utils/flipperLibImplementation.tsx | 1 + .../request-mocking/NetworkRouteManager.tsx | 48 ++++++++----------- 8 files changed, 71 insertions(+), 28 deletions(-) diff --git a/desktop/app/src/electron/initializeElectron.tsx b/desktop/app/src/electron/initializeElectron.tsx index 1b32a2373..3da31dfcd 100644 --- a/desktop/app/src/electron/initializeElectron.tsx +++ b/desktop/app/src/electron/initializeElectron.tsx @@ -111,6 +111,26 @@ export function initializeElectron() { return undefined; }); }, + async importFile({defaultPath, extensions} = {}) { + const {filePaths} = await remote.dialog.showOpenDialog({ + defaultPath, + properties: ['openFile'], + filters: extensions ? [{extensions, name: ''}] : undefined, + }); + + if (!filePaths.length) { + return; + } + + const filePath = filePaths[0]; + const fileName = path.basename(filePath); + + const data = await fs.promises.readFile(filePath, {encoding: 'utf-8'}); + return { + data, + name: fileName, + }; + }, async exportFile(data, {defaultPath} = {}) { const {filePath} = await remote.dialog.showSaveDialog({ defaultPath, diff --git a/desktop/flipper-plugin/src/__tests__/api.node.tsx b/desktop/flipper-plugin/src/__tests__/api.node.tsx index c9e2f2ab6..3ac5fb4cc 100644 --- a/desktop/flipper-plugin/src/__tests__/api.node.tsx +++ b/desktop/flipper-plugin/src/__tests__/api.node.tsx @@ -97,6 +97,7 @@ test('Correct top level API exposed', () => { "ElementSearchResultSet", "ElementsInspectorElement", "ElementsInspectorProps", + "FileDescriptor", "FlipperLib", "HighlightManager", "Idler", diff --git a/desktop/flipper-plugin/src/index.ts b/desktop/flipper-plugin/src/index.ts index 5d6cebd30..9550a6a5d 100644 --- a/desktop/flipper-plugin/src/index.ts +++ b/desktop/flipper-plugin/src/index.ts @@ -37,6 +37,7 @@ export { FlipperLib, getFlipperLib, setFlipperLibImplementation as _setFlipperLibImplementation, + FileDescriptor, } from './plugin/FlipperLib'; export { MenuEntry, diff --git a/desktop/flipper-plugin/src/plugin/FlipperLib.tsx b/desktop/flipper-plugin/src/plugin/FlipperLib.tsx index 5b9c0bb0f..f174ec85b 100644 --- a/desktop/flipper-plugin/src/plugin/FlipperLib.tsx +++ b/desktop/flipper-plugin/src/plugin/FlipperLib.tsx @@ -14,6 +14,11 @@ import {RealFlipperClient} from './Plugin'; import {Notification} from './Notification'; import {DetailSidebarProps} from '../ui/DetailSidebar'; +export interface FileDescriptor { + data: string; + name: string; +} + /** * This interface exposes all global methods for which an implementation will be provided by Flipper itself */ @@ -42,6 +47,20 @@ export interface FlipperLib { name: string; }; }): Promise; + /** + * @returns + * Imported file data. + * If user cancelled a file selection - undefined. + */ + importFile(options: { + defaultPath?: string; + extensions?: string[]; + }): Promise; + /** + * @returns + * An exported file path (if available) or a file name. + * If user cancelled a file selection - undefined. + */ exportFile( data: string, options?: { diff --git a/desktop/flipper-plugin/src/test-utils/test-utils.tsx b/desktop/flipper-plugin/src/test-utils/test-utils.tsx index afcf4732d..aca614e98 100644 --- a/desktop/flipper-plugin/src/test-utils/test-utils.tsx +++ b/desktop/flipper-plugin/src/test-utils/test-utils.tsx @@ -380,6 +380,7 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib { openLink: jest.fn(), showNotification: jest.fn(), exportFile: jest.fn(), + importFile: jest.fn(), paths: { appPath: process.cwd(), homePath: `/dev/null`, diff --git a/desktop/flipper-ui-core/src/RenderHost.tsx b/desktop/flipper-ui-core/src/RenderHost.tsx index 86770ed29..92af9366b 100644 --- a/desktop/flipper-ui-core/src/RenderHost.tsx +++ b/desktop/flipper-ui-core/src/RenderHost.tsx @@ -66,8 +66,13 @@ export interface RenderHost { message?: string; title?: string; }): Promise; + /** + * @deprecated + * TODO: Remove in favor of "importFile" + */ showOpenDialog?: FlipperLib['showOpenDialog']; showSelectDirectoryDialog?(defaultPath?: string): Promise; + importFile: FlipperLib['importFile']; exportFile: FlipperLib['exportFile']; /** * @returns @@ -106,6 +111,9 @@ if (process.env.NODE_ENV === 'test') { return ''; }, writeTextToClipboard() {}, + async importFile() { + return undefined; + }, async exportFile() { return undefined; }, diff --git a/desktop/flipper-ui-core/src/utils/flipperLibImplementation.tsx b/desktop/flipper-ui-core/src/utils/flipperLibImplementation.tsx index 89b284a78..2ace9f251 100644 --- a/desktop/flipper-ui-core/src/utils/flipperLibImplementation.tsx +++ b/desktop/flipper-ui-core/src/utils/flipperLibImplementation.tsx @@ -60,6 +60,7 @@ export function initializeFlipperLibImplementation( ); }, DetailsSidebarImplementation: DetailSidebarImpl, + importFile: renderHost.importFile, exportFile: renderHost.exportFile, showOpenDialog: renderHost.showOpenDialog, paths: { diff --git a/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx b/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx index 1dfcb443a..33bd9722d 100644 --- a/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx +++ b/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx @@ -7,11 +7,9 @@ * @format */ -import fs from 'fs'; import {Atom, DataTableManager, getFlipperLib} from 'flipper-plugin'; import {createContext} from 'react'; import {Header, Request} from '../types'; -import {message} from 'antd'; export type Route = { requestUrl: string; @@ -136,35 +134,29 @@ export function createNetworkManager( }, importRoutes() { getFlipperLib() - .showOpenDialog?.({ - filter: {extensions: ['json'], name: 'Flipper Route Files'}, + .importFile({ + extensions: ['.json'], }) - .then((filePath) => { - if (filePath) { - fs.readFile(filePath, 'utf8', (err, data) => { - if (err) { - message.error('Unable to import file'); - return; + .then((res) => { + if (res) { + const importedRoutes = JSON.parse(res.data); + importedRoutes?.forEach((importedRoute: Route) => { + if (importedRoute != null) { + const newNextRouteId = nextRouteId.get(); + routes.update((draft) => { + draft[newNextRouteId.toString()] = { + requestUrl: importedRoute.requestUrl, + requestMethod: importedRoute.requestMethod, + responseData: importedRoute.responseData as string, + responseHeaders: importedRoute.responseHeaders, + responseStatus: importedRoute.responseStatus, + enabled: true, + }; + }); + nextRouteId.set(newNextRouteId + 1); } - const importedRoutes = JSON.parse(data); - importedRoutes?.forEach((importedRoute: Route) => { - if (importedRoute != null) { - const newNextRouteId = nextRouteId.get(); - routes.update((draft) => { - draft[newNextRouteId.toString()] = { - requestUrl: importedRoute.requestUrl, - requestMethod: importedRoute.requestMethod, - responseData: importedRoute.responseData as string, - responseHeaders: importedRoute.responseHeaders, - responseStatus: importedRoute.responseStatus, - enabled: true, - }; - }); - nextRouteId.set(newNextRouteId + 1); - } - }); - informClientMockChange(routes.get()); }); + informClientMockChange(routes.get()); } }) .catch((e) =>