Remove plugin bundling
Summary: Remove the notion of bundled plugins Reviewed By: lblasa Differential Revision: D39308888 fbshipit-source-id: aa88ddbf2801ad1da95f89e4c761259b697b0d66
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f835e07c46
commit
650ff4bcfb
@@ -73,21 +73,12 @@ export type PluginType = 'client' | 'device';
|
|||||||
export type DeviceSpec = 'KaiOS';
|
export type DeviceSpec = 'KaiOS';
|
||||||
|
|
||||||
export interface ConcretePluginDetails extends PluginDetails {
|
export interface ConcretePluginDetails extends PluginDetails {
|
||||||
// Determines whether the plugin is a part of the Flipper JS bundle.
|
|
||||||
isBundled: boolean;
|
|
||||||
// Determines whether the plugin is physically available for activation in Flipper.
|
// Determines whether the plugin is physically available for activation in Flipper.
|
||||||
isActivatable: boolean;
|
isActivatable: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describes plugin which is a part of the Flipper JS bundle.
|
|
||||||
export interface BundledPluginDetails extends ConcretePluginDetails {
|
|
||||||
isBundled: true;
|
|
||||||
isActivatable: true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes plugin installed on the disk.
|
// Describes plugin installed on the disk.
|
||||||
export interface InstalledPluginDetails extends ConcretePluginDetails {
|
export interface InstalledPluginDetails extends ConcretePluginDetails {
|
||||||
isBundled: false;
|
|
||||||
isActivatable: true;
|
isActivatable: true;
|
||||||
dir: string;
|
dir: string;
|
||||||
entry: string;
|
entry: string;
|
||||||
@@ -95,14 +86,11 @@ export interface InstalledPluginDetails extends ConcretePluginDetails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Describes plugin physically available for activation in Flipper.
|
// Describes plugin physically available for activation in Flipper.
|
||||||
export type ActivatablePluginDetails =
|
export type ActivatablePluginDetails = InstalledPluginDetails;
|
||||||
| BundledPluginDetails
|
|
||||||
| InstalledPluginDetails;
|
|
||||||
|
|
||||||
// Describes plugin available for downloading. Until downloaded to the disk it is not available for activation in Flipper.
|
// Describes plugin available for downloading. Until downloaded to the disk it is not available for activation in Flipper.
|
||||||
export interface DownloadablePluginDetails extends ConcretePluginDetails {
|
export interface DownloadablePluginDetails extends ConcretePluginDetails {
|
||||||
isActivatable: false;
|
isActivatable: false;
|
||||||
isBundled: false;
|
|
||||||
downloadUrl: string;
|
downloadUrl: string;
|
||||||
lastUpdated: Date;
|
lastUpdated: Date;
|
||||||
// Indicates whether plugin should be enabled by default for new users
|
// Indicates whether plugin should be enabled by default for new users
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ import {
|
|||||||
FlipperServerEvents,
|
FlipperServerEvents,
|
||||||
} from './server-types';
|
} from './server-types';
|
||||||
|
|
||||||
export type ServerAddOnStartDetails =
|
export type ServerAddOnStartDetails = {path: string};
|
||||||
| {isBundled: true; path?: never}
|
|
||||||
| {isBundled?: false; path: string};
|
|
||||||
|
|
||||||
export interface ServerAddOnControls {
|
export interface ServerAddOnControls {
|
||||||
start: FlipperServerCommands['plugins-server-add-on-start'];
|
start: FlipperServerCommands['plugins-server-add-on-start'];
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
createRequirePluginFunction,
|
createRequirePluginFunction,
|
||||||
getLatestCompatibleVersionOfEachPlugin,
|
getLatestCompatibleVersionOfEachPlugin,
|
||||||
} from '../plugins';
|
} from '../plugins';
|
||||||
import {BundledPluginDetails, InstalledPluginDetails} from 'flipper-common';
|
import {InstalledPluginDetails} from 'flipper-common';
|
||||||
import {_SandyPluginDefinition} from 'flipper-plugin-core';
|
import {_SandyPluginDefinition} from 'flipper-plugin-core';
|
||||||
import {getRenderHostInstance} from '../RenderHost';
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
|
||||||
@@ -31,16 +31,9 @@ const sampleInstalledPluginDetails: InstalledPluginDetails = {
|
|||||||
title: 'Sample',
|
title: 'Sample',
|
||||||
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample',
|
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample',
|
||||||
entry: 'this/path/does not/exist',
|
entry: 'this/path/does not/exist',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const sampleBundledPluginDetails: BundledPluginDetails = {
|
|
||||||
...sampleInstalledPluginDetails,
|
|
||||||
id: 'SampleBundled',
|
|
||||||
isBundled: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
loadDynamicPluginsMock = getRenderHostInstance().flipperServer.exec =
|
loadDynamicPluginsMock = getRenderHostInstance().flipperServer.exec =
|
||||||
jest.fn();
|
jest.fn();
|
||||||
@@ -66,14 +59,14 @@ test('checkDisabled', () => {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
disabled({
|
disabled({
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
name: 'other Name',
|
name: 'other Name',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
}),
|
}),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
disabled({
|
disabled({
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
name: disabledPlugin,
|
name: disabledPlugin,
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
}),
|
}),
|
||||||
@@ -86,7 +79,7 @@ test('checkDisabled', () => {
|
|||||||
test('checkGK for plugin without GK', () => {
|
test('checkGK for plugin without GK', () => {
|
||||||
expect(
|
expect(
|
||||||
checkGK([])({
|
checkGK([])({
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
name: 'pluginID',
|
name: 'pluginID',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
}),
|
}),
|
||||||
@@ -96,7 +89,7 @@ test('checkGK for plugin without GK', () => {
|
|||||||
test('checkGK for passing plugin', () => {
|
test('checkGK for passing plugin', () => {
|
||||||
expect(
|
expect(
|
||||||
checkGK([])({
|
checkGK([])({
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
name: 'pluginID',
|
name: 'pluginID',
|
||||||
gatekeeper: 'TEST_PASSING_GK',
|
gatekeeper: 'TEST_PASSING_GK',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
@@ -108,7 +101,7 @@ test('checkGK for failing plugin', () => {
|
|||||||
const gatekeepedPlugins: InstalledPluginDetails[] = [];
|
const gatekeepedPlugins: InstalledPluginDetails[] = [];
|
||||||
const name = 'pluginID';
|
const name = 'pluginID';
|
||||||
const plugins = checkGK(gatekeepedPlugins)({
|
const plugins = checkGK(gatekeepedPlugins)({
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
name,
|
name,
|
||||||
gatekeeper: 'TEST_FAILING_GK',
|
gatekeeper: 'TEST_FAILING_GK',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
@@ -134,15 +127,15 @@ test('requirePlugin returns null for invalid requires', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('newest version of each plugin is used', () => {
|
test('newest version of each plugin is used', () => {
|
||||||
const bundledPlugins: BundledPluginDetails[] = [
|
const sourcePlugins: InstalledPluginDetails[] = [
|
||||||
{
|
{
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
id: 'TestPlugin1',
|
id: 'TestPlugin1',
|
||||||
name: 'flipper-plugin-test1',
|
name: 'flipper-plugin-test1',
|
||||||
version: '0.1.0',
|
version: '0.1.0',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
id: 'TestPlugin2',
|
id: 'TestPlugin2',
|
||||||
name: 'flipper-plugin-test2',
|
name: 'flipper-plugin-test2',
|
||||||
version: '0.1.0-alpha.201',
|
version: '0.1.0-alpha.201',
|
||||||
@@ -167,7 +160,7 @@ test('newest version of each plugin is used', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
const filteredPlugins = getLatestCompatibleVersionOfEachPlugin(
|
const filteredPlugins = getLatestCompatibleVersionOfEachPlugin(
|
||||||
[...bundledPlugins, ...installedPlugins],
|
[...sourcePlugins, ...installedPlugins],
|
||||||
'0.1.0',
|
'0.1.0',
|
||||||
);
|
);
|
||||||
expect(filteredPlugins).toHaveLength(2);
|
expect(filteredPlugins).toHaveLength(2);
|
||||||
@@ -180,7 +173,7 @@ test('newest version of each plugin is used', () => {
|
|||||||
entry: './test/index.js',
|
entry: './test/index.js',
|
||||||
});
|
});
|
||||||
expect(filteredPlugins).toContainEqual({
|
expect(filteredPlugins).toContainEqual({
|
||||||
...sampleBundledPluginDetails,
|
...sampleInstalledPluginDetails,
|
||||||
id: 'TestPlugin2',
|
id: 'TestPlugin2',
|
||||||
name: 'flipper-plugin-test2',
|
name: 'flipper-plugin-test2',
|
||||||
version: '0.1.0-alpha.201',
|
version: '0.1.0-alpha.201',
|
||||||
|
|||||||
@@ -12,11 +12,7 @@ import {
|
|||||||
tryCatchReportPluginFailuresAsync,
|
tryCatchReportPluginFailuresAsync,
|
||||||
notNull,
|
notNull,
|
||||||
} from 'flipper-common';
|
} from 'flipper-common';
|
||||||
import {
|
import {ActivatablePluginDetails, ConcretePluginDetails} from 'flipper-common';
|
||||||
ActivatablePluginDetails,
|
|
||||||
BundledPluginDetails,
|
|
||||||
ConcretePluginDetails,
|
|
||||||
} from 'flipper-common';
|
|
||||||
import {reportUsage} from 'flipper-common';
|
import {reportUsage} from 'flipper-common';
|
||||||
import {_SandyPluginDefinition} from 'flipper-plugin-core';
|
import {_SandyPluginDefinition} from 'flipper-plugin-core';
|
||||||
import isPluginCompatible from './utils/isPluginCompatible';
|
import isPluginCompatible from './utils/isPluginCompatible';
|
||||||
@@ -28,10 +24,7 @@ export abstract class AbstractPluginInitializer {
|
|||||||
protected gatekeepedPlugins: Array<ActivatablePluginDetails> = [];
|
protected gatekeepedPlugins: Array<ActivatablePluginDetails> = [];
|
||||||
protected disabledPlugins: Array<ActivatablePluginDetails> = [];
|
protected disabledPlugins: Array<ActivatablePluginDetails> = [];
|
||||||
protected failedPlugins: Array<[ActivatablePluginDetails, string]> = [];
|
protected failedPlugins: Array<[ActivatablePluginDetails, string]> = [];
|
||||||
protected bundledPlugins: Array<BundledPluginDetails> = [];
|
protected loadedPlugins: Array<InstalledPluginDetails> = [];
|
||||||
protected loadedPlugins: Array<
|
|
||||||
BundledPluginDetails | InstalledPluginDetails
|
|
||||||
> = [];
|
|
||||||
protected _initialPlugins: _SandyPluginDefinition[] = [];
|
protected _initialPlugins: _SandyPluginDefinition[] = [];
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
@@ -69,7 +62,7 @@ export abstract class AbstractPluginInitializer {
|
|||||||
}
|
}
|
||||||
protected async loadAllLocalVersions(
|
protected async loadAllLocalVersions(
|
||||||
uninstalledPluginNames: Set<string>,
|
uninstalledPluginNames: Set<string>,
|
||||||
): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> {
|
): Promise<InstalledPluginDetails[]> {
|
||||||
const allLocalVersions = [...(await getDynamicPlugins())].filter(
|
const allLocalVersions = [...(await getDynamicPlugins())].filter(
|
||||||
(p) => !uninstalledPluginNames.has(p.name),
|
(p) => !uninstalledPluginNames.has(p.name),
|
||||||
);
|
);
|
||||||
@@ -77,7 +70,7 @@ export abstract class AbstractPluginInitializer {
|
|||||||
return allLocalVersions;
|
return allLocalVersions;
|
||||||
}
|
}
|
||||||
protected async filterAllLocalVersions(
|
protected async filterAllLocalVersions(
|
||||||
allLocalVersions: (BundledPluginDetails | InstalledPluginDetails)[],
|
allLocalVersions: InstalledPluginDetails[],
|
||||||
): Promise<ActivatablePluginDetails[]> {
|
): Promise<ActivatablePluginDetails[]> {
|
||||||
const flipperVersion = await this.getFlipperVersion();
|
const flipperVersion = await this.getFlipperVersion();
|
||||||
const loadedPlugins = getLatestCompatibleVersionOfEachPlugin(
|
const loadedPlugins = getLatestCompatibleVersionOfEachPlugin(
|
||||||
|
|||||||
@@ -33,13 +33,6 @@ export function isPluginVersionMoreRecent(
|
|||||||
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
|
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
|
||||||
versionDetails.isBundled
|
|
||||||
) {
|
|
||||||
// prefer bundled versions
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
||||||
versionDetails.isActivatable &&
|
versionDetails.isActivatable &&
|
||||||
|
|||||||
@@ -547,9 +547,7 @@ export abstract class BasePluginInstance {
|
|||||||
this.serverAddOnControls
|
this.serverAddOnControls
|
||||||
.start(
|
.start(
|
||||||
pluginDetails.name,
|
pluginDetails.name,
|
||||||
pluginDetails.isBundled
|
{path: pluginDetails.serverAddOnEntry!},
|
||||||
? {isBundled: true}
|
|
||||||
: {path: pluginDetails.serverAddOnEntry!},
|
|
||||||
this.serverAddOnOwner,
|
this.serverAddOnOwner,
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|||||||
@@ -128,10 +128,6 @@ export class SandyPluginDefinition {
|
|||||||
return this.details.version;
|
return this.details.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isBundled() {
|
|
||||||
return this.details.isBundled;
|
|
||||||
}
|
|
||||||
|
|
||||||
get keyboardActions() {
|
get keyboardActions() {
|
||||||
// TODO: T68882551 support keyboard actions
|
// TODO: T68882551 support keyboard actions
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -7,11 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {fsConstants, InstalledPluginDetails} from 'flipper-common';
|
||||||
BundledPluginDetails,
|
|
||||||
fsConstants,
|
|
||||||
InstalledPluginDetails,
|
|
||||||
} from 'flipper-common';
|
|
||||||
|
|
||||||
import {FlipperServer, FlipperServerCommands} from 'flipper-common';
|
import {FlipperServer, FlipperServerCommands} from 'flipper-common';
|
||||||
import {Device} from '../plugin/DevicePlugin';
|
import {Device} from '../plugin/DevicePlugin';
|
||||||
@@ -115,7 +111,6 @@ export function createMockPluginDetails(
|
|||||||
name: 'TestPlugin',
|
name: 'TestPlugin',
|
||||||
specVersion: 0,
|
specVersion: 0,
|
||||||
entry: '',
|
entry: '',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
main: '',
|
main: '',
|
||||||
source: '',
|
source: '',
|
||||||
@@ -166,24 +161,6 @@ export function createTestDevicePlugin(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createMockBundledPluginDetails(
|
|
||||||
details?: Partial<BundledPluginDetails>,
|
|
||||||
): BundledPluginDetails {
|
|
||||||
return {
|
|
||||||
id: 'TestBundledPlugin',
|
|
||||||
name: 'TestBundledPlugin',
|
|
||||||
specVersion: 0,
|
|
||||||
pluginType: 'client',
|
|
||||||
isBundled: true,
|
|
||||||
isActivatable: true,
|
|
||||||
main: '',
|
|
||||||
source: '',
|
|
||||||
title: 'Testing Bundled Plugin',
|
|
||||||
version: '',
|
|
||||||
...details,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createFlipperServerMock(
|
export function createFlipperServerMock(
|
||||||
overrides?: Partial<FlipperServerCommands>,
|
overrides?: Partial<FlipperServerCommands>,
|
||||||
): FlipperServer {
|
): FlipperServer {
|
||||||
|
|||||||
@@ -484,6 +484,4 @@ export const createMockFlipperLib = TestUtils.createMockFlipperLib;
|
|||||||
export const createMockPluginDetails = TestUtils.createMockPluginDetails;
|
export const createMockPluginDetails = TestUtils.createMockPluginDetails;
|
||||||
export const createTestPlugin = TestUtils.createTestPlugin;
|
export const createTestPlugin = TestUtils.createTestPlugin;
|
||||||
export const createTestDevicePlugin = TestUtils.createTestDevicePlugin;
|
export const createTestDevicePlugin = TestUtils.createTestDevicePlugin;
|
||||||
export const createMockBundledPluginDetails =
|
|
||||||
TestUtils.createMockBundledPluginDetails;
|
|
||||||
export const createFlipperServerMock = TestUtils.createFlipperServerMock;
|
export const createFlipperServerMock = TestUtils.createFlipperServerMock;
|
||||||
|
|||||||
@@ -7,11 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {ActivatablePluginDetails, InstalledPluginDetails} from 'flipper-common';
|
||||||
ActivatablePluginDetails,
|
|
||||||
BundledPluginDetails,
|
|
||||||
InstalledPluginDetails,
|
|
||||||
} from 'flipper-common';
|
|
||||||
import {
|
import {
|
||||||
AbstractPluginInitializer,
|
AbstractPluginInitializer,
|
||||||
getRenderHostInstance,
|
getRenderHostInstance,
|
||||||
@@ -31,7 +27,7 @@ export class HeadlessPluginInitializer extends AbstractPluginInitializer {
|
|||||||
pluginDetails: ActivatablePluginDetails,
|
pluginDetails: ActivatablePluginDetails,
|
||||||
): Promise<_SandyPluginDefinition> {
|
): Promise<_SandyPluginDefinition> {
|
||||||
const plugin = await getRenderHostInstance().requirePlugin(
|
const plugin = await getRenderHostInstance().requirePlugin(
|
||||||
(pluginDetails as InstalledPluginDetails).entry,
|
pluginDetails.entry,
|
||||||
);
|
);
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -42,7 +38,7 @@ export class HeadlessPluginInitializer extends AbstractPluginInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async filterAllLocalVersions(
|
protected async filterAllLocalVersions(
|
||||||
allLocalVersions: (BundledPluginDetails | InstalledPluginDetails)[],
|
allLocalVersions: InstalledPluginDetails[],
|
||||||
): Promise<ActivatablePluginDetails[]> {
|
): Promise<ActivatablePluginDetails[]> {
|
||||||
const pluginsToLoad = await super.filterAllLocalVersions(allLocalVersions);
|
const pluginsToLoad = await super.filterAllLocalVersions(allLocalVersions);
|
||||||
return pluginsToLoad
|
return pluginsToLoad
|
||||||
|
|||||||
@@ -12,12 +12,7 @@ import {loadServerAddOn} from '../loadServerAddOn';
|
|||||||
import {PluginManager} from '../PluginManager';
|
import {PluginManager} from '../PluginManager';
|
||||||
import {ServerAddOnManager} from '../ServerAddManager';
|
import {ServerAddOnManager} from '../ServerAddManager';
|
||||||
import {ServerAddOnModuleToDesktopConnection} from '../ServerAddOnModuleToDesktopConnection';
|
import {ServerAddOnModuleToDesktopConnection} from '../ServerAddOnModuleToDesktopConnection';
|
||||||
import {
|
import {detailsInstalled, initialOwner, pluginName} from './utils';
|
||||||
detailsBundled,
|
|
||||||
detailsInstalled,
|
|
||||||
initialOwner,
|
|
||||||
pluginName,
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
jest.mock('../loadServerAddOn');
|
jest.mock('../loadServerAddOn');
|
||||||
const loadServerAddOnMock = loadServerAddOn as jest.Mock;
|
const loadServerAddOnMock = loadServerAddOn as jest.Mock;
|
||||||
@@ -70,10 +65,7 @@ describe('PluginManager', () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
describe.each([
|
describe.each([['installed', detailsInstalled]])('%s', (_name, details) => {
|
||||||
['bundled', detailsBundled],
|
|
||||||
['installed', detailsInstalled],
|
|
||||||
])('%s', (_name, details) => {
|
|
||||||
test('stops the add-on when the initial owner is removed', async () => {
|
test('stops the add-on when the initial owner is removed', async () => {
|
||||||
const {pluginManager, addOnCleanupMock} = await startServerAddOn(
|
const {pluginManager, addOnCleanupMock} = await startServerAddOn(
|
||||||
details,
|
details,
|
||||||
|
|||||||
@@ -11,12 +11,7 @@ import {ServerAddOnStartDetails, createControlledPromise} from 'flipper-common';
|
|||||||
import {loadServerAddOn} from '../loadServerAddOn';
|
import {loadServerAddOn} from '../loadServerAddOn';
|
||||||
import {ServerAddOn} from '../ServerAddOn';
|
import {ServerAddOn} from '../ServerAddOn';
|
||||||
import {ServerAddOnModuleToDesktopConnection} from '../ServerAddOnModuleToDesktopConnection';
|
import {ServerAddOnModuleToDesktopConnection} from '../ServerAddOnModuleToDesktopConnection';
|
||||||
import {
|
import {detailsInstalled, initialOwner, pluginName} from './utils';
|
||||||
detailsBundled,
|
|
||||||
detailsInstalled,
|
|
||||||
initialOwner,
|
|
||||||
pluginName,
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
jest.mock('../loadServerAddOn');
|
jest.mock('../loadServerAddOn');
|
||||||
const loadServerAddOnMock = loadServerAddOn as jest.Mock;
|
const loadServerAddOnMock = loadServerAddOn as jest.Mock;
|
||||||
@@ -67,10 +62,7 @@ describe('ServerAddOn', () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
describe.each([
|
describe.each([['installed', detailsInstalled]])('%s', (_name, details) => {
|
||||||
['bundled', detailsBundled],
|
|
||||||
['installed', detailsInstalled],
|
|
||||||
])('%s', (_name, details) => {
|
|
||||||
test('stops the add-on when the initial owner is removed', async () => {
|
test('stops the add-on when the initial owner is removed', async () => {
|
||||||
const {serverAddOn, addOnCleanupMock} = await startServerAddOn(details);
|
const {serverAddOn, addOnCleanupMock} = await startServerAddOn(details);
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ import {ServerAddOnStartDetails} from 'flipper-common';
|
|||||||
|
|
||||||
export const pluginName = 'lightSaber';
|
export const pluginName = 'lightSaber';
|
||||||
export const initialOwner = 'yoda';
|
export const initialOwner = 'yoda';
|
||||||
export const detailsBundled: ServerAddOnStartDetails = {
|
|
||||||
isBundled: true,
|
|
||||||
};
|
|
||||||
export const detailsInstalled: ServerAddOnStartDetails = {
|
export const detailsInstalled: ServerAddOnStartDetails = {
|
||||||
path: '/dagobar/',
|
path: '/dagobar/',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,13 +26,6 @@ export function isPluginVersionMoreRecent(
|
|||||||
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
|
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
|
||||||
versionDetails.isBundled
|
|
||||||
) {
|
|
||||||
// prefer bundled versions
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
||||||
versionDetails.isActivatable &&
|
versionDetails.isActivatable &&
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ Object {
|
|||||||
|
|
||||||
exports[`can create a Fake flipper with legacy wrapper 2`] = `
|
exports[`can create a Fake flipper with legacy wrapper 2`] = `
|
||||||
Object {
|
Object {
|
||||||
"bundledPlugins": Map {},
|
|
||||||
"clientPlugins": Map {
|
"clientPlugins": Map {
|
||||||
"TestPlugin" => SandyPluginDefinition {
|
"TestPlugin" => SandyPluginDefinition {
|
||||||
"details": Object {
|
"details": Object {
|
||||||
@@ -63,7 +62,6 @@ Object {
|
|||||||
"entry": "./test/index.js",
|
"entry": "./test/index.js",
|
||||||
"id": "TestPlugin",
|
"id": "TestPlugin",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-hello",
|
"name": "flipper-plugin-hello",
|
||||||
"pluginType": "client",
|
"pluginType": "client",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import {Alert, Button} from 'antd';
|
import {Alert, Button} from 'antd';
|
||||||
import {BundledPluginDetails, DownloadablePluginDetails} from 'flipper-common';
|
import {DownloadablePluginDetails} from 'flipper-common';
|
||||||
import React, {useMemo} from 'react';
|
import React, {useMemo} from 'react';
|
||||||
import {useCallback} from 'react';
|
import {useCallback} from 'react';
|
||||||
import {useDispatch, useSelector} from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
@@ -86,16 +86,12 @@ function InstallButton({
|
|||||||
plugin,
|
plugin,
|
||||||
type = 'primary',
|
type = 'primary',
|
||||||
}: {
|
}: {
|
||||||
plugin: DownloadablePluginDetails | BundledPluginDetails;
|
plugin: DownloadablePluginDetails;
|
||||||
type: 'link' | 'primary';
|
type: 'link' | 'primary';
|
||||||
}) {
|
}) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const installPlugin = useCallback(() => {
|
const installPlugin = useCallback(() => {
|
||||||
if (plugin.isBundled) {
|
|
||||||
dispatch(loadPlugin({plugin, enable: true, notifyIfFailed: true}));
|
|
||||||
} else {
|
|
||||||
dispatch(startPluginDownload({plugin, startedByUser: true}));
|
dispatch(startPluginDownload({plugin, startedByUser: true}));
|
||||||
}
|
|
||||||
}, [plugin, dispatch]);
|
}, [plugin, dispatch]);
|
||||||
const downloads = useSelector(getPluginDownloadStatusMap);
|
const downloads = useSelector(getPluginDownloadStatusMap);
|
||||||
const downloadStatus = useMemo(
|
const downloadStatus = useMemo(
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class PluginDebugger extends Component<Props> {
|
|||||||
getRows(): Array<TableBodyRow> {
|
getRows(): Array<TableBodyRow> {
|
||||||
const rows: Array<TableBodyRow> = [];
|
const rows: Array<TableBodyRow> = [];
|
||||||
|
|
||||||
const externalPluginPath = (p: any) => (p.isBundled ? 'bundled' : p.entry);
|
const externalPluginPath = (p: any) => p.entry;
|
||||||
|
|
||||||
this.props.gatekeepedPlugins.forEach((plugin) =>
|
this.props.gatekeepedPlugins.forEach((plugin) =>
|
||||||
rows.push(
|
rows.push(
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ const samplePluginDetails1: UpdatablePluginDetails = {
|
|||||||
id: 'Hello',
|
id: 'Hello',
|
||||||
title: 'Hello',
|
title: 'Hello',
|
||||||
description: 'World?',
|
description: 'World?',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
updateStatus: {
|
updateStatus: {
|
||||||
kind: 'not-installed',
|
kind: 'not-installed',
|
||||||
@@ -63,7 +62,6 @@ const samplePluginDetails2: UpdatablePluginDetails = {
|
|||||||
id: 'World',
|
id: 'World',
|
||||||
title: 'World',
|
title: 'World',
|
||||||
description: 'Hello?',
|
description: 'Hello?',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
updateStatus: {
|
updateStatus: {
|
||||||
kind: 'not-installed',
|
kind: 'not-installed',
|
||||||
|
|||||||
@@ -168,34 +168,6 @@ test('uninstall plugin', async () => {
|
|||||||
expect(mockClient.sandyPluginStates.has('plugin1')).toBeFalsy();
|
expect(mockClient.sandyPluginStates.has('plugin1')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('uninstall bundled plugin', async () => {
|
|
||||||
const pluginDetails = TestUtils.createMockBundledPluginDetails({
|
|
||||||
id: 'bundled-plugin',
|
|
||||||
name: 'flipper-bundled-plugin',
|
|
||||||
version: '0.43.0',
|
|
||||||
});
|
|
||||||
const pluginDefinition = new SandyPluginDefinition(pluginDetails, TestPlugin);
|
|
||||||
mockedRequirePlugin.mockReturnValue(Promise.resolve(pluginDefinition));
|
|
||||||
mockFlipper.dispatch(
|
|
||||||
loadPlugin({plugin: pluginDetails, enable: true, notifyIfFailed: false}),
|
|
||||||
);
|
|
||||||
mockFlipper.dispatch(uninstallPlugin({plugin: pluginDefinition}));
|
|
||||||
|
|
||||||
await awaitPluginCommandQueueEmpty(mockFlipper.store);
|
|
||||||
expect(
|
|
||||||
mockFlipper.getState().plugins.clientPlugins.has('bundled-plugin'),
|
|
||||||
).toBeFalsy();
|
|
||||||
expect(
|
|
||||||
mockFlipper.getState().plugins.loadedPlugins.has('bundled-plugin'),
|
|
||||||
).toBeFalsy();
|
|
||||||
expect(
|
|
||||||
mockFlipper
|
|
||||||
.getState()
|
|
||||||
.plugins.uninstalledPluginNames.has('flipper-bundled-plugin'),
|
|
||||||
).toBeTruthy();
|
|
||||||
expect(mockClient.sandyPluginStates.has('bundled-plugin')).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('star plugin', async () => {
|
test('star plugin', async () => {
|
||||||
mockFlipper.dispatch(
|
mockFlipper.dispatch(
|
||||||
loadPlugin({plugin: pluginDetails1, enable: false, notifyIfFailed: false}),
|
loadPlugin({plugin: pluginDetails1, enable: false, notifyIfFailed: false}),
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ const sampleInstalledPluginDetails: InstalledPluginDetails = {
|
|||||||
title: 'Sample',
|
title: 'Sample',
|
||||||
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample',
|
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample',
|
||||||
entry: 'this/path/does not/exist',
|
entry: 'this/path/does not/exist',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,7 +111,6 @@ test('requirePluginInternal loads valid Sandy plugin', async () => {
|
|||||||
expect(plugin.details).toMatchObject({
|
expect(plugin.details).toMatchObject({
|
||||||
flipperSDKVersion: '0.0.0',
|
flipperSDKVersion: '0.0.0',
|
||||||
id: 'Sample',
|
id: 'Sample',
|
||||||
isBundled: false,
|
|
||||||
main: 'dist/bundle.js',
|
main: 'dist/bundle.js',
|
||||||
name: 'pluginID',
|
name: 'pluginID',
|
||||||
source: 'src/index.js',
|
source: 'src/index.js',
|
||||||
@@ -170,7 +168,6 @@ test('requirePluginInternal loads valid Sandy Device plugin', async () => {
|
|||||||
expect(plugin.details).toMatchObject({
|
expect(plugin.details).toMatchObject({
|
||||||
flipperSDKVersion: '0.0.0',
|
flipperSDKVersion: '0.0.0',
|
||||||
id: 'Sample',
|
id: 'Sample',
|
||||||
isBundled: false,
|
|
||||||
main: 'dist/bundle.js',
|
main: 'dist/bundle.js',
|
||||||
name: 'pluginID',
|
name: 'pluginID',
|
||||||
source: 'src/index.js',
|
source: 'src/index.js',
|
||||||
|
|||||||
@@ -367,11 +367,6 @@ async function verifyPluginStatus(
|
|||||||
return [false, status];
|
return [false, status];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'bundle_installable': {
|
|
||||||
// For convenience, don't ask user to install bundled plugins, handle it directly
|
|
||||||
await installBundledPlugin(store, pluginId, title);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'marketplace_installable': {
|
case 'marketplace_installable': {
|
||||||
if (!(await installMarketPlacePlugin(store, pluginId, title))) {
|
if (!(await installMarketPlacePlugin(store, pluginId, title))) {
|
||||||
return [false, status];
|
return [false, status];
|
||||||
@@ -384,30 +379,6 @@ async function verifyPluginStatus(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function installBundledPlugin(
|
|
||||||
store: Store,
|
|
||||||
pluginId: string,
|
|
||||||
title: string,
|
|
||||||
) {
|
|
||||||
const plugin = store.getState().plugins.bundledPlugins.get(pluginId);
|
|
||||||
if (!plugin || !plugin.isBundled) {
|
|
||||||
throw new Error(`Failed to find bundled plugin '${pluginId}'`);
|
|
||||||
}
|
|
||||||
const loadingDialog = Dialog.loading({
|
|
||||||
title,
|
|
||||||
message: `Loading plugin '${pluginId}'...`,
|
|
||||||
});
|
|
||||||
store.dispatch(loadPlugin({plugin, enable: true, notifyIfFailed: true}));
|
|
||||||
try {
|
|
||||||
await waitFor(
|
|
||||||
store,
|
|
||||||
() => getPluginStatus(store, pluginId)[0] !== 'bundle_installable',
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
loadingDialog.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function installMarketPlacePlugin(
|
async function installMarketPlacePlugin(
|
||||||
store: Store,
|
store: Store,
|
||||||
pluginId: string,
|
pluginId: string,
|
||||||
|
|||||||
@@ -183,9 +183,7 @@ function uninstallPlugin(store: Store, {plugin}: UninstallPluginActionPayload) {
|
|||||||
clients.forEach((client) => {
|
clients.forEach((client) => {
|
||||||
stopPlugin(client, plugin.id);
|
stopPlugin(client, plugin.id);
|
||||||
});
|
});
|
||||||
if (!plugin.details.isBundled) {
|
|
||||||
unloadPluginModule(plugin.details);
|
unloadPluginModule(plugin.details);
|
||||||
}
|
|
||||||
store.dispatch(pluginUninstalled(plugin.details));
|
store.dispatch(pluginUninstalled(plugin.details));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
@@ -368,9 +366,5 @@ function stopPlugin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function unloadPluginModule(plugin: ActivatablePluginDetails) {
|
function unloadPluginModule(plugin: ActivatablePluginDetails) {
|
||||||
if (plugin.isBundled) {
|
|
||||||
// We cannot unload bundled plugin.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
getRenderHostInstance().unloadModule?.(plugin.entry);
|
getRenderHostInstance().unloadModule?.(plugin.entry);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
addDisabledPlugins,
|
addDisabledPlugins,
|
||||||
addFailedPlugins,
|
addFailedPlugins,
|
||||||
registerLoadedPlugins,
|
registerLoadedPlugins,
|
||||||
registerBundledPlugins,
|
|
||||||
registerMarketplacePlugins,
|
registerMarketplacePlugins,
|
||||||
pluginsInitialized,
|
pluginsInitialized,
|
||||||
} from '../reducers/plugins';
|
} from '../reducers/plugins';
|
||||||
@@ -73,7 +72,6 @@ class UIPluginInitializer extends AbstractPluginInitializer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store.dispatch(registerBundledPlugins(this.bundledPlugins));
|
|
||||||
this.store.dispatch(registerLoadedPlugins(this.loadedPlugins));
|
this.store.dispatch(registerLoadedPlugins(this.loadedPlugins));
|
||||||
this.store.dispatch(addGatekeepedPlugins(this.gatekeepedPlugins));
|
this.store.dispatch(addGatekeepedPlugins(this.gatekeepedPlugins));
|
||||||
this.store.dispatch(addDisabledPlugins(this.disabledPlugins));
|
this.store.dispatch(addDisabledPlugins(this.disabledPlugins));
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ export abstract class FlipperBasePlugin<
|
|||||||
static version: string = '';
|
static version: string = '';
|
||||||
static icon: string | null = null;
|
static icon: string | null = null;
|
||||||
static gatekeeper: string | null = null;
|
static gatekeeper: string | null = null;
|
||||||
static isBundled: boolean;
|
|
||||||
static details: ActivatablePluginDetails;
|
static details: ActivatablePluginDetails;
|
||||||
static keyboardActions: KeyboardActions | null;
|
static keyboardActions: KeyboardActions | null;
|
||||||
static screenshot: string | null;
|
static screenshot: string | null;
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ test('add clientPlugin', () => {
|
|||||||
devicePlugins: new Map(),
|
devicePlugins: new Map(),
|
||||||
clientPlugins: new Map(),
|
clientPlugins: new Map(),
|
||||||
loadedPlugins: new Map(),
|
loadedPlugins: new Map(),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -58,7 +57,6 @@ test('add devicePlugin', () => {
|
|||||||
devicePlugins: new Map(),
|
devicePlugins: new Map(),
|
||||||
clientPlugins: new Map(),
|
clientPlugins: new Map(),
|
||||||
loadedPlugins: new Map(),
|
loadedPlugins: new Map(),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -79,7 +77,6 @@ test('do not add plugin twice', () => {
|
|||||||
devicePlugins: new Map(),
|
devicePlugins: new Map(),
|
||||||
clientPlugins: new Map(),
|
clientPlugins: new Map(),
|
||||||
loadedPlugins: new Map(),
|
loadedPlugins: new Map(),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -103,7 +100,6 @@ test('add gatekeeped plugin', () => {
|
|||||||
specVersion: 2,
|
specVersion: 2,
|
||||||
pluginType: 'client',
|
pluginType: 'client',
|
||||||
source: 'src/index.ts',
|
source: 'src/index.ts',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
main: 'lib/index.js',
|
main: 'lib/index.js',
|
||||||
title: 'test',
|
title: 'test',
|
||||||
@@ -116,7 +112,6 @@ test('add gatekeeped plugin', () => {
|
|||||||
devicePlugins: new Map(),
|
devicePlugins: new Map(),
|
||||||
clientPlugins: new Map(),
|
clientPlugins: new Map(),
|
||||||
loadedPlugins: new Map(),
|
loadedPlugins: new Map(),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -143,7 +138,6 @@ const EXAMPLE_PLUGIN = {
|
|||||||
dir: '/plugins/test',
|
dir: '/plugins/test',
|
||||||
specVersion: 2,
|
specVersion: 2,
|
||||||
source: 'src/index.ts',
|
source: 'src/index.ts',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
main: 'lib/index.js',
|
main: 'lib/index.js',
|
||||||
title: 'test',
|
title: 'test',
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import type {
|
|||||||
import type {
|
import type {
|
||||||
DownloadablePluginDetails,
|
DownloadablePluginDetails,
|
||||||
ActivatablePluginDetails,
|
ActivatablePluginDetails,
|
||||||
BundledPluginDetails,
|
|
||||||
InstalledPluginDetails,
|
InstalledPluginDetails,
|
||||||
MarketplacePluginDetails,
|
MarketplacePluginDetails,
|
||||||
} from 'flipper-common';
|
} from 'flipper-common';
|
||||||
@@ -30,7 +29,6 @@ type StateV1 = {
|
|||||||
devicePlugins: DevicePluginMap;
|
devicePlugins: DevicePluginMap;
|
||||||
clientPlugins: ClientPluginMap;
|
clientPlugins: ClientPluginMap;
|
||||||
loadedPlugins: Map<string, ActivatablePluginDetails>;
|
loadedPlugins: Map<string, ActivatablePluginDetails>;
|
||||||
bundledPlugins: Map<string, BundledPluginDetails>;
|
|
||||||
gatekeepedPlugins: Array<ActivatablePluginDetails>;
|
gatekeepedPlugins: Array<ActivatablePluginDetails>;
|
||||||
disabledPlugins: Array<ActivatablePluginDetails>;
|
disabledPlugins: Array<ActivatablePluginDetails>;
|
||||||
failedPlugins: Array<[ActivatablePluginDetails, string]>;
|
failedPlugins: Array<[ActivatablePluginDetails, string]>;
|
||||||
@@ -88,10 +86,6 @@ export type Action =
|
|||||||
type: 'REGISTER_LOADED_PLUGINS';
|
type: 'REGISTER_LOADED_PLUGINS';
|
||||||
payload: Array<ActivatablePluginDetails>;
|
payload: Array<ActivatablePluginDetails>;
|
||||||
}
|
}
|
||||||
| {
|
|
||||||
type: 'REGISTER_BUNDLED_PLUGINS';
|
|
||||||
payload: Array<BundledPluginDetails>;
|
|
||||||
}
|
|
||||||
| {
|
| {
|
||||||
type: 'REGISTER_INSTALLED_PLUGINS';
|
type: 'REGISTER_INSTALLED_PLUGINS';
|
||||||
payload: InstalledPluginDetails[];
|
payload: InstalledPluginDetails[];
|
||||||
@@ -116,7 +110,6 @@ const INITIAL_STATE: State = {
|
|||||||
devicePlugins: new Map(),
|
devicePlugins: new Map(),
|
||||||
clientPlugins: new Map(),
|
clientPlugins: new Map(),
|
||||||
loadedPlugins: new Map(),
|
loadedPlugins: new Map(),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
@@ -175,11 +168,6 @@ export default function reducer(
|
|||||||
...state,
|
...state,
|
||||||
loadedPlugins: new Map(action.payload.map((p) => [p.id, p])),
|
loadedPlugins: new Map(action.payload.map((p) => [p.id, p])),
|
||||||
};
|
};
|
||||||
} else if (action.type === 'REGISTER_BUNDLED_PLUGINS') {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
bundledPlugins: new Map(action.payload.map((p) => [p.id, p])),
|
|
||||||
};
|
|
||||||
} else if (action.type === 'REGISTER_INSTALLED_PLUGINS') {
|
} else if (action.type === 'REGISTER_INSTALLED_PLUGINS') {
|
||||||
return produce(state, (draft) => {
|
return produce(state, (draft) => {
|
||||||
draft.installedPlugins.clear();
|
draft.installedPlugins.clear();
|
||||||
@@ -270,13 +258,6 @@ export const registerLoadedPlugins = (
|
|||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const registerBundledPlugins = (
|
|
||||||
payload: Array<BundledPluginDetails>,
|
|
||||||
): Action => ({
|
|
||||||
type: 'REGISTER_BUNDLED_PLUGINS',
|
|
||||||
payload,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const registerInstalledPlugins = (
|
export const registerInstalledPlugins = (
|
||||||
payload: InstalledPluginDetails[],
|
payload: InstalledPluginDetails[],
|
||||||
): Action => ({
|
): Action => ({
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import {
|
|||||||
switchPlugin,
|
switchPlugin,
|
||||||
uninstallPlugin,
|
uninstallPlugin,
|
||||||
} from '../../reducers/pluginManager';
|
} from '../../reducers/pluginManager';
|
||||||
import {BundledPluginDetails} from 'flipper-common';
|
|
||||||
import {reportUsage} from 'flipper-common';
|
import {reportUsage} from 'flipper-common';
|
||||||
import ConnectivityStatus from './fb-stubs/ConnectivityStatus';
|
import ConnectivityStatus from './fb-stubs/ConnectivityStatus';
|
||||||
import {useSelector} from 'react-redux';
|
import {useSelector} from 'react-redux';
|
||||||
@@ -73,14 +72,8 @@ export const PluginList = memo(function PluginList({
|
|||||||
const isArchived = activeDevice?.isArchived;
|
const isArchived = activeDevice?.isArchived;
|
||||||
|
|
||||||
const annotatedDownloadablePlugins = useMemoize<
|
const annotatedDownloadablePlugins = useMemoize<
|
||||||
[
|
[Record<string, DownloadablePluginState>, DownloadablePluginDetails[]],
|
||||||
Record<string, DownloadablePluginState>,
|
[plugin: DownloadablePluginDetails, downloadStatus?: PluginDownloadStatus][]
|
||||||
(DownloadablePluginDetails | BundledPluginDetails)[],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
plugin: DownloadablePluginDetails | BundledPluginDetails,
|
|
||||||
downloadStatus?: PluginDownloadStatus,
|
|
||||||
][]
|
|
||||||
>(
|
>(
|
||||||
(downloads, downloadablePlugins) => {
|
(downloads, downloadablePlugins) => {
|
||||||
const downloadMap = new Map(
|
const downloadMap = new Map(
|
||||||
@@ -137,11 +130,7 @@ export const PluginList = memo(function PluginList({
|
|||||||
(id: string) => {
|
(id: string) => {
|
||||||
const plugin = downloadablePlugins.find((p) => p.id === id)!;
|
const plugin = downloadablePlugins.find((p) => p.id === id)!;
|
||||||
reportUsage('plugin:install', {version: plugin.version}, plugin.id);
|
reportUsage('plugin:install', {version: plugin.version}, plugin.id);
|
||||||
if (plugin.isBundled) {
|
|
||||||
dispatch(loadPlugin({plugin, enable: true, notifyIfFailed: true}));
|
|
||||||
} else {
|
|
||||||
dispatch(startPluginDownload({plugin, startedByUser: true}));
|
dispatch(startPluginDownload({plugin, startedByUser: true}));
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[downloadablePlugins, dispatch],
|
[downloadablePlugins, dispatch],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ export const getPluginLists = createSelector(
|
|||||||
plugins: {
|
plugins: {
|
||||||
clientPlugins,
|
clientPlugins,
|
||||||
devicePlugins,
|
devicePlugins,
|
||||||
bundledPlugins,
|
|
||||||
marketplacePlugins,
|
marketplacePlugins,
|
||||||
loadedPlugins,
|
loadedPlugins,
|
||||||
disabledPlugins,
|
disabledPlugins,
|
||||||
@@ -96,7 +95,6 @@ export const getPluginLists = createSelector(
|
|||||||
}: State) => ({
|
}: State) => ({
|
||||||
clientPlugins,
|
clientPlugins,
|
||||||
devicePlugins,
|
devicePlugins,
|
||||||
bundledPlugins,
|
|
||||||
marketplacePlugins,
|
marketplacePlugins,
|
||||||
loadedPlugins,
|
loadedPlugins,
|
||||||
disabledPlugins,
|
disabledPlugins,
|
||||||
|
|||||||
@@ -776,7 +776,6 @@ test('test determinePluginsToProcess for mutilple clients having plugins present
|
|||||||
['RandomPlugin', TestPlugin.details],
|
['RandomPlugin', TestPlugin.details],
|
||||||
['TestDevicePlugin', TestDevicePlugin.details],
|
['TestDevicePlugin', TestDevicePlugin.details],
|
||||||
]),
|
]),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
@@ -851,7 +850,6 @@ test('test determinePluginsToProcess for no selected plugin present in any clien
|
|||||||
['RandomPlugin', TestPlugin.details],
|
['RandomPlugin', TestPlugin.details],
|
||||||
['TestDevicePlugin', TestDevicePlugin.details],
|
['TestDevicePlugin', TestDevicePlugin.details],
|
||||||
]),
|
]),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
@@ -905,7 +903,6 @@ test('test determinePluginsToProcess for multiple clients on same device', async
|
|||||||
['TestPlugin', TestPlugin.details],
|
['TestPlugin', TestPlugin.details],
|
||||||
['TestDevicePlugin', TestDevicePlugin.details],
|
['TestDevicePlugin', TestDevicePlugin.details],
|
||||||
]),
|
]),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
@@ -998,7 +995,6 @@ test('test determinePluginsToProcess for multiple clients on different device',
|
|||||||
['TestPlugin', TestPlugin.details],
|
['TestPlugin', TestPlugin.details],
|
||||||
['TestDevicePlugin', TestDevicePlugin.details],
|
['TestDevicePlugin', TestDevicePlugin.details],
|
||||||
]),
|
]),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
@@ -1085,7 +1081,6 @@ test('test determinePluginsToProcess to ignore archived clients', async () => {
|
|||||||
['TestPlugin', TestPlugin.details],
|
['TestPlugin', TestPlugin.details],
|
||||||
['TestDevicePlugin', TestDevicePlugin.details],
|
['TestDevicePlugin', TestDevicePlugin.details],
|
||||||
]),
|
]),
|
||||||
bundledPlugins: new Map(),
|
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
failedPlugins: [],
|
failedPlugins: [],
|
||||||
|
|||||||
@@ -26,13 +26,6 @@ export function isPluginVersionMoreRecent(
|
|||||||
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
|
if (semver.gt(versionDetails.version, otherVersionDetails.version)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
|
||||||
versionDetails.isBundled
|
|
||||||
) {
|
|
||||||
// prefer bundled versions
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
semver.eq(versionDetails.version, otherVersionDetails.version) &&
|
||||||
versionDetails.isActivatable &&
|
versionDetails.isActivatable &&
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {
|
|||||||
import type Client from '../Client';
|
import type Client from '../Client';
|
||||||
import type {
|
import type {
|
||||||
ActivatablePluginDetails,
|
ActivatablePluginDetails,
|
||||||
BundledPluginDetails,
|
|
||||||
DownloadablePluginDetails,
|
DownloadablePluginDetails,
|
||||||
PluginDetails,
|
PluginDetails,
|
||||||
} from 'flipper-common';
|
} from 'flipper-common';
|
||||||
@@ -30,7 +29,7 @@ export type PluginLists = {
|
|||||||
enabledPlugins: PluginDefinition[];
|
enabledPlugins: PluginDefinition[];
|
||||||
disabledPlugins: PluginDefinition[];
|
disabledPlugins: PluginDefinition[];
|
||||||
unavailablePlugins: [plugin: PluginDetails, reason: string][];
|
unavailablePlugins: [plugin: PluginDetails, reason: string][];
|
||||||
downloadablePlugins: (DownloadablePluginDetails | BundledPluginDetails)[];
|
downloadablePlugins: DownloadablePluginDetails[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ActivePluginListItem =
|
export type ActivePluginListItem =
|
||||||
@@ -46,7 +45,7 @@ export type ActivePluginListItem =
|
|||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
status: 'uninstalled';
|
status: 'uninstalled';
|
||||||
details: DownloadablePluginDetails | BundledPluginDetails;
|
details: DownloadablePluginDetails;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
status: 'unavailable';
|
status: 'unavailable';
|
||||||
@@ -162,7 +161,6 @@ export function computePluginLists(
|
|||||||
>,
|
>,
|
||||||
plugins: Pick<
|
plugins: Pick<
|
||||||
State['plugins'],
|
State['plugins'],
|
||||||
| 'bundledPlugins'
|
|
||||||
| 'marketplacePlugins'
|
| 'marketplacePlugins'
|
||||||
| 'loadedPlugins'
|
| 'loadedPlugins'
|
||||||
| 'devicePlugins'
|
| 'devicePlugins'
|
||||||
@@ -180,12 +178,12 @@ export function computePluginLists(
|
|||||||
enabledPlugins: PluginDefinition[];
|
enabledPlugins: PluginDefinition[];
|
||||||
disabledPlugins: PluginDefinition[];
|
disabledPlugins: PluginDefinition[];
|
||||||
unavailablePlugins: [plugin: PluginDetails, reason: string][];
|
unavailablePlugins: [plugin: PluginDetails, reason: string][];
|
||||||
downloadablePlugins: (DownloadablePluginDetails | BundledPluginDetails)[];
|
downloadablePlugins: DownloadablePluginDetails[];
|
||||||
} {
|
} {
|
||||||
const enabledDevicePluginsState = connections.enabledDevicePlugins;
|
const enabledDevicePluginsState = connections.enabledDevicePlugins;
|
||||||
const enabledPluginsState = connections.enabledPlugins;
|
const enabledPluginsState = connections.enabledPlugins;
|
||||||
const uninstalledMarketplacePlugins = getLatestCompatibleVersionOfEachPlugin(
|
const uninstalledMarketplacePlugins = getLatestCompatibleVersionOfEachPlugin(
|
||||||
[...plugins.bundledPlugins.values(), ...plugins.marketplacePlugins],
|
[...plugins.marketplacePlugins],
|
||||||
getAppVersion(),
|
getAppVersion(),
|
||||||
).filter((p) => !plugins.loadedPlugins.has(p.id));
|
).filter((p) => !plugins.loadedPlugins.has(p.id));
|
||||||
const devicePlugins: PluginDefinition[] = [...plugins.devicePlugins.values()]
|
const devicePlugins: PluginDefinition[] = [...plugins.devicePlugins.values()]
|
||||||
@@ -205,10 +203,7 @@ export function computePluginLists(
|
|||||||
)
|
)
|
||||||
.filter((p) => !enabledDevicePluginsState.has(p.id));
|
.filter((p) => !enabledDevicePluginsState.has(p.id));
|
||||||
const unavailablePlugins: [plugin: PluginDetails, reason: string][] = [];
|
const unavailablePlugins: [plugin: PluginDetails, reason: string][] = [];
|
||||||
const downloadablePlugins: (
|
const downloadablePlugins: DownloadablePluginDetails[] = [];
|
||||||
| DownloadablePluginDetails
|
|
||||||
| BundledPluginDetails
|
|
||||||
)[] = [];
|
|
||||||
|
|
||||||
if (device) {
|
if (device) {
|
||||||
// find all device plugins that aren't part of the current device / metro
|
// find all device plugins that aren't part of the current device / metro
|
||||||
@@ -431,7 +426,6 @@ export type PluginStatus =
|
|||||||
| 'unknown'
|
| 'unknown'
|
||||||
| 'failed'
|
| 'failed'
|
||||||
| 'gatekeeped'
|
| 'gatekeeped'
|
||||||
| 'bundle_installable'
|
|
||||||
| 'marketplace_installable';
|
| 'marketplace_installable';
|
||||||
|
|
||||||
export function getPluginStatus(
|
export function getPluginStatus(
|
||||||
@@ -452,9 +446,6 @@ export function getPluginStatus(
|
|||||||
if (failedPluginEntry) {
|
if (failedPluginEntry) {
|
||||||
return ['failed', failedPluginEntry[1]];
|
return ['failed', failedPluginEntry[1]];
|
||||||
}
|
}
|
||||||
if (state.bundledPlugins.has(id)) {
|
|
||||||
return ['bundle_installable'];
|
|
||||||
}
|
|
||||||
if (state.marketplacePlugins.find((d) => d.id === id)) {
|
if (state.marketplacePlugins.find((d) => d.id === id)) {
|
||||||
return ['marketplace_installable'];
|
return ['marketplace_installable'];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ export function createMockDownloadablePluginDetails(
|
|||||||
version: version,
|
version: version,
|
||||||
downloadUrl: `http://localhost/${lowercasedID}/${version}`,
|
downloadUrl: `http://localhost/${lowercasedID}/${version}`,
|
||||||
lastUpdated: lastUpdated,
|
lastUpdated: lastUpdated,
|
||||||
isBundled: false,
|
|
||||||
isActivatable: false,
|
isActivatable: false,
|
||||||
isEnabledByDefault: false,
|
isEnabledByDefault: false,
|
||||||
};
|
};
|
||||||
@@ -69,7 +68,6 @@ export function createMockActivatablePluginDetails(
|
|||||||
return {
|
return {
|
||||||
id: 'Hello',
|
id: 'Hello',
|
||||||
specVersion: 2,
|
specVersion: 2,
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample1',
|
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample1',
|
||||||
entry: './test/index.js',
|
entry: './test/index.js',
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ test('getPluginDetailsV1', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": undefined,
|
"pluginType": undefined,
|
||||||
@@ -95,7 +94,6 @@ test('getPluginDetailsV2', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": undefined,
|
"pluginType": undefined,
|
||||||
@@ -143,7 +141,6 @@ test('id used as title if the latter omited', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "test",
|
"id": "test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": undefined,
|
"pluginType": undefined,
|
||||||
@@ -190,7 +187,6 @@ test('name without "flipper-plugin-" prefix is used as title if the latter omite
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": undefined,
|
"pluginType": undefined,
|
||||||
@@ -240,7 +236,6 @@ test('flipper-plugin-version is parsed', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": undefined,
|
"pluginType": undefined,
|
||||||
@@ -294,7 +289,6 @@ test('plugin type and supported devices parsed', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": "device",
|
"pluginType": "device",
|
||||||
@@ -364,7 +358,6 @@ test('plugin type and supported apps parsed', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": "client",
|
"pluginType": "client",
|
||||||
@@ -454,7 +447,6 @@ test('can merge two package.json files', async () => {
|
|||||||
"icon": undefined,
|
"icon": undefined,
|
||||||
"id": "flipper-plugin-test",
|
"id": "flipper-plugin-test",
|
||||||
"isActivatable": true,
|
"isActivatable": true,
|
||||||
"isBundled": false,
|
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"name": "flipper-plugin-test",
|
"name": "flipper-plugin-test",
|
||||||
"pluginType": "device",
|
"pluginType": "device",
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ const installedPlugins: InstalledPluginDetails[] = [
|
|||||||
id: 'Hello',
|
id: 'Hello',
|
||||||
title: 'Hello',
|
title: 'Hello',
|
||||||
description: 'World?',
|
description: 'World?',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -82,7 +81,6 @@ const installedPlugins: InstalledPluginDetails[] = [
|
|||||||
id: 'World',
|
id: 'World',
|
||||||
title: 'World',
|
title: 'World',
|
||||||
description: 'Hello?',
|
description: 'Hello?',
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ export async function getInstalledPluginDetails(
|
|||||||
: undefined;
|
: undefined;
|
||||||
return {
|
return {
|
||||||
...pluginDetails,
|
...pluginDetails,
|
||||||
isBundled: false,
|
|
||||||
isActivatable: true,
|
isActivatable: true,
|
||||||
dir,
|
dir,
|
||||||
entry,
|
entry,
|
||||||
|
|||||||
Reference in New Issue
Block a user