优化配置文件

This commit is contained in:
yml
2026-05-21 19:29:00 +08:00
parent 589de4b50b
commit 7513958a4c
23 changed files with 1061 additions and 676 deletions
@@ -0,0 +1,229 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import {
RuntimeConfigValidationError,
assertRuntimeConfigValid,
validateRuntimeConfig,
} from './runtime-validation.js'
import { deepMerge } from './runtime-merge.js'
import type { RuntimeConfig } from '../types/runtime-config.js'
test('validateRuntimeConfig allows missing admin credentials outside production', () => {
const issues = validateRuntimeConfig(createRuntimeConfig({
admin: {
sessionSecret: '',
defaultUsers: [],
},
}), {
env: { NODE_ENV: 'development' },
})
assert.deepEqual(issues, [])
})
test('validateRuntimeConfig requires admin credentials in production', () => {
const issues = validateRuntimeConfig(createRuntimeConfig({
admin: {
sessionSecret: '',
defaultUsers: [],
},
}), {
env: { NODE_ENV: 'production' },
})
assert.deepEqual(issues.map((issue) => issue.path), [
'admin.sessionSecret',
'admin.defaultUsers',
])
})
test('validateRuntimeConfig rejects unsafe production placeholders', () => {
const issues = validateRuntimeConfig(createRuntimeConfig({
admin: {
sessionSecret: 'change-me-long-random-session-secret',
defaultUsers: [
{
username: 'admin',
password: 'change-me-admin-password',
role: 'admin',
},
],
},
}), {
env: { NODE_ENV: 'production' },
})
assert.deepEqual(issues.map((issue) => issue.path), [
'admin.sessionSecret',
'admin.defaultUsers[0].password',
])
})
test('validateRuntimeConfig accepts complete production config', () => {
const issues = validateRuntimeConfig(createRuntimeConfig(), {
env: { NODE_ENV: 'production' },
})
assert.deepEqual(issues, [])
})
test('validateRuntimeConfig catches invalid numeric and url values', () => {
const issues = validateRuntimeConfig(createRuntimeConfig({
server: {
port: 70000,
},
database: {
maxConnections: 0,
},
orders: {
claimBaseUrl: 'not-a-url',
tokenTtlHours: 0,
},
}), {
env: { NODE_ENV: 'development' },
})
assert.deepEqual(issues.map((issue) => issue.path), [
'server.port',
'database.maxConnections',
'orders.tokenTtlHours',
'orders.claimBaseUrl',
])
})
test('assertRuntimeConfigValid throws a readable validation error', () => {
assert.throws(() => {
assertRuntimeConfigValid(createRuntimeConfig({
server: {
port: 0,
},
}))
}, (error) => {
assert.equal(error instanceof RuntimeConfigValidationError, true)
assert.match((error as Error).message, /运行时配置校验失败/)
assert.match((error as Error).message, /server\.port/)
return true
})
})
function createRuntimeConfig(overrides: Record<string, unknown> = {}): RuntimeConfig {
return deepMerge({
server: {
port: 3000,
},
browser: {
chromePath: '',
headless: null,
devtools: null,
keepAlive: null,
prewarm: null,
slowMoMs: null,
vncResolution: '1600x900x24',
},
session: {
debug: false,
},
ocr: {
baseUrl: '',
},
data: {
root: '/tmp/order-site',
},
logging: {
level: 'info',
},
database: {
url: 'postgres://postgres:postgres@postgres:5432/order_site',
ssl: false,
maxConnections: 10,
},
orders: {
claimBaseUrl: 'https://order.example.test/#/claim',
tokenTtlHours: 24,
},
admin: {
sessionSecret: '0123456789abcdef0123456789abcdef',
sessionTtlHours: 12,
defaultUsers: [
{
username: 'admin',
password: 'Qp7xT2mN9vR4',
role: 'admin',
},
],
},
platforms: {
agiso: {
appSecret: '',
tradeDetail: {
endpoint: 'https://gw-api.agiso.com/aldsIdle/Order/Detail',
apiVersion: '1',
timeoutMs: 5000,
},
autoDelivery: {
enabled: true,
endpoint: 'https://gw-api.agiso.com/aldsIdle/Order/DummySend',
apiVersion: '1',
},
messaging: {
enabled: false,
sendMessageEndpoint: 'https://gw-api.agiso.com/aldsIdle/ImMsg/SendMsg',
apiVersion: '1',
messageTemplate: '',
autoDeliveryMessageTemplate: '',
shops: {},
},
},
ninetyone: {
userId: '',
secret: '',
version: '1.0',
shopId: '91kaquan',
shopName: '91卡券',
timestampToleranceSeconds: 600,
cardsEncoding: 'aes-256-ecb-base64',
},
cloudtentacles: {
baseUrl: 'https://123.207.217.176',
timeoutMs: 5000,
sendSmsPath: '/public/verif_code',
loginPath: '/public/login',
userInfoPath: '/user/info',
assetPath: '/user/get_asset',
permissionPath: '/user/get_permission',
categoriesPath: '/categories/get',
skuListPath: '/sku/list',
skuBuyPath: '/sku/buy',
skuUsePath: '/sku/use',
knapsackPath: '/user/get_knapsack',
vnListPath: '/vn/list',
vnAppointPath: '/vn/appoint',
vnGenerateLoginCodePath: '/vn/generate_login_code',
vnVerifCodePath: '/public/vn_verif_code',
vnVerifyLoginCodePath: '/vn/verify_login_code',
vnBindUrlPath: '/vn/bind_url',
vnBindInfoPath: '/vn/bind_info',
vnBackPath: '/vn/back',
bindUrlTtlSeconds: 600,
bindUrlProbeIntervalSeconds: 30,
bindUrlProbeTimeoutMs: 5000,
bindUrlProbeUserAgent: '',
bindUrlProbeEndpoint: 'https://comm.ams.game.qq.com/ide/',
bindUrlProbeChartId: '323794',
bindUrlProbeSubChartId: '323794',
bindUrlProbeIdeToken: 'z90Syo',
bindUrlProbeActivityUrl: '',
bindUrlProbeReferer: 'https://gp.qq.com/',
bindUrlProbeExtraCookie: '',
publicKeyPem: '',
clientSource: 'ct-client',
deviceId: '-',
deviceType: 0,
},
},
redeem: {
proofMode: 'full',
},
}, overrides) as RuntimeConfig
}