mirror of
https://github.com/langgenius/dify.git
synced 2026-07-14 08:57:02 +08:00
Signed-off-by: yyh <yuanyouhuilyz@gmail.com> Co-authored-by: 盐粒 Yanli <mail@yanli.one> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: zyssyz123 <916125788@qq.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: 盐粒 Yanli <yanli@dify.ai> Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
151 lines
6.1 KiB
TypeScript
151 lines
6.1 KiB
TypeScript
import { existsSync, readFileSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
import { createEnv } from '@t3-oss/env-core'
|
|
import * as z from 'zod'
|
|
import { e2eDir } from './common'
|
|
|
|
const booleanString = z.enum(['0', '1', 'false', 'true'])
|
|
const jsonObjectString = z.string().refine((value) => {
|
|
try {
|
|
const parsed = JSON.parse(value) as unknown
|
|
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
|
|
}
|
|
catch {
|
|
return false
|
|
}
|
|
}, 'must be a JSON object string')
|
|
|
|
const parseEnvLine = (line: string) => {
|
|
const trimmed = line.trim()
|
|
if (!trimmed || trimmed.startsWith('#'))
|
|
return undefined
|
|
|
|
const normalized = trimmed.startsWith('export ')
|
|
? trimmed.slice('export '.length).trim()
|
|
: trimmed
|
|
const separatorIndex = normalized.indexOf('=')
|
|
if (separatorIndex === -1)
|
|
return undefined
|
|
|
|
const key = normalized.slice(0, separatorIndex).trim()
|
|
let value = normalized.slice(separatorIndex + 1).trim()
|
|
if (!key)
|
|
return undefined
|
|
|
|
if (
|
|
(value.startsWith('"') && value.endsWith('"'))
|
|
|| (value.startsWith('\'') && value.endsWith('\''))
|
|
) {
|
|
value = value.slice(1, -1)
|
|
}
|
|
|
|
return [key, value] as const
|
|
}
|
|
|
|
export const loadE2eEnv = () => {
|
|
const envFilePath = process.env.E2E_ENV_FILE
|
|
? path.resolve(process.env.E2E_ENV_FILE)
|
|
: path.join(e2eDir, '.env.local')
|
|
|
|
if (!existsSync(envFilePath))
|
|
return
|
|
|
|
const content = readFileSync(envFilePath, 'utf8')
|
|
for (const line of content.split(/\r?\n/)) {
|
|
const entry = parseEnvLine(line)
|
|
if (!entry)
|
|
continue
|
|
|
|
const [key, value] = entry
|
|
process.env[key] ??= value
|
|
}
|
|
}
|
|
|
|
export const validateE2eEnv = () => createEnv({
|
|
client: {},
|
|
clientPrefix: 'NEXT_PUBLIC_',
|
|
emptyStringAsUndefined: true,
|
|
onValidationError: (issues) => {
|
|
const messages = issues.map((issue) => {
|
|
const path = Array.isArray(issue.path) && issue.path.length > 0
|
|
? issue.path.join('.')
|
|
: '(root)'
|
|
return `- ${path}: ${issue.message}`
|
|
})
|
|
|
|
throw new Error(`Invalid E2E env:\n${messages.join('\n')}`)
|
|
},
|
|
runtimeEnv: {
|
|
CUCUMBER_HEADLESS: process.env.CUCUMBER_HEADLESS,
|
|
E2E_ADMIN_EMAIL: process.env.E2E_ADMIN_EMAIL,
|
|
E2E_ADMIN_NAME: process.env.E2E_ADMIN_NAME,
|
|
E2E_ADMIN_PASSWORD: process.env.E2E_ADMIN_PASSWORD,
|
|
E2E_AGENT_BACKEND_PORT: process.env.E2E_AGENT_BACKEND_PORT,
|
|
E2E_AGENT_BACKEND_URL: process.env.E2E_AGENT_BACKEND_URL,
|
|
E2E_API_URL: process.env.E2E_API_URL,
|
|
E2E_BASE_URL: process.env.E2E_BASE_URL,
|
|
E2E_BROKEN_MODEL_NAME: process.env.E2E_BROKEN_MODEL_NAME,
|
|
E2E_BROKEN_MODEL_PROVIDER: process.env.E2E_BROKEN_MODEL_PROVIDER,
|
|
E2E_BROKEN_MODEL_TYPE: process.env.E2E_BROKEN_MODEL_TYPE,
|
|
E2E_CUCUMBER_TAGS: process.env.E2E_CUCUMBER_TAGS,
|
|
E2E_EXTERNAL_RUNTIME_SEED_SPECS: process.env.E2E_EXTERNAL_RUNTIME_SEED_SPECS,
|
|
E2E_EXTERNAL_RUNTIME_TAGS: process.env.E2E_EXTERNAL_RUNTIME_TAGS,
|
|
E2E_FORCE_WEB_BUILD: process.env.E2E_FORCE_WEB_BUILD,
|
|
E2E_INIT_PASSWORD: process.env.E2E_INIT_PASSWORD,
|
|
E2E_MARKETPLACE_API_URL: process.env.E2E_MARKETPLACE_API_URL,
|
|
E2E_MARKETPLACE_PLUGIN_IDS: process.env.E2E_MARKETPLACE_PLUGIN_IDS,
|
|
E2E_MARKETPLACE_PLUGIN_UNIQUE_IDENTIFIERS: process.env.E2E_MARKETPLACE_PLUGIN_UNIQUE_IDENTIFIERS,
|
|
E2E_MODEL_PROVIDER_CREDENTIALS_JSON: process.env.E2E_MODEL_PROVIDER_CREDENTIALS_JSON,
|
|
E2E_OAUTH_TOOL_CREDENTIAL_ID: process.env.E2E_OAUTH_TOOL_CREDENTIAL_ID,
|
|
E2E_OAUTH_TOOL_NAME: process.env.E2E_OAUTH_TOOL_NAME,
|
|
E2E_OAUTH_TOOL_PROVIDER: process.env.E2E_OAUTH_TOOL_PROVIDER,
|
|
E2E_REUSE_WEB_SERVER: process.env.E2E_REUSE_WEB_SERVER,
|
|
E2E_SLOW_MO: process.env.E2E_SLOW_MO,
|
|
E2E_SHELLCTL_AUTH_TOKEN: process.env.E2E_SHELLCTL_AUTH_TOKEN,
|
|
E2E_SHELLCTL_CONTAINER_NAME: process.env.E2E_SHELLCTL_CONTAINER_NAME,
|
|
E2E_SHELLCTL_IMAGE: process.env.E2E_SHELLCTL_IMAGE,
|
|
E2E_SHELLCTL_PORT: process.env.E2E_SHELLCTL_PORT,
|
|
E2E_SHELLCTL_URL: process.env.E2E_SHELLCTL_URL,
|
|
E2E_START_AGENT_BACKEND: process.env.E2E_START_AGENT_BACKEND,
|
|
E2E_STABLE_MODEL_NAME: process.env.E2E_STABLE_MODEL_NAME,
|
|
E2E_STABLE_MODEL_PROVIDER: process.env.E2E_STABLE_MODEL_PROVIDER,
|
|
E2E_STABLE_MODEL_TYPE: process.env.E2E_STABLE_MODEL_TYPE,
|
|
},
|
|
server: {
|
|
CUCUMBER_HEADLESS: booleanString.optional(),
|
|
E2E_ADMIN_EMAIL: z.email().optional(),
|
|
E2E_ADMIN_NAME: z.string().min(1).optional(),
|
|
E2E_ADMIN_PASSWORD: z.string().min(1).optional(),
|
|
E2E_AGENT_BACKEND_PORT: z.coerce.number().int().positive().max(65535).optional(),
|
|
E2E_AGENT_BACKEND_URL: z.url().optional(),
|
|
E2E_API_URL: z.url().optional(),
|
|
E2E_BASE_URL: z.url().optional(),
|
|
E2E_BROKEN_MODEL_NAME: z.string().min(1).optional(),
|
|
E2E_BROKEN_MODEL_PROVIDER: z.string().min(1).optional(),
|
|
E2E_BROKEN_MODEL_TYPE: z.string().min(1).optional(),
|
|
E2E_CUCUMBER_TAGS: z.string().min(1).optional(),
|
|
E2E_EXTERNAL_RUNTIME_SEED_SPECS: z.string().min(1).optional(),
|
|
E2E_EXTERNAL_RUNTIME_TAGS: z.string().min(1).optional(),
|
|
E2E_FORCE_WEB_BUILD: z.literal('1').optional(),
|
|
E2E_INIT_PASSWORD: z.string().min(1).optional(),
|
|
E2E_MARKETPLACE_API_URL: z.url().optional(),
|
|
E2E_MARKETPLACE_PLUGIN_IDS: z.string().min(1).optional(),
|
|
E2E_MARKETPLACE_PLUGIN_UNIQUE_IDENTIFIERS: z.string().min(1).optional(),
|
|
E2E_MODEL_PROVIDER_CREDENTIALS_JSON: jsonObjectString.optional(),
|
|
E2E_OAUTH_TOOL_CREDENTIAL_ID: z.string().min(1).optional(),
|
|
E2E_OAUTH_TOOL_NAME: z.string().min(1).optional(),
|
|
E2E_OAUTH_TOOL_PROVIDER: z.string().min(1).optional(),
|
|
E2E_REUSE_WEB_SERVER: booleanString.optional(),
|
|
E2E_SLOW_MO: z.coerce.number().nonnegative().optional(),
|
|
E2E_SHELLCTL_AUTH_TOKEN: z.string().min(1).optional(),
|
|
E2E_SHELLCTL_CONTAINER_NAME: z.string().min(1).optional(),
|
|
E2E_SHELLCTL_IMAGE: z.string().min(1).optional(),
|
|
E2E_SHELLCTL_PORT: z.coerce.number().int().positive().max(65535).optional(),
|
|
E2E_SHELLCTL_URL: z.url().optional(),
|
|
E2E_START_AGENT_BACKEND: booleanString.optional(),
|
|
E2E_STABLE_MODEL_NAME: z.string().min(1).optional(),
|
|
E2E_STABLE_MODEL_PROVIDER: z.string().min(1).optional(),
|
|
E2E_STABLE_MODEL_TYPE: z.string().min(1).optional(),
|
|
},
|
|
})
|