migrations.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import type { MigrationLiveDefinition } from '@d8d-appcontainer/types'
  2. /**
  3. * 异步加载所有迁移文件
  4. * @returns Promise<MigrationLiveDefinition[]> 返回加载并排序后的迁移数组
  5. */
  6. export async function loadMigrations(): Promise<MigrationLiveDefinition[]> {
  7. const migrations: MigrationLiveDefinition[] = [];
  8. try {
  9. // 读取并加载所有迁移文件
  10. const migrationsDir = import.meta.dirname + '/migrations';
  11. for await (const entry of Deno.readDir(migrationsDir)) {
  12. if (!entry.isFile || !entry.name.endsWith('.ts')) continue;
  13. // 匹配文件名格式:数字前缀_描述.ts
  14. const match = entry.name.match(/^(\d+)_(.+)\.ts$/);
  15. if (!match) continue;
  16. const [_, prefix, name] = match;
  17. try {
  18. const migration = await import(`${migrationsDir}/${entry.name}`);
  19. // 确保导出的迁移对象有效
  20. if (migration?.default?.name && migration?.default?.up && migration?.default?.down) {
  21. migrations.push(migration.default);
  22. console.log(`✅ Loaded migration: ${entry.name}`);
  23. } else {
  24. console.warn(`⚠️ Invalid migration format in ${entry.name}`);
  25. }
  26. } catch (err) {
  27. console.error(`❌ Failed to load migration ${entry.name}:`, err);
  28. }
  29. }
  30. // 按数字前缀排序
  31. migrations.sort((a, b) => {
  32. const aNum = parseInt(a.name.match(/^(\d+)_/)?.[1] || '0');
  33. const bNum = parseInt(b.name.match(/^(\d+)_/)?.[1] || '0');
  34. return aNum - bNum;
  35. });
  36. console.log(`🎉 Successfully loaded ${migrations.length} migrations`);
  37. return migrations;
  38. } catch (err) {
  39. console.error('❌ Failed to load migrations:', err);
  40. throw err;
  41. }
  42. }