UNPKG

flipper-common

Version:

Server & UI shared Flipper utilities

537 lines 18.3 kB
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import { FlipperDoctor } from './doctor'; import { DeviceSpec, DownloadablePluginDetails, InstalledPluginDetails, MarketplacePluginDetails, UpdatablePluginDetails } from './PluginDetails'; import { ServerAddOnStartDetails } from './ServerAddOn'; import { EnvironmentInfo, LauncherSettings, ProcessConfig, Settings } from './settings'; import { LoggerInfo } from './utils/Logger'; export type FlipperServerType = 'embedded' | 'external'; export type CertificateExchangeMedium = 'FS_ACCESS' | 'WWW' | 'NONE'; export type FlipperServerState = 'pending' | 'starting' | 'started' | 'error' | 'closed'; export type DeviceOS = OS; export type DeviceDescription = { readonly os: DeviceOS; readonly title: string; readonly deviceType: DeviceType; readonly serial: string; readonly icon?: string; readonly features: { screenshotAvailable: boolean; screenCaptureAvailable: boolean; }; readonly specs?: DeviceSpec[]; readonly abiList?: string[]; readonly sdkVersion?: string; }; export type DeviceLogEntry = { readonly date: Date; readonly type: DeviceLogLevel; readonly message: string; readonly pid: number; readonly tid: number; readonly app?: string; readonly tag: string; }; export type DeviceLogLevel = 'unknown' | 'verbose' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'; export type ConnectionRecordEntry = { time: Date; type: 'warning' | 'info' | 'error'; os: DeviceOS; device: string; app: string; message: string; medium: CertificateExchangeMedium; }; export type CommandRecordEntry = ConnectionRecordEntry & { cmd: string; description: string; success: boolean; stdout?: string; stderr?: string; troubleshoot?: string; }; export type UninitializedClient = { os: string; deviceName: string; appName: string; }; export type ClientQuery = { readonly app: string; readonly app_id?: string; readonly os: DeviceOS; readonly device: string; readonly device_id: string; readonly sdk_version?: number; medium: CertificateExchangeMedium; rsocket?: boolean; }; export type SecureClientQuery = ClientQuery & { csr?: string | undefined; csr_path?: string | undefined; }; export type ClientDescription = { readonly id: string; readonly query: ClientQuery; }; export type ClientErrorType = { message: string; stacktrace: string; name: string; }; export type ClientResponseType = { success: object | string | number | boolean | null; error?: never; length: number; } | { success?: never; error: ClientErrorType; length: number; }; export type FlipperServerEvents = { 'server-state': { state: FlipperServerState; error?: string; }; 'server-error': any; notification: { type: 'success' | 'info' | 'error' | 'warning'; title: string; description: string; }; 'device-connected': DeviceDescription; 'device-disconnected': DeviceDescription; 'device-removed': DeviceDescription; 'device-log': { serial: string; entry: DeviceLogEntry; }; 'device-crash': { serial: string; crash: CrashLog; }; 'client-setup': UninitializedClient; 'client-setup-secret-exchange': { client: UninitializedClient; secret: string; }; 'client-setup-error': { client: UninitializedClient; type: 'error' | 'warning'; message: string; }; 'client-setup-step': { client: UninitializedClient; step: string; }; 'client-connected': ClientDescription; 'client-disconnected': { id: string; }; 'client-message': { id: string; message: string; }; 'connectivity-troubleshoot-cmd': CommandRecordEntry; 'connectivity-troubleshoot-log': ConnectionRecordEntry[]; 'plugins-server-add-on-message': ExecuteMessage; 'download-file-update': DownloadFileUpdate; 'server-log': LoggerInfo; 'browser-connection-created': {}; }; export type OS = 'iOS' | 'Android' | 'Metro' | 'Windows' | 'MacOS' | 'Browser' | 'Linux'; export type DeviceType = 'physical' | 'emulator' | 'dummy'; export type DeviceTarget = { udid: string; type: DeviceType; name: string; osVersion?: string; state?: string; }; export interface FSStatsLike { isFile: boolean; isDirectory: boolean; isSymbolicLink: boolean; mode: number; uid: number; gid: number; size: number; atimeMs: number; mtimeMs: number; ctimeMs: number; birthtimeMs: number; } export interface DeviceDebugFile { path: string; data: string; } export interface DeviceDebugCommand { command: string; result: string; } export interface DeviceDebugData { serial: string; appId: string; data: (DeviceDebugFile | DeviceDebugCommand)[]; } export interface PluginSource { js: string; css?: string; } export type FlipperServerCommands = { 'get-server-state': () => Promise<{ state: FlipperServerState; error?: string; }>; '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-rm': (path: string, options?: RmOptions) => Promise<void>; 'node-api-fs-copyFile': (src: string, dest: string, flags?: number) => Promise<void>; 'node-api-fs-stat': (path: string) => Promise<FSStatsLike>; 'node-api-fs-readlink': (path: string) => Promise<string>; 'node-api-fs-readfile': (path: string, options?: { encoding?: BufferEncoding; }) => Promise<string>; 'node-api-fs-readfile-binary': (path: string) => Promise<string>; 'node-api-fs-writefile': (path: string, contents: string, options?: { encoding?: BufferEncoding; }) => Promise<void>; 'node-api-fs-writefile-binary': (path: string, base64contents: string) => Promise<void>; /** * @throws ExecError */ 'node-api-exec': (command: string, options?: ExecOptions & { encoding?: BufferEncoding; }) => Promise<ExecOut<string>>; 'download-file-start': (url: string, dest: string, options?: DownloadFileStartOptions) => Promise<DownloadFileStartResponse>; 'get-config': () => Promise<FlipperServerConfig>; 'get-changelog': () => Promise<string>; 'device-list': () => Promise<DeviceDescription[]>; 'device-find': (deviceSerial: string) => Promise<DeviceDescription | undefined>; 'device-take-screenshot': (serial: string) => Promise<string>; 'device-start-screencapture': (serial: string, destination: string) => Promise<void>; 'log-connectivity-event': (level: 'info' | 'warning' | 'error', query: ClientQuery | null, ...message: any) => Promise<void>; 'device-stop-screencapture': (serial: string) => Promise<string>; 'device-shell-exec': (serial: string, command: string) => Promise<string>; 'device-install-app': (serial: string, appBundlePath: string) => Promise<void>; 'device-open-app': (serial: string, name: string) => Promise<void>; 'device-forward-port': (serial: string, local: string, remote: string) => Promise<boolean>; 'device-clear-logs': (serial: string) => Promise<void>; 'device-navigate': (serial: string, location: string) => Promise<void>; 'fetch-debug-data': () => Promise<DeviceDebugData[]>; 'metro-command': (serial: string, command: string) => Promise<void>; 'client-list': () => Promise<ClientDescription[]>; 'client-find': (clientId: string) => Promise<ClientDescription | undefined>; 'client-request': (clientId: string, payload: any) => Promise<void>; 'client-request-response': (clientId: string, payload: any) => Promise<ClientResponseType>; 'android-get-emulators': () => Promise<string[]>; 'android-launch-emulator': (name: string, coldboot: boolean) => Promise<void>; 'android-adb-kill': () => Promise<void>; 'ios-get-simulators': (bootedOnly: boolean) => Promise<DeviceTarget[]>; 'ios-launch-simulator': (udid: string) => Promise<void>; 'ios-launch-app': (udid: string, appName: string) => Promise<void>; 'ios-idb-kill': () => Promise<void>; 'persist-settings': (settings: Settings) => Promise<void>; 'persist-launcher-settings': (settings: LauncherSettings) => Promise<void>; 'keychain-write': (service: string, token: string) => Promise<void>; 'keychain-read': (service: string) => Promise<string>; 'keychain-unset': (service: string) => Promise<void>; 'plugins-load-dynamic-plugins': () => Promise<InstalledPluginDetails[]>; 'plugins-load-marketplace-plugins': () => Promise<MarketplacePluginDetails[]>; 'plugins-get-installed-plugins': () => Promise<InstalledPluginDetails[]>; 'plugins-get-updatable-plugins': (query: string | undefined) => Promise<UpdatablePluginDetails[]>; 'plugin-start-download': (plugin: DownloadablePluginDetails) => Promise<InstalledPluginDetails>; 'plugin-source': (path: string) => Promise<PluginSource>; 'plugins-install-from-marketplace': (name: string) => Promise<InstalledPluginDetails>; 'plugins-install-from-npm': (name: string) => Promise<InstalledPluginDetails>; 'plugins-install-from-content': (contents: string) => Promise<InstalledPluginDetails>; 'plugins-remove-plugins': (names: string[]) => Promise<void>; 'plugins-server-add-on-start': (pluginName: string, details: ServerAddOnStartDetails, owner: string) => Promise<void>; 'plugins-server-add-on-stop': (pluginName: string, owner: string) => Promise<void>; 'plugins-server-add-on-request-response': (payload: ExecuteMessage) => Promise<ClientResponseType>; 'doctor-get-healthchecks': (settings: FlipperDoctor.HealthcheckSettings) => Promise<FlipperDoctor.Healthchecks>; 'doctor-run-healthcheck': (settings: FlipperDoctor.HealthcheckSettings, category: keyof FlipperDoctor.Healthchecks, name: string) => Promise<FlipperDoctor.HealthcheckResult>; 'open-file': (path: string) => Promise<void>; 'intern-graph-post': (endpoint: string, formFields: Record<string, any>, fileFields: Record<string, GraphFileUpload>, options: { timeout?: number; internGraphUrl?: string; headers?: Record<string, string | number | boolean>; vpnMode?: 'vpn' | 'vpnless'; }) => Promise<GraphResponse>; 'intern-graph-get': (endpoint: string, params: Record<string, any>, options: { timeout?: number; internGraphUrl?: string; headers?: Record<string, string | number | boolean>; vpnMode?: 'vpn' | 'vpnless'; }) => Promise<GraphResponse>; 'intern-upload-scribe-logs': (messages: { category: string; message: string; }[]) => Promise<void>; 'intern-cloud-upload': (path: string) => Promise<string>; shutdown: () => Promise<void>; restart: () => Promise<void>; 'is-logged-in': () => Promise<boolean>; 'environment-info': () => Promise<EnvironmentInfo>; 'move-pwa': () => Promise<void>; 'fetch-new-version': (version: string) => Promise<void>; }; export type GraphResponse = { status: number; data: any; }; export type GraphFileUpload = { path?: string; contents?: string; filename?: string; contentType?: string; }; /** * White listed environment variables that can be used in Flipper UI / plugins */ declare const environmentVariables: { readonly NODE_ENV: 1; readonly DEV_SERVER_URL: 1; readonly CONFIG: 1; readonly FLIPPER_ENABLED_PLUGINS: 1; readonly FB_ONDEMAND: 1; readonly FLIPPER_INTERNGRAPH_URL: 1; readonly JEST_WORKER_ID: 1; readonly FLIPPER_DOCS_BASE_URL: 1; readonly FLIPPER_NO_PLUGIN_AUTO_UPDATE: 1; readonly FLIPPER_NO_PLUGIN_MARKETPLACE: 1; readonly HOME: 1; readonly METRO_PORT_ENV_VAR: 1; readonly FLIPPER_PLUGIN_AUTO_UPDATE_POLLING_INTERVAL: 1; readonly SKIP_TOKEN_VERIFICATION: 1; }; export type ENVIRONMENT_VARIABLES = keyof typeof environmentVariables; /** * Grab all environment variables from a process.env object, without leaking variables which usage isn't declared in ENVIRONMENT_VARIABLES */ export declare function parseEnvironmentVariables(baseEnv: any): Partial<Record<ENVIRONMENT_VARIABLES, string>>; type ENVIRONMENT_PATHS = 'appPath' | 'homePath' | 'execPath' | 'staticPath' | 'tempPath' | 'desktopPath'; export interface ExecOptions { maxBuffer?: number; timeout?: number; cwd?: string; } export interface ExecError { message: string; stdout: string; stderr: string; stack?: string; cmd?: string; killed?: boolean; code?: number; } export interface ExecOut<StdOutErrType> { stdout: StdOutErrType; stderr: StdOutErrType; } export type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex'; export interface MkdirOptions { mode?: string | number; } export interface RmOptions { maxRetries?: number; } export interface DownloadFileStartOptions { method?: 'GET' | 'POST'; timeout?: number; maxRedirects?: number; headers?: Record<string, string>; overwrite?: boolean; proxy?: { host: string; port: number; protocol?: string; }; } export type DownloadFileUpdate = { id: string; downloaded: number; /** * Set to 0 if unknown */ totalSize: number; } & ({ status: 'downloading'; } | { status: 'success'; } | { status: 'error'; message: string; stack?: string; }); export interface DownloadFileStartResponse { /** * Download ID */ id: string; /** * Response status */ status: number; /** * Response status text */ statusText: string; /** * Response headers */ headers: Record<string, string>; /** * Size of the file, being downloaded, in bytes. Inferred from the "Content-Length" header. Set to 0 if unknown. */ totalSize: number; } export type FlipperServerConfig = { gatekeepers: Record<string, boolean>; env: Partial<Record<ENVIRONMENT_VARIABLES, string>>; paths: Record<ENVIRONMENT_PATHS, string>; settings: Settings; launcherSettings: LauncherSettings; processConfig: ProcessConfig; validWebSocketOrigins: string[]; environmentInfo: EnvironmentInfo; type?: FlipperServerType; sessionId: string; }; export interface FlipperServerExecOptions { timeout: number; } export interface FlipperServer { connect(): Promise<void>; on<Event extends keyof FlipperServerEvents>(event: Event, callback: (payload: FlipperServerEvents[Event]) => void): void; off<Event extends keyof FlipperServerEvents>(event: Event, callback: (payload: FlipperServerEvents[Event]) => void): void; exec<Event extends keyof FlipperServerCommands>(options: FlipperServerExecOptions, event: Event, ...args: Parameters<FlipperServerCommands[Event]>): ReturnType<FlipperServerCommands[Event]>; exec<Event extends keyof FlipperServerCommands>(event: Event, ...args: Parameters<FlipperServerCommands[Event]>): ReturnType<FlipperServerCommands[Event]>; close(): void; } export type MetroBundleDetails = { entryFile: string; platform?: string; dev: boolean; minify: boolean; bundleType: string; }; export type MetroGlobalCacheDisabledReason = 'too_many_errors' | 'too_many_misses'; /** * A tagged union of all the actions that may happen and we may want to * report to the tool user. * * Based on xplat/js/metro/packages/metro/src/lib/TerminalReporter.js */ export type MetroReportableEvent = { port: number; projectRoots: ReadonlyArray<string>; type: 'initialize_started'; } | { type: 'initialize_done'; } | { type: 'initialize_failed'; port: number; error: Error; } | { buildID: string; type: 'bundle_build_done'; } | { buildID: string; type: 'bundle_build_failed'; } | { buildID: string; bundleDetails: MetroBundleDetails; type: 'bundle_build_started'; } | { error: Error; type: 'bundling_error'; } | { type: 'dep_graph_loading'; } | { type: 'dep_graph_loaded'; } | { buildID: string; type: 'bundle_transform_progressed'; transformedFileCount: number; totalFileCount: number; } | { type: 'global_cache_error'; error: Error; } | { type: 'global_cache_disabled'; reason: MetroGlobalCacheDisabledReason; } | { type: 'transform_cache_reset'; } | { type: 'worker_stdout_chunk'; chunk: string; } | { type: 'worker_stderr_chunk'; chunk: string; } | { type: 'hmr_client_error'; error: Error; } | { type: 'client_log'; level: 'trace' | 'info' | 'warn' | 'log' | 'group' | 'groupCollapsed' | 'groupEnd' | 'debug'; data: Array<any>; }; export type SignCertificateMessage = { method: 'signCertificate'; csr: string; destination: string; medium: number | undefined; timestamp?: number; logs?: string[]; }; export type SignCertificateAckMessage = { method: 'signCertificateAck'; isError: boolean; medium: number | undefined; hasRequiredFiles: boolean; config: any; logs?: string[]; }; export type GetPluginsMessage = { id: number; method: 'getPlugins'; }; export type GetBackgroundPluginsMessage = { id: number; method: 'getBackgroundPlugins'; }; export type ExecuteMessage = { method: 'execute'; params: { method: string; api: string; params?: unknown; }; }; export type ResponseMessage = { id: number; success: object | string | number | boolean | null; error?: never; } | { id: number; success?: never; error: ClientErrorType; }; export type CrashLog = { callstack?: string; reason: string; name: string; date?: number; }; export {}; //# sourceMappingURL=server-types.d.ts.map