feat: update env validation

This commit is contained in:
nite-knite 2024-05-09 18:00:21 +08:00
parent ea3f54f28f
commit 2e1766e040
13 changed files with 77 additions and 89 deletions

View File

@ -4,15 +4,15 @@ NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
# example: http://cloud.dify.ai/console/api or http://localhost:5001/console/api
NEXT_PUBLIC_API_PREFIX=
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# SENTRY
# example: http://udify.app/api or http://localhost:5001/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=
# Sentry
NEXT_PUBLIC_SENTRY_DSN=
NEXT_PUBLIC_SITE_ABOUT=
# Pass 'TRUE' to show maintenance notice
NEXT_PUBLIC_MAINTENANCE_NOTICE=
# Pass 'TRUE' to hide cloud service release info and running status
NEXT_PUBLIC_HIDE_ABOUT_INFO=

View File

@ -22,19 +22,18 @@ NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
# example: http://cloud.dify.ai/console/api or http://localhost:5001/console/api
NEXT_PUBLIC_API_PREFIX=
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
# SENTRY
# example: http://udify.app/api or http://localhost:5001/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=
# Sentry
NEXT_PUBLIC_SENTRY_DSN=
# Pass 'TRUE' to show maintenance notice
NEXT_PUBLIC_MAINTENANCE_NOTICE=
# Pass 'TRUE' to hide release info and service status
NEXT_PUBLIC_HIDE_ABOUT_INFO=
```
Finally, run the development server:

View File

@ -17,6 +17,8 @@ import { ArrowUpRight, ChevronDown } from '@/app/components/base/icons/src/vende
import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general'
import { useModalContext } from '@/context/modal-context'
import { LanguagesSupported } from '@/i18n/language'
import { env } from '@/env'
export type IAppSelecotr = {
isMobile: boolean
}
@ -134,7 +136,7 @@ export default function AppSelector({ isMobile }: IAppSelecotr) {
</Link>
</Menu.Item>
{
document?.body?.getAttribute('data-public-site-about') !== 'hide' && (
env.NEXT_PUBLIC_HIDE_ABOUT_INFO !== 'TRUE' && (
<Menu.Item>
<div className={classNames(itemClassName, 'justify-between')} onClick={() => setAboutVisible(true)}>
<div>{t('common.userProfile.about')}</div>

View File

@ -19,7 +19,7 @@ const GithubStar = () => {
useEffect(() => {
(async () => {
try {
if (env.NODE_ENV === 'development')
if (env.NODE_ENV?.toUpperCase() === 'DEVELOPMENT')
return
setGithubRepo(await getStar())

View File

@ -6,7 +6,6 @@ import Topbar from './components/base/topbar'
import { getLocaleOnServer } from '@/i18n/server'
import './styles/globals.css'
import './styles/markdown.scss'
import { env } from '@/env'
export const metadata = {
title: 'Dify',
@ -35,12 +34,8 @@ const LocaleLayout = ({
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
</head>
<body
className="h-full select-auto"
data-public-maintenance-notice={env.NEXT_PUBLIC_MAINTENANCE_NOTICE}
data-public-site-about={env.NEXT_PUBLIC_SITE_ABOUT}
>
<Topbar/>
<body className="h-full select-auto">
<Topbar />
<BrowerInitor>
<SentryInitor>
{/* @ts-expect-error Async Server Component */}

View File

@ -5,13 +5,11 @@ import { useRouter } from 'next/navigation'
import classNames from 'classnames'
import useSWR from 'swr'
import Link from 'next/link'
import { useContext } from 'use-context-selector'
import Toast from '../components/base/toast'
import style from './page.module.css'
import { IS_CE_EDITION, apiPrefix } from '@/config'
import { API_PREFIX, IS_CE_EDITION } from '@/config'
import Button from '@/app/components/base/button'
import { login, oauth } from '@/service/common'
import I18n from '@/context/i18n'
import { getPurifyHref } from '@/utils'
const validEmailReg = /^[\w\.-]+@([\w-]+\.)+[\w-]{2,}$/
@ -65,7 +63,6 @@ function reducer(state: IState, action: IAction) {
const NormalForm = () => {
const { t } = useTranslation()
const router = useRouter()
const { locale } = useContext(I18n)
const [state, dispatch] = useReducer(reducer, {
formValid: false,
@ -157,7 +154,7 @@ const NormalForm = () => {
{!IS_CE_EDITION && (
<div className="flex flex-col gap-3 mt-6">
<div className='w-full'>
<a href={getPurifyHref(`${apiPrefix}/oauth/login/github`)}>
<a href={getPurifyHref(`${API_PREFIX}/oauth/login/github`)}>
<Button
type='default'
disabled={isLoading}
@ -176,7 +173,7 @@ const NormalForm = () => {
</a>
</div>
<div className='w-full'>
<a href={getPurifyHref(`${apiPrefix}/oauth/login/google`)}>
<a href={getPurifyHref(`${API_PREFIX}/oauth/login/google`)}>
<Button
type='default'
disabled={isLoading}

View File

@ -92,7 +92,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
const result = await userProfileResponse.json()
setUserProfile(result)
const current_version = userProfileResponse.headers.get('x-version')
const current_env = env.NODE_ENV === 'development' ? 'DEVELOPMENT' : userProfileResponse.headers.get('x-env')
const current_env = env.NODE_ENV?.toUpperCase() === 'DEVELOPMENT' ? 'DEVELOPMENT' : userProfileResponse.headers.get('x-env')
const versionData = await fetchLanggeniusVersion({ url: '/version', params: { current_version } })
setLangeniusVersionInfo({ ...versionData, current_version, latest_version: versionData.version, current_env })
}
@ -125,7 +125,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
mutateCurrentWorkspace,
}}>
<div className='flex flex-col h-full overflow-y-auto'>
{globalThis.document?.body?.getAttribute('data-public-maintenance-notice') && <MaintenanceNotice />}
{env.NEXT_PUBLIC_MAINTENANCE_NOTICE && <MaintenanceNotice />}
<div ref={pageContainerRef} className='grow relative flex flex-col overflow-y-auto overflow-x-hidden bg-gray-100'>
{children}
</div>

View File

@ -18,6 +18,6 @@ export NEXT_PUBLIC_API_PREFIX=${CONSOLE_API_URL}/console/api
export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_API_URL}/api
export NEXT_PUBLIC_SENTRY_DSN=${SENTRY_DSN}
export NEXT_PUBLIC_SITE_ABOUT=${SITE_ABOUT}
export NEXT_PUBLIC_HIDE_ABOUT_INFO=${HIDE_ABOUT_INFO}
pm2 start ./pm2.json --no-daemon

View File

@ -22,15 +22,15 @@ export const env = createEnv({
NEXT_PUBLIC_DEPLOY_ENV: z
.enum(['DEVELOPMENT', 'PRODUCTION']),
NEXT_PUBLIC_EDITION: z
.enum(['SELF_HOSTED']),
NEXT_PUBLIC_API_PREFIX: z.string().url(),
NEXT_PUBLIC_PUBLIC_API_PREFIX: z.string().url(),
NEXT_PUBLIC_SENTRY_DSN: z.string().url().url().optional(),
.enum(['SELF_HOSTED', 'CLOUD']),
NEXT_PUBLIC_API_PREFIX: z.string().optional().default('http://localhost:5001/console/api'),
NEXT_PUBLIC_PUBLIC_API_PREFIX: z.string().default('http://localhost:5001/api'),
NEXT_PUBLIC_SENTRY_DSN: z.string().optional(),
NEXT_PUBLIC_NODE_ENV: z
.enum(['DEVELOPMENT', 'PRODUCTION'])
.default('DEVELOPMENT'),
NEXT_PUBLIC_MAINTENANCE_NOTICE: z.boolean().optional(),
NEXT_PUBLIC_SITE_ABOUT: z.boolean().optional(),
NEXT_PUBLIC_MAINTENANCE_NOTICE: z.enum(['TRUE']).optional(),
NEXT_PUBLIC_HIDE_ABOUT_INFO: z.enum(['TRUE']).optional(),
},
/**
@ -46,7 +46,10 @@ export const env = createEnv({
NEXT_PUBLIC_PUBLIC_API_PREFIX: process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX,
NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN,
NEXT_PUBLIC_MAINTENANCE_NOTICE: process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE,
NEXT_PUBLIC_SITE_ABOUT: process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE,
// forward compatibility with the old env var
NEXT_PUBLIC_HIDE_ABOUT_INFO: process.env.NEXT_PUBLIC_SITE_ABOUT?.toUpperCase() === 'HIDE'
? 'TRUE'
: process.env.NEXT_PUBLIC_HIDE_ABOUT_INFO,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially

View File

@ -9,7 +9,7 @@
"lint": "next lint",
"fix": "next lint --fix",
"eslint-fix": "eslint --fix",
"prepare": "node ./scripts/update-env.mjs && cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install ./web/.husky",
"prepare": "shx test -f .env.local || shx cp .env.example .env.local && cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install ./web/.husky",
"gen-icons": "node ./app/components/base/icons/script.js",
"uglify-embed": "node ./bin/uglify-embed",
"check-i18n": "node ./i18n/script.js"
@ -118,6 +118,7 @@
"lint-staged": "^13.2.2",
"postcss": "^8.4.31",
"sass": "^1.61.0",
"shx": "^0.3.4",
"tailwindcss": "^3.3.3",
"typescript": "^5.4.5",
"uglify-js": "^3.17.4"
@ -133,4 +134,4 @@
"engines": {
"node": ">=18.17.0"
}
}
}

View File

@ -1,37 +0,0 @@
import * as fs from 'node:fs'
function parseEnvFile(contents) {
return contents.split('\n').reduce((acc, line) => {
const [key, value] = line.split('=')
if (key)
acc.set(key.trim(), value === undefined ? '' : value.trim())
return acc
}, new Map())
}
function updateEnvironmentFile() {
const examplePath = '.env.example'
const envPath = '.env'
const exampleContents = fs.readFileSync(examplePath, 'utf-8')
const envContents = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf-8') : ''
const exampleConfig = parseEnvFile(exampleContents)
const envConfig = parseEnvFile(envContents)
exampleConfig.forEach((value, key) => {
if (!envConfig.has(key))
envConfig.set(key, value)
})
// 生成新的 .env 内容
const newEnvContents = Array.from(envConfig.entries())
.map(([key, value]) => `${key}=${value}`)
.join('\n')
fs.writeFileSync(envPath, newEnvContents)
console.log('.env file has been updated')
}
updateEnvironmentFile()

View File

@ -33,8 +33,7 @@
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"app/components/develop/Prose.jsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"

View File

@ -3487,7 +3487,7 @@ glob@^10.3.10:
minipass "^7.0.4"
path-scurry "^1.10.2"
glob@^7.1.3:
glob@^7.0.0, glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@ -3856,6 +3856,11 @@ internmap@^1.0.0:
resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
intersection-observer@^0.12.0:
version "0.12.2"
resolved "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz#4a45349cc0cd91916682b1f44c28d7ec737dc375"
@ -4165,7 +4170,7 @@ jackspeak@^2.3.5, jackspeak@^2.3.6:
jiti@^1.21.0:
version "1.21.0"
resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
js-audio-recorder@^1.0.7:
@ -5167,7 +5172,7 @@ minimatch@^9.0.1:
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.6:
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@ -5960,6 +5965,13 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
dependencies:
resolve "^1.1.6"
recordrtc@^5.6.2:
version "5.6.2"
resolved "https://registry.npmjs.org/recordrtc/-/recordrtc-5.6.2.tgz#48fc214b35084973ccce82c6251198b5742bc327"
@ -6102,7 +6114,7 @@ resolve-pkg-maps@^1.0.0:
resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f"
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4:
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4:
version "1.22.8"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
@ -6306,6 +6318,23 @@ shebang-regex@^3.0.0:
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shelljs@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
shx@^0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/shx/-/shx-0.3.4.tgz#74289230b4b663979167f94e1935901406e40f02"
integrity sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==
dependencies:
minimist "^1.2.3"
shelljs "^0.8.5"
side-channel@^1.0.4, side-channel@^1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
@ -6816,7 +6845,7 @@ typed-array-length@^1.0.6:
typescript@^5.4.5:
version "5.4.5"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==
uglify-js@^3.17.4: