准备迁移1

This commit is contained in:
yml2213
2026-08-23 12:54:38 +08:00
parent 360c5ea20e
commit 6d7f9b5f3f
16 changed files with 999 additions and 339 deletions
+8
View File
@@ -32,12 +32,20 @@ export function createDefaultRuntimeConfig(projectRoot: string): RuntimeConfig {
},
storage: {
mode: 'minio',
endpoint: 'http://127.0.0.1:9000',
bucket: 'order-site',
accessKeyId: 'minioadmin',
secretAccessKey: 'minioadmin',
region: 'us-east-1',
maxUploadSizeMb: 10,
oss: {
endpoint: '',
bucket: '',
accessKeyId: '',
secretAccessKey: '',
region: 'oss-cn-hangzhou',
},
},
orders: {
+6
View File
@@ -40,12 +40,18 @@ export const ENV_OVERRIDES: readonly EnvOverride[] = [
integerEnv('DATABASE_CONNECTION_TIMEOUT_MS', ['database', 'connectionTimeoutMs']),
integerEnv('DATABASE_STATEMENT_TIMEOUT_MS', ['database', 'statementTimeoutMs']),
integerEnv('DATABASE_SLOW_QUERY_THRESHOLD_MS', ['database', 'slowQueryThresholdMs']),
stringEnv('STORAGE_MODE', ['storage', 'mode']),
stringEnv('STORAGE_ENDPOINT', ['storage', 'endpoint']),
stringEnv('STORAGE_BUCKET', ['storage', 'bucket']),
stringEnv('STORAGE_ACCESS_KEY_ID', ['storage', 'accessKeyId']),
stringEnv('STORAGE_SECRET_ACCESS_KEY', ['storage', 'secretAccessKey']),
stringEnv('STORAGE_REGION', ['storage', 'region']),
integerEnv('STORAGE_MAX_UPLOAD_SIZE_MB', ['storage', 'maxUploadSizeMb']),
stringEnv('STORAGE_OSS_ENDPOINT', ['storage', 'oss', 'endpoint']),
stringEnv('STORAGE_OSS_BUCKET', ['storage', 'oss', 'bucket']),
stringEnv('STORAGE_OSS_ACCESS_KEY_ID', ['storage', 'oss', 'accessKeyId']),
stringEnv('STORAGE_OSS_SECRET_ACCESS_KEY', ['storage', 'oss', 'secretAccessKey']),
stringEnv('STORAGE_OSS_REGION', ['storage', 'oss', 'region']),
integerEnv('CLAIM_TOKEN_TTL_HOURS', ['orders', 'tokenTtlHours']),
stringEnv('ADMIN_SESSION_SECRET', ['admin', 'sessionSecret']),
integerEnv('ADMIN_SESSION_TTL_HOURS', ['admin', 'sessionTtlHours']),
+43 -7
View File
@@ -79,6 +79,13 @@ export function validateRuntimeConfig(
min: 1,
max: 100,
})
const storageMode = normalizeStorageMode(config.storage?.mode)
if (!storageMode) {
issues.push({
path: 'storage.mode',
message: '仅支持 minio、dual 或 oss',
})
}
requireInteger(issues, 'orders.tokenTtlHours', config.orders?.tokenTtlHours, { min: 0 })
requireInteger(issues, 'admin.sessionTtlHours', config.admin?.sessionTtlHours, { min: 1 })
requireInteger(
@@ -116,17 +123,17 @@ export function validateRuntimeConfig(
validateOptionalHttpUrl(issues, 'orders.claimBaseUrl', config.orders?.claimBaseUrl)
validateOptionalStorageEndpoint(issues, 'storage.endpoint', config.storage?.endpoint)
validateOptionalStorageEndpoint(issues, 'storage.oss.endpoint', config.storage?.oss?.endpoint)
validateRequiredString(issues, 'data.root', config.data?.root)
if (productionLike) {
validateRequiredString(issues, 'database.url', config.database?.url)
validateRequiredString(issues, 'storage.endpoint', config.storage?.endpoint)
validateOptionalStorageEndpoint(issues, 'storage.endpoint', config.storage?.endpoint)
validateRequiredString(issues, 'storage.bucket', config.storage?.bucket)
validateRequiredString(issues, 'storage.accessKeyId', config.storage?.accessKeyId)
validateSecret(issues, 'storage.secretAccessKey', config.storage?.secretAccessKey, {
minLength: 8,
})
if (storageMode === 'minio' || storageMode === 'dual') {
validateStorageCredentials(issues, 'storage', config.storage)
}
if (storageMode === 'oss' || storageMode === 'dual') {
validateStorageCredentials(issues, 'storage.oss', config.storage?.oss)
}
validateRequiredHttpUrl(issues, 'orders.claimBaseUrl', config.orders?.claimBaseUrl)
validateSecret(issues, 'admin.sessionSecret', config.admin?.sessionSecret, { minLength: 32 })
validateAdminDefaultUsers(issues, config.admin?.defaultUsers)
@@ -135,6 +142,35 @@ export function validateRuntimeConfig(
return issues
}
function normalizeStorageMode(value: unknown): 'minio' | 'dual' | 'oss' | '' {
const mode = String(value || 'minio')
.trim()
.toLowerCase()
return mode === 'minio' || mode === 'dual' || mode === 'oss' ? mode : ''
}
function validateStorageCredentials(
issues: RuntimeConfigValidationIssue[],
configPath: string,
storage:
| {
endpoint?: unknown
bucket?: unknown
accessKeyId?: unknown
secretAccessKey?: unknown
}
| null
| undefined,
): void {
validateRequiredString(issues, `${configPath}.endpoint`, storage?.endpoint)
validateOptionalStorageEndpoint(issues, `${configPath}.endpoint`, storage?.endpoint)
validateRequiredString(issues, `${configPath}.bucket`, storage?.bucket)
validateRequiredString(issues, `${configPath}.accessKeyId`, storage?.accessKeyId)
validateSecret(issues, `${configPath}.secretAccessKey`, storage?.secretAccessKey, {
minLength: 8,
})
}
export function isProductionLike(env: RuntimeEnvironment = process.env): boolean {
return env.NODE_ENV === 'production'
}