handleRowClick(log)}>
+ className={cn('cursor-pointer border-b border-divider-subtle hover:bg-background-default-hover', currentConversation?.id !== log.id ? '' : 'bg-background-default-hover')}
+ onClick={() => {
+ setShowDrawer(true)
+ setCurrentConversation(log)
+ }}>
|
{!log.read_at && (
diff --git a/web/app/components/base/markdown/react-markdown-wrapper.tsx b/web/app/components/base/markdown/react-markdown-wrapper.tsx
index 054b5f66cb..afe3d8a737 100644
--- a/web/app/components/base/markdown/react-markdown-wrapper.tsx
+++ b/web/app/components/base/markdown/react-markdown-wrapper.tsx
@@ -4,6 +4,7 @@ import RemarkBreaks from 'remark-breaks'
import RehypeKatex from 'rehype-katex'
import RemarkGfm from 'remark-gfm'
import RehypeRaw from 'rehype-raw'
+import { ENABLE_SINGLE_DOLLAR_LATEX } from '@/config'
import AudioBlock from '@/app/components/base/markdown-blocks/audio-block'
import Img from '@/app/components/base/markdown-blocks/img'
import Link from '@/app/components/base/markdown-blocks/link'
@@ -34,7 +35,7 @@ export const ReactMarkdownWrapper: FC = (props) => {
{t('datasetCreation.stepOne.uploader.tip', {
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
- batchCount: fileUploadConfig.batch_count_limit,
+ batchCount: notSupportBatchUpload ? 1 : fileUploadConfig.batch_count_limit,
})}
{dragging && }
diff --git a/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/index.tsx b/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/index.tsx
index da47a4664c..47da96c2de 100644
--- a/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/index.tsx
+++ b/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/index.tsx
@@ -287,7 +287,7 @@ const LocalFile = ({
- {t('datasetCreation.stepOne.uploader.button')}
+ {notSupportBatchUpload ? t('datasetCreation.stepOne.uploader.buttonSingleFile') : t('datasetCreation.stepOne.uploader.button')}
{allowedExtensions.length > 0 && (
)}
@@ -296,7 +296,7 @@ const LocalFile = ({
{t('datasetCreation.stepOne.uploader.tip', {
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
- batchCount: fileUploadConfig.batch_count_limit,
+ batchCount: notSupportBatchUpload ? 1 : fileUploadConfig.batch_count_limit,
})}
{dragging && }
diff --git a/web/app/components/swr-initializer.tsx b/web/app/components/swr-initializer.tsx
index 1ab1567659..b7cd767c7a 100644
--- a/web/app/components/swr-initializer.tsx
+++ b/web/app/components/swr-initializer.tsx
@@ -56,10 +56,10 @@ const SwrInitializer = ({
}
const redirectUrl = resolvePostLoginRedirect(searchParams)
- if (redirectUrl)
+ if (redirectUrl) {
location.replace(redirectUrl)
- else
- router.replace(pathname)
+ return
+ }
setInit(true)
}
diff --git a/web/app/layout.tsx b/web/app/layout.tsx
index 1be802460b..c83ea7fd85 100644
--- a/web/app/layout.tsx
+++ b/web/app/layout.tsx
@@ -57,6 +57,7 @@ const LocaleLayout = async ({
[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,
diff --git a/web/app/signin/normal-form.tsx b/web/app/signin/normal-form.tsx
index 920a992b4f..29e21b8ba2 100644
--- a/web/app/signin/normal-form.tsx
+++ b/web/app/signin/normal-form.tsx
@@ -135,8 +135,8 @@ const NormalForm = () => {
{!systemFeatures.branding.enabled && {t('login.joinTipStart')}{workspaceName}{t('login.joinTipEnd')} }
:
- {t('login.pageTitle')}
- {!systemFeatures.branding.enabled && {t('login.welcome')} }
+ {systemFeatures.branding.enabled ? t('login.pageTitleForE') : t('login.pageTitle')}
+ {t('login.welcome')}
}
diff --git a/web/config/index.ts b/web/config/index.ts
index 0e876b800e..158d9976fc 100644
--- a/web/config/index.ts
+++ b/web/config/index.ts
@@ -375,6 +375,11 @@ export const ENABLE_WEBSITE_WATERCRAWL = getBooleanConfig(
DatasetAttr.DATA_PUBLIC_ENABLE_WEBSITE_WATERCRAWL,
false,
)
+export const ENABLE_SINGLE_DOLLAR_LATEX = getBooleanConfig(
+ process.env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
+ DatasetAttr.DATA_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX,
+ false,
+)
export const VALUE_SELECTOR_DELIMITER = '@@@'
diff --git a/web/docker/entrypoint.sh b/web/docker/entrypoint.sh
index c12ebc0812..b32e648922 100755
--- a/web/docker/entrypoint.sh
+++ b/web/docker/entrypoint.sh
@@ -34,6 +34,7 @@ export NEXT_PUBLIC_MAX_TOOLS_NUM=${MAX_TOOLS_NUM}
export NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER=${ENABLE_WEBSITE_JINAREADER:-true}
export NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL=${ENABLE_WEBSITE_FIRECRAWL:-true}
export NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL=${ENABLE_WEBSITE_WATERCRAWL:-true}
+export NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX=${NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX:-false}
export NEXT_PUBLIC_LOOP_NODE_MAX_COUNT=${LOOP_NODE_MAX_COUNT}
export NEXT_PUBLIC_MAX_PARALLEL_LIMIT=${MAX_PARALLEL_LIMIT}
export NEXT_PUBLIC_MAX_ITERATIONS_NUM=${MAX_ITERATIONS_NUM}
diff --git a/web/i18n/de-DE/login.ts b/web/i18n/de-DE/login.ts
index a4c9165e23..4705a73087 100644
--- a/web/i18n/de-DE/login.ts
+++ b/web/i18n/de-DE/login.ts
@@ -120,6 +120,7 @@ const translation = {
noAccount: 'Haben Sie kein Konto?',
verifyMail: 'Fahren Sie mit dem Bestätigungscode fort',
},
+ pageTitleForE: 'Hey, lass uns anfangen!',
}
export default translation
diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts
index 6015098022..dd923db217 100644
--- a/web/i18n/en-US/login.ts
+++ b/web/i18n/en-US/login.ts
@@ -1,5 +1,6 @@
const translation = {
pageTitle: 'Log in to Dify',
+ pageTitleForE: 'Hey, let\'s get started!',
welcome: '👋 Welcome! Please log in to get started.',
email: 'Email address',
emailPlaceholder: 'Your email',
diff --git a/web/i18n/es-ES/login.ts b/web/i18n/es-ES/login.ts
index ba8ad292cc..cbc223e7da 100644
--- a/web/i18n/es-ES/login.ts
+++ b/web/i18n/es-ES/login.ts
@@ -120,6 +120,7 @@ const translation = {
welcome: '👋 ¡Bienvenido! Por favor, completa los detalles para comenzar.',
verifyMail: 'Continuar con el código de verificación',
},
+ pageTitleForE: '¡Hola, vamos a empezar!',
}
export default translation
diff --git a/web/i18n/fa-IR/login.ts b/web/i18n/fa-IR/login.ts
index b57687cf5d..83382f3c9d 100644
--- a/web/i18n/fa-IR/login.ts
+++ b/web/i18n/fa-IR/login.ts
@@ -120,6 +120,7 @@ const translation = {
noAccount: 'حساب کاربری ندارید؟',
verifyMail: 'ادامه با کد تأیید',
},
+ pageTitleForE: 'هی، بیا شروع کنیم!',
}
export default translation
diff --git a/web/i18n/fr-FR/login.ts b/web/i18n/fr-FR/login.ts
index deae8e3ff4..3abb6fba2a 100644
--- a/web/i18n/fr-FR/login.ts
+++ b/web/i18n/fr-FR/login.ts
@@ -120,6 +120,7 @@ const translation = {
verifyMail: 'Continuez avec le code de vérification',
createAccount: 'Créez votre compte',
},
+ pageTitleForE: 'Hé, commençons !',
}
export default translation
diff --git a/web/i18n/hi-IN/login.ts b/web/i18n/hi-IN/login.ts
index fee51208c7..27b7df9849 100644
--- a/web/i18n/hi-IN/login.ts
+++ b/web/i18n/hi-IN/login.ts
@@ -125,6 +125,7 @@ const translation = {
welcome: '👋 स्वागत है! कृपया शुरू करने के लिए विवरण भरें।',
haveAccount: 'क्या आपका पहले से एक खाता है?',
},
+ pageTitleForE: 'अरे, चलो शुरू करें!',
}
export default translation
diff --git a/web/i18n/id-ID/login.ts b/web/i18n/id-ID/login.ts
index 41c7e04ec4..1590aa81a2 100644
--- a/web/i18n/id-ID/login.ts
+++ b/web/i18n/id-ID/login.ts
@@ -120,6 +120,7 @@ const translation = {
noAccount: 'Tidak punya akun?',
welcome: '👋 Selamat datang! Silakan isi detail untuk memulai.',
},
+ pageTitleForE: 'Hei, ayo kita mulai!',
}
export default translation
diff --git a/web/i18n/it-IT/login.ts b/web/i18n/it-IT/login.ts
index 5d6b040daf..e19baca6a3 100644
--- a/web/i18n/it-IT/login.ts
+++ b/web/i18n/it-IT/login.ts
@@ -130,6 +130,7 @@ const translation = {
signUp: 'Iscriviti',
welcome: '👋 Benvenuto! Per favore compila i dettagli per iniziare.',
},
+ pageTitleForE: 'Ehi, cominciamo!',
}
export default translation
diff --git a/web/i18n/ja-JP/login.ts b/web/i18n/ja-JP/login.ts
index d1e9a9e0e2..7069315c9d 100644
--- a/web/i18n/ja-JP/login.ts
+++ b/web/i18n/ja-JP/login.ts
@@ -1,5 +1,6 @@
const translation = {
pageTitle: 'Dify にログイン',
+ pageTitleForE: 'はじめましょう!',
welcome: '👋 ようこそ!まずはログインしてご利用ください。',
email: 'メールアドレス',
emailPlaceholder: 'メールアドレスを入力してください',
diff --git a/web/i18n/ko-KR/login.ts b/web/i18n/ko-KR/login.ts
index 8cde21472c..6d3d47a602 100644
--- a/web/i18n/ko-KR/login.ts
+++ b/web/i18n/ko-KR/login.ts
@@ -120,6 +120,7 @@ const translation = {
noAccount: '계정이 없으신가요?',
welcome: '👋 환영합니다! 시작하려면 세부 정보를 입력해 주세요.',
},
+ pageTitleForE: '이봐, 시작하자!',
}
export default translation
diff --git a/web/i18n/pl-PL/login.ts b/web/i18n/pl-PL/login.ts
index 394fe6c402..34519cd2b3 100644
--- a/web/i18n/pl-PL/login.ts
+++ b/web/i18n/pl-PL/login.ts
@@ -125,6 +125,7 @@ const translation = {
haveAccount: 'Masz już konto?',
welcome: '👋 Witaj! Proszę wypełnić szczegóły, aby rozpocząć.',
},
+ pageTitleForE: 'Hej, zaczynajmy!',
}
export default translation
diff --git a/web/i18n/pt-BR/login.ts b/web/i18n/pt-BR/login.ts
index 200e7bf30c..4fa9f36146 100644
--- a/web/i18n/pt-BR/login.ts
+++ b/web/i18n/pt-BR/login.ts
@@ -120,6 +120,7 @@ const translation = {
signUp: 'Inscreva-se',
welcome: '👋 Bem-vindo! Por favor, preencha os detalhes para começar.',
},
+ pageTitleForE: 'Ei, vamos começar!',
}
export default translation
diff --git a/web/i18n/ro-RO/login.ts b/web/i18n/ro-RO/login.ts
index 34cd4a5ffd..f676b812cb 100644
--- a/web/i18n/ro-RO/login.ts
+++ b/web/i18n/ro-RO/login.ts
@@ -120,6 +120,7 @@ const translation = {
createAccount: 'Creează-ți contul',
welcome: '👋 Buna! Te rugăm să completezi detaliile pentru a începe.',
},
+ pageTitleForE: 'Hei, hai să începem!',
}
export default translation
diff --git a/web/i18n/ru-RU/login.ts b/web/i18n/ru-RU/login.ts
index bfb2860b57..f864bdb845 100644
--- a/web/i18n/ru-RU/login.ts
+++ b/web/i18n/ru-RU/login.ts
@@ -120,6 +120,7 @@ const translation = {
verifyMail: 'Продолжите с кодом проверки',
welcome: '👋 Добро пожаловать! Пожалуйста, заполните данные, чтобы начать.',
},
+ pageTitleForE: 'Привет, давай начнем!',
}
export default translation
diff --git a/web/i18n/sl-SI/login.ts b/web/i18n/sl-SI/login.ts
index 4e5b12689d..81f280666b 100644
--- a/web/i18n/sl-SI/login.ts
+++ b/web/i18n/sl-SI/login.ts
@@ -120,6 +120,7 @@ const translation = {
noAccount: 'Nimate računa?',
welcome: '👋 Dobrodošli! Prosimo, izpolnite podatke, da začnete.',
},
+ pageTitleForE: 'Hej, začnimo!',
}
export default translation
diff --git a/web/i18n/th-TH/login.ts b/web/i18n/th-TH/login.ts
index 732af8a875..517eee95a2 100644
--- a/web/i18n/th-TH/login.ts
+++ b/web/i18n/th-TH/login.ts
@@ -120,6 +120,7 @@ const translation = {
verifyMail: 'โปรดดำเนินการต่อด้วยรหัสการตรวจสอบ',
haveAccount: 'มีบัญชีอยู่แล้วใช่ไหม?',
},
+ pageTitleForE: 'เฮ้ เรามาเริ่มกันเถอะ!',
}
export default translation
diff --git a/web/i18n/tr-TR/login.ts b/web/i18n/tr-TR/login.ts
index b8bd6d74af..d6ada5f950 100644
--- a/web/i18n/tr-TR/login.ts
+++ b/web/i18n/tr-TR/login.ts
@@ -120,6 +120,7 @@ const translation = {
haveAccount: 'Zaten bir hesabınız var mı?',
welcome: '👋 Hoş geldiniz! Başlamak için lütfen detayları doldurun.',
},
+ pageTitleForE: 'Hey, haydi başlayalım!',
}
export default translation
diff --git a/web/i18n/uk-UA/login.ts b/web/i18n/uk-UA/login.ts
index 1fa4d414f7..1a1a6d7068 100644
--- a/web/i18n/uk-UA/login.ts
+++ b/web/i18n/uk-UA/login.ts
@@ -120,6 +120,7 @@ const translation = {
noAccount: 'Не маєте облікового запису?',
welcome: '👋 Ласкаво просимо! Будь ласка, заповніть деталі, щоб почати.',
},
+ pageTitleForE: 'Гей, давай почнемо!',
}
export default translation
diff --git a/web/i18n/vi-VN/login.ts b/web/i18n/vi-VN/login.ts
index 6d877fffef..dec7eddee2 100644
--- a/web/i18n/vi-VN/login.ts
+++ b/web/i18n/vi-VN/login.ts
@@ -120,6 +120,7 @@ const translation = {
verifyMail: 'Tiếp tục với mã xác minh',
welcome: '👋 Chào mừng! Vui lòng điền vào các chi tiết để bắt đầu.',
},
+ pageTitleForE: 'Này, hãy bắt đầu nào!',
}
export default translation
diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts
index 82c6b355f9..13a75eaaaa 100644
--- a/web/i18n/zh-Hans/login.ts
+++ b/web/i18n/zh-Hans/login.ts
@@ -1,5 +1,6 @@
const translation = {
pageTitle: '登录 Dify',
+ pageTitleForE: '嗨,近来可好',
welcome: '👋 欢迎!请登录以开始使用。',
email: '邮箱',
emailPlaceholder: '输入邮箱地址',
diff --git a/web/i18n/zh-Hant/login.ts b/web/i18n/zh-Hant/login.ts
index 0e7608140f..56150a0ed3 100644
--- a/web/i18n/zh-Hant/login.ts
+++ b/web/i18n/zh-Hant/login.ts
@@ -1,5 +1,6 @@
const translation = {
pageTitle: '嗨,近來可好',
+ pageTitleForE: '嗨,近來可好',
welcome: '👋 歡迎來到 Dify, 登入以繼續',
email: '郵箱',
emailPlaceholder: '輸入郵箱地址',
diff --git a/web/package.json b/web/package.json
index 4f76537acf..88927ca5c4 100644
--- a/web/package.json
+++ b/web/package.json
@@ -2,7 +2,7 @@
"name": "dify-web",
"version": "1.9.2",
"private": true,
- "packageManager": "pnpm@10.18.3+sha512.bbd16e6d7286fd7e01f6b3c0b3c932cda2965c06a908328f74663f10a9aea51f1129eea615134bf992831b009eabe167ecb7008b597f40ff9bc75946aadfb08d",
+ "packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8",
"engines": {
"node": ">=v22.11.0"
},
@@ -22,7 +22,7 @@
"dev": "cross-env NODE_OPTIONS='--inspect' next dev --turbopack",
"build": "next build",
"build:docker": "next build && node scripts/optimize-standalone.js",
- "start": "cp -r .next/static .next/standalone/.next/static && cp -r public .next/standalone/public && cross-env PORT=$npm_config_port HOSTNAME=$npm_config_host node .next/standalone/server.js",
+ "start": "node ./scripts/copy-and-start.mjs",
"lint": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache",
"lint:fix": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --fix",
"lint:quiet": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --quiet",
@@ -144,7 +144,7 @@
"@babel/core": "^7.28.4",
"@chromatic-com/storybook": "^4.1.1",
"@eslint-react/eslint-plugin": "^1.53.1",
- "@happy-dom/jest-environment": "^20.0.7",
+ "@happy-dom/jest-environment": "^20.0.8",
"@mdx-js/loader": "^3.1.1",
"@mdx-js/react": "^3.1.1",
"@next/bundle-analyzer": "15.5.4",
diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml
index f05c225cab..1422f071c6 100644
--- a/web/pnpm-lock.yaml
+++ b/web/pnpm-lock.yaml
@@ -356,8 +356,8 @@ importers:
specifier: ^1.53.1
version: 1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3)
'@happy-dom/jest-environment':
- specifier: ^20.0.7
- version: 20.0.7(@jest/environment@29.7.0)(@jest/fake-timers@29.7.0)(@jest/types@29.6.3)(jest-mock@29.7.0)(jest-util@29.7.0)
+ specifier: ^20.0.8
+ version: 20.0.8(@jest/environment@29.7.0)(@jest/fake-timers@29.7.0)(@jest/types@29.6.3)(jest-mock@29.7.0)(jest-util@29.7.0)
'@mdx-js/loader':
specifier: ^3.1.1
version: 3.1.1(webpack@5.102.1(esbuild@0.25.0)(uglify-js@3.19.3))
@@ -688,6 +688,10 @@ packages:
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
engines: {node: '>=6.9.0'}
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
'@babel/helper-validator-option@7.27.1':
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
engines: {node: '>=6.9.0'}
@@ -705,6 +709,11 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
+ '@babel/parser@7.28.5':
+ resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1':
resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==}
engines: {node: '>=6.9.0'}
@@ -1230,6 +1239,10 @@ packages:
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
engines: {node: '>=6.9.0'}
+ '@babel/types@7.28.5':
+ resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
+ engines: {node: '>=6.9.0'}
+
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
@@ -1747,8 +1760,8 @@ packages:
'@formatjs/intl-localematcher@0.5.10':
resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==}
- '@happy-dom/jest-environment@20.0.7':
- resolution: {integrity: sha512-f7cvUghxPIUS8L21uSNab1GYXPr6+7FvltpsWyzrSzhSbjhDWr5Ixcy5bv2DqaQEhAKIQ7SYBYD5n4+SSHwfig==}
+ '@happy-dom/jest-environment@20.0.8':
+ resolution: {integrity: sha512-e8/c1EW+vUF7MFTZZtPbWrD3rStPnx3X8M4pAaOU++x+1lsXr/bsdoLoHs6bQ2kEZyPRhate3sC6MnpVD/O/9A==}
engines: {node: '>=20.0.0'}
peerDependencies:
'@jest/environment': '>=25.0.0'
@@ -3525,8 +3538,8 @@ packages:
'@types/node@18.15.0':
resolution: {integrity: sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==}
- '@types/node@20.19.22':
- resolution: {integrity: sha512-hRnu+5qggKDSyWHlnmThnUqg62l29Aj/6vcYgUaSFL9oc7DVjeWEQN3PRgdSc6F8d9QRMWkf36CLMch1Do/+RQ==}
+ '@types/node@20.19.23':
+ resolution: {integrity: sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==}
'@types/papaparse@5.3.16':
resolution: {integrity: sha512-T3VuKMC2H0lgsjI9buTB3uuKj3EMD2eap1MOuEQuBQ44EnDx/IkGhU6EwiTf9zG3za4SKlmwKAImdDKdNnCsXg==}
@@ -5575,8 +5588,8 @@ packages:
hachure-fill@0.5.2:
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
- happy-dom@20.0.7:
- resolution: {integrity: sha512-CywLfzmYxP5OYpuAG0usFY0CpxJtwYR+w8Mms5J8W29Y2Pzf6rbfQS2M523tRZTb0oLA+URopPtnAQX2fupHZQ==}
+ happy-dom@20.0.8:
+ resolution: {integrity: sha512-TlYaNQNtzsZ97rNMBAm8U+e2cUQXNithgfCizkDgc11lgmN4j9CKMhO3FPGKWQYPwwkFcPpoXYF/CqEPLgzfOg==}
engines: {node: '>=20.0.0'}
has-flag@4.0.0:
@@ -5803,6 +5816,7 @@ packages:
intersection-observer@0.12.2:
resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==}
+ deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019.
is-alphabetical@1.0.4:
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
@@ -6354,6 +6368,9 @@ packages:
magic-string@0.30.19:
resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
magicast@0.3.5:
resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
@@ -8932,6 +8949,8 @@ snapshots:
'@babel/helper-validator-identifier@7.27.1': {}
+ '@babel/helper-validator-identifier@7.28.5': {}
+
'@babel/helper-validator-option@7.27.1': {}
'@babel/helper-wrap-function@7.28.3':
@@ -8951,6 +8970,10 @@ snapshots:
dependencies:
'@babel/types': 7.28.4
+ '@babel/parser@7.28.5':
+ dependencies:
+ '@babel/types': 7.28.5
+
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)':
dependencies:
'@babel/core': 7.28.4
@@ -9607,6 +9630,11 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
+ '@babel/types@7.28.5':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
'@bcoe/v8-coverage@0.2.3': {}
'@braintree/sanitize-url@7.1.1': {}
@@ -10099,12 +10127,12 @@ snapshots:
dependencies:
tslib: 2.8.1
- '@happy-dom/jest-environment@20.0.7(@jest/environment@29.7.0)(@jest/fake-timers@29.7.0)(@jest/types@29.6.3)(jest-mock@29.7.0)(jest-util@29.7.0)':
+ '@happy-dom/jest-environment@20.0.8(@jest/environment@29.7.0)(@jest/fake-timers@29.7.0)(@jest/types@29.6.3)(jest-mock@29.7.0)(jest-util@29.7.0)':
dependencies:
'@jest/environment': 29.7.0
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- happy-dom: 20.0.7
+ happy-dom: 20.0.8
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -12091,7 +12119,7 @@ snapshots:
'@types/node@18.15.0': {}
- '@types/node@20.19.22':
+ '@types/node@20.19.23':
dependencies:
undici-types: 6.21.0
@@ -12292,7 +12320,7 @@ snapshots:
'@vue/compiler-core@3.5.17':
dependencies:
- '@babel/parser': 7.28.4
+ '@babel/parser': 7.28.5
'@vue/shared': 3.5.17
entities: 4.5.0
estree-walker: 2.0.2
@@ -12318,13 +12346,13 @@ snapshots:
'@vue/compiler-sfc@3.5.17':
dependencies:
- '@babel/parser': 7.28.4
+ '@babel/parser': 7.28.5
'@vue/compiler-core': 3.5.17
'@vue/compiler-dom': 3.5.17
'@vue/compiler-ssr': 3.5.17
'@vue/shared': 3.5.17
estree-walker: 2.0.2
- magic-string: 0.30.19
+ magic-string: 0.30.21
postcss: 8.5.6
source-map-js: 1.2.1
@@ -14504,9 +14532,9 @@ snapshots:
hachure-fill@0.5.2: {}
- happy-dom@20.0.7:
+ happy-dom@20.0.8:
dependencies:
- '@types/node': 20.19.22
+ '@types/node': 20.19.23
'@types/whatwg-mimetype': 3.0.2
whatwg-mimetype: 3.0.0
@@ -15518,6 +15546,10 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
magicast@0.3.5:
dependencies:
'@babel/parser': 7.28.4
diff --git a/web/scripts/copy-and-start.mjs b/web/scripts/copy-and-start.mjs
new file mode 100644
index 0000000000..b23ce636a4
--- /dev/null
+++ b/web/scripts/copy-and-start.mjs
@@ -0,0 +1,115 @@
+#!/usr/bin/env node
+/**
+ * This script copies static files to the target directory and starts the server.
+ * It is intended to be used as a replacement for `next start`.
+ */
+
+import { cp, mkdir, stat } from 'node:fs/promises'
+import { spawn } from 'node:child_process'
+import path from 'node:path'
+
+// Configuration for directories to copy
+const DIRS_TO_COPY = [
+ {
+ src: path.join('.next', 'static'),
+ dest: path.join('.next', 'standalone', '.next', 'static'),
+ },
+ {
+ src: 'public',
+ dest: path.join('.next', 'standalone', 'public'),
+ },
+]
+
+// Path to the server script
+const SERVER_SCRIPT_PATH = path.join('.next', 'standalone', 'server.js')
+
+// Function to check if a path exists
+const pathExists = async (path) => {
+ try {
+ console.debug(`Checking if path exists: ${path}`)
+ await stat(path)
+ console.debug(`Path exists: ${path}`)
+ return true
+ }
+ catch (err) {
+ if (err.code === 'ENOENT') {
+ console.warn(`Path does not exist: ${path}`)
+ return false
+ }
+ throw err
+ }
+}
+
+// Function to recursively copy directories
+const copyDir = async (src, dest) => {
+ console.debug(`Copying directory from ${src} to ${dest}`)
+ await cp(src, dest, { recursive: true })
+ console.info(`Successfully copied ${src} to ${dest}`)
+}
+
+// Process each directory copy operation
+const copyAllDirs = async () => {
+ console.debug('Starting directory copy operations')
+ for (const { src, dest } of DIRS_TO_COPY) {
+ try {
+ // Instead of pre-creating destination directory, we ensure parent directory exists
+ const destParent = path.dirname(dest)
+ console.debug(`Ensuring destination parent directory exists: ${destParent}`)
+ await mkdir(destParent, { recursive: true })
+ if (await pathExists(src)) {
+ await copyDir(src, dest)
+ }
+ else {
+ console.error(`Error: ${src} directory does not exist. This is a required build artifact.`)
+ process.exit(1)
+ }
+ }
+ catch (err) {
+ console.error(`Error processing ${src}:`, err.message)
+ process.exit(1)
+ }
+ }
+ console.debug('Finished directory copy operations')
+}
+
+// Run copy operations and start server
+const main = async () => {
+ console.debug('Starting copy-and-start script')
+ await copyAllDirs()
+
+ // Start server
+ const port = process.env.npm_config_port || process.env.PORT || '3000'
+ const host = process.env.npm_config_host || process.env.HOSTNAME || '0.0.0.0'
+
+ console.info(`Starting server on ${host}:${port}`)
+ console.debug(`Server script path: ${SERVER_SCRIPT_PATH}`)
+ console.debug(`Environment variables - PORT: ${port}, HOSTNAME: ${host}`)
+
+ const server = spawn(
+ process.execPath,
+ [SERVER_SCRIPT_PATH],
+ {
+ env: {
+ ...process.env,
+ PORT: port,
+ HOSTNAME: host,
+ },
+ stdio: 'inherit',
+ },
+ )
+
+ server.on('error', (err) => {
+ console.error('Failed to start server:', err)
+ process.exit(1)
+ })
+
+ server.on('exit', (code) => {
+ console.debug(`Server exited with code: ${code}`)
+ process.exit(code || 0)
+ })
+}
+
+main().catch((err) => {
+ console.error('Unexpected error:', err)
+ process.exit(1)
+})
diff --git a/web/types/feature.ts b/web/types/feature.ts
index 56fe0c0484..05421f53c3 100644
--- a/web/types/feature.ts
+++ b/web/types/feature.ts
@@ -122,6 +122,7 @@ export enum DatasetAttr {
DATA_PUBLIC_ENABLE_WEBSITE_JINAREADER = 'data-public-enable-website-jinareader',
DATA_PUBLIC_ENABLE_WEBSITE_FIRECRAWL = 'data-public-enable-website-firecrawl',
DATA_PUBLIC_ENABLE_WEBSITE_WATERCRAWL = 'data-public-enable-website-watercrawl',
+ DATA_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX = 'data-public-enable-single-dollar-latex',
NEXT_PUBLIC_ZENDESK_WIDGET_KEY = 'next-public-zendesk-widget-key',
NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT = 'next-public-zendesk-field-id-environment',
NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION = 'next-public-zendesk-field-id-version',
|