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>;
|
||||
sendMetroCommand(command: string): Promise<void>;
|
||||
navigateToLocation(location: string): Promise<void>;
|
||||
screenshot(): Promise<Buffer>;
|
||||
screenshot(): Promise<Uint8Array>;
|
||||
}
|
||||
|
||||
export type DevicePluginPredicate = (device: Device) => boolean;
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
import {Button as AntButton, message} from 'antd';
|
||||
import React, {useState, useEffect, useCallback} from 'react';
|
||||
import path from 'path';
|
||||
import {capture, getCaptureLocation, getFileName} from '../utils/screenshot';
|
||||
import {CameraOutlined, VideoCameraOutlined} from '@ant-design/icons';
|
||||
import {useStore} from '../utils/useStore';
|
||||
import {getRenderHostInstance} from '../RenderHost';
|
||||
import {path} from 'flipper-plugin';
|
||||
|
||||
async function openFile(path: string) {
|
||||
getRenderHostInstance().flipperServer.exec('open-file', path);
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
import React, {Component} from 'react';
|
||||
import BaseDevice from '../devices/BaseDevice';
|
||||
import {Button, Glyph, colors} from '../ui';
|
||||
import path from 'path';
|
||||
import {getRenderHostInstance} from '../RenderHost';
|
||||
import {path} from 'flipper-plugin';
|
||||
|
||||
type OwnProps = {
|
||||
recordingFinished: (path: string | null) => void;
|
||||
|
||||
@@ -16,11 +16,9 @@ import {
|
||||
colors,
|
||||
Glyph,
|
||||
} from '../../ui';
|
||||
import React, {useState} from 'react';
|
||||
import {promises as fs} from 'fs';
|
||||
import {theme} from 'flipper-plugin';
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {getFlipperLib, theme} from 'flipper-plugin';
|
||||
import {getRenderHostInstance} from '../../RenderHost';
|
||||
import {useEffect} from 'react';
|
||||
|
||||
export const ConfigFieldContainer = styled(FlexRow)({
|
||||
paddingLeft: 10,
|
||||
@@ -75,8 +73,8 @@ export function FilePathConfigField(props: {
|
||||
useEffect(() => {
|
||||
(async function () {
|
||||
try {
|
||||
const stat = await fs.stat(value);
|
||||
setIsValid(props.isRegularFile !== stat.isDirectory());
|
||||
const stat = await getFlipperLib().remoteServerContext.fs.stat(value);
|
||||
setIsValid(props.isRegularFile !== stat.isDirectory);
|
||||
} catch (_) {
|
||||
setIsValid(false);
|
||||
}
|
||||
@@ -93,8 +91,9 @@ export function FilePathConfigField(props: {
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value);
|
||||
props.onChange(e.target.value);
|
||||
fs.stat(e.target.value)
|
||||
.then((stat) => stat.isDirectory())
|
||||
getFlipperLib()
|
||||
.remoteServerContext.fs.stat(e.target.value)
|
||||
.then((stat) => stat.isDirectory)
|
||||
.then((valid) => {
|
||||
if (valid !== isValid) {
|
||||
setIsValid(valid);
|
||||
|
||||
@@ -27,7 +27,6 @@ export {PluginClient, Props, KeyboardActions} from './plugin';
|
||||
export {default as Client} from './Client';
|
||||
export {reportUsage} from 'flipper-common';
|
||||
export {default as promiseTimeout} from './utils/promiseTimeout';
|
||||
export {bufferToBlob} from './utils/screenshot';
|
||||
export {getPluginKey} from './utils/pluginKey';
|
||||
export {Notification, Idler} from 'flipper-plugin';
|
||||
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 {Component, PureComponent} from 'react';
|
||||
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 Sidebar} from './ui/components/Sidebar';
|
||||
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);
|
||||
}
|
||||
|
||||
async screenshot(): Promise<Buffer> {
|
||||
async screenshot(): Promise<Uint8Array> {
|
||||
if (this.isArchived) {
|
||||
return Buffer.from([]);
|
||||
return new Uint8Array();
|
||||
}
|
||||
return Buffer.from(
|
||||
Base64.toUint8Array(
|
||||
await this.flipperServer.exec('device-take-screenshot', this.serial),
|
||||
),
|
||||
return Base64.toUint8Array(
|
||||
await this.flipperServer.exec('device-take-screenshot', this.serial),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ import dispatcher, {
|
||||
getLatestCompatibleVersionOfEachPlugin,
|
||||
} from '../plugins';
|
||||
import {BundledPluginDetails, InstalledPluginDetails} from 'flipper-common';
|
||||
import path from 'path';
|
||||
import {createRootReducer, State} from '../../reducers/index';
|
||||
import {getLogger} from 'flipper-common';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import TestPlugin from './TestPlugin';
|
||||
import {_SandyPluginDefinition} from 'flipper-plugin';
|
||||
import {getRenderHostInstance} from '../../RenderHost';
|
||||
import path from 'path';
|
||||
|
||||
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
|
||||
export {default as ContextMenu} from './components/ContextMenu';
|
||||
|
||||
// file
|
||||
export {FileListFile, FileListFiles} from './components/FileList';
|
||||
export {default as FileList} from './components/FileList';
|
||||
// utility elements
|
||||
export {default as View} from './components/View';
|
||||
export {default as Sidebar} from './components/Sidebar';
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import path from 'path';
|
||||
import {getLogger} from 'flipper-common';
|
||||
import {Store, MiddlewareAPI} from '../reducers';
|
||||
import {DeviceExport} from '../devices/BaseDevice';
|
||||
@@ -20,7 +19,6 @@ import {pluginKey} from '../utils/pluginKey';
|
||||
import {DevicePluginMap, ClientPluginMap} from '../plugin';
|
||||
import {default as BaseDevice} from '../devices/BaseDevice';
|
||||
import {default as ArchivedDevice} from '../devices/ArchivedDevice';
|
||||
import fs from 'fs-extra';
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
||||
import {TestIdler} from './Idler';
|
||||
@@ -33,7 +31,7 @@ import {deconstructClientId} from 'flipper-common';
|
||||
import {processMessageQueue} from './messageQueue';
|
||||
import {getPluginTitle} from './pluginUtils';
|
||||
import {capture} from './screenshot';
|
||||
import {Dialog, Idler} from 'flipper-plugin';
|
||||
import {Dialog, getFlipperLib, Idler, path} from 'flipper-plugin';
|
||||
import {ClientQuery} from 'flipper-common';
|
||||
import ShareSheetExportUrl from '../chrome/ShareSheetExportUrl';
|
||||
import ShareSheetExportFile from '../chrome/ShareSheetExportFile';
|
||||
@@ -521,7 +519,10 @@ export const exportStoreToFile = (
|
||||
}> => {
|
||||
return exportStore(store, includeSupportDetails, idler, statusUpdate).then(
|
||||
async ({serializedString, fetchMetaDataErrors}) => {
|
||||
await fs.writeFile(exportFilePath, serializedString);
|
||||
await getFlipperLib().remoteServerContext.fs.writeFile(
|
||||
exportFilePath,
|
||||
serializedString,
|
||||
);
|
||||
store.dispatch(resetSupportFormV2State());
|
||||
return {fetchMetaDataErrors};
|
||||
},
|
||||
@@ -584,17 +585,17 @@ 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] importFileToStore for file ${file} failed:`,
|
||||
err,
|
||||
);
|
||||
return;
|
||||
}
|
||||
export const importFileToStore = async (file: string, store: Store) => {
|
||||
try {
|
||||
const data = await getFlipperLib().remoteServerContext.fs.readFile(file);
|
||||
importDataToStore(file, data, store);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`[exportData] importFileToStore for file ${file} failed:`,
|
||||
err,
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
export function canOpenDialog() {
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import util from 'util';
|
||||
import {exec as execImport} from 'child_process';
|
||||
import {getFlipperLib} from 'flipper-plugin';
|
||||
|
||||
const cmd = 'klist --json';
|
||||
const endWith = '@THEFACEBOOK.COM';
|
||||
|
||||
export async function isFBEmployee(): Promise<boolean> {
|
||||
return util
|
||||
.promisify(execImport)(cmd)
|
||||
return getFlipperLib()
|
||||
.remoteServerContext.childProcess.exec(cmd)
|
||||
.then(
|
||||
(stdobj: {stderr: string; stdout: string}) => {
|
||||
const principal = String(JSON.parse(stdobj.stdout).principal);
|
||||
|
||||
@@ -7,17 +7,15 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import BaseDevice from '../devices/BaseDevice';
|
||||
import {reportPlatformFailures} from 'flipper-common';
|
||||
import expandTilde from 'expand-tilde';
|
||||
import {getRenderHostInstance} from '../RenderHost';
|
||||
import {getFlipperLib, path} from 'flipper-plugin';
|
||||
|
||||
export function getCaptureLocation() {
|
||||
return expandTilde(
|
||||
return (
|
||||
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'));
|
||||
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',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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/detect-port": "^1.3.1",
|
||||
"@types/electron-devtools-installer": "^2.2.0",
|
||||
"@types/expand-tilde": "^2.0.0",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/fb-watchman": "^2.0.1",
|
||||
"@types/form-data": "^2.2.1",
|
||||
@@ -150,7 +149,6 @@
|
||||
"eslint-plugin-react": "^7.27.1",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"eslint-plugin-rulesdir": "^0.2.1",
|
||||
"expand-tilde": "^2.0.2",
|
||||
"express": "^4.15.2",
|
||||
"fb-watchman": "^2.0.1",
|
||||
"flipper-babel-transformer": "0.0.0",
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"decompress": "^4.2.1",
|
||||
"decompress-targz": "^4.1.1",
|
||||
"decompress-unzip": "^4.0.1",
|
||||
"expand-tilde": "^2.0.2",
|
||||
"flipper-common": "^0.0.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"live-plugin-manager": "^0.17.0",
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import expandTilde from 'expand-tilde';
|
||||
import {getPluginSourceFolders} from './pluginPaths';
|
||||
import pmap from 'p-map';
|
||||
import pfilter from 'p-filter';
|
||||
@@ -49,7 +48,6 @@ export async function getSourcePlugins(): Promise<InstalledPluginDetails[]> {
|
||||
async function entryPointForPluginFolder(
|
||||
pluginsDir: string,
|
||||
): Promise<{[key: string]: InstalledPluginDetails}> {
|
||||
pluginsDir = expandTilde(pluginsDir);
|
||||
if (!(await fs.pathExists(pluginsDir))) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import path from 'path';
|
||||
import {homedir} from 'os';
|
||||
import fs from 'fs-extra';
|
||||
import pFilter from 'p-filter';
|
||||
import expandTilde from 'expand-tilde';
|
||||
|
||||
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', 'fb'));
|
||||
return pFilter(pluginFolders.map(expandTilde), (p) => fs.pathExists(p));
|
||||
return pFilter(pluginFolders, (p) => fs.pathExists(p));
|
||||
}
|
||||
|
||||
export function getPluginInstallationDir(name: string) {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import {bufferToBlob} from 'flipper';
|
||||
import {RequiredParametersDialog} from './components';
|
||||
import {
|
||||
removeBookmarkFromDB,
|
||||
@@ -73,14 +72,14 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
||||
draft.unshift(navigationEvent);
|
||||
});
|
||||
|
||||
const screenshot: Buffer = await client.device.screenshot();
|
||||
const screenshot = await client.device.screenshot();
|
||||
if (screenshot.byteLength === 0) {
|
||||
console.warn(
|
||||
'[navigation] Could not retrieve valid screenshot from the device.',
|
||||
);
|
||||
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..
|
||||
const navigationEventIndex = navigationEvents
|
||||
.get()
|
||||
|
||||
@@ -2620,11 +2620,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#32ee4ebbe99b3daf9847a6d2097dc00b5de94f10"
|
||||
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":
|
||||
version "4.17.19"
|
||||
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