From 152913e29dd0072005bcdde6264448ac8912ca7a Mon Sep 17 00:00:00 2001 From: Arvin Xu Date: Sun, 24 Dec 2023 18:07:07 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20fix=20`PLUGINS=5FINDEX=5F?= =?UTF-8?q?URL`=20not=20working=20(#793)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/{plugins => plugin/gateway}/route.ts | 6 ++++-- src/app/api/plugin/store/Store.ts | 19 +++++++++++++++++ src/app/api/plugin/store/route.ts | 21 +++++++++++++++++++ src/const/url.ts | 9 -------- src/services/__tests__/plugin.test.ts | 13 +++--------- src/services/_url.ts | 9 +++++--- src/services/chat.ts | 4 ++-- src/services/file.ts | 4 ++-- src/services/plugin.ts | 15 ++++++------- 9 files changed, 63 insertions(+), 37 deletions(-) rename src/app/api/{plugins => plugin/gateway}/route.ts (54%) create mode 100644 src/app/api/plugin/store/Store.ts create mode 100644 src/app/api/plugin/store/route.ts diff --git a/src/app/api/plugins/route.ts b/src/app/api/plugin/gateway/route.ts similarity index 54% rename from src/app/api/plugins/route.ts rename to src/app/api/plugin/gateway/route.ts index 0b9589c39a81..27e464916418 100644 --- a/src/app/api/plugins/route.ts +++ b/src/app/api/plugin/gateway/route.ts @@ -1,5 +1,7 @@ import { createGatewayOnEdgeRuntime } from '@lobehub/chat-plugins-gateway'; -import { PLUGINS_INDEX_URL } from '@/const/url'; +import { getServerConfig } from '@/config/server'; -export const POST = createGatewayOnEdgeRuntime({ pluginsIndexUrl: PLUGINS_INDEX_URL }); +const pluginsIndexUrl = getServerConfig().PLUGINS_INDEX_URL; + +export const POST = createGatewayOnEdgeRuntime({ pluginsIndexUrl }); diff --git a/src/app/api/plugin/store/Store.ts b/src/app/api/plugin/store/Store.ts new file mode 100644 index 000000000000..5da346c20e10 --- /dev/null +++ b/src/app/api/plugin/store/Store.ts @@ -0,0 +1,19 @@ +import urlJoin from 'url-join'; + +import { getServerConfig } from '@/config/server'; +import { DEFAULT_LANG, checkLang } from '@/const/locale'; +import { Locales } from '@/locales/resources'; + +export class PluginStore { + private readonly baseUrl: string; + + constructor(baseUrl?: string) { + this.baseUrl = baseUrl || getServerConfig().PLUGINS_INDEX_URL; + } + + getPluginIndexUrl = (lang: Locales = DEFAULT_LANG) => { + if (checkLang(lang)) return this.baseUrl; + + return urlJoin(this.baseUrl, `index.${lang}.json`); + }; +} diff --git a/src/app/api/plugin/store/route.ts b/src/app/api/plugin/store/route.ts new file mode 100644 index 000000000000..afe198ba99be --- /dev/null +++ b/src/app/api/plugin/store/route.ts @@ -0,0 +1,21 @@ +import { DEFAULT_LANG } from '@/const/locale'; + +import { PluginStore } from './Store'; + +export const runtime = 'edge'; + +export const GET = async (req: Request) => { + const locale = new URL(req.url).searchParams.get('locale'); + + const pluginStore = new PluginStore(); + + let res: Response; + + res = await fetch(pluginStore.getPluginIndexUrl(locale as any)); + + if (res.status === 404) { + res = await fetch(pluginStore.getPluginIndexUrl(DEFAULT_LANG)); + } + + return res; +}; diff --git a/src/const/url.ts b/src/const/url.ts index 8847bb4491ce..fc9fbb8d6660 100644 --- a/src/const/url.ts +++ b/src/const/url.ts @@ -1,9 +1,6 @@ import urlJoin from 'url-join'; -import { Locales } from '@/locales/resources'; - import pkg from '../../package.json'; -import { DEFAULT_LANG, checkLang } from './locale'; import { INBOX_SESSION_ID } from './session'; export const GITHUB = pkg.homepage; @@ -16,12 +13,6 @@ export const DISCORD = 'https://discord.gg/AYFPHvv2jT'; export const PLUGINS_INDEX_URL = 'https://chat-plugins.lobehub.com'; -export const getPluginIndexJSON = (lang: Locales = DEFAULT_LANG, baseUrl = PLUGINS_INDEX_URL) => { - if (checkLang(lang)) return baseUrl; - - return urlJoin(baseUrl, `index.${lang}.json`); -}; - export const AGENTS_INDEX_GITHUB = 'https://github.com/lobehub/lobe-chat-agents'; export const AGENTS_INDEX_GITHUB_ISSUE = urlJoin(AGENTS_INDEX_GITHUB, 'issues/new'); diff --git a/src/services/__tests__/plugin.test.ts b/src/services/__tests__/plugin.test.ts index f5b70cda7330..4634f9559e25 100644 --- a/src/services/__tests__/plugin.test.ts +++ b/src/services/__tests__/plugin.test.ts @@ -1,7 +1,6 @@ import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk'; import { Mock, beforeEach, describe, expect, it, vi } from 'vitest'; -import { getPluginIndexJSON } from '@/const/url'; import { PluginModel } from '@/database/models/plugin'; import { DB_Plugin } from '@/database/schemas/plugin'; import { globalHelpers } from '@/store/global/helpers'; @@ -13,9 +12,7 @@ import openAPIV3 from './openai/OpenAPI_V3.json'; import OpenAIPlugin from './openai/plugin.json'; // Mocking modules and functions -vi.mock('@/const/url', () => ({ - getPluginIndexJSON: vi.fn(), -})); + vi.mock('@/store/global/helpers', () => ({ globalHelpers: { getCurrentLanguage: vi.fn(), @@ -40,9 +37,7 @@ describe('PluginService', () => { it('should fetch and return the plugin list', async () => { // Arrange const fakeResponse = { plugins: [{ name: 'TestPlugin' }] }; - const fakeUrl = 'http://fake-url.com/plugins.json'; - (globalHelpers.getCurrentLanguage as Mock).mockReturnValue('en'); - (getPluginIndexJSON as Mock).mockReturnValue(fakeUrl); + (globalHelpers.getCurrentLanguage as Mock).mockReturnValue('tt'); global.fetch = vi.fn(() => Promise.resolve({ json: () => Promise.resolve(fakeResponse), @@ -54,8 +49,7 @@ describe('PluginService', () => { // Assert expect(globalHelpers.getCurrentLanguage).toHaveBeenCalled(); - expect(getPluginIndexJSON).toHaveBeenCalledWith('en'); - expect(fetch).toHaveBeenCalledWith(fakeUrl); + expect(fetch).toHaveBeenCalledWith('/api/plugin/store?locale=tt'); expect(pluginList).toEqual(fakeResponse); }); @@ -63,7 +57,6 @@ describe('PluginService', () => { // Arrange const fakeUrl = 'http://fake-url.com/plugins.json'; (globalHelpers.getCurrentLanguage as Mock).mockReturnValue('en'); - (getPluginIndexJSON as Mock).mockReturnValue(fakeUrl); global.fetch = vi.fn(() => Promise.reject(new Error('Network error'))); // Act & Assert diff --git a/src/services/_url.ts b/src/services/_url.ts index a827f89b2059..1cd56915be34 100644 --- a/src/services/_url.ts +++ b/src/services/_url.ts @@ -1,7 +1,12 @@ export const URLS = { config: '/api/config', market: '/api/market', - plugins: '/api/plugins', + proxy: '/api/proxy', +}; + +export const PLUGINS_URLS = { + gateway: '/api/plugin/gateway', + store: '/api/plugin/store', }; export const OPENAI_URLS = { @@ -16,5 +21,3 @@ export const TTS_URL = { edge: '/api/tts/edge-speech', microsoft: '/api/tts/microsoft-speech', }; - -export const PROXY_URL = '/api/proxy'; diff --git a/src/services/chat.ts b/src/services/chat.ts index 7ab0cc6b7cdc..9aac41b5ab35 100644 --- a/src/services/chat.ts +++ b/src/services/chat.ts @@ -13,7 +13,7 @@ import { UserMessageContentPart } from '@/types/openai/chat'; import { fetchAIFactory, getMessageError } from '@/utils/fetch'; import { createHeaderWithOpenAI } from './_header'; -import { OPENAI_URLS, URLS } from './_url'; +import { OPENAI_URLS, PLUGINS_URLS } from './_url'; const isVisionModel = (model?: string) => model && VISION_MODEL_WHITE_LIST.includes(model); @@ -92,7 +92,7 @@ class ChatService { const gatewayURL = manifest?.gateway; - const res = await fetch(gatewayURL ?? URLS.plugins, { + const res = await fetch(gatewayURL ?? PLUGINS_URLS.gateway, { body: JSON.stringify({ ...params, manifest }), headers: createHeadersWithPluginSettings(settings), method: 'POST', diff --git a/src/services/file.ts b/src/services/file.ts index 61fcdfdbe746..fd1592695191 100644 --- a/src/services/file.ts +++ b/src/services/file.ts @@ -1,6 +1,6 @@ import { FileModel } from '@/database/models/file'; import { DB_File } from '@/database/schemas/files'; -import { PROXY_URL } from '@/services/_url'; +import { URLS } from '@/services/_url'; import { FilePreview } from '@/types/files'; import compressImage from '@/utils/compressImage'; @@ -43,7 +43,7 @@ class FileService { } async uploadImageByUrl(url: string, file: Pick) { - const res = await fetch(PROXY_URL, { body: url, method: 'POST' }); + const res = await fetch(URLS.proxy, { body: url, method: 'POST' }); const data = await res.arrayBuffer(); const fileType = res.headers.get('content-type') || 'image/webp'; diff --git a/src/services/plugin.ts b/src/services/plugin.ts index 95cd308d6b87..b236ae05ef2f 100644 --- a/src/services/plugin.ts +++ b/src/services/plugin.ts @@ -4,9 +4,8 @@ import { pluginManifestSchema, } from '@lobehub/chat-plugin-sdk'; -import { getPluginIndexJSON } from '@/const/url'; import { PluginModel } from '@/database/models/plugin'; -import { PROXY_URL } from '@/services/_url'; +import { PLUGINS_URLS, URLS } from '@/services/_url'; import { globalHelpers } from '@/store/global/helpers'; import { OpenAIPluginManifest } from '@/types/openai/plugin'; import { LobeTool } from '@/types/tool'; @@ -22,7 +21,7 @@ class PluginService { // 2. 发送请求 let res: Response; try { - res = await (proxy ? fetch(PROXY_URL, { body: url, method: 'POST' }) : fetch(url)); + res = await (proxy ? fetch(URLS.proxy, { body: url, method: 'POST' }) : fetch(url)); } catch { throw new TypeError('fetchError'); } @@ -52,14 +51,12 @@ class PluginService { /** * get plugin list from store */ - getPluginList = async () => { - const url = getPluginIndexJSON(globalHelpers.getCurrentLanguage()); + getPluginList = async (): Promise => { + const locale = globalHelpers.getCurrentLanguage(); - const res = await fetch(url); + const res = await fetch(`${PLUGINS_URLS.store}?locale=${locale}`); - const data: LobeChatPluginsMarketIndex = await res.json(); - - return data; + return res.json(); }; getPluginManifest = async (