mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
♻️ refactor: remove base path (#9015)
* clean * remove * fix * move config to envs * remove envs
This commit is contained in:
@@ -37,13 +37,6 @@ When using the `random` mode, a random API Key will be selected from the availab
|
||||
|
||||
When using the `turn` mode, the API Keys will be retrieved in a polling manner according to the specified order.
|
||||
|
||||
### `NEXT_PUBLIC_BASE_PATH`
|
||||
|
||||
- Type: Optional
|
||||
- Description: Add a `basePath` for LobeChat.
|
||||
- Default: -
|
||||
- Example: `/test`
|
||||
|
||||
### `DEFAULT_AGENT_CONFIG`
|
||||
|
||||
- Type: Optional
|
||||
|
||||
@@ -34,13 +34,6 @@ LobeChat 在部署时提供了一些额外的配置项,你可以使用环境
|
||||
|
||||
使用 `turn` 模式下,将按照填写的顺序,轮询获取得到 API Key。
|
||||
|
||||
### `NEXT_PUBLIC_BASE_PATH`
|
||||
|
||||
- 类型:可选
|
||||
- 描述:为 LobeChat 添加 `basePath`
|
||||
- 默认值: `-`
|
||||
- 示例: `/test`
|
||||
|
||||
### `DEFAULT_AGENT_CONFIG`
|
||||
|
||||
- 类型:可选
|
||||
|
||||
@@ -13,7 +13,6 @@ const shouldUseCSP = process.env.ENABLED_CSP === '1';
|
||||
|
||||
// if you need to proxy the api endpoint to remote server
|
||||
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
|
||||
const isStandaloneMode = buildWithDocker || isDesktop;
|
||||
|
||||
const standaloneConfig: NextConfig = {
|
||||
@@ -23,7 +22,6 @@ const standaloneConfig: NextConfig = {
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
...(isStandaloneMode ? standaloneConfig : {}),
|
||||
basePath,
|
||||
compress: isProd,
|
||||
experimental: {
|
||||
optimizePackageImports: [
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import qs from 'query-string';
|
||||
import urlJoin from 'url-join';
|
||||
|
||||
import { withBasePath } from '@/utils/basePath';
|
||||
import { isDev } from '@/utils/env';
|
||||
|
||||
import { INBOX_SESSION_ID } from './session';
|
||||
@@ -56,7 +55,7 @@ export const SESSION_CHAT_URL = (id: string = INBOX_SESSION_ID, mobile?: boolean
|
||||
url: '/chat',
|
||||
});
|
||||
|
||||
export const imageUrl = (filename: string) => withBasePath(`/images/${filename}`);
|
||||
export const imageUrl = (filename: string) => `/images/${filename}`;
|
||||
|
||||
export const LOBE_URL_IMPORT_NAME = 'settings';
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Langfuse } from 'langfuse';
|
||||
import { LangfuseGenerationClient, LangfuseTraceClient } from 'langfuse-core';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import * as langfuseCfg from '@/config/langfuse';
|
||||
import * as langfuseCfg from '@/envs/langfuse';
|
||||
import { createTraceOptions } from '@/server/modules/ModelRuntime';
|
||||
|
||||
import { ChatStreamPayload, LobeOpenAI, ModelProvider, ModelRuntime } from '.';
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { appEnv } from '@/envs/app';
|
||||
|
||||
export const withBasePath = (path: string) => appEnv.NEXT_PUBLIC_BASE_PATH + path;
|
||||
@@ -2,16 +2,10 @@ import { BRANDING_LOGO_URL, BRANDING_NAME, ORG_NAME } from '@/const/branding';
|
||||
import { DEFAULT_LANG } from '@/const/locale';
|
||||
import { OFFICIAL_URL, OG_URL } from '@/const/url';
|
||||
import { isCustomBranding, isCustomORG } from '@/const/version';
|
||||
import { appEnv } from '@/envs/app';
|
||||
import { translation } from '@/server/translation';
|
||||
import { DynamicLayoutProps } from '@/types/next';
|
||||
import { RouteVariants } from '@/utils/server/routeVariants';
|
||||
|
||||
const BASE_PATH = appEnv.NEXT_PUBLIC_BASE_PATH;
|
||||
|
||||
// if there is a base path, then we don't need the manifest
|
||||
const noManifest = !!BASE_PATH;
|
||||
|
||||
export const generateMetadata = async (props: DynamicLayoutProps) => {
|
||||
const locale = await RouteVariants.getLocale(props);
|
||||
const { t } = await translation('metadata', locale);
|
||||
@@ -32,7 +26,7 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
|
||||
icon: '/favicon.ico?v=1',
|
||||
shortcut: '/favicon-32x32.ico?v=1',
|
||||
},
|
||||
manifest: noManifest ? undefined : '/manifest.json',
|
||||
manifest: '/manifest.json',
|
||||
metadataBase: new URL(OFFICIAL_URL),
|
||||
openGraph: {
|
||||
description: t('chat.description', { appName: BRANDING_NAME }),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { GoogleAnalytics as GA } from '@next/third-parties/google';
|
||||
|
||||
import { analyticsEnv } from '@/config/analytics';
|
||||
import { analyticsEnv } from '@/envs/analytics';
|
||||
|
||||
const GoogleAnalytics = () => <GA gaId={analyticsEnv.GOOGLE_ANALYTICS_MEASUREMENT_ID!} />;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ReactNode, memo } from 'react';
|
||||
|
||||
import { LobeAnalyticsProvider } from '@/components/Analytics/LobeAnalyticsProvider';
|
||||
import { analyticsEnv } from '@/config/analytics';
|
||||
import { analyticsEnv } from '@/envs/analytics';
|
||||
import { isDev } from '@/utils/env';
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Analytics } from '@vercel/analytics/react';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { analyticsEnv } from '@/config/analytics';
|
||||
import { analyticsEnv } from '@/envs/analytics';
|
||||
|
||||
const VercelAnalytics = memo(() => <Analytics debug={analyticsEnv.DEBUG_VERCEL_ANALYTICS} />);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
import { analyticsEnv } from '@/config/analytics';
|
||||
import { isDesktop } from '@/const/version';
|
||||
import { analyticsEnv } from '@/envs/analytics';
|
||||
|
||||
import Desktop from './Desktop';
|
||||
import Google from './Google';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @vitest-environment node
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { analyticsEnv, getAnalyticsConfig } from '../analytics';
|
||||
import { analyticsEnv, getAnalyticsConfig } from '../../envs/analytics';
|
||||
|
||||
beforeEach(() => {
|
||||
// 在每个测试用例之前,清除所有的 console.warn mock
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { getDebugConfig } from '../debug';
|
||||
import { getDebugConfig } from '../../envs/debug';
|
||||
|
||||
// 测试前重置 process.env
|
||||
vi.stubGlobal('process', {
|
||||
|
||||
@@ -32,7 +32,6 @@ export const getAppConfig = () => {
|
||||
|
||||
return createEnv({
|
||||
client: {
|
||||
NEXT_PUBLIC_BASE_PATH: z.string(),
|
||||
NEXT_PUBLIC_ENABLE_SENTRY: z.boolean(),
|
||||
},
|
||||
server: {
|
||||
@@ -59,8 +58,6 @@ export const getAppConfig = () => {
|
||||
SSRF_ALLOW_IP_ADDRESS_LIST: z.string().optional(),
|
||||
},
|
||||
runtimeEnv: {
|
||||
NEXT_PUBLIC_BASE_PATH: process.env.NEXT_PUBLIC_BASE_PATH || '',
|
||||
|
||||
// Sentry
|
||||
NEXT_PUBLIC_ENABLE_SENTRY: !!process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createServerAnalytics } from '@lobehub/analytics/server';
|
||||
|
||||
import { analyticsEnv } from '@/config/analytics';
|
||||
import { BUSINESS_LINE } from '@/const/analytics';
|
||||
import { analyticsEnv } from '@/envs/analytics';
|
||||
import { isDev } from '@/utils/env';
|
||||
|
||||
export const serverAnalytics = createServerAnalytics({
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Langfuse } from 'langfuse';
|
||||
import { CreateLangfuseTraceBody } from 'langfuse-core';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import * as server from '@/config/langfuse';
|
||||
import * as server from '@/envs/langfuse';
|
||||
|
||||
import { TraceClient } from './index';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Langfuse } from 'langfuse';
|
||||
import { CreateLangfuseTraceBody } from 'langfuse-core';
|
||||
|
||||
import { getLangfuseConfig } from '@/config/langfuse';
|
||||
import { CURRENT_VERSION } from '@/const/version';
|
||||
import { getLangfuseConfig } from '@/envs/langfuse';
|
||||
import { TraceEventClient } from '@/libs/traces/event';
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@ import superjson from 'superjson';
|
||||
|
||||
import { isDesktop } from '@/const/version';
|
||||
import type { EdgeRouter } from '@/server/routers/edge';
|
||||
import { withBasePath } from '@/utils/basePath';
|
||||
import { fetchWithDesktopRemoteRPC } from '@/utils/electron/desktopRemoteRPCFetch';
|
||||
|
||||
export const edgeClient = createTRPCClient<EdgeRouter>({
|
||||
@@ -21,7 +20,7 @@ export const edgeClient = createTRPCClient<EdgeRouter>({
|
||||
},
|
||||
maxURLLength: 2083,
|
||||
transformer: superjson,
|
||||
url: withBasePath('/trpc/edge'),
|
||||
url: '/trpc/edge',
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import { UnstructuredClient } from 'unstructured-client';
|
||||
import { Strategy } from 'unstructured-client/sdk/models/shared';
|
||||
import { PartitionResponse } from 'unstructured-client/src/sdk/models/operations';
|
||||
|
||||
import { knowledgeEnv } from '@/config/knowledge';
|
||||
import { knowledgeEnv } from '@/envs/knowledge';
|
||||
|
||||
export enum ChunkingStrategy {
|
||||
Basic = 'basic',
|
||||
|
||||
@@ -4,8 +4,8 @@ import resourcesToBackend from 'i18next-resources-to-backend';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import { isRtlLang } from 'rtl-detect';
|
||||
|
||||
import { getDebugConfig } from '@/config/debug';
|
||||
import { DEFAULT_LANG } from '@/const/locale';
|
||||
import { getDebugConfig } from '@/envs/debug';
|
||||
import { normalizeLocale } from '@/locales/resources';
|
||||
import { isDev, isOnServerSide } from '@/utils/env';
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { knowledgeEnv } from '@/config/knowledge';
|
||||
import { getAppConfig } from '@/envs/app';
|
||||
import { SystemEmbeddingConfig } from '@/types/knowledgeBase';
|
||||
import { FilesConfigItem } from '@/types/user/settings/filesConfig';
|
||||
@@ -13,7 +12,7 @@ vi.mock('@/envs/app', () => ({
|
||||
getAppConfig: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@/config/knowledge', () => ({
|
||||
vi.mock('@/envs/knowledge', () => ({
|
||||
knowledgeEnv: {
|
||||
DEFAULT_FILES_CONFIG: 'test_config',
|
||||
},
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { authEnv } from '@/config/auth';
|
||||
import { fileEnv } from '@/config/file';
|
||||
import { knowledgeEnv } from '@/config/knowledge';
|
||||
import { langfuseEnv } from '@/config/langfuse';
|
||||
import { enableNextAuth } from '@/const/auth';
|
||||
import { isDesktop } from '@/const/version';
|
||||
import { appEnv, getAppConfig } from '@/envs/app';
|
||||
import { knowledgeEnv } from '@/envs/knowledge';
|
||||
import { langfuseEnv } from '@/envs/langfuse';
|
||||
import { parseSystemAgent } from '@/server/globalConfig/parseSystemAgent';
|
||||
import { GlobalServerConfig } from '@/types/serverConfig';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Strategy } from 'unstructured-client/sdk/models/shared';
|
||||
|
||||
import { knowledgeEnv } from '@/config/knowledge';
|
||||
import type { NewChunkItem, NewUnstructuredChunkItem } from '@/database/schemas';
|
||||
import { knowledgeEnv } from '@/envs/knowledge';
|
||||
import { ChunkingLoader } from '@/libs/langchain';
|
||||
import { ChunkingStrategy, Unstructured } from '@/libs/unstructured';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { toolsEnv } from '@/config/tools';
|
||||
import { toolsEnv } from '@/envs/tools';
|
||||
import { SearXNGClient } from '@/server/services/search/impls/searxng/client';
|
||||
import { SEARCH_SEARXNG_NOT_CONFIG } from '@/types/tool/search';
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SearXNGClient } from './client';
|
||||
import { hetongxue } from './fixtures/searXNG';
|
||||
import { SearXNGImpl } from './index';
|
||||
|
||||
vi.mock('@/config/tools', () => ({
|
||||
vi.mock('@/envs/tools', () => ({
|
||||
toolsEnv: {
|
||||
SEARXNG_URL: 'https://demo.com',
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
|
||||
import { toolsEnv } from '@/config/tools';
|
||||
import { toolsEnv } from '@/envs/tools';
|
||||
import { SearXNGClient } from '@/server/services/search/impls/searxng/client';
|
||||
import { SEARCH_SEARXNG_NOT_CONFIG, UniformSearchResponse } from '@/types/tool/search';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CrawlImplType, Crawler } from '@lobechat/web-crawler';
|
||||
import pMap from 'p-map';
|
||||
|
||||
import { toolsEnv } from '@/config/tools';
|
||||
import { toolsEnv } from '@/envs/tools';
|
||||
import { SearchParams } from '@/types/tool/search';
|
||||
|
||||
import { SearchImplType, SearchServiceImpl, createSearchServiceImpl } from './impls';
|
||||
|
||||
+5
-18
@@ -1,20 +1,7 @@
|
||||
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
||||
import { transform } from 'lodash-es';
|
||||
|
||||
import { withBasePath } from '@/utils/basePath';
|
||||
|
||||
const mapWithBasePath = <T extends object>(apis: T): T => {
|
||||
return transform(apis, (result, value, key) => {
|
||||
if (typeof value === 'string') {
|
||||
// @ts-ignore
|
||||
result[key] = withBasePath(value);
|
||||
} else {
|
||||
result[key] = value;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const API_ENDPOINTS = mapWithBasePath({
|
||||
export const API_ENDPOINTS = {
|
||||
oauth: '/api/auth',
|
||||
|
||||
proxy: '/webapi/proxy',
|
||||
@@ -26,11 +13,11 @@ export const API_ENDPOINTS = mapWithBasePath({
|
||||
trace: '/webapi/trace',
|
||||
|
||||
// chat
|
||||
chat: (provider: string) => withBasePath(`/webapi/chat/${provider}`),
|
||||
chat: (provider: string) => `/webapi/chat/${provider}`,
|
||||
|
||||
// models
|
||||
models: (provider: string) => withBasePath(`/webapi/models/${provider}`),
|
||||
modelPull: (provider: string) => withBasePath(`/webapi/models/${provider}/pull`),
|
||||
models: (provider: string) => `/webapi/models/${provider}`,
|
||||
modelPull: (provider: string) => `/webapi/models/${provider}/pull`,
|
||||
|
||||
// image
|
||||
images: (provider: string) => `/webapi/text-to-image/${provider}`,
|
||||
@@ -42,4 +29,4 @@ export const API_ENDPOINTS = mapWithBasePath({
|
||||
tts: '/webapi/tts/openai',
|
||||
edge: '/webapi/tts/edge',
|
||||
microsoft: '/webapi/tts/microsoft',
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { PartialDeep } from 'type-fest';
|
||||
|
||||
import { LOBE_URL_IMPORT_NAME } from '@/const/url';
|
||||
import { UserSettings } from '@/types/user/settings';
|
||||
import { withBasePath } from '@/utils/basePath';
|
||||
|
||||
class ShareService {
|
||||
/**
|
||||
@@ -11,7 +10,7 @@ class ShareService {
|
||||
* @returns The share settings URL.
|
||||
*/
|
||||
public createShareSettingsUrl = (settings: PartialDeep<UserSettings>) => {
|
||||
return withBasePath(`/?${LOBE_URL_IMPORT_NAME}=${encodeURI(JSON.stringify(settings))}`);
|
||||
return `/?${LOBE_URL_IMPORT_NAME}=${encodeURI(JSON.stringify(settings))}`;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user