init
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user