import { BaseMigration } from './base-migration.ts'; import { MigrationV1ToV2 } from './migration-v1-to-v2.ts'; import { MigrationV3ToV4 } from './migration-v3-to-v4.ts'; import { MigrationV4_1ToV4_2 } from './migration-v4.1-to-v4.2.ts'; import { logger } from '../logger.ts'; /** * Migration runner * * Discovers all available migrations, sorts them by order, * and runs applicable migrations in sequence. */ export class MigrationRunner { private migrations: BaseMigration[]; constructor() { // Register all migrations here this.migrations = [ new MigrationV1ToV2(), new MigrationV3ToV4(), new MigrationV4_1ToV4_2(), // Add future migrations here (v4.3, v4.4, etc.) ]; // Sort by version order to ensure they run in sequence this.migrations.sort((a, b) => a.getVersionOrder() - b.getVersionOrder()); } /** * Run all applicable migrations on the config * * @param config - Raw configuration object to migrate * @returns Migrated configuration and whether migrations ran */ async run(config: any): Promise<{ config: any; migrated: boolean }> { let currentConfig = config; let anyMigrationsRan = false; for (const migration of this.migrations) { const shouldRun = await migration.shouldRun(currentConfig); if (shouldRun) { // Only show "checking" message when we actually need to migrate if (!anyMigrationsRan) { logger.dim('Checking for required config migrations...'); } logger.info(`Running ${migration.getName()}...`); currentConfig = await migration.migrate(currentConfig); anyMigrationsRan = true; } } if (anyMigrationsRan) { logger.success('Configuration migrations complete'); } else { logger.success('config format ok'); } return { config: currentConfig, migrated: anyMigrationsRan, }; } /** * Get all registered migrations * * @returns Array of all migrations sorted by order */ getMigrations(): BaseMigration[] { return [...this.migrations]; } }