This commit is contained in:
Stephen Zhou
2026-02-06 11:34:00 +08:00
parent 7d34faaf74
commit 5b22d5026b
8 changed files with 182 additions and 75 deletions

View File

@ -3,6 +3,7 @@
import { SerwistProvider } from '@serwist/turbopack/react'
import { useEffect } from 'react'
import { IS_DEV } from '@/config'
import { env } from '@/env'
import { isClient } from '@/utils/client'
export function PWAProvider({ children }: { children: React.ReactNode }) {
@ -10,7 +11,7 @@ export function PWAProvider({ children }: { children: React.ReactNode }) {
return <DisabledPWAProvider>{children}</DisabledPWAProvider>
}
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ''
const basePath = env.NEXT_PUBLIC_BASE_PATH || ''
const swUrl = `${basePath}/serwist/sw.js`
return (

View File

@ -5,6 +5,7 @@ import { Instrument_Serif } from 'next/font/google'
import { NuqsAdapter } from 'nuqs/adapters/next/app'
import GlobalPublicStoreProvider from '@/context/global-public-context'
import { TanstackQueryInitializer } from '@/context/query-client'
import { env } from '@/env'
import { getLocaleOnServer } from '@/i18n-config/server'
import { DatasetAttr } from '@/types/feature'
import { cn } from '@/utils/classnames'
@ -41,37 +42,37 @@ const LocaleLayout = async ({
const locale = await getLocaleOnServer()
const datasetMap: Record<DatasetAttr, string | undefined> = {
[DatasetAttr.DATA_API_PREFIX]: process.env.NEXT_PUBLIC_API_PREFIX,
[DatasetAttr.DATA_PUBLIC_API_PREFIX]: process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX,
[DatasetAttr.DATA_MARKETPLACE_API_PREFIX]: process.env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX,
[DatasetAttr.DATA_MARKETPLACE_URL_PREFIX]: process.env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX,
[DatasetAttr.DATA_PUBLIC_EDITION]: process.env.NEXT_PUBLIC_EDITION,
[DatasetAttr.DATA_PUBLIC_AMPLITUDE_API_KEY]: process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY,
[DatasetAttr.DATA_PUBLIC_COOKIE_DOMAIN]: process.env.NEXT_PUBLIC_COOKIE_DOMAIN,
[DatasetAttr.DATA_PUBLIC_SUPPORT_MAIL_LOGIN]: process.env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN,
[DatasetAttr.DATA_PUBLIC_SENTRY_DSN]: process.env.NEXT_PUBLIC_SENTRY_DSN,
[DatasetAttr.DATA_PUBLIC_MAINTENANCE_NOTICE]: process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE,
[DatasetAttr.DATA_PUBLIC_SITE_ABOUT]: process.env.NEXT_PUBLIC_SITE_ABOUT,
[DatasetAttr.DATA_PUBLIC_TEXT_GENERATION_TIMEOUT_MS]: process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS,
[DatasetAttr.DATA_PUBLIC_MAX_TOOLS_NUM]: process.env.NEXT_PUBLIC_MAX_TOOLS_NUM,
[DatasetAttr.DATA_PUBLIC_MAX_PARALLEL_LIMIT]: process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT,
[DatasetAttr.DATA_PUBLIC_TOP_K_MAX_VALUE]: process.env.NEXT_PUBLIC_TOP_K_MAX_VALUE,
[DatasetAttr.DATA_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH]: process.env.NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH,
[DatasetAttr.DATA_PUBLIC_LOOP_NODE_MAX_COUNT]: process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT,
[DatasetAttr.DATA_PUBLIC_MAX_ITERATIONS_NUM]: process.env.NEXT_PUBLIC_MAX_ITERATIONS_NUM,
[DatasetAttr.DATA_PUBLIC_MAX_TREE_DEPTH]: process.env.NEXT_PUBLIC_MAX_TREE_DEPTH,
[DatasetAttr.DATA_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME]: process.env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME,
[DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_JINAREADER]: process.env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER,
[DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_FIRECRAWL]: process.env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL,
[DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_WATERCRAWL]: process.env.NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
[DatasetAttr.DATA_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX]: process.env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_WIDGET_KEY]: process.env.NEXT_PUBLIC_ZENDESK_WIDGET_KEY,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT]: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION]: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL]: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID]: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN]: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN,
[DatasetAttr.DATA_PUBLIC_BATCH_CONCURRENCY]: process.env.NEXT_PUBLIC_BATCH_CONCURRENCY,
[DatasetAttr.DATA_API_PREFIX]: env.NEXT_PUBLIC_API_PREFIX,
[DatasetAttr.DATA_PUBLIC_API_PREFIX]: env.NEXT_PUBLIC_PUBLIC_API_PREFIX,
[DatasetAttr.DATA_MARKETPLACE_API_PREFIX]: env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX,
[DatasetAttr.DATA_MARKETPLACE_URL_PREFIX]: env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX,
[DatasetAttr.DATA_PUBLIC_EDITION]: env.NEXT_PUBLIC_EDITION,
[DatasetAttr.DATA_PUBLIC_AMPLITUDE_API_KEY]: env.NEXT_PUBLIC_AMPLITUDE_API_KEY,
[DatasetAttr.DATA_PUBLIC_COOKIE_DOMAIN]: env.NEXT_PUBLIC_COOKIE_DOMAIN,
[DatasetAttr.DATA_PUBLIC_SUPPORT_MAIL_LOGIN]: env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN,
[DatasetAttr.DATA_PUBLIC_SENTRY_DSN]: env.NEXT_PUBLIC_SENTRY_DSN,
[DatasetAttr.DATA_PUBLIC_MAINTENANCE_NOTICE]: env.NEXT_PUBLIC_MAINTENANCE_NOTICE,
[DatasetAttr.DATA_PUBLIC_SITE_ABOUT]: env.NEXT_PUBLIC_SITE_ABOUT,
[DatasetAttr.DATA_PUBLIC_TEXT_GENERATION_TIMEOUT_MS]: env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS,
[DatasetAttr.DATA_PUBLIC_MAX_TOOLS_NUM]: env.NEXT_PUBLIC_MAX_TOOLS_NUM,
[DatasetAttr.DATA_PUBLIC_MAX_PARALLEL_LIMIT]: env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT,
[DatasetAttr.DATA_PUBLIC_TOP_K_MAX_VALUE]: env.NEXT_PUBLIC_TOP_K_MAX_VALUE,
[DatasetAttr.DATA_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH]: env.NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH,
[DatasetAttr.DATA_PUBLIC_LOOP_NODE_MAX_COUNT]: env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT,
[DatasetAttr.DATA_PUBLIC_MAX_ITERATIONS_NUM]: env.NEXT_PUBLIC_MAX_ITERATIONS_NUM,
[DatasetAttr.DATA_PUBLIC_MAX_TREE_DEPTH]: env.NEXT_PUBLIC_MAX_TREE_DEPTH,
[DatasetAttr.DATA_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME]: env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME,
[DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_JINAREADER]: env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER,
[DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_FIRECRAWL]: env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL,
[DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_WATERCRAWL]: env.NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
[DatasetAttr.DATA_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX]: env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_WIDGET_KEY]: env.NEXT_PUBLIC_ZENDESK_WIDGET_KEY,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT]: env.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION]: env.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL]: env.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID]: env.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID,
[DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN]: env.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN,
[DatasetAttr.DATA_PUBLIC_BATCH_CONCURRENCY]: env.NEXT_PUBLIC_BATCH_CONCURRENCY,
}
return (

View File

@ -1,6 +1,7 @@
import { createSerwistRoute } from '@serwist/turbopack'
import { env } from '@/env'
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ''
const basePath = env.NEXT_PUBLIC_BASE_PATH || ''
export const { dynamic, dynamicParams, revalidate, generateStaticParams, GET } = createSerwistRoute({
swSrc: 'app/sw.ts',

View File

@ -1,5 +1,6 @@
import type { ModelParameterRule } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { InputVarType } from '@/app/components/workflow/types'
import { env } from '@/env'
import { PromptRole } from '@/models/debug'
import { PipelineInputVarType } from '@/models/pipeline'
import { AgentStrategy } from '@/types/app'
@ -54,28 +55,28 @@ const getStringConfig = (
}
export const API_PREFIX = getStringConfig(
process.env.NEXT_PUBLIC_API_PREFIX,
env.NEXT_PUBLIC_API_PREFIX,
DatasetAttr.DATA_API_PREFIX,
'http://localhost:5001/console/api',
)
export const PUBLIC_API_PREFIX = getStringConfig(
process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX,
env.NEXT_PUBLIC_PUBLIC_API_PREFIX,
DatasetAttr.DATA_PUBLIC_API_PREFIX,
'http://localhost:5001/api',
)
export const MARKETPLACE_API_PREFIX = getStringConfig(
process.env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX,
env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX,
DatasetAttr.DATA_MARKETPLACE_API_PREFIX,
'http://localhost:5002/api',
)
export const MARKETPLACE_URL_PREFIX = getStringConfig(
process.env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX,
env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX,
DatasetAttr.DATA_MARKETPLACE_URL_PREFIX,
'',
)
const EDITION = getStringConfig(
process.env.NEXT_PUBLIC_EDITION,
env.NEXT_PUBLIC_EDITION,
DatasetAttr.DATA_PUBLIC_EDITION,
'SELF_HOSTED',
)
@ -84,16 +85,16 @@ export const IS_CE_EDITION = EDITION === 'SELF_HOSTED'
export const IS_CLOUD_EDITION = EDITION === 'CLOUD'
export const AMPLITUDE_API_KEY = getStringConfig(
process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY,
env.NEXT_PUBLIC_AMPLITUDE_API_KEY,
DatasetAttr.DATA_PUBLIC_AMPLITUDE_API_KEY,
'',
)
export const IS_DEV = process.env.NODE_ENV === 'development'
export const IS_PROD = process.env.NODE_ENV === 'production'
export const IS_DEV = env.NODE_ENV === 'development'
export const IS_PROD = env.NODE_ENV === 'production'
export const SUPPORT_MAIL_LOGIN = !!(
process.env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN
env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN
|| globalThis.document?.body?.getAttribute('data-public-support-mail-login')
)
@ -161,13 +162,13 @@ export const getMaxToken = (modelId: string) => {
export const LOCALE_COOKIE_NAME = 'locale'
const COOKIE_DOMAIN = getStringConfig(
process.env.NEXT_PUBLIC_COOKIE_DOMAIN,
env.NEXT_PUBLIC_COOKIE_DOMAIN,
DatasetAttr.DATA_PUBLIC_COOKIE_DOMAIN,
'',
).trim()
export const BATCH_CONCURRENCY = getNumberConfig(
process.env.NEXT_PUBLIC_BATCH_CONCURRENCY,
env.NEXT_PUBLIC_BATCH_CONCURRENCY,
DatasetAttr.DATA_PUBLIC_BATCH_CONCURRENCY,
5, // default
)
@ -342,10 +343,10 @@ export const VAR_REGEX
export const resetReg = () => (VAR_REGEX.lastIndex = 0)
export const DISABLE_UPLOAD_IMAGE_AS_ICON
= process.env.NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON === 'true'
= env.NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON === 'true'
export const GITHUB_ACCESS_TOKEN
= process.env.NEXT_PUBLIC_GITHUB_ACCESS_TOKEN || ''
= env.NEXT_PUBLIC_GITHUB_ACCESS_TOKEN || ''
export const SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS = '.difypkg,.difybndl'
export const FULL_DOC_PREVIEW_LENGTH = 50
@ -353,58 +354,58 @@ export const FULL_DOC_PREVIEW_LENGTH = 50
export const JSON_SCHEMA_MAX_DEPTH = 10
export const MAX_TOOLS_NUM = getNumberConfig(
process.env.NEXT_PUBLIC_MAX_TOOLS_NUM,
env.NEXT_PUBLIC_MAX_TOOLS_NUM,
DatasetAttr.DATA_PUBLIC_MAX_TOOLS_NUM,
10,
)
export const MAX_PARALLEL_LIMIT = getNumberConfig(
process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT,
env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT,
DatasetAttr.DATA_PUBLIC_MAX_PARALLEL_LIMIT,
10,
)
export const TEXT_GENERATION_TIMEOUT_MS = getNumberConfig(
process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS,
env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS,
DatasetAttr.DATA_PUBLIC_TEXT_GENERATION_TIMEOUT_MS,
60000,
)
export const LOOP_NODE_MAX_COUNT = getNumberConfig(
process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT,
env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT,
DatasetAttr.DATA_PUBLIC_LOOP_NODE_MAX_COUNT,
100,
)
export const MAX_ITERATIONS_NUM = getNumberConfig(
process.env.NEXT_PUBLIC_MAX_ITERATIONS_NUM,
env.NEXT_PUBLIC_MAX_ITERATIONS_NUM,
DatasetAttr.DATA_PUBLIC_MAX_ITERATIONS_NUM,
99,
)
export const MAX_TREE_DEPTH = getNumberConfig(
process.env.NEXT_PUBLIC_MAX_TREE_DEPTH,
env.NEXT_PUBLIC_MAX_TREE_DEPTH,
DatasetAttr.DATA_PUBLIC_MAX_TREE_DEPTH,
50,
)
export const ALLOW_UNSAFE_DATA_SCHEME = getBooleanConfig(
process.env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME,
env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME,
DatasetAttr.DATA_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME,
false,
)
export const ENABLE_WEBSITE_JINAREADER = getBooleanConfig(
process.env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER,
env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER,
DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_JINAREADER,
true,
)
export const ENABLE_WEBSITE_FIRECRAWL = getBooleanConfig(
process.env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL,
env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL,
DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_FIRECRAWL,
true,
)
export const ENABLE_WEBSITE_WATERCRAWL = getBooleanConfig(
process.env.NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
env.NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
false,
)
export const ENABLE_SINGLE_DOLLAR_LATEX = getBooleanConfig(
process.env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
DatasetAttr.DATA_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
false,
)
@ -414,33 +415,33 @@ export const VALUE_SELECTOR_DELIMITER = '@@@'
export const validPassword = /^(?=.*[a-z])(?=.*\d)\S{8,}$/i
export const ZENDESK_WIDGET_KEY = getStringConfig(
process.env.NEXT_PUBLIC_ZENDESK_WIDGET_KEY,
env.NEXT_PUBLIC_ZENDESK_WIDGET_KEY,
DatasetAttr.NEXT_PUBLIC_ZENDESK_WIDGET_KEY,
'',
)
export const ZENDESK_FIELD_IDS = {
ENVIRONMENT: getStringConfig(
process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT,
env.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT,
DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT,
'',
),
VERSION: getStringConfig(
process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION,
env.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION,
DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION,
'',
),
EMAIL: getStringConfig(
process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL,
env.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL,
DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL,
'',
),
WORKSPACE_ID: getStringConfig(
process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID,
env.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID,
DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID,
'',
),
PLAN: getStringConfig(
process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN,
env.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN,
DatasetAttr.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN,
'',
),

101
web/env.ts Normal file
View File

@ -0,0 +1,101 @@
import { createEnv } from '@t3-oss/env-nextjs'
import { z } from 'zod'
const optionalString = z.string().optional()
export const env = createEnv({
server: {
ANALYZE: optionalString,
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: optionalString,
NEXT_TELEMETRY_DISABLED: optionalString,
PORT: optionalString,
TEXT_GENERATION_TIMEOUT_MS: optionalString,
},
shared: {
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
},
client: {
NEXT_PUBLIC_ALLOW_EMBED: optionalString,
NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME: optionalString,
NEXT_PUBLIC_AMPLITUDE_API_KEY: optionalString,
NEXT_PUBLIC_API_PREFIX: optionalString,
NEXT_PUBLIC_BASE_PATH: optionalString,
NEXT_PUBLIC_BATCH_CONCURRENCY: optionalString,
NEXT_PUBLIC_COOKIE_DOMAIN: optionalString,
NEXT_PUBLIC_CSP_WHITELIST: optionalString,
NEXT_PUBLIC_DEPLOY_ENV: optionalString,
NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON: optionalString,
NEXT_PUBLIC_EDITION: optionalString,
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX: optionalString,
NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL: optionalString,
NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER: optionalString,
NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL: optionalString,
NEXT_PUBLIC_GITHUB_ACCESS_TOKEN: optionalString,
NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: optionalString,
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT: optionalString,
NEXT_PUBLIC_MAINTENANCE_NOTICE: optionalString,
NEXT_PUBLIC_MARKETPLACE_API_PREFIX: optionalString,
NEXT_PUBLIC_MARKETPLACE_URL_PREFIX: optionalString,
NEXT_PUBLIC_MAX_ITERATIONS_NUM: optionalString,
NEXT_PUBLIC_MAX_PARALLEL_LIMIT: optionalString,
NEXT_PUBLIC_MAX_TOOLS_NUM: optionalString,
NEXT_PUBLIC_MAX_TREE_DEPTH: optionalString,
NEXT_PUBLIC_PUBLIC_API_PREFIX: optionalString,
NEXT_PUBLIC_SENTRY_DSN: optionalString,
NEXT_PUBLIC_SITE_ABOUT: optionalString,
NEXT_PUBLIC_SUPPORT_MAIL_LOGIN: optionalString,
NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS: optionalString,
NEXT_PUBLIC_TOP_K_MAX_VALUE: optionalString,
NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON: optionalString,
NEXT_PUBLIC_WEB_PREFIX: optionalString,
NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL: optionalString,
NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT: optionalString,
NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN: optionalString,
NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION: optionalString,
NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID: optionalString,
NEXT_PUBLIC_ZENDESK_WIDGET_KEY: optionalString,
},
experimental__runtimeEnv: {
NODE_ENV: process.env.NODE_ENV,
NEXT_PUBLIC_ALLOW_EMBED: process.env.NEXT_PUBLIC_ALLOW_EMBED,
NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME: process.env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME,
NEXT_PUBLIC_AMPLITUDE_API_KEY: process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY,
NEXT_PUBLIC_API_PREFIX: process.env.NEXT_PUBLIC_API_PREFIX,
NEXT_PUBLIC_BASE_PATH: process.env.NEXT_PUBLIC_BASE_PATH,
NEXT_PUBLIC_BATCH_CONCURRENCY: process.env.NEXT_PUBLIC_BATCH_CONCURRENCY,
NEXT_PUBLIC_COOKIE_DOMAIN: process.env.NEXT_PUBLIC_COOKIE_DOMAIN,
NEXT_PUBLIC_CSP_WHITELIST: process.env.NEXT_PUBLIC_CSP_WHITELIST,
NEXT_PUBLIC_DEPLOY_ENV: process.env.NEXT_PUBLIC_DEPLOY_ENV,
NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON: process.env.NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON,
NEXT_PUBLIC_EDITION: process.env.NEXT_PUBLIC_EDITION,
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX: process.env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL: process.env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL,
NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER: process.env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER,
NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL: process.env.NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
NEXT_PUBLIC_GITHUB_ACCESS_TOKEN: process.env.NEXT_PUBLIC_GITHUB_ACCESS_TOKEN,
NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: process.env.NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH,
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT: process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT,
NEXT_PUBLIC_MAINTENANCE_NOTICE: process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE,
NEXT_PUBLIC_MARKETPLACE_API_PREFIX: process.env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX,
NEXT_PUBLIC_MARKETPLACE_URL_PREFIX: process.env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX,
NEXT_PUBLIC_MAX_ITERATIONS_NUM: process.env.NEXT_PUBLIC_MAX_ITERATIONS_NUM,
NEXT_PUBLIC_MAX_PARALLEL_LIMIT: process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT,
NEXT_PUBLIC_MAX_TOOLS_NUM: process.env.NEXT_PUBLIC_MAX_TOOLS_NUM,
NEXT_PUBLIC_MAX_TREE_DEPTH: process.env.NEXT_PUBLIC_MAX_TREE_DEPTH,
NEXT_PUBLIC_PUBLIC_API_PREFIX: process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX,
NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN,
NEXT_PUBLIC_SITE_ABOUT: process.env.NEXT_PUBLIC_SITE_ABOUT,
NEXT_PUBLIC_SUPPORT_MAIL_LOGIN: process.env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN,
NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS: process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS,
NEXT_PUBLIC_TOP_K_MAX_VALUE: process.env.NEXT_PUBLIC_TOP_K_MAX_VALUE,
NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON: process.env.NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON,
NEXT_PUBLIC_WEB_PREFIX: process.env.NEXT_PUBLIC_WEB_PREFIX,
NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL,
NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT,
NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN,
NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION,
NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID: process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID,
NEXT_PUBLIC_ZENDESK_WIDGET_KEY: process.env.NEXT_PUBLIC_ZENDESK_WIDGET_KEY,
},
emptyStringAsUndefined: true,
})

View File

@ -1,10 +1,10 @@
import type { NextConfig } from 'next'
import process from 'node:process'
import withBundleAnalyzerInit from '@next/bundle-analyzer'
import createMDX from '@next/mdx'
import { codeInspectorPlugin } from 'code-inspector-plugin'
import { env } from './env'
const isDev = process.env.NODE_ENV === 'development'
const isDev = env.NODE_ENV === 'development'
const withMDX = createMDX({
extension: /\.mdx?$/,
options: {
@ -18,19 +18,19 @@ const withMDX = createMDX({
},
})
const withBundleAnalyzer = withBundleAnalyzerInit({
enabled: process.env.ANALYZE === 'true',
enabled: env.ANALYZE === 'true',
})
// the default url to prevent parse url error when running jest
const hasSetWebPrefix = process.env.NEXT_PUBLIC_WEB_PREFIX
const port = process.env.PORT || 3000
const hasSetWebPrefix = env.NEXT_PUBLIC_WEB_PREFIX
const port = env.PORT || '3000'
const locImageURLs = !hasSetWebPrefix ? [new URL(`http://localhost:${port}/**`), new URL(`http://127.0.0.1:${port}/**`)] : []
const remoteImageURLs = ([hasSetWebPrefix ? new URL(`${process.env.NEXT_PUBLIC_WEB_PREFIX}/**`) : '', ...locImageURLs].filter(item => !!item)) as URL[]
const remoteImageURLs = ([hasSetWebPrefix ? new URL(`${env.NEXT_PUBLIC_WEB_PREFIX}/**`) : '', ...locImageURLs].filter(item => !!item)) as URL[]
const nextConfig: NextConfig = {
basePath: process.env.NEXT_PUBLIC_BASE_PATH || '',
basePath: env.NEXT_PUBLIC_BASE_PATH || '',
serverExternalPackages: ['esbuild'],
transpilePackages: ['echarts', 'zrender'],
transpilePackages: ['@t3-oss/env-core', '@t3-oss/env-nextjs', 'echarts', 'zrender'],
turbopack: {
rules: codeInspectorPlugin({
bundler: 'turbopack',

View File

@ -1,13 +1,14 @@
import type { NextRequest } from 'next/server'
import { Buffer } from 'node:buffer'
import { NextResponse } from 'next/server'
import { env } from '@/env'
const NECESSARY_DOMAIN = '*.sentry.io http://localhost:* http://127.0.0.1:* https://analytics.google.com googletagmanager.com *.googletagmanager.com https://www.google-analytics.com https://api.github.com https://api2.amplitude.com *.amplitude.com'
const wrapResponseWithXFrameOptions = (response: NextResponse, pathname: string) => {
// prevent clickjacking: https://owasp.org/www-community/attacks/Clickjacking
// Chatbot page should be allowed to be embedded in iframe. It's a feature
if (process.env.NEXT_PUBLIC_ALLOW_EMBED !== 'true' && !pathname.startsWith('/chat') && !pathname.startsWith('/workflow') && !pathname.startsWith('/completion') && !pathname.startsWith('/webapp-signin'))
if (env.NEXT_PUBLIC_ALLOW_EMBED !== 'true' && !pathname.startsWith('/chat') && !pathname.startsWith('/workflow') && !pathname.startsWith('/completion') && !pathname.startsWith('/webapp-signin'))
response.headers.set('X-Frame-Options', 'DENY')
return response
@ -21,11 +22,11 @@ export function proxy(request: NextRequest) {
},
})
const isWhiteListEnabled = !!process.env.NEXT_PUBLIC_CSP_WHITELIST && process.env.NODE_ENV === 'production'
const isWhiteListEnabled = !!env.NEXT_PUBLIC_CSP_WHITELIST && env.NODE_ENV === 'production'
if (!isWhiteListEnabled)
return wrapResponseWithXFrameOptions(response, pathname)
const whiteList = `${process.env.NEXT_PUBLIC_CSP_WHITELIST} ${NECESSARY_DOMAIN}`
const whiteList = `${env.NEXT_PUBLIC_CSP_WHITELIST} ${NECESSARY_DOMAIN}`
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const csp = `'nonce-${nonce}'`

View File

@ -8,6 +8,7 @@ import {
} from '@/app/components/base/prompt-editor/constants'
import { InputVarType } from '@/app/components/workflow/types'
import { getMaxVarNameLength, MARKETPLACE_URL_PREFIX, MAX_VAR_KEY_LENGTH, VAR_ITEM_TEMPLATE, VAR_ITEM_TEMPLATE_IN_WORKFLOW } from '@/config'
import { env } from '@/env'
const otherAllowedRegex = /^\w+$/
@ -129,7 +130,7 @@ export const getVars = (value: string) => {
// Set the value of basePath
// example: /dify
export const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ''
export const basePath = env.NEXT_PUBLIC_BASE_PATH || ''
export function getMarketplaceUrl(path: string, params?: Record<string, string | undefined>) {
const searchParams = new URLSearchParams({ source: encodeURIComponent(window.location.origin) })