/** * Abstract base class for configuration migrations * * Each migration represents an upgrade from one config version to another. * Migrations run in order based on the `order` field, allowing users to jump * multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4). */ /** * Abstract base class for configuration migrations * * Each migration represents an upgrade from one config version to another. * Migrations run in order based on the `toVersion` field, allowing users to jump * multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4). */ export abstract class BaseMigration { /** * Source version this migration upgrades from * e.g., "1.x", "3.x" */ abstract readonly fromVersion: string; /** * Target version this migration upgrades to * e.g., "2.0", "4.0", "4.1" */ abstract readonly toVersion: string; /** * Check if this migration should run on the given config * * @param config - Raw configuration object to check (unknown schema for migrations) * @returns True if migration should run, false otherwise */ abstract shouldRun(config: Record): Promise; /** * Perform the migration on the given config * * @param config - Raw configuration object to migrate (unknown schema for migrations) * @returns Migrated configuration object */ abstract migrate(config: Record): Promise>; /** * Get human-readable name for this migration * * @returns Migration name */ getName(): string { return `Migration ${this.fromVersion} → ${this.toVersion}`; } /** * Parse version string into a comparable number * Supports formats like "2.0", "4.1", etc. * Returns a number like 2.0, 4.1 for sorting * * @returns Parsed version number for ordering */ getVersionOrder(): number { const parsed = parseFloat(this.toVersion); if (isNaN(parsed)) { throw new Error(`Invalid version format: ${this.toVersion}`); } return parsed; } }