Add remote fs API

Summary: Changelog: Expose Flipper Server FS access to Flipper plugins

Reviewed By: lblasa

Differential Revision: D32883144

fbshipit-source-id: 47637b61849ef60a2d8fe91a0a28d2a358e0b8c4
This commit is contained in:
Andrey Goncharov
2021-12-10 06:34:37 -08:00
committed by Facebook GitHub Bot
parent a87b99cd3d
commit 0e785fb18d
5 changed files with 84 additions and 5 deletions

View File

@@ -132,6 +132,18 @@ export type IOSDeviceParams = {
}; };
export type FlipperServerCommands = { export type FlipperServerCommands = {
'node-api-fs-access': (path: string, mode?: number) => Promise<void>;
'node-api-fs-pathExists': (path: string, mode?: number) => Promise<boolean>;
'node-api-fs-unlink': (path: string) => Promise<void>;
'node-api-fs-mkdir': (
path: string,
options?: {recursive?: boolean} & MkdirOptions,
) => Promise<string | void>;
'node-api-fs-copyFile': (
src: string,
dest: string,
flags?: number,
) => Promise<void>;
/** /**
* @throws ExecError * @throws ExecError
*/ */
@@ -310,6 +322,10 @@ export type BufferEncoding =
| 'binary' | 'binary'
| 'hex'; | 'hex';
export interface MkdirOptions {
mode?: string | number;
}
export type FlipperServerConfig = { export type FlipperServerConfig = {
gatekeepers: Record<string, boolean>; gatekeepers: Record<string, boolean>;
env: Partial<Record<ENVIRONMENT_VARIABLES, string>>; env: Partial<Record<ENVIRONMENT_VARIABLES, string>>;

View File

@@ -13,7 +13,12 @@ import {NormalizedMenuEntry} from './MenuEntry';
import {RealFlipperClient} from './Plugin'; import {RealFlipperClient} from './Plugin';
import {Notification} from './Notification'; import {Notification} from './Notification';
import {DetailSidebarProps} from '../ui/DetailSidebar'; import {DetailSidebarProps} from '../ui/DetailSidebar';
import {ExecOptions, ExecOut, BufferEncoding} from 'flipper-common'; import {
ExecOptions,
ExecOut,
BufferEncoding,
MkdirOptions,
} from 'flipper-common';
export type FileEncoding = 'utf-8' | 'base64'; export type FileEncoding = 'utf-8' | 'base64';
@@ -31,7 +36,18 @@ export type RemoteNodeAPI = {
): Promise<ExecOut<string>>; ): Promise<ExecOut<string>>;
}; };
fs: { fs: {
// TODO: Fill me access(path: string, mode?: number): Promise<void>;
pathExists(path: string, mode?: number): Promise<boolean>;
unlink(path: string): Promise<void>;
mkdir(
path: string,
options: {recursive: true} & MkdirOptions,
): Promise<string | undefined>;
mkdir(
path: string,
options?: {recursive?: false} & MkdirOptions,
): Promise<void>;
copyFile(src: string, dest: string, flags?: number): Promise<void>;
}; };
}; };

View File

@@ -393,7 +393,13 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
childProcess: { childProcess: {
exec: jest.fn(), exec: jest.fn(),
}, },
fs: {}, fs: {
access: jest.fn(),
pathExists: jest.fn(),
unlink: jest.fn(),
mkdir: jest.fn(),
copyFile: jest.fn(),
},
}, },
}; };
} }

View File

@@ -44,6 +44,7 @@ import {
internGraphPOSTAPIRequest, internGraphPOSTAPIRequest,
} from './fb-stubs/internRequests'; } from './fb-stubs/internRequests';
import {commandNodeApiExec} from './commands/NodeApiExec'; import {commandNodeApiExec} from './commands/NodeApiExec';
import {access, copyFile, mkdir, unlink} from 'fs/promises';
export const SERVICE_FLIPPER = 'flipper.oAuthToken'; export const SERVICE_FLIPPER = 'flipper.oAuthToken';
@@ -215,6 +216,18 @@ export class FlipperServerImpl implements FlipperServer {
private commandHandler: FlipperServerCommands = { private commandHandler: FlipperServerCommands = {
'node-api-exec': commandNodeApiExec, 'node-api-exec': commandNodeApiExec,
'node-api-fs-access': access,
'node-api-fs-pathExists': async (path, mode) => {
try {
await access(path, mode);
return true;
} catch {
return false;
}
},
'node-api-fs-unlink': unlink,
'node-api-fs-mkdir': mkdir,
'node-api-fs-copyFile': copyFile,
'get-config': async () => this.config, 'get-config': async () => this.config,
'get-changelog': getChangelog, 'get-changelog': getChangelog,
'device-list': async () => { 'device-list': async () => {

View File

@@ -8,7 +8,12 @@
*/ */
import {_setFlipperLibImplementation, RemoteNodeAPI} from 'flipper-plugin'; import {_setFlipperLibImplementation, RemoteNodeAPI} from 'flipper-plugin';
import type {BufferEncoding, ExecOptions, Logger} from 'flipper-common'; import type {
BufferEncoding,
ExecOptions,
Logger,
MkdirOptions,
} from 'flipper-common';
import type {Store} from '../reducers'; import type {Store} from '../reducers';
import createPaste from '../fb-stubs/createPaste'; import createPaste from '../fb-stubs/createPaste';
import type BaseDevice from '../devices/BaseDevice'; import type BaseDevice from '../devices/BaseDevice';
@@ -75,7 +80,30 @@ export function initializeFlipperLibImplementation(
options, options,
)) as RemoteNodeAPI['childProcess']['exec'], )) as RemoteNodeAPI['childProcess']['exec'],
}, },
fs: {}, fs: {
access: async (path: string, mode?: number) =>
renderHost.flipperServer.exec('node-api-fs-access', path, mode),
pathExists: async (path: string, mode?: number) =>
renderHost.flipperServer.exec('node-api-fs-pathExists', path, mode),
unlink: async (path: string) =>
renderHost.flipperServer.exec('node-api-fs-unlink', path),
mkdir: (async (
path: string,
options?: {recursive?: boolean} & MkdirOptions,
) =>
renderHost.flipperServer.exec(
'node-api-fs-mkdir',
path,
options,
)) as RemoteNodeAPI['fs']['mkdir'],
copyFile: async (src: string, dest: string, flags?: number) =>
renderHost.flipperServer.exec(
'node-api-fs-copyFile',
src,
dest,
flags,
),
},
}, },
}); });
} }