diff --git a/HISTORY.md b/HISTORY.md index a01d6ee..0702c69 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -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 - 统一处理路由注册逻辑 diff --git a/server/migrations.ts b/server/migrations.ts index 473d5e5..8862ffb 100644 --- a/server/migrations.ts +++ b/server/migrations.ts @@ -1,46 +1,50 @@ import type { MigrationLiveDefinition } from '@d8d-appcontainer/types' -// 动态加载迁移文件 -const migrations: MigrationLiveDefinition[] = []; +/** + * 异步加载所有迁移文件 + * @returns Promise 返回加载并排序后的迁移数组 + */ +export async function loadMigrations(): Promise { + 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 }; \ No newline at end of file +} \ No newline at end of file diff --git a/server/routes_migrations.ts b/server/routes_migrations.ts index 0b5fae6..b6a9c9c 100644 --- a/server/routes_migrations.ts +++ b/server/routes_migrations.ts @@ -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')