Remove remaining Node imports from core
Summary: Removed remaining path / fs imports from Flipper core. `expand-tide` needed replacement too, but noticed that it never actually rewrites paths since all use cases were already using absolute paths, so removed it instead. Reviewed By: aigoncharov Differential Revision: D33017654 fbshipit-source-id: e12f66ef68b5f9e4279411c94445a2fb87249e9a
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d95b15094f
commit
accef856fc
@@ -30,7 +30,7 @@ export interface Device {
|
|||||||
clearLogs(): Promise<void>;
|
clearLogs(): Promise<void>;
|
||||||
sendMetroCommand(command: string): Promise<void>;
|
sendMetroCommand(command: string): Promise<void>;
|
||||||
navigateToLocation(location: string): Promise<void>;
|
navigateToLocation(location: string): Promise<void>;
|
||||||
screenshot(): Promise<Buffer>;
|
screenshot(): Promise<Uint8Array>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DevicePluginPredicate = (device: Device) => boolean;
|
export type DevicePluginPredicate = (device: Device) => boolean;
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
import {Button as AntButton, message} from 'antd';
|
import {Button as AntButton, message} from 'antd';
|
||||||
import React, {useState, useEffect, useCallback} from 'react';
|
import React, {useState, useEffect, useCallback} from 'react';
|
||||||
import path from 'path';
|
|
||||||
import {capture, getCaptureLocation, getFileName} from '../utils/screenshot';
|
import {capture, getCaptureLocation, getFileName} from '../utils/screenshot';
|
||||||
import {CameraOutlined, VideoCameraOutlined} from '@ant-design/icons';
|
import {CameraOutlined, VideoCameraOutlined} from '@ant-design/icons';
|
||||||
import {useStore} from '../utils/useStore';
|
import {useStore} from '../utils/useStore';
|
||||||
import {getRenderHostInstance} from '../RenderHost';
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
import {path} from 'flipper-plugin';
|
||||||
|
|
||||||
async function openFile(path: string) {
|
async function openFile(path: string) {
|
||||||
getRenderHostInstance().flipperServer.exec('open-file', path);
|
getRenderHostInstance().flipperServer.exec('open-file', path);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import BaseDevice from '../devices/BaseDevice';
|
import BaseDevice from '../devices/BaseDevice';
|
||||||
import {Button, Glyph, colors} from '../ui';
|
import {Button, Glyph, colors} from '../ui';
|
||||||
import path from 'path';
|
|
||||||
import {getRenderHostInstance} from '../RenderHost';
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
import {path} from 'flipper-plugin';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
recordingFinished: (path: string | null) => void;
|
recordingFinished: (path: string | null) => void;
|
||||||
|
|||||||
@@ -16,11 +16,9 @@ import {
|
|||||||
colors,
|
colors,
|
||||||
Glyph,
|
Glyph,
|
||||||
} from '../../ui';
|
} from '../../ui';
|
||||||
import React, {useState} from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
import {promises as fs} from 'fs';
|
import {getFlipperLib, theme} from 'flipper-plugin';
|
||||||
import {theme} from 'flipper-plugin';
|
|
||||||
import {getRenderHostInstance} from '../../RenderHost';
|
import {getRenderHostInstance} from '../../RenderHost';
|
||||||
import {useEffect} from 'react';
|
|
||||||
|
|
||||||
export const ConfigFieldContainer = styled(FlexRow)({
|
export const ConfigFieldContainer = styled(FlexRow)({
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
@@ -75,8 +73,8 @@ export function FilePathConfigField(props: {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async function () {
|
(async function () {
|
||||||
try {
|
try {
|
||||||
const stat = await fs.stat(value);
|
const stat = await getFlipperLib().remoteServerContext.fs.stat(value);
|
||||||
setIsValid(props.isRegularFile !== stat.isDirectory());
|
setIsValid(props.isRegularFile !== stat.isDirectory);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
setIsValid(false);
|
setIsValid(false);
|
||||||
}
|
}
|
||||||
@@ -93,8 +91,9 @@ export function FilePathConfigField(props: {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setValue(e.target.value);
|
setValue(e.target.value);
|
||||||
props.onChange(e.target.value);
|
props.onChange(e.target.value);
|
||||||
fs.stat(e.target.value)
|
getFlipperLib()
|
||||||
.then((stat) => stat.isDirectory())
|
.remoteServerContext.fs.stat(e.target.value)
|
||||||
|
.then((stat) => stat.isDirectory)
|
||||||
.then((valid) => {
|
.then((valid) => {
|
||||||
if (valid !== isValid) {
|
if (valid !== isValid) {
|
||||||
setIsValid(valid);
|
setIsValid(valid);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ export {PluginClient, Props, KeyboardActions} from './plugin';
|
|||||||
export {default as Client} from './Client';
|
export {default as Client} from './Client';
|
||||||
export {reportUsage} from 'flipper-common';
|
export {reportUsage} from 'flipper-common';
|
||||||
export {default as promiseTimeout} from './utils/promiseTimeout';
|
export {default as promiseTimeout} from './utils/promiseTimeout';
|
||||||
export {bufferToBlob} from './utils/screenshot';
|
|
||||||
export {getPluginKey} from './utils/pluginKey';
|
export {getPluginKey} from './utils/pluginKey';
|
||||||
export {Notification, Idler} from 'flipper-plugin';
|
export {Notification, Idler} from 'flipper-plugin';
|
||||||
export {IdlerImpl} from './utils/Idler';
|
export {IdlerImpl} from './utils/Idler';
|
||||||
@@ -72,8 +71,6 @@ export {default as Checkbox} from './ui/components/Checkbox';
|
|||||||
export {default as Orderable} from './ui/components/Orderable';
|
export {default as Orderable} from './ui/components/Orderable';
|
||||||
export {Component, PureComponent} from 'react';
|
export {Component, PureComponent} from 'react';
|
||||||
export {default as ContextMenu} from './ui/components/ContextMenu';
|
export {default as ContextMenu} from './ui/components/ContextMenu';
|
||||||
export {FileListFiles} from './ui/components/FileList';
|
|
||||||
export {default as FileList} from './ui/components/FileList';
|
|
||||||
export {default as View} from './ui/components/View';
|
export {default as View} from './ui/components/View';
|
||||||
export {default as Sidebar} from './ui/components/Sidebar';
|
export {default as Sidebar} from './ui/components/Sidebar';
|
||||||
export {default as FlexBox} from './ui/components/FlexBox';
|
export {default as FlexBox} from './ui/components/FlexBox';
|
||||||
|
|||||||
@@ -199,14 +199,12 @@ export default class BaseDevice implements Device {
|
|||||||
return this.flipperServer.exec('device-supports-screenshot', this.serial);
|
return this.flipperServer.exec('device-supports-screenshot', this.serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
async screenshot(): Promise<Buffer> {
|
async screenshot(): Promise<Uint8Array> {
|
||||||
if (this.isArchived) {
|
if (this.isArchived) {
|
||||||
return Buffer.from([]);
|
return new Uint8Array();
|
||||||
}
|
}
|
||||||
return Buffer.from(
|
return Base64.toUint8Array(
|
||||||
Base64.toUint8Array(
|
await this.flipperServer.exec('device-take-screenshot', this.serial),
|
||||||
await this.flipperServer.exec('device-take-screenshot', this.serial),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ import dispatcher, {
|
|||||||
getLatestCompatibleVersionOfEachPlugin,
|
getLatestCompatibleVersionOfEachPlugin,
|
||||||
} from '../plugins';
|
} from '../plugins';
|
||||||
import {BundledPluginDetails, InstalledPluginDetails} from 'flipper-common';
|
import {BundledPluginDetails, InstalledPluginDetails} from 'flipper-common';
|
||||||
import path from 'path';
|
|
||||||
import {createRootReducer, State} from '../../reducers/index';
|
import {createRootReducer, State} from '../../reducers/index';
|
||||||
import {getLogger} from 'flipper-common';
|
import {getLogger} from 'flipper-common';
|
||||||
import configureStore from 'redux-mock-store';
|
import configureStore from 'redux-mock-store';
|
||||||
import TestPlugin from './TestPlugin';
|
import TestPlugin from './TestPlugin';
|
||||||
import {_SandyPluginDefinition} from 'flipper-plugin';
|
import {_SandyPluginDefinition} from 'flipper-plugin';
|
||||||
import {getRenderHostInstance} from '../../RenderHost';
|
import {getRenderHostInstance} from '../../RenderHost';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
let loadDynamicPluginsMock: jest.Mock;
|
let loadDynamicPluginsMock: jest.Mock;
|
||||||
|
|
||||||
|
|||||||
@@ -1,217 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its 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 {Component} from 'react';
|
|
||||||
import path from 'path';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
const EMPTY_MAP = new Map();
|
|
||||||
const EMPTY_FILE_LIST_STATE = {error: null, files: EMPTY_MAP};
|
|
||||||
|
|
||||||
export type FileListFileType = 'file' | 'folder';
|
|
||||||
|
|
||||||
export type FileListFile = {
|
|
||||||
name: string;
|
|
||||||
src: string;
|
|
||||||
type: FileListFileType;
|
|
||||||
size: number;
|
|
||||||
mtime: number;
|
|
||||||
atime: number;
|
|
||||||
ctime: number;
|
|
||||||
birthtime: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FileListFiles = Array<FileListFile>;
|
|
||||||
|
|
||||||
type FileListProps = {
|
|
||||||
/** Path to the folder */
|
|
||||||
src: string;
|
|
||||||
/** Content to be rendered in case of an error */
|
|
||||||
onError?: (err: Error) => React.ReactNode | null | undefined;
|
|
||||||
/** Content to be rendered while loading */
|
|
||||||
onLoad?: () => void;
|
|
||||||
/** Content to be rendered when the file list is loaded */
|
|
||||||
onFiles: (files: FileListFiles) => React.ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
type FileListState = {
|
|
||||||
files: Map<string, FileListFile>;
|
|
||||||
error: Error | null | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List the contents of a folder from the user's file system. The file system is watched for
|
|
||||||
* changes and this list will automatically update.
|
|
||||||
*/
|
|
||||||
export default class FileList extends Component<FileListProps, FileListState> {
|
|
||||||
constructor(props: FileListProps, context: Object) {
|
|
||||||
super(props, context);
|
|
||||||
this.state = EMPTY_FILE_LIST_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
watcher: fs.FSWatcher | null | undefined;
|
|
||||||
|
|
||||||
fetchFile(src: string, name: string): Promise<FileListFile> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const loc = path.join(src, name);
|
|
||||||
|
|
||||||
fs.lstat(loc, (err, stat) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
const details: FileListFile = {
|
|
||||||
atime: Number(stat.atime),
|
|
||||||
birthtime:
|
|
||||||
typeof stat.birthtime === 'object' ? Number(stat.birthtime) : 0,
|
|
||||||
ctime: Number(stat.ctime),
|
|
||||||
mtime: Number(stat.mtime),
|
|
||||||
name,
|
|
||||||
size: stat.size,
|
|
||||||
src: loc,
|
|
||||||
type: stat.isDirectory() ? 'folder' : 'file',
|
|
||||||
};
|
|
||||||
resolve(details);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchFilesFromFolder(
|
|
||||||
originalSrc: string,
|
|
||||||
currentSrc: string,
|
|
||||||
callback: Function,
|
|
||||||
) {
|
|
||||||
const hasChangedDir = () => this.props.src !== originalSrc;
|
|
||||||
|
|
||||||
let filesSet: Map<string, FileListFile> = new Map();
|
|
||||||
fs.readdir(currentSrc, (err, files) => {
|
|
||||||
if (err) {
|
|
||||||
return callback(err, EMPTY_MAP);
|
|
||||||
}
|
|
||||||
let remainingPaths = files.length;
|
|
||||||
|
|
||||||
const next = () => {
|
|
||||||
if (hasChangedDir()) {
|
|
||||||
return callback(null, EMPTY_MAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!remainingPaths) {
|
|
||||||
return callback(null, filesSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = files.shift();
|
|
||||||
if (name) {
|
|
||||||
this.fetchFile(currentSrc, name)
|
|
||||||
.then((data) => {
|
|
||||||
filesSet.set(name, data);
|
|
||||||
if (data.type == 'folder') {
|
|
||||||
this.fetchFilesFromFolder(
|
|
||||||
originalSrc,
|
|
||||||
path.join(currentSrc, name),
|
|
||||||
function (err: Error, files: Map<string, FileListFile>) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err, EMPTY_MAP);
|
|
||||||
}
|
|
||||||
filesSet = new Map([...filesSet, ...files]);
|
|
||||||
remainingPaths--;
|
|
||||||
if (!remainingPaths) {
|
|
||||||
return callback(null, filesSet);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
remainingPaths--;
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
return callback(err, EMPTY_MAP);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchFiles(callback?: Function) {
|
|
||||||
const {src} = this.props;
|
|
||||||
|
|
||||||
const setState = (data: FileListState) => {
|
|
||||||
if (!hasChangedDir()) {
|
|
||||||
this.setState(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const hasChangedDir = () => this.props.src !== src;
|
|
||||||
|
|
||||||
this.fetchFilesFromFolder(
|
|
||||||
src,
|
|
||||||
src,
|
|
||||||
function (err: Error, files: Map<string, FileListFile>) {
|
|
||||||
setState({error: err, files: files});
|
|
||||||
if (callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps: FileListProps) {
|
|
||||||
if (nextProps.src !== this.props.src) {
|
|
||||||
this.initialFetch(nextProps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.initialFetch(this.props);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.removeWatcher();
|
|
||||||
}
|
|
||||||
|
|
||||||
initialFetch(props: FileListProps) {
|
|
||||||
this.removeWatcher();
|
|
||||||
|
|
||||||
fs.access(props.src, fs.constants.R_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
this.setState({error: err, files: EMPTY_MAP});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fetchFiles(props.onLoad);
|
|
||||||
|
|
||||||
this.watcher = fs.watch(props.src, () => {
|
|
||||||
this.fetchFiles();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.watcher.on('error', (err) => {
|
|
||||||
this.setState({error: err, files: EMPTY_MAP});
|
|
||||||
this.removeWatcher();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
removeWatcher() {
|
|
||||||
if (this.watcher) {
|
|
||||||
this.watcher.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {error, files} = this.state;
|
|
||||||
const {onError, onFiles} = this.props;
|
|
||||||
if (error && onError) {
|
|
||||||
return onError(error);
|
|
||||||
} else {
|
|
||||||
return onFiles(Array.from(files.values()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -62,9 +62,6 @@ export {Component, PureComponent} from 'react';
|
|||||||
// context menus and dropdowns
|
// context menus and dropdowns
|
||||||
export {default as ContextMenu} from './components/ContextMenu';
|
export {default as ContextMenu} from './components/ContextMenu';
|
||||||
|
|
||||||
// file
|
|
||||||
export {FileListFile, FileListFiles} from './components/FileList';
|
|
||||||
export {default as FileList} from './components/FileList';
|
|
||||||
// utility elements
|
// utility elements
|
||||||
export {default as View} from './components/View';
|
export {default as View} from './components/View';
|
||||||
export {default as Sidebar} from './components/Sidebar';
|
export {default as Sidebar} from './components/Sidebar';
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import path from 'path';
|
|
||||||
import {getLogger} from 'flipper-common';
|
import {getLogger} from 'flipper-common';
|
||||||
import {Store, MiddlewareAPI} from '../reducers';
|
import {Store, MiddlewareAPI} from '../reducers';
|
||||||
import {DeviceExport} from '../devices/BaseDevice';
|
import {DeviceExport} from '../devices/BaseDevice';
|
||||||
@@ -20,7 +19,6 @@ import {pluginKey} from '../utils/pluginKey';
|
|||||||
import {DevicePluginMap, ClientPluginMap} from '../plugin';
|
import {DevicePluginMap, ClientPluginMap} from '../plugin';
|
||||||
import {default as BaseDevice} from '../devices/BaseDevice';
|
import {default as BaseDevice} from '../devices/BaseDevice';
|
||||||
import {default as ArchivedDevice} from '../devices/ArchivedDevice';
|
import {default as ArchivedDevice} from '../devices/ArchivedDevice';
|
||||||
import fs from 'fs-extra';
|
|
||||||
import {v4 as uuidv4} from 'uuid';
|
import {v4 as uuidv4} from 'uuid';
|
||||||
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
||||||
import {TestIdler} from './Idler';
|
import {TestIdler} from './Idler';
|
||||||
@@ -33,7 +31,7 @@ import {deconstructClientId} from 'flipper-common';
|
|||||||
import {processMessageQueue} from './messageQueue';
|
import {processMessageQueue} from './messageQueue';
|
||||||
import {getPluginTitle} from './pluginUtils';
|
import {getPluginTitle} from './pluginUtils';
|
||||||
import {capture} from './screenshot';
|
import {capture} from './screenshot';
|
||||||
import {Dialog, Idler} from 'flipper-plugin';
|
import {Dialog, getFlipperLib, Idler, path} from 'flipper-plugin';
|
||||||
import {ClientQuery} from 'flipper-common';
|
import {ClientQuery} from 'flipper-common';
|
||||||
import ShareSheetExportUrl from '../chrome/ShareSheetExportUrl';
|
import ShareSheetExportUrl from '../chrome/ShareSheetExportUrl';
|
||||||
import ShareSheetExportFile from '../chrome/ShareSheetExportFile';
|
import ShareSheetExportFile from '../chrome/ShareSheetExportFile';
|
||||||
@@ -521,7 +519,10 @@ export const exportStoreToFile = (
|
|||||||
}> => {
|
}> => {
|
||||||
return exportStore(store, includeSupportDetails, idler, statusUpdate).then(
|
return exportStore(store, includeSupportDetails, idler, statusUpdate).then(
|
||||||
async ({serializedString, fetchMetaDataErrors}) => {
|
async ({serializedString, fetchMetaDataErrors}) => {
|
||||||
await fs.writeFile(exportFilePath, serializedString);
|
await getFlipperLib().remoteServerContext.fs.writeFile(
|
||||||
|
exportFilePath,
|
||||||
|
serializedString,
|
||||||
|
);
|
||||||
store.dispatch(resetSupportFormV2State());
|
store.dispatch(resetSupportFormV2State());
|
||||||
return {fetchMetaDataErrors};
|
return {fetchMetaDataErrors};
|
||||||
},
|
},
|
||||||
@@ -584,17 +585,17 @@ export function importDataToStore(source: string, data: string, store: Store) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const importFileToStore = (file: string, store: Store) => {
|
export const importFileToStore = async (file: string, store: Store) => {
|
||||||
fs.readFile(file, 'utf8', (err, data) => {
|
try {
|
||||||
if (err) {
|
const data = await getFlipperLib().remoteServerContext.fs.readFile(file);
|
||||||
console.error(
|
|
||||||
`[exportData] importFileToStore for file ${file} failed:`,
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
importDataToStore(file, data, store);
|
importDataToStore(file, data, store);
|
||||||
});
|
} catch (err) {
|
||||||
|
console.error(
|
||||||
|
`[exportData] importFileToStore for file ${file} failed:`,
|
||||||
|
err,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function canOpenDialog() {
|
export function canOpenDialog() {
|
||||||
|
|||||||
@@ -7,15 +7,14 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import util from 'util';
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
import {exec as execImport} from 'child_process';
|
|
||||||
|
|
||||||
const cmd = 'klist --json';
|
const cmd = 'klist --json';
|
||||||
const endWith = '@THEFACEBOOK.COM';
|
const endWith = '@THEFACEBOOK.COM';
|
||||||
|
|
||||||
export async function isFBEmployee(): Promise<boolean> {
|
export async function isFBEmployee(): Promise<boolean> {
|
||||||
return util
|
return getFlipperLib()
|
||||||
.promisify(execImport)(cmd)
|
.remoteServerContext.childProcess.exec(cmd)
|
||||||
.then(
|
.then(
|
||||||
(stdobj: {stderr: string; stdout: string}) => {
|
(stdobj: {stderr: string; stdout: string}) => {
|
||||||
const principal = String(JSON.parse(stdobj.stdout).principal);
|
const principal = String(JSON.parse(stdobj.stdout).principal);
|
||||||
|
|||||||
@@ -7,17 +7,15 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import BaseDevice from '../devices/BaseDevice';
|
import BaseDevice from '../devices/BaseDevice';
|
||||||
import {reportPlatformFailures} from 'flipper-common';
|
import {reportPlatformFailures} from 'flipper-common';
|
||||||
import expandTilde from 'expand-tilde';
|
|
||||||
import {getRenderHostInstance} from '../RenderHost';
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
import {getFlipperLib, path} from 'flipper-plugin';
|
||||||
|
|
||||||
export function getCaptureLocation() {
|
export function getCaptureLocation() {
|
||||||
return expandTilde(
|
return (
|
||||||
getRenderHostInstance().serverConfig.processConfig.screenCapturePath ||
|
getRenderHostInstance().serverConfig.processConfig.screenCapturePath ||
|
||||||
getRenderHostInstance().serverConfig.paths.desktopPath,
|
getRenderHostInstance().serverConfig.paths.desktopPath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,33 +32,14 @@ export async function capture(device: BaseDevice): Promise<string> {
|
|||||||
}
|
}
|
||||||
const pngPath = path.join(getCaptureLocation(), getFileName('png'));
|
const pngPath = path.join(getCaptureLocation(), getFileName('png'));
|
||||||
return reportPlatformFailures(
|
return reportPlatformFailures(
|
||||||
device.screenshot().then((buffer) => writeBufferToFile(pngPath, buffer)),
|
// TODO: there is no reason to read the screenshot first, grab it over the websocket, than send it back
|
||||||
|
// again to write in a file, probably easier to change screenshot api to `device.screenshot(): path`
|
||||||
|
device
|
||||||
|
.screenshot()
|
||||||
|
.then((buffer) =>
|
||||||
|
getFlipperLib().remoteServerContext.fs.writeFileBinary(pngPath, buffer),
|
||||||
|
)
|
||||||
|
.then(() => pngPath),
|
||||||
'captureScreenshot',
|
'captureScreenshot',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a buffer to a specified file path.
|
|
||||||
* Returns a Promise which resolves to the file path.
|
|
||||||
*/
|
|
||||||
export const writeBufferToFile = (
|
|
||||||
filePath: string,
|
|
||||||
buffer: Buffer,
|
|
||||||
): Promise<string> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
fs.writeFile(filePath, buffer, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve(filePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Blob from a Buffer
|
|
||||||
*/
|
|
||||||
export const bufferToBlob = (buffer: Buffer): Blob => {
|
|
||||||
return new Blob([buffer]);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -83,7 +83,6 @@
|
|||||||
"@types/deep-equal": "^1.0.1",
|
"@types/deep-equal": "^1.0.1",
|
||||||
"@types/detect-port": "^1.3.1",
|
"@types/detect-port": "^1.3.1",
|
||||||
"@types/electron-devtools-installer": "^2.2.0",
|
"@types/electron-devtools-installer": "^2.2.0",
|
||||||
"@types/expand-tilde": "^2.0.0",
|
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/fb-watchman": "^2.0.1",
|
"@types/fb-watchman": "^2.0.1",
|
||||||
"@types/form-data": "^2.2.1",
|
"@types/form-data": "^2.2.1",
|
||||||
@@ -150,7 +149,6 @@
|
|||||||
"eslint-plugin-react": "^7.27.1",
|
"eslint-plugin-react": "^7.27.1",
|
||||||
"eslint-plugin-react-hooks": "^4.3.0",
|
"eslint-plugin-react-hooks": "^4.3.0",
|
||||||
"eslint-plugin-rulesdir": "^0.2.1",
|
"eslint-plugin-rulesdir": "^0.2.1",
|
||||||
"expand-tilde": "^2.0.2",
|
|
||||||
"express": "^4.15.2",
|
"express": "^4.15.2",
|
||||||
"fb-watchman": "^2.0.1",
|
"fb-watchman": "^2.0.1",
|
||||||
"flipper-babel-transformer": "0.0.0",
|
"flipper-babel-transformer": "0.0.0",
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
"decompress": "^4.2.1",
|
"decompress": "^4.2.1",
|
||||||
"decompress-targz": "^4.1.1",
|
"decompress-targz": "^4.1.1",
|
||||||
"decompress-unzip": "^4.0.1",
|
"decompress-unzip": "^4.0.1",
|
||||||
"expand-tilde": "^2.0.2",
|
|
||||||
"flipper-common": "^0.0.0",
|
"flipper-common": "^0.0.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"live-plugin-manager": "^0.17.0",
|
"live-plugin-manager": "^0.17.0",
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import expandTilde from 'expand-tilde';
|
|
||||||
import {getPluginSourceFolders} from './pluginPaths';
|
import {getPluginSourceFolders} from './pluginPaths';
|
||||||
import pmap from 'p-map';
|
import pmap from 'p-map';
|
||||||
import pfilter from 'p-filter';
|
import pfilter from 'p-filter';
|
||||||
@@ -49,7 +48,6 @@ export async function getSourcePlugins(): Promise<InstalledPluginDetails[]> {
|
|||||||
async function entryPointForPluginFolder(
|
async function entryPointForPluginFolder(
|
||||||
pluginsDir: string,
|
pluginsDir: string,
|
||||||
): Promise<{[key: string]: InstalledPluginDetails}> {
|
): Promise<{[key: string]: InstalledPluginDetails}> {
|
||||||
pluginsDir = expandTilde(pluginsDir);
|
|
||||||
if (!(await fs.pathExists(pluginsDir))) {
|
if (!(await fs.pathExists(pluginsDir))) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import path from 'path';
|
|||||||
import {homedir} from 'os';
|
import {homedir} from 'os';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import pFilter from 'p-filter';
|
import pFilter from 'p-filter';
|
||||||
import expandTilde from 'expand-tilde';
|
|
||||||
|
|
||||||
const flipperDataDir = path.join(homedir(), '.flipper');
|
const flipperDataDir = path.join(homedir(), '.flipper');
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ export async function getPluginSourceFolders(): Promise<string[]> {
|
|||||||
}
|
}
|
||||||
pluginFolders.push(path.resolve(__dirname, '..', '..', 'plugins', 'public'));
|
pluginFolders.push(path.resolve(__dirname, '..', '..', 'plugins', 'public'));
|
||||||
pluginFolders.push(path.resolve(__dirname, '..', '..', 'plugins', 'fb'));
|
pluginFolders.push(path.resolve(__dirname, '..', '..', 'plugins', 'fb'));
|
||||||
return pFilter(pluginFolders.map(expandTilde), (p) => fs.pathExists(p));
|
return pFilter(pluginFolders, (p) => fs.pathExists(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPluginInstallationDir(name: string) {
|
export function getPluginInstallationDir(name: string) {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* @flow strict-local
|
* @flow strict-local
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {bufferToBlob} from 'flipper';
|
|
||||||
import {RequiredParametersDialog} from './components';
|
import {RequiredParametersDialog} from './components';
|
||||||
import {
|
import {
|
||||||
removeBookmarkFromDB,
|
removeBookmarkFromDB,
|
||||||
@@ -73,14 +72,14 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
|||||||
draft.unshift(navigationEvent);
|
draft.unshift(navigationEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
const screenshot: Buffer = await client.device.screenshot();
|
const screenshot = await client.device.screenshot();
|
||||||
if (screenshot.byteLength === 0) {
|
if (screenshot.byteLength === 0) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'[navigation] Could not retrieve valid screenshot from the device.',
|
'[navigation] Could not retrieve valid screenshot from the device.',
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const blobURL = URL.createObjectURL(bufferToBlob(screenshot));
|
const blobURL = URL.createObjectURL(new Blob([screenshot.buffer]));
|
||||||
// this process is async, make sure we update the correct one..
|
// this process is async, make sure we update the correct one..
|
||||||
const navigationEventIndex = navigationEvents
|
const navigationEventIndex = navigationEvents
|
||||||
.get()
|
.get()
|
||||||
|
|||||||
@@ -2620,11 +2620,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#32ee4ebbe99b3daf9847a6d2097dc00b5de94f10"
|
resolved "https://registry.yarnpkg.com/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#32ee4ebbe99b3daf9847a6d2097dc00b5de94f10"
|
||||||
integrity sha512-HJNxpaOXuykCK4rQ6FOMxAA0NLFYsf7FiPFGmab0iQmtVBHSAfxzy3MRFpLTTDDWbV0yD2YsHOQvdu8yCqtCfw==
|
integrity sha512-HJNxpaOXuykCK4rQ6FOMxAA0NLFYsf7FiPFGmab0iQmtVBHSAfxzy3MRFpLTTDDWbV0yD2YsHOQvdu8yCqtCfw==
|
||||||
|
|
||||||
"@types/expand-tilde@^2.0.0":
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/expand-tilde/-/expand-tilde-2.0.0.tgz#c01a706675b9d60931bf6a7dc7dfa45d63540c97"
|
|
||||||
integrity sha512-17h/6MRHoetV2QVUVnUfrmaFCXNIFJ3uDJmXlklX2xDtlEb1W0OXLgP+qwND2Ibg/PtQfQi0vx19KGuPayjLiw==
|
|
||||||
|
|
||||||
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18":
|
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18":
|
||||||
version "4.17.19"
|
version "4.17.19"
|
||||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d"
|
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d"
|
||||||
|
|||||||
Reference in New Issue
Block a user