Add download file API

Summary: Changelog: Expose "downloadFile" API to Flipper plugins. Allow them to download files form the web to Flipper Server.

Reviewed By: mweststrate

Differential Revision: D32950685

fbshipit-source-id: 7b7f666e165ff7bf209230cdc96078272ede3616
This commit is contained in:
Andrey Goncharov
2021-12-10 06:34:37 -08:00
committed by Facebook GitHub Bot
parent 4cb80a452f
commit 92f0ed67f4
12 changed files with 271 additions and 10 deletions

View File

@@ -0,0 +1,72 @@
/**
* 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 {assertNever, DownloadFileUpdate} from 'flipper-common';
import {FlipperLib, DownloadFileResponse} from 'flipper-plugin';
import {RenderHost} from '../../RenderHost';
export const downloadFileFactory =
(renderHost: RenderHost): FlipperLib['remoteServerContext']['downloadFile'] =>
async (url, dest, {onProgressUpdate, ...options} = {}) => {
const downloadDescriptor = (await renderHost.flipperServer.exec(
'download-file-start',
url,
dest,
options,
// Casting to DownloadFileResponse to add `completed` field to `downloadDescriptor`.
)) as DownloadFileResponse;
let onProgressUpdateWrapped: (progressUpdate: DownloadFileUpdate) => void;
const completed = new Promise<number>((resolve, reject) => {
onProgressUpdateWrapped = (progressUpdate: DownloadFileUpdate) => {
if (progressUpdate.id === downloadDescriptor.id) {
const {status} = progressUpdate;
switch (status) {
case 'downloading': {
onProgressUpdate?.(progressUpdate);
break;
}
case 'success': {
resolve(progressUpdate.downloaded);
break;
}
case 'error': {
reject(
new Error(
`File download failed. Last message: ${JSON.stringify(
progressUpdate,
)}`,
),
);
break;
}
default: {
assertNever(status);
}
}
}
};
renderHost.flipperServer.on(
'download-file-update',
onProgressUpdateWrapped,
);
});
// eslint-disable-next-line promise/catch-or-return
completed.finally(() => {
renderHost.flipperServer.off(
'download-file-update',
onProgressUpdateWrapped,
);
});
downloadDescriptor.completed = completed;
return downloadDescriptor;
};

View File

@@ -11,21 +11,22 @@ import {
_setFlipperLibImplementation,
RemoteServerContext,
} from 'flipper-plugin';
import type {
import {
BufferEncoding,
ExecOptions,
Logger,
MkdirOptions,
} from 'flipper-common';
import type {Store} from '../reducers';
import createPaste from '../fb-stubs/createPaste';
import type BaseDevice from '../devices/BaseDevice';
import constants from '../fb-stubs/constants';
import {addNotification} from '../reducers/notifications';
import type {Store} from '../../reducers';
import createPaste from '../../fb-stubs/createPaste';
import type BaseDevice from '../../devices/BaseDevice';
import constants from '../../fb-stubs/constants';
import {addNotification} from '../../reducers/notifications';
import {deconstructPluginKey} from 'flipper-common';
import {DetailSidebarImpl} from '../sandy-chrome/DetailSidebarImpl';
import {RenderHost} from '../RenderHost';
import {setMenuEntries} from '../reducers/connections';
import {DetailSidebarImpl} from '../../sandy-chrome/DetailSidebarImpl';
import {RenderHost} from '../../RenderHost';
import {setMenuEntries} from '../../reducers/connections';
import {downloadFileFactory} from './downloadFile';
export function initializeFlipperLibImplementation(
renderHost: RenderHost,
@@ -102,6 +103,7 @@ export function initializeFlipperLibImplementation(
flags,
),
},
downloadFile: downloadFileFactory(renderHost),
},
});
}