This commit is contained in:
yml
2026-04-08 16:30:42 +08:00
commit 313c036845
131 changed files with 22393 additions and 0 deletions
+255
View File
@@ -0,0 +1,255 @@
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'
const require = createRequire(import.meta.url)
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url))
export const PROJECT_ROOT = path.resolve(CURRENT_DIR, '../..')
const CONFIG_ROOT = path.join(PROJECT_ROOT, 'config')
const defaultConfig = loadConfig(path.join(CONFIG_ROOT, 'default.cjs'))
const localConfig = loadConfig(path.join(CONFIG_ROOT, 'local.cjs'))
const mergedConfig = deepMerge(defaultConfig, localConfig)
export const runtimeConfig = applyEnvOverrides(mergedConfig)
function loadConfig(configPath) {
if (!fs.existsSync(configPath)) {
return {}
}
const loaded = require(configPath)
return isPlainObject(loaded) ? loaded : {}
}
function applyEnvOverrides(baseConfig) {
const nextConfig = deepMerge(baseConfig, {})
const port = parseInteger(process.env.PORT)
if (port !== null) {
nextConfig.server.port = port
}
const chromePath = String(process.env.CHROME_PATH || '').trim()
if (chromePath) {
nextConfig.browser.chromePath = chromePath
}
const browserHeadless = parseBoolean(process.env.TENCENT_BROWSER_HEADLESS)
if (browserHeadless !== null) {
nextConfig.browser.headless = browserHeadless
}
const browserDevtools = parseBoolean(process.env.TENCENT_BROWSER_DEVTOOLS)
if (browserDevtools !== null) {
nextConfig.browser.devtools = browserDevtools
}
const browserKeepAlive = parseBoolean(process.env.TENCENT_BROWSER_KEEP_ALIVE)
if (browserKeepAlive !== null) {
nextConfig.browser.keepAlive = browserKeepAlive
}
const browserPrewarm = parseBoolean(process.env.TENCENT_BROWSER_PREWARM)
if (browserPrewarm !== null) {
nextConfig.browser.prewarm = browserPrewarm
}
const browserSlowMoMs = parseInteger(process.env.TENCENT_BROWSER_SLOW_MO)
if (browserSlowMoMs !== null) {
nextConfig.browser.slowMoMs = browserSlowMoMs
}
const sessionDebug = parseBoolean(process.env.TENCENT_SESSION_DEBUG)
if (sessionDebug !== null) {
nextConfig.session.debug = sessionDebug
}
const ocrProjectRoot = String(process.env.OCR_PROJECT_ROOT || '').trim()
if (ocrProjectRoot) {
nextConfig.ocr.projectRoot = ocrProjectRoot
}
const proofMode = String(process.env.TENCENT_REDEEM_PROOF_MODE || '').trim()
if (proofMode) {
nextConfig.redeem.proofMode = proofMode
}
const databaseFilePath = String(process.env.DATABASE_FILE_PATH || '').trim()
if (databaseFilePath) {
nextConfig.database.filePath = databaseFilePath
}
const claimBaseUrl = String(process.env.CLAIM_BASE_URL || '').trim()
if (claimBaseUrl) {
nextConfig.orders.claimBaseUrl = claimBaseUrl
}
const skuMappings = parseJsonObject(process.env.ORDER_SKU_MAPPINGS_JSON)
if (skuMappings) {
nextConfig.orders.skuMappings = skuMappings
}
const adminSessionSecret = String(process.env.ADMIN_SESSION_SECRET || '').trim()
if (adminSessionSecret) {
nextConfig.admin.sessionSecret = adminSessionSecret
}
const adminSessionTtlHours = parseInteger(process.env.ADMIN_SESSION_TTL_HOURS)
if (adminSessionTtlHours !== null) {
nextConfig.admin.sessionTtlHours = adminSessionTtlHours
}
const adminDefaultUsers = parseJsonArray(process.env.ADMIN_DEFAULT_USERS_JSON)
if (adminDefaultUsers) {
nextConfig.admin.defaultUsers = adminDefaultUsers
}
const agisoAppSecret = String(process.env.AGISO_APP_SECRET || '').trim()
if (agisoAppSecret) {
nextConfig.platforms.agiso.appSecret = agisoAppSecret
}
const agisoAppId = String(process.env.AGISO_APP_ID || '').trim()
if (agisoAppId) {
nextConfig.platforms.agiso.messaging.appId = agisoAppId
}
const agisoAccessToken = String(process.env.AGISO_ACCESS_TOKEN || '').trim()
if (agisoAccessToken) {
nextConfig.platforms.agiso.messaging.accessToken = agisoAccessToken
}
const agisoMessageAppSecret = String(process.env.AGISO_MESSAGE_APP_SECRET || '').trim()
if (agisoMessageAppSecret) {
nextConfig.platforms.agiso.messaging.appSecret = agisoMessageAppSecret
}
const agisoMessageApiVersion = String(process.env.AGISO_MESSAGE_API_VERSION || '').trim()
if (agisoMessageApiVersion) {
nextConfig.platforms.agiso.messaging.apiVersion = agisoMessageApiVersion
}
const agisoSendMessageEndpoint = String(process.env.AGISO_SEND_MESSAGE_ENDPOINT || '').trim()
if (agisoSendMessageEndpoint) {
nextConfig.platforms.agiso.messaging.sendMessageEndpoint = agisoSendMessageEndpoint
}
const agisoMessagingEnabled = parseBoolean(process.env.AGISO_MESSAGING_ENABLED)
if (agisoMessagingEnabled !== null) {
nextConfig.platforms.agiso.messaging.enabled = agisoMessagingEnabled
}
const agisoMessageTemplate = String(process.env.AGISO_MESSAGE_TEMPLATE || '').trim()
if (agisoMessageTemplate) {
nextConfig.platforms.agiso.messaging.messageTemplate = agisoMessageTemplate
}
return nextConfig
}
function deepMerge(baseValue, overrideValue) {
if (!isPlainObject(baseValue)) {
return cloneValue(overrideValue)
}
const result = cloneValue(baseValue)
if (!isPlainObject(overrideValue)) {
return result
}
for (const [key, value] of Object.entries(overrideValue)) {
if (isPlainObject(value) && isPlainObject(result[key])) {
result[key] = deepMerge(result[key], value)
continue
}
result[key] = cloneValue(value)
}
return result
}
function cloneValue(value) {
if (Array.isArray(value)) {
return value.map((item) => cloneValue(item))
}
if (isPlainObject(value)) {
const output = {}
for (const [key, item] of Object.entries(value)) {
output[key] = cloneValue(item)
}
return output
}
return value
}
function isPlainObject(value) {
return Object.prototype.toString.call(value) === '[object Object]'
}
function parseBoolean(rawValue) {
const normalized = String(rawValue || '')
.trim()
.toLowerCase()
if (!normalized) {
return null
}
if (['1', 'true', 'yes', 'on'].includes(normalized)) {
return true
}
if (['0', 'false', 'no', 'off'].includes(normalized)) {
return false
}
return null
}
function parseInteger(rawValue) {
const normalized = String(rawValue || '').trim()
if (!normalized) {
return null
}
const parsed = Number(normalized)
return Number.isFinite(parsed) ? parsed : null
}
function parseJsonObject(rawValue) {
const normalized = String(rawValue || '').trim()
if (!normalized) {
return null
}
try {
const parsed = JSON.parse(normalized)
return isPlainObject(parsed) ? parsed : null
} catch {
return null
}
}
function parseJsonArray(rawValue) {
const normalized = String(rawValue || '').trim()
if (!normalized) {
return null
}
try {
const parsed = JSON.parse(normalized)
return Array.isArray(parsed) ? parsed : null
} catch {
return null
}
}