将 server/migrations.ts 中的静态加载逻辑改为异步函数 loadMigrations()

This commit is contained in:
yourname
2025-05-14 03:18:37 +00:00
parent f4d692472e
commit 1f89d93468
3 changed files with 48 additions and 40 deletions

View File

@@ -2,6 +2,9 @@
待实现
迁移管理页面在正式环境中需要验证env中配置的密码参数才能打开
2025.05.14 0.1.2
将 server/migrations.ts 中的静态加载逻辑改为异步函数 loadMigrations()
2025.05.14 0.1.1
创建 server/middlewares.ts - 集中管理所有中间件配置
创建 server/router.ts - 统一处理路由注册逻辑

View File

@@ -1,46 +1,50 @@
import type { MigrationLiveDefinition } from '@d8d-appcontainer/types'
// 动态加载迁移文件
const migrations: MigrationLiveDefinition[] = [];
/**
* 异步加载所有迁移文件
* @returns Promise<MigrationLiveDefinition[]> 返回加载并排序后的迁移数组
*/
export async function loadMigrations(): Promise<MigrationLiveDefinition[]> {
const migrations: MigrationLiveDefinition[] = [];
try {
// 读取并加载所有迁移文件
const migrationsDir = import.meta.dirname + '/migrations';
for await (const entry of Deno.readDir(migrationsDir)) {
if (!entry.isFile || !entry.name.endsWith('.ts')) continue;
try {
// 读取并加载所有迁移文件
const migrationsDir = import.meta.dirname + '/migrations';
// 匹配文件名格式数字前缀_描述.ts
const match = entry.name.match(/^(\d+)_(.+)\.ts$/);
if (!match) continue;
const [_, prefix, name] = match;
try {
const migration = await import(`${migrationsDir}/${entry.name}`);
for await (const entry of Deno.readDir(migrationsDir)) {
if (!entry.isFile || !entry.name.endsWith('.ts')) continue;
// 确保导出的迁移对象有效
if (migration?.default?.name && migration?.default?.up && migration?.default?.down) {
migrations.push(migration.default);
console.log(`✅ Loaded migration: ${entry.name}`);
} else {
console.warn(`⚠️ Invalid migration format in ${entry.name}`);
// 匹配文件名格式数字前缀_描述.ts
const match = entry.name.match(/^(\d+)_(.+)\.ts$/);
if (!match) continue;
const [_, prefix, name] = match;
try {
const migration = await import(`${migrationsDir}/${entry.name}`);
// 确保导出的迁移对象有效
if (migration?.default?.name && migration?.default?.up && migration?.default?.down) {
migrations.push(migration.default);
console.log(`✅ Loaded migration: ${entry.name}`);
} else {
console.warn(`⚠️ Invalid migration format in ${entry.name}`);
}
} catch (err) {
console.error(`❌ Failed to load migration ${entry.name}:`, err);
}
} catch (err) {
console.error(`❌ Failed to load migration ${entry.name}:`, err);
}
// 按数字前缀排序
migrations.sort((a, b) => {
const aNum = parseInt(a.name.match(/^(\d+)_/)?.[1] || '0');
const bNum = parseInt(b.name.match(/^(\d+)_/)?.[1] || '0');
return aNum - bNum;
});
console.log(`🎉 Successfully loaded ${migrations.length} migrations`);
return migrations;
} catch (err) {
console.error('❌ Failed to load migrations:', err);
throw err;
}
// 按数字前缀排序
migrations.sort((a, b) => {
const aNum = parseInt(a.name.match(/^(\d+)_/)?.[1] || '0');
const bNum = parseInt(b.name.match(/^(\d+)_/)?.[1] || '0');
return aNum - bNum;
});
console.log(`🎉 Successfully loaded ${migrations.length} migrations`);
} catch (err) {
console.error('❌ Failed to load migrations:', err);
}
// 导出所有迁移
export { migrations };
}

View File

@@ -1,7 +1,7 @@
import { Hono } from 'hono'
import { APIClient } from '@d8d-appcontainer/api'
import type { Variables, WithAuth } from "./middlewares.ts";
import { migrations } from './migrations.ts'
import { loadMigrations } from './migrations.ts'
import debug from "debug";
const log = {
api: debug("api:migrations"),
@@ -13,6 +13,7 @@ export function createMigrationsRoutes(withAuth: WithAuth) {
migrationsRoutes.get('/', async (c) => {
const apiClient = c.get('apiClient')
log.api('正在执行数据库迁移...')
const migrations = await loadMigrations()
const migrationsResult = await apiClient.database.executeLiveMigrations(migrations)
// log.app('数据库迁移完成 %O',migrationsResult)
@@ -47,7 +48,7 @@ export function createMigrationsRoutes(withAuth: WithAuth) {
const apiClient = c.get('apiClient')
const all = c.req.query('all') === 'true'
log.api('正在执行数据库回滚...')
const migrations = await loadMigrations()
const rollbackResult = await apiClient.database.rollbackLiveMigrations(migrations, all)
const failedResult = rollbackResult?.find((migration) => migration.status === 'failed')