diff --git a/desktop/flipper-plugin/src/__tests__/test-utils.node.tsx b/desktop/flipper-plugin/src/__tests__/test-utils.node.tsx index d301e8aae..2efc5fea1 100644 --- a/desktop/flipper-plugin/src/__tests__/test-utils.node.tsx +++ b/desktop/flipper-plugin/src/__tests__/test-utils.node.tsx @@ -346,3 +346,46 @@ test('plugins can create pastes', async () => { plugin.instance.doIt(); expect(plugin.flipperLib.createPaste).toBeCalledWith('test'); }); + +test('plugins support all methods by default', async () => { + type Methods = { + doit(): Promise; + }; + const plugin = TestUtils.startPlugin({ + plugin(client: PluginClient<{}, Methods>) { + return { + async checkEnabled() { + return client.supportsMethod('doit'); + }, + }; + }, + Component() { + return null; + }, + }); + expect(await plugin.instance.checkEnabled()).toBeTruthy(); +}); + +test('available methods can be overridden', async () => { + type Methods = { + doit(): Promise; + }; + const plugin = TestUtils.startPlugin( + { + plugin(client: PluginClient<{}, Methods>) { + return { + async checkEnabled() { + return client.supportsMethod('doit'); + }, + }; + }, + Component() { + return null; + }, + }, + { + unsupportedMethods: ['doit'], + }, + ); + expect(await plugin.instance.checkEnabled()).toBeFalsy(); +}); diff --git a/desktop/flipper-plugin/src/plugin/Plugin.tsx b/desktop/flipper-plugin/src/plugin/Plugin.tsx index b7c38e640..ea194d0a6 100644 --- a/desktop/flipper-plugin/src/plugin/Plugin.tsx +++ b/desktop/flipper-plugin/src/plugin/Plugin.tsx @@ -59,6 +59,11 @@ export interface PluginClient< method: Method, params: Parameters[0], ): ReturnType; + + /** + * Checks if a method is available on the client implementation + */ + supportsMethod(method: keyof Methods): Promise; } /** @@ -75,6 +80,7 @@ export interface RealFlipperClient { fromPlugin: boolean, params?: Object, ): Promise; + supportsMethod(api: string, method: string): Promise; } export type PluginFactory< @@ -125,6 +131,13 @@ export class SandyPluginInstance extends BasePluginInstance { onMessage: (event, callback) => { this.events.on('event-' + event, callback); }, + supportsMethod: async (method) => { + this.assertConnected(); + return await realClient.supportsMethod( + this.definition.id, + method as any, + ); + }, }; this.initializePlugin(() => definition.asPluginModule().plugin(this.client), diff --git a/desktop/flipper-plugin/src/test-utils/test-utils.tsx b/desktop/flipper-plugin/src/test-utils/test-utils.tsx index a55cd9e8c..58f7deb4d 100644 --- a/desktop/flipper-plugin/src/test-utils/test-utils.tsx +++ b/desktop/flipper-plugin/src/test-utils/test-utils.tsx @@ -43,6 +43,8 @@ interface StartPluginOptions { initialState?: Record; isArchived?: boolean; isBackgroundPlugin?: boolean; + /** Provide a set of unsupported methods to simulate older clients that don't support certain methods yet */ + unsupportedMethods?: string[]; } type ExtractClientType> = Parameters< @@ -195,6 +197,9 @@ export function startPlugin>( ): Promise { return sendStub(method, params); }, + async supportsMethod(_api: string, method: string) { + return !options?.unsupportedMethods?.includes(method); + }, }; const pluginInstance = new SandyPluginInstance(