- 新增每日数据保留清理任务:按保留期清空原始报文、删除过期 事件/审计记录,批量幂等可重跑;067 迁移补齐清理索引并清理 冗余索引,check-sql-guard 增加防线 - 生产 CORS 改为显式来源白名单(CORS_ALLOWED_ORIGINS),禁用 通配符,非通配响应补充 Vary: Origin - 文件上传任一步失败时回滚已上传对象,清理失败记录 warn 日志 - 新增 HTTP/CORS 与 PostgreSQL 集成测试;若干文件仅 prettier 重排
96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
import { ENV_OVERRIDES } from './env-overrides.js'
|
|
|
|
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url))
|
|
const BACKEND_ROOT = path.resolve(CURRENT_DIR, '../..')
|
|
const WORKSPACE_ROOT = process.env.WORKSPACE_ROOT || path.resolve(BACKEND_ROOT, '../..')
|
|
|
|
const SPECIAL_RUNTIME_ENV_NAMES = ['APP_BASE_URL', 'CLAIM_BASE_URL']
|
|
|
|
const DEPLOYMENT_ONLY_ENV_NAMES = [
|
|
'APP_DOMAIN',
|
|
'BACKEND_PORT',
|
|
'CADDY_SITE_ADDR',
|
|
'CHOKIDAR_USEPOLLING',
|
|
'DB_BACKUP_KEEP',
|
|
'DB_BACKUP_OSS_PREFIX',
|
|
'KUASHOU_INDUSTRY_RATE_LIMIT_MAX',
|
|
'MINIO_API_PORT',
|
|
'MINIO_CONSOLE_PORT',
|
|
'MINIO_ROOT_PASSWORD',
|
|
'MINIO_ROOT_USER',
|
|
'NPM_CONFIG_REGISTRY',
|
|
'POSTGRES_DB',
|
|
'POSTGRES_LOG_MIN_DURATION_STATEMENT_MS',
|
|
'POSTGRES_MEM_LIMIT',
|
|
'POSTGRES_CPUS',
|
|
'POSTGRES_SHARED_BUFFERS',
|
|
'POSTGRES_EFFECTIVE_CACHE_SIZE',
|
|
'POSTGRES_WORK_MEM',
|
|
'POSTGRES_MAINTENANCE_WORK_MEM',
|
|
'BACKEND_MEM_LIMIT',
|
|
'BACKEND_CPUS',
|
|
'WEB_MEM_LIMIT',
|
|
'WEB_CPUS',
|
|
'POSTGRES_PASSWORD',
|
|
'POSTGRES_PORT',
|
|
'POSTGRES_USER',
|
|
'TZ',
|
|
'VITE_API_TARGET',
|
|
'VITE_ALLOWED_HOSTS',
|
|
'VITE_WORKER_SITE_URL',
|
|
'WORKSPACE_ROOT',
|
|
'WORKER_SITE_ADDR',
|
|
]
|
|
|
|
const KNOWN_ENV_NAMES = new Set([
|
|
...ENV_OVERRIDES.map((override) => override.env),
|
|
...SPECIAL_RUNTIME_ENV_NAMES,
|
|
...DEPLOYMENT_ONLY_ENV_NAMES,
|
|
])
|
|
|
|
test('env example files only document known runtime or deployment variables', () => {
|
|
const envFiles = [
|
|
path.join(WORKSPACE_ROOT, '.env.server.example'),
|
|
path.join(WORKSPACE_ROOT, '.env.mac-docker.example'),
|
|
]
|
|
|
|
const unknownNames = envFiles.flatMap((filePath) => {
|
|
return extractExampleEnvNames(filePath)
|
|
.filter((name) => !KNOWN_ENV_NAMES.has(name))
|
|
.map((name) => `${path.basename(filePath)}:${name}`)
|
|
})
|
|
|
|
assert.deepEqual(unknownNames, [])
|
|
})
|
|
|
|
test('compose environment keys only use known runtime or deployment variables', () => {
|
|
const composeFiles = [
|
|
path.join(WORKSPACE_ROOT, 'docker-compose.yml'),
|
|
path.join(WORKSPACE_ROOT, 'docker-compose.dev.yml'),
|
|
]
|
|
|
|
const unknownNames = composeFiles.flatMap((filePath) => {
|
|
return extractComposeEnvironmentKeys(filePath)
|
|
.filter((name) => !KNOWN_ENV_NAMES.has(name))
|
|
.map((name) => `${path.basename(filePath)}:${name}`)
|
|
})
|
|
|
|
assert.deepEqual(unknownNames, [])
|
|
})
|
|
|
|
function extractExampleEnvNames(filePath: string): string[] {
|
|
const text = fs.readFileSync(filePath, 'utf8')
|
|
return [...text.matchAll(/^([A-Z][A-Z0-9_]*)=/gm)].map((match) => match[1])
|
|
}
|
|
|
|
function extractComposeEnvironmentKeys(filePath: string): string[] {
|
|
const text = fs.readFileSync(filePath, 'utf8')
|
|
return [...text.matchAll(/^\s{6}([A-Z][A-Z0-9_]*):/gm)].map((match) => match[1])
|
|
}
|