mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
🐛 fix: updown the old lobehub plugins (#12674)
* fix: updown the old lobehub plugins * fix: update test.ts
This commit is contained in:
@@ -102,26 +102,5 @@ export const getToolManifest = async (
|
||||
throw new TypeError('manifestInvalid', { cause: parser.error });
|
||||
}
|
||||
|
||||
// 4. if exist OpenAPI api, merge the OpenAPIs to api
|
||||
if (parser.data.openapi) {
|
||||
const openapiJson = await fetchJSON(parser.data.openapi, useProxy);
|
||||
|
||||
// avoid https://github.com/lobehub/lobe-chat/issues/9059
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
const { OpenAPIConvertor } = await import('@lobehub/chat-plugin-sdk/openapi');
|
||||
|
||||
const convertor = new OpenAPIConvertor(openapiJson);
|
||||
const openAPIs = await convertor.convertOpenAPIToPluginSchema();
|
||||
|
||||
data.api = [...data.api, ...openAPIs];
|
||||
|
||||
data.settings = await convertor.convertAuthToSettingsSchema(data.settings);
|
||||
} catch (error) {
|
||||
throw new TypeError('openAPIInvalid', { cause: error });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -5,13 +5,11 @@ import type { Plugin } from 'vite';
|
||||
*
|
||||
* - `node:stream`: dynamically imported in azureai provider behind `typeof window === 'undefined'`
|
||||
* guard — dead code in browser but Rollup still resolves it.
|
||||
* - `@lobehub/chat-plugin-sdk/openapi`: dynamically imported in toolManifest, pulls in
|
||||
* @apidevtools/swagger-parser which depends on Node built-ins (util, path).
|
||||
* - `node-fetch`: dynamically imported by klavis SDK's getFetchFn behind a runtime
|
||||
* Node.js version check — dead code in browser since native fetch is available.
|
||||
*/
|
||||
export function viteNodeModuleStub(): Plugin {
|
||||
const stubbedModules = new Set(['node:stream', 'node-fetch', '@lobehub/chat-plugin-sdk/openapi']);
|
||||
const stubbedModules = new Set(['node:stream', 'node-fetch']);
|
||||
const VIRTUAL_PREFIX = '\0node-stub:';
|
||||
|
||||
return {
|
||||
|
||||
@@ -77,128 +77,3 @@ getWolframCloudResults guidelines:
|
||||
"version": "1",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`ToolService > getToolManifest > support OpenAPI manifest > should get plugin manifest 1`] = `
|
||||
{
|
||||
"$schema": "../node_modules/@lobehub/chat-plugin-sdk/schema.json",
|
||||
"api": [
|
||||
{
|
||||
"description": "Read Course Segments",
|
||||
"name": "read_course_segments_course_segments__get",
|
||||
"parameters": {
|
||||
"properties": {},
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Read Problem Set Item",
|
||||
"name": "read_problem_set_item_problem_set__problem_set_id___question_number__get",
|
||||
"parameters": {
|
||||
"properties": {
|
||||
"problem_set_id": {
|
||||
"title": "Problem Set Id",
|
||||
"type": "integer",
|
||||
},
|
||||
"question_number": {
|
||||
"title": "Question Number",
|
||||
"type": "integer",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"problem_set_id",
|
||||
"question_number",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Read Random Problem Set Items",
|
||||
"name": "read_random_problem_set_items_problem_set_random__problem_set_id___n_items__get",
|
||||
"parameters": {
|
||||
"properties": {
|
||||
"n_items": {
|
||||
"title": "N Items",
|
||||
"type": "integer",
|
||||
},
|
||||
"problem_set_id": {
|
||||
"title": "Problem Set Id",
|
||||
"type": "integer",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"problem_set_id",
|
||||
"n_items",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Read Range Of Problem Set Items",
|
||||
"name": "read_range_of_problem_set_items_problem_set_range__problem_set_id___start___end__get",
|
||||
"parameters": {
|
||||
"properties": {
|
||||
"end": {
|
||||
"title": "End",
|
||||
"type": "integer",
|
||||
},
|
||||
"problem_set_id": {
|
||||
"title": "Problem Set Id",
|
||||
"type": "integer",
|
||||
},
|
||||
"start": {
|
||||
"title": "Start",
|
||||
"type": "integer",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"problem_set_id",
|
||||
"start",
|
||||
"end",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Read User Id",
|
||||
"name": "read_user_id_user__get",
|
||||
"parameters": {
|
||||
"properties": {},
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
],
|
||||
"author": "LobeHub",
|
||||
"createAt": "2023-08-12",
|
||||
"homepage": "https://github.com/lobehub/chat-plugin-realtime-weather",
|
||||
"identifier": "realtime-weather",
|
||||
"meta": {
|
||||
"avatar": "🌈",
|
||||
"description": "Get realtime weather information",
|
||||
"tags": [
|
||||
"weather",
|
||||
"realtime",
|
||||
],
|
||||
"title": "Realtime Weather",
|
||||
},
|
||||
"openapi": "http://fake-url.com/openapiUrl.json",
|
||||
"settings": {
|
||||
"properties": {
|
||||
"HTTPBearer": {
|
||||
"description": "HTTPBearer Bearer token",
|
||||
"format": "password",
|
||||
"title": "HTTPBearer",
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"HTTPBearer",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"ui": {
|
||||
"height": 310,
|
||||
"url": "https://realtime-weather.chat-plugin.lobehub.com/iframe",
|
||||
},
|
||||
"version": "1",
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { toolService } from '../tool';
|
||||
import openAPIV3 from './openai/OpenAPI_V3.json';
|
||||
import OpenAIPlugin from './openai/plugin.json';
|
||||
|
||||
// Mocking modules and functions
|
||||
@@ -136,85 +135,6 @@ describe('ToolService', () => {
|
||||
expect(e).toEqual(new TypeError('fetchError'));
|
||||
}
|
||||
});
|
||||
|
||||
describe('support OpenAPI manifest', () => {
|
||||
it('should get plugin manifest', async () => {
|
||||
const manifestUrl = 'http://fake-url.com/manifest.json';
|
||||
const openapiUrl = 'http://fake-url.com/openapiUrl.json';
|
||||
|
||||
const fakeManifest = {
|
||||
$schema: '../node_modules/@lobehub/chat-plugin-sdk/schema.json',
|
||||
api: [],
|
||||
openapi: openapiUrl,
|
||||
author: 'LobeHub',
|
||||
createAt: '2023-08-12',
|
||||
homepage: 'https://github.com/lobehub/chat-plugin-realtime-weather',
|
||||
identifier: 'realtime-weather',
|
||||
meta: {
|
||||
avatar: '🌈',
|
||||
tags: ['weather', 'realtime'],
|
||||
title: 'Realtime Weather',
|
||||
description: 'Get realtime weather information',
|
||||
},
|
||||
ui: {
|
||||
url: 'https://realtime-weather.chat-plugin.lobehub.com/iframe',
|
||||
height: 310,
|
||||
},
|
||||
version: '1',
|
||||
};
|
||||
|
||||
global.fetch = vi.fn((url) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
headers: new Headers({ 'content-type': 'application/json' }),
|
||||
json: () => Promise.resolve(url === openapiUrl ? openAPIV3 : fakeManifest),
|
||||
}),
|
||||
) as any;
|
||||
|
||||
const manifest = await toolService.getToolManifest(manifestUrl);
|
||||
|
||||
expect(manifest).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return error on openAPIInvalid', async () => {
|
||||
const openapiUrl = 'http://fake-url.com/openapiUrl.json';
|
||||
const manifestUrl = 'http://fake-url.com/manifest.json';
|
||||
const fakeManifest = {
|
||||
$schema: '../node_modules/@lobehub/chat-plugin-sdk/schema.json',
|
||||
api: [],
|
||||
openapi: openapiUrl,
|
||||
author: 'LobeHub',
|
||||
createAt: '2023-08-12',
|
||||
homepage: 'https://github.com/lobehub/chat-plugin-realtime-weather',
|
||||
identifier: 'realtime-weather',
|
||||
meta: {
|
||||
avatar: '🌈',
|
||||
tags: ['weather', 'realtime'],
|
||||
title: 'Realtime Weather',
|
||||
description: 'Get realtime weather information',
|
||||
},
|
||||
ui: {
|
||||
url: 'https://realtime-weather.chat-plugin.lobehub.com/iframe',
|
||||
height: 310,
|
||||
},
|
||||
version: '1',
|
||||
};
|
||||
|
||||
global.fetch = vi.fn((url) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
headers: new Headers({ 'content-type': 'application/json' }),
|
||||
json: () => Promise.resolve(url === openapiUrl ? [] : fakeManifest),
|
||||
}),
|
||||
) as any;
|
||||
|
||||
try {
|
||||
await toolService.getToolManifest(manifestUrl);
|
||||
} catch (e) {
|
||||
expect(e).toEqual(new TypeError('openAPIInvalid'));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can parse the OpenAI plugin', async () => {
|
||||
|
||||
@@ -161,137 +161,28 @@ describe('useToolStore:pluginStore', () => {
|
||||
});
|
||||
|
||||
describe('installPlugin', () => {
|
||||
it('should install a plugin with valid manifest', async () => {
|
||||
const pluginIdentifier = 'plugin1';
|
||||
|
||||
const originalUpdateInstallLoadingState = useToolStore.getState().updateInstallLoadingState;
|
||||
const updateInstallLoadingStateMock = vi.fn();
|
||||
|
||||
act(() => {
|
||||
useToolStore.setState({
|
||||
updateInstallLoadingState: updateInstallLoadingStateMock,
|
||||
});
|
||||
});
|
||||
|
||||
const pluginManifestMock = {
|
||||
$schema: '../node_modules/@lobehub/chat-plugin-sdk/schema.json',
|
||||
api: [
|
||||
{
|
||||
url: 'https://realtime-weather.chat-plugin.lobehub.com/api/v1',
|
||||
name: 'fetchCurrentWeather',
|
||||
description: '获取当前天气情况',
|
||||
parameters: {
|
||||
properties: {
|
||||
city: {
|
||||
description: '城市名称',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['city'],
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
],
|
||||
author: 'LobeHub',
|
||||
createAt: '2023-08-12',
|
||||
homepage: 'https://github.com/lobehub/chat-plugin-realtime-weather',
|
||||
identifier: 'realtime-weather',
|
||||
meta: {
|
||||
avatar: '🌈',
|
||||
tags: ['weather', 'realtime'],
|
||||
title: 'Realtime Weather',
|
||||
description: 'Get realtime weather information',
|
||||
},
|
||||
ui: {
|
||||
url: 'https://realtime-weather.chat-plugin.lobehub.com/iframe',
|
||||
height: 310,
|
||||
},
|
||||
version: '1',
|
||||
};
|
||||
(toolService.getToolManifest as Mock).mockResolvedValue(pluginManifestMock);
|
||||
|
||||
await act(async () => {
|
||||
await useToolStore.getState().installPlugin(pluginIdentifier);
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(toolService.getToolManifest).toHaveBeenCalled();
|
||||
expect(notification.error).not.toHaveBeenCalled();
|
||||
expect(updateInstallLoadingStateMock).toHaveBeenCalledTimes(2);
|
||||
expect(pluginService.installPlugin).toHaveBeenCalledWith({
|
||||
identifier: 'plugin1',
|
||||
type: 'plugin',
|
||||
manifest: pluginManifestMock,
|
||||
});
|
||||
|
||||
act(() => {
|
||||
useToolStore.setState({
|
||||
updateInstallLoadingState: originalUpdateInstallLoadingState,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error with no error', async () => {
|
||||
// Given
|
||||
|
||||
const error = new TypeError('noManifest');
|
||||
|
||||
// Mock necessary modules and functions
|
||||
(toolService.getToolManifest as Mock).mockRejectedValue(error);
|
||||
|
||||
useToolStore.setState({
|
||||
oldPluginItems: [
|
||||
{
|
||||
identifier: 'plugin1',
|
||||
title: 'plugin1',
|
||||
avatar: '🍏',
|
||||
} as DiscoverPluginItem,
|
||||
],
|
||||
});
|
||||
|
||||
it('should be deprecated and do nothing', async () => {
|
||||
// Old plugin system has been deprecated
|
||||
await act(async () => {
|
||||
await useToolStore.getState().installPlugin('plugin1');
|
||||
});
|
||||
|
||||
expect(notification.error).toHaveBeenCalledWith({
|
||||
description: 'error.noManifest',
|
||||
message: 'error.installError',
|
||||
});
|
||||
// Should not call any service
|
||||
expect(toolService.getToolManifest).not.toHaveBeenCalled();
|
||||
expect(pluginService.installPlugin).not.toHaveBeenCalled();
|
||||
expect(notification.error).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('installPlugins', () => {
|
||||
it('should install multiple plugins', async () => {
|
||||
// Given
|
||||
act(() => {
|
||||
useToolStore.setState({
|
||||
oldPluginItems: [
|
||||
{
|
||||
identifier: 'plugin1',
|
||||
title: 'plugin1',
|
||||
avatar: '🍏',
|
||||
manifest: 'https://abc.com/manifest.json',
|
||||
} as DiscoverPluginItem,
|
||||
{
|
||||
identifier: 'plugin2',
|
||||
title: 'plugin2',
|
||||
avatar: '🍏',
|
||||
manifest: 'https://abc.com/manifest.json',
|
||||
} as DiscoverPluginItem,
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
const plugins = ['plugin1', 'plugin2'];
|
||||
|
||||
(toolService.getToolManifest as Mock).mockResolvedValue(pluginManifestMock);
|
||||
|
||||
// When
|
||||
it('should be deprecated and do nothing', async () => {
|
||||
// Old plugin system has been deprecated
|
||||
await act(async () => {
|
||||
await useToolStore.getState().installPlugins(plugins);
|
||||
await useToolStore.getState().installPlugins(['plugin1', 'plugin2']);
|
||||
});
|
||||
|
||||
expect(pluginService.installPlugin).toHaveBeenCalledTimes(2);
|
||||
// Should not call any service
|
||||
expect(pluginService.installPlugin).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
import { type LobeTool } from '@lobechat/types';
|
||||
import { uniqBy } from 'es-toolkit/compat';
|
||||
import { t } from 'i18next';
|
||||
import { produce } from 'immer';
|
||||
import { type SWRResponse } from 'swr';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { notification } from '@/components/AntdStaticMethods';
|
||||
import { mutate } from '@/libs/swr';
|
||||
import { pluginService } from '@/services/plugin';
|
||||
import { toolService } from '@/services/tool';
|
||||
import { globalHelpers } from '@/store/global/helpers';
|
||||
import { pluginStoreSelectors } from '@/store/tool/selectors';
|
||||
import { type StoreSetter } from '@/store/types';
|
||||
import {
|
||||
type DiscoverPluginItem,
|
||||
type PluginListResponse,
|
||||
type PluginQueryParams,
|
||||
} from '@/types/discover';
|
||||
import { type PluginInstallError } from '@/types/tool/plugin';
|
||||
import { sleep } from '@/utils/sleep';
|
||||
import { setNamespace } from '@/utils/storeDebug';
|
||||
|
||||
import { type ToolStore } from '../../store';
|
||||
import { type PluginInstallProgress, type PluginStoreState } from './initialState';
|
||||
import { PluginInstallStep } from './initialState';
|
||||
|
||||
const n = setNamespace('pluginStore');
|
||||
|
||||
@@ -44,107 +38,21 @@ export class PluginStoreActionImpl {
|
||||
}
|
||||
|
||||
installOldPlugin = async (
|
||||
name: string,
|
||||
type: 'plugin' | 'customPlugin' = 'plugin',
|
||||
_name: string,
|
||||
_type: 'plugin' | 'customPlugin' = 'plugin',
|
||||
): Promise<void> => {
|
||||
const plugin = pluginStoreSelectors.getPluginById(name)(this.#get());
|
||||
if (!plugin) return;
|
||||
|
||||
const { updateInstallLoadingState, refreshPlugins, updatePluginInstallProgress } = this.#get();
|
||||
|
||||
try {
|
||||
// Start installation process
|
||||
updateInstallLoadingState(name, true);
|
||||
|
||||
// Step 1: Fetch plugin manifest
|
||||
updatePluginInstallProgress(name, {
|
||||
progress: 25,
|
||||
step: PluginInstallStep.FETCHING_MANIFEST,
|
||||
});
|
||||
|
||||
const data = await toolService.getToolManifest(plugin.manifest);
|
||||
|
||||
// Step 2: Install plugin
|
||||
updatePluginInstallProgress(name, {
|
||||
progress: 60,
|
||||
step: PluginInstallStep.INSTALLING_PLUGIN,
|
||||
});
|
||||
|
||||
await pluginService.installPlugin({ identifier: plugin.identifier, manifest: data, type });
|
||||
|
||||
updatePluginInstallProgress(name, {
|
||||
progress: 85,
|
||||
step: PluginInstallStep.INSTALLING_PLUGIN,
|
||||
});
|
||||
|
||||
await refreshPlugins();
|
||||
|
||||
// Step 4: Complete installation
|
||||
updatePluginInstallProgress(name, {
|
||||
progress: 100,
|
||||
step: PluginInstallStep.COMPLETED,
|
||||
});
|
||||
|
||||
// Briefly show completion status then clear progress
|
||||
await sleep(1000);
|
||||
|
||||
updatePluginInstallProgress(name, undefined);
|
||||
updateInstallLoadingState(name, undefined);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
const err = error as PluginInstallError;
|
||||
|
||||
// Set error state
|
||||
updatePluginInstallProgress(name, {
|
||||
error: err.message,
|
||||
progress: 0,
|
||||
step: PluginInstallStep.ERROR,
|
||||
});
|
||||
|
||||
updateInstallLoadingState(name, undefined);
|
||||
|
||||
notification.error({
|
||||
description: t(`error.${err.message}`, { ns: 'plugin' }),
|
||||
message: t('error.installError', { name: plugin.title, ns: 'plugin' }),
|
||||
});
|
||||
}
|
||||
// Old plugin system has been deprecated, skip installation silently
|
||||
};
|
||||
|
||||
installPlugin = async (
|
||||
name: string,
|
||||
type: 'plugin' | 'customPlugin' = 'plugin',
|
||||
_name: string,
|
||||
_type: 'plugin' | 'customPlugin' = 'plugin',
|
||||
): Promise<void> => {
|
||||
const plugin = pluginStoreSelectors.getPluginById(name)(this.#get());
|
||||
if (!plugin) return;
|
||||
|
||||
const { updateInstallLoadingState, refreshPlugins } = this.#get();
|
||||
try {
|
||||
updateInstallLoadingState(name, true);
|
||||
const data = await toolService.getToolManifest(plugin.manifest);
|
||||
|
||||
await pluginService.installPlugin({ identifier: plugin.identifier, manifest: data, type });
|
||||
await refreshPlugins();
|
||||
|
||||
updateInstallLoadingState(name, undefined);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
const err = error as PluginInstallError;
|
||||
|
||||
updateInstallLoadingState(name, undefined);
|
||||
|
||||
notification.error({
|
||||
description: t(`error.${err.message}`, { ns: 'plugin' }),
|
||||
message: t('error.installError', { name: plugin.title, ns: 'plugin' }),
|
||||
});
|
||||
}
|
||||
// Old plugin system has been deprecated, skip installation silently
|
||||
};
|
||||
|
||||
installPlugins = async (plugins: string[]): Promise<void> => {
|
||||
const { installPlugin } = this.#get();
|
||||
|
||||
await Promise.all(plugins.map((identifier) => installPlugin(identifier)));
|
||||
installPlugins = async (_plugins: string[]): Promise<void> => {
|
||||
// Old plugin system has been deprecated, skip installation silently
|
||||
};
|
||||
|
||||
loadMorePlugins = (): void => {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { act, renderHook } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { pluginService } from '@/services/plugin';
|
||||
import { type DiscoverPluginItem } from '@/types/discover';
|
||||
import { merge } from '@/utils/merge';
|
||||
|
||||
import { useToolStore } from '../../store';
|
||||
@@ -22,24 +21,8 @@ beforeEach(() => {
|
||||
|
||||
describe('useToolStore:plugin', () => {
|
||||
describe('checkPluginsIsInstalled', () => {
|
||||
it('should not perform any operations if the plugin list is empty', async () => {
|
||||
const installPluginsMock = vi.fn();
|
||||
useToolStore.setState({
|
||||
loadPluginStore: vi.fn(),
|
||||
installPlugins: installPluginsMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useToolStore());
|
||||
|
||||
await act(async () => {
|
||||
await result.current.checkPluginsIsInstalled([]);
|
||||
});
|
||||
|
||||
expect(installPluginsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load the plugin store and install plugins if necessary', async () => {
|
||||
const plugins = ['plugin1', 'plugin2'];
|
||||
it('should be deprecated and do nothing', async () => {
|
||||
// Old plugin system has been deprecated
|
||||
const loadPluginStoreMock = vi.fn();
|
||||
const installPluginsMock = vi.fn();
|
||||
useToolStore.setState({
|
||||
@@ -50,32 +33,12 @@ describe('useToolStore:plugin', () => {
|
||||
const { result } = renderHook(() => useToolStore());
|
||||
|
||||
await act(async () => {
|
||||
await result.current.checkPluginsIsInstalled(plugins);
|
||||
});
|
||||
|
||||
expect(loadPluginStoreMock).toHaveBeenCalled();
|
||||
expect(installPluginsMock).toHaveBeenCalledWith(plugins);
|
||||
});
|
||||
|
||||
it('should not load the plugin store and install plugins', async () => {
|
||||
const plugins = ['plugin1', 'plugin2'];
|
||||
const loadPluginStoreMock = vi.fn();
|
||||
const installPluginsMock = vi.fn();
|
||||
useToolStore.setState({
|
||||
loadPluginStore: loadPluginStoreMock,
|
||||
installPlugins: installPluginsMock,
|
||||
installedPlugins: [{ identifier: 'abc' }] as LobeTool[],
|
||||
oldPluginItems: [{ identifier: 'abc' }] as DiscoverPluginItem[],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useToolStore());
|
||||
|
||||
await act(async () => {
|
||||
await result.current.checkPluginsIsInstalled(plugins);
|
||||
await result.current.checkPluginsIsInstalled(['plugin1', 'plugin2']);
|
||||
});
|
||||
|
||||
// Should not call any methods since old plugin system is deprecated
|
||||
expect(loadPluginStoreMock).not.toHaveBeenCalled();
|
||||
expect(installPluginsMock).toHaveBeenCalledWith(plugins);
|
||||
expect(installPluginsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import { type StoreSetter } from '@/store/types';
|
||||
import { merge } from '@/utils/merge';
|
||||
|
||||
import { type ToolStore } from '../../store';
|
||||
import { pluginStoreSelectors } from '../oldStore/selectors';
|
||||
import { pluginSelectors } from './selectors';
|
||||
|
||||
/**
|
||||
@@ -29,19 +28,8 @@ export class PluginActionImpl {
|
||||
this.#get = get;
|
||||
}
|
||||
|
||||
checkPluginsIsInstalled = async (plugins: string[]): Promise<void> => {
|
||||
// if there is no plugins, just skip.
|
||||
if (plugins.length === 0) return;
|
||||
|
||||
const { loadPluginStore, installPlugins } = this.#get();
|
||||
|
||||
// check if the store is empty
|
||||
// if it is, we need to load the plugin store
|
||||
if (pluginStoreSelectors.onlinePluginStore(this.#get()).length === 0) {
|
||||
await loadPluginStore();
|
||||
}
|
||||
|
||||
await installPlugins(plugins);
|
||||
checkPluginsIsInstalled = async (_plugins: string[]): Promise<void> => {
|
||||
// Old plugin system has been deprecated, skip auto-installation
|
||||
};
|
||||
|
||||
removeAllPlugins = async (): Promise<void> => {
|
||||
|
||||
Reference in New Issue
Block a user