drizzle-multitenant 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/migrator/table-format.ts","../../src/migrator/migrator.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Pool } from 'pg';\n\n/**\n * Table format for tracking migrations\n * - \"name\": drizzle-multitenant native (filename-based)\n * - \"hash\": SHA-256 hash with timestamp\n * - \"drizzle-kit\": Exact drizzle-kit format (hash + bigint timestamp)\n */\nexport type TableFormat = 'name' | 'hash' | 'drizzle-kit';\n\n/**\n * Detected table format information\n */\nexport interface DetectedFormat {\n /** The detected format type */\n format: TableFormat;\n /** The table name */\n tableName: string;\n /** Column configuration */\n columns: {\n /** Column used for identifying migrations */\n identifier: 'name' | 'hash';\n /** Column used for timestamp */\n timestamp: 'applied_at' | 'created_at';\n /** Data type of timestamp column */\n timestampType: 'timestamp' | 'bigint';\n };\n}\n\n/**\n * Default format configuration for new tables\n */\nexport const DEFAULT_FORMAT: DetectedFormat = {\n format: 'name',\n tableName: '__drizzle_migrations',\n columns: {\n identifier: 'name',\n timestamp: 'applied_at',\n timestampType: 'timestamp',\n },\n};\n\n/**\n * drizzle-kit format configuration\n */\nexport const DRIZZLE_KIT_FORMAT: DetectedFormat = {\n format: 'drizzle-kit',\n tableName: '__drizzle_migrations',\n columns: {\n identifier: 'hash',\n timestamp: 'created_at',\n timestampType: 'bigint',\n },\n};\n\ninterface ColumnInfo {\n column_name: string;\n data_type: string;\n}\n\n/**\n * Detect the format of an existing migrations table\n *\n * @param pool - Database connection pool\n * @param schemaName - Schema to check\n * @param tableName - Migrations table name\n * @returns Detected format or null if table doesn't exist\n */\nexport async function detectTableFormat(\n pool: Pool,\n schemaName: string,\n tableName: string\n): Promise<DetectedFormat | null> {\n // Check if table exists\n const tableExists = await pool.query<{ exists: boolean }>(\n `SELECT EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = $1 AND table_name = $2\n ) as exists`,\n [schemaName, tableName]\n );\n\n if (!tableExists.rows[0]?.exists) {\n return null;\n }\n\n // Get column information\n const columnsResult = await pool.query<ColumnInfo>(\n `SELECT column_name, data_type\n FROM information_schema.columns\n WHERE table_schema = $1 AND table_name = $2`,\n [schemaName, tableName]\n );\n\n const columnMap = new Map<string, string>(\n columnsResult.rows.map((r) => [r.column_name, r.data_type])\n );\n\n // Detect format based on columns\n if (columnMap.has('name')) {\n // drizzle-multitenant native format\n return {\n format: 'name',\n tableName,\n columns: {\n identifier: 'name',\n timestamp: columnMap.has('applied_at') ? 'applied_at' : 'created_at',\n timestampType: 'timestamp',\n },\n };\n }\n\n if (columnMap.has('hash')) {\n const createdAtType = columnMap.get('created_at');\n\n // drizzle-kit uses bigint for created_at\n if (createdAtType === 'bigint') {\n return {\n format: 'drizzle-kit',\n tableName,\n columns: {\n identifier: 'hash',\n timestamp: 'created_at',\n timestampType: 'bigint',\n },\n };\n }\n\n // Custom hash-based format with regular timestamp\n return {\n format: 'hash',\n tableName,\n columns: {\n identifier: 'hash',\n timestamp: 'created_at',\n timestampType: 'timestamp',\n },\n };\n }\n\n // Unknown format - return null to trigger error handling\n return null;\n}\n\n/**\n * Get the format configuration for a specific format type\n */\nexport function getFormatConfig(\n format: TableFormat,\n tableName: string = '__drizzle_migrations'\n): DetectedFormat {\n switch (format) {\n case 'name':\n return {\n format: 'name',\n tableName,\n columns: {\n identifier: 'name',\n timestamp: 'applied_at',\n timestampType: 'timestamp',\n },\n };\n case 'hash':\n return {\n format: 'hash',\n tableName,\n columns: {\n identifier: 'hash',\n timestamp: 'created_at',\n timestampType: 'timestamp',\n },\n };\n case 'drizzle-kit':\n return {\n format: 'drizzle-kit',\n tableName,\n columns: {\n identifier: 'hash',\n timestamp: 'created_at',\n timestampType: 'bigint',\n },\n };\n }\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, basename } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { Pool } from 'pg';\nimport type { Config } from '../types.js';\nimport type {\n MigratorConfig,\n MigrationFile,\n MigrateOptions,\n TenantMigrationResult,\n MigrationResults,\n TenantMigrationStatus,\n AppliedMigration,\n CreateTenantOptions,\n DropTenantOptions,\n TenantSyncStatus,\n SyncStatus,\n TenantSyncResult,\n SyncResults,\n SyncOptions,\n} from './types.js';\nimport { detectTableFormat, getFormatConfig, type DetectedFormat, type TableFormat } from './table-format.js';\n\nconst DEFAULT_MIGRATIONS_TABLE = '__drizzle_migrations';\n\n/**\n * Parallel migration engine for multi-tenant applications\n */\nexport class Migrator<\n TTenantSchema extends Record<string, unknown>,\n TSharedSchema extends Record<string, unknown>,\n> {\n private readonly migrationsTable: string;\n\n constructor(\n private readonly tenantConfig: Config<TTenantSchema, TSharedSchema>,\n private readonly migratorConfig: MigratorConfig\n ) {\n this.migrationsTable = migratorConfig.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE;\n }\n\n /**\n * Migrate all tenants in parallel\n */\n async migrateAll(options: MigrateOptions = {}): Promise<MigrationResults> {\n const {\n concurrency = 10,\n onProgress,\n onError,\n dryRun = false,\n } = options;\n\n const tenantIds = await this.migratorConfig.tenantDiscovery();\n const migrations = await this.loadMigrations();\n\n const results: TenantMigrationResult[] = [];\n let aborted = false;\n\n // Process tenants in batches\n for (let i = 0; i < tenantIds.length && !aborted; i += concurrency) {\n const batch = tenantIds.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(async (tenantId) => {\n if (aborted) {\n return this.createSkippedResult(tenantId);\n }\n\n try {\n onProgress?.(tenantId, 'starting');\n const result = await this.migrateTenant(tenantId, migrations, { dryRun, onProgress });\n onProgress?.(tenantId, result.success ? 'completed' : 'failed');\n return result;\n } catch (error) {\n onProgress?.(tenantId, 'failed');\n const action = onError?.(tenantId, error as Error);\n if (action === 'abort') {\n aborted = true;\n }\n return this.createErrorResult(tenantId, error as Error);\n }\n })\n );\n\n results.push(...batchResults);\n }\n\n // Mark remaining tenants as skipped if aborted\n if (aborted) {\n const remaining = tenantIds.slice(results.length);\n for (const tenantId of remaining) {\n results.push(this.createSkippedResult(tenantId));\n }\n }\n\n return this.aggregateResults(results);\n }\n\n /**\n * Migrate a single tenant\n */\n async migrateTenant(\n tenantId: string,\n migrations?: MigrationFile[],\n options: { dryRun?: boolean; onProgress?: MigrateOptions['onProgress'] } = {}\n ): Promise<TenantMigrationResult> {\n const startTime = Date.now();\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n const appliedMigrations: string[] = [];\n\n const pool = await this.createPool(schemaName);\n\n try {\n await this.migratorConfig.hooks?.beforeTenant?.(tenantId);\n\n // Detect or determine the format before creating table\n const format = await this.getOrDetectFormat(pool, schemaName);\n\n // Ensure migrations table exists with correct format\n await this.ensureMigrationsTable(pool, schemaName, format);\n\n // Load migrations if not provided\n const allMigrations = migrations ?? await this.loadMigrations();\n\n // Get applied migrations using format-aware query\n const applied = await this.getAppliedMigrations(pool, schemaName, format);\n const appliedSet = new Set(applied.map((m) => m.identifier));\n\n // Filter pending migrations using format-aware comparison\n const pending = allMigrations.filter(\n (m) => !this.isMigrationApplied(m, appliedSet, format)\n );\n\n if (options.dryRun) {\n return {\n tenantId,\n schemaName,\n success: true,\n appliedMigrations: pending.map((m) => m.name),\n durationMs: Date.now() - startTime,\n format: format.format,\n };\n }\n\n // Apply pending migrations\n for (const migration of pending) {\n const migrationStart = Date.now();\n options.onProgress?.(tenantId, 'migrating', migration.name);\n\n await this.migratorConfig.hooks?.beforeMigration?.(tenantId, migration.name);\n await this.applyMigration(pool, schemaName, migration, format);\n await this.migratorConfig.hooks?.afterMigration?.(\n tenantId,\n migration.name,\n Date.now() - migrationStart\n );\n\n appliedMigrations.push(migration.name);\n }\n\n const result: TenantMigrationResult = {\n tenantId,\n schemaName,\n success: true,\n appliedMigrations,\n durationMs: Date.now() - startTime,\n format: format.format,\n };\n\n await this.migratorConfig.hooks?.afterTenant?.(tenantId, result);\n\n return result;\n } catch (error) {\n const result: TenantMigrationResult = {\n tenantId,\n schemaName,\n success: false,\n appliedMigrations,\n error: (error as Error).message,\n durationMs: Date.now() - startTime,\n };\n\n await this.migratorConfig.hooks?.afterTenant?.(tenantId, result);\n\n return result;\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Migrate specific tenants\n */\n async migrateTenants(tenantIds: string[], options: MigrateOptions = {}): Promise<MigrationResults> {\n const migrations = await this.loadMigrations();\n const results: TenantMigrationResult[] = [];\n\n const { concurrency = 10, onProgress, onError } = options;\n\n for (let i = 0; i < tenantIds.length; i += concurrency) {\n const batch = tenantIds.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(async (tenantId) => {\n try {\n onProgress?.(tenantId, 'starting');\n const result = await this.migrateTenant(tenantId, migrations, { dryRun: options.dryRun ?? false, onProgress });\n onProgress?.(tenantId, result.success ? 'completed' : 'failed');\n return result;\n } catch (error) {\n onProgress?.(tenantId, 'failed');\n onError?.(tenantId, error as Error);\n return this.createErrorResult(tenantId, error as Error);\n }\n })\n );\n\n results.push(...batchResults);\n }\n\n return this.aggregateResults(results);\n }\n\n /**\n * Get migration status for all tenants\n */\n async getStatus(): Promise<TenantMigrationStatus[]> {\n const tenantIds = await this.migratorConfig.tenantDiscovery();\n const migrations = await this.loadMigrations();\n const statuses: TenantMigrationStatus[] = [];\n\n for (const tenantId of tenantIds) {\n statuses.push(await this.getTenantStatus(tenantId, migrations));\n }\n\n return statuses;\n }\n\n /**\n * Get migration status for a specific tenant\n */\n async getTenantStatus(tenantId: string, migrations?: MigrationFile[]): Promise<TenantMigrationStatus> {\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n const pool = await this.createPool(schemaName);\n\n try {\n const allMigrations = migrations ?? await this.loadMigrations();\n\n // Check if migrations table exists\n const tableExists = await this.migrationsTableExists(pool, schemaName);\n if (!tableExists) {\n return {\n tenantId,\n schemaName,\n appliedCount: 0,\n pendingCount: allMigrations.length,\n pendingMigrations: allMigrations.map((m) => m.name),\n status: allMigrations.length > 0 ? 'behind' : 'ok',\n format: null, // New tenant, no table yet\n };\n }\n\n // Detect the table format\n const format = await this.getOrDetectFormat(pool, schemaName);\n\n const applied = await this.getAppliedMigrations(pool, schemaName, format);\n const appliedSet = new Set(applied.map((m) => m.identifier));\n\n // Use format-aware comparison\n const pending = allMigrations.filter(\n (m) => !this.isMigrationApplied(m, appliedSet, format)\n );\n\n return {\n tenantId,\n schemaName,\n appliedCount: applied.length,\n pendingCount: pending.length,\n pendingMigrations: pending.map((m) => m.name),\n status: pending.length > 0 ? 'behind' : 'ok',\n format: format.format,\n };\n } catch (error) {\n return {\n tenantId,\n schemaName,\n appliedCount: 0,\n pendingCount: 0,\n pendingMigrations: [],\n status: 'error',\n error: (error as Error).message,\n format: null,\n };\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Create a new tenant schema and optionally apply migrations\n */\n async createTenant(tenantId: string, options: CreateTenantOptions = {}): Promise<void> {\n const { migrate = true } = options;\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n\n const pool = new Pool({\n connectionString: this.tenantConfig.connection.url,\n ...this.tenantConfig.connection.poolConfig,\n });\n\n try {\n // Create schema\n await pool.query(`CREATE SCHEMA IF NOT EXISTS \"${schemaName}\"`);\n\n if (migrate) {\n // Apply all migrations\n await this.migrateTenant(tenantId);\n }\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Drop a tenant schema\n */\n async dropTenant(tenantId: string, options: DropTenantOptions = {}): Promise<void> {\n const { cascade = true } = options;\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n\n const pool = new Pool({\n connectionString: this.tenantConfig.connection.url,\n ...this.tenantConfig.connection.poolConfig,\n });\n\n try {\n const cascadeSql = cascade ? 'CASCADE' : 'RESTRICT';\n await pool.query(`DROP SCHEMA IF EXISTS \"${schemaName}\" ${cascadeSql}`);\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Check if a tenant schema exists\n */\n async tenantExists(tenantId: string): Promise<boolean> {\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n\n const pool = new Pool({\n connectionString: this.tenantConfig.connection.url,\n ...this.tenantConfig.connection.poolConfig,\n });\n\n try {\n const result = await pool.query(\n `SELECT 1 FROM information_schema.schemata WHERE schema_name = $1`,\n [schemaName]\n );\n return result.rowCount !== null && result.rowCount > 0;\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Mark migrations as applied without executing SQL\n * Useful for syncing tracking state with already-applied migrations\n */\n async markAsApplied(\n tenantId: string,\n options: { onProgress?: MigrateOptions['onProgress'] } = {}\n ): Promise<TenantMigrationResult> {\n const startTime = Date.now();\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n const markedMigrations: string[] = [];\n\n const pool = await this.createPool(schemaName);\n\n try {\n await this.migratorConfig.hooks?.beforeTenant?.(tenantId);\n\n // Detect or determine the format before creating table\n const format = await this.getOrDetectFormat(pool, schemaName);\n\n // Ensure migrations table exists with correct format\n await this.ensureMigrationsTable(pool, schemaName, format);\n\n // Load all migrations\n const allMigrations = await this.loadMigrations();\n\n // Get applied migrations\n const applied = await this.getAppliedMigrations(pool, schemaName, format);\n const appliedSet = new Set(applied.map((m) => m.identifier));\n\n // Filter pending migrations\n const pending = allMigrations.filter(\n (m) => !this.isMigrationApplied(m, appliedSet, format)\n );\n\n // Mark each pending migration as applied (without executing SQL)\n for (const migration of pending) {\n const migrationStart = Date.now();\n options.onProgress?.(tenantId, 'migrating', migration.name);\n\n await this.migratorConfig.hooks?.beforeMigration?.(tenantId, migration.name);\n await this.recordMigration(pool, schemaName, migration, format);\n await this.migratorConfig.hooks?.afterMigration?.(\n tenantId,\n migration.name,\n Date.now() - migrationStart\n );\n\n markedMigrations.push(migration.name);\n }\n\n const result: TenantMigrationResult = {\n tenantId,\n schemaName,\n success: true,\n appliedMigrations: markedMigrations,\n durationMs: Date.now() - startTime,\n format: format.format,\n };\n\n await this.migratorConfig.hooks?.afterTenant?.(tenantId, result);\n\n return result;\n } catch (error) {\n const result: TenantMigrationResult = {\n tenantId,\n schemaName,\n success: false,\n appliedMigrations: markedMigrations,\n error: (error as Error).message,\n durationMs: Date.now() - startTime,\n };\n\n await this.migratorConfig.hooks?.afterTenant?.(tenantId, result);\n\n return result;\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Mark migrations as applied for all tenants without executing SQL\n * Useful for syncing tracking state with already-applied migrations\n */\n async markAllAsApplied(options: MigrateOptions = {}): Promise<MigrationResults> {\n const {\n concurrency = 10,\n onProgress,\n onError,\n } = options;\n\n const tenantIds = await this.migratorConfig.tenantDiscovery();\n const results: TenantMigrationResult[] = [];\n let aborted = false;\n\n // Process tenants in batches\n for (let i = 0; i < tenantIds.length && !aborted; i += concurrency) {\n const batch = tenantIds.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(async (tenantId) => {\n if (aborted) {\n return this.createSkippedResult(tenantId);\n }\n\n try {\n onProgress?.(tenantId, 'starting');\n const result = await this.markAsApplied(tenantId, { onProgress });\n onProgress?.(tenantId, result.success ? 'completed' : 'failed');\n return result;\n } catch (error) {\n onProgress?.(tenantId, 'failed');\n const action = onError?.(tenantId, error as Error);\n if (action === 'abort') {\n aborted = true;\n }\n return this.createErrorResult(tenantId, error as Error);\n }\n })\n );\n\n results.push(...batchResults);\n }\n\n // Mark remaining tenants as skipped if aborted\n if (aborted) {\n const remaining = tenantIds.slice(results.length);\n for (const tenantId of remaining) {\n results.push(this.createSkippedResult(tenantId));\n }\n }\n\n return this.aggregateResults(results);\n }\n\n /**\n * Get sync status for all tenants\n * Detects divergences between migrations on disk and tracking in database\n */\n async getSyncStatus(): Promise<SyncStatus> {\n const tenantIds = await this.migratorConfig.tenantDiscovery();\n const migrations = await this.loadMigrations();\n const statuses: TenantSyncStatus[] = [];\n\n for (const tenantId of tenantIds) {\n statuses.push(await this.getTenantSyncStatus(tenantId, migrations));\n }\n\n return {\n total: statuses.length,\n inSync: statuses.filter((s) => s.inSync && !s.error).length,\n outOfSync: statuses.filter((s) => !s.inSync && !s.error).length,\n error: statuses.filter((s) => !!s.error).length,\n details: statuses,\n };\n }\n\n /**\n * Get sync status for a specific tenant\n */\n async getTenantSyncStatus(tenantId: string, migrations?: MigrationFile[]): Promise<TenantSyncStatus> {\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n const pool = await this.createPool(schemaName);\n\n try {\n const allMigrations = migrations ?? await this.loadMigrations();\n const migrationNames = new Set(allMigrations.map((m) => m.name));\n const migrationHashes = new Set(allMigrations.map((m) => m.hash));\n\n // Check if migrations table exists\n const tableExists = await this.migrationsTableExists(pool, schemaName);\n if (!tableExists) {\n return {\n tenantId,\n schemaName,\n missing: allMigrations.map((m) => m.name),\n orphans: [],\n inSync: allMigrations.length === 0,\n format: null,\n };\n }\n\n // Detect the table format\n const format = await this.getOrDetectFormat(pool, schemaName);\n const applied = await this.getAppliedMigrations(pool, schemaName, format);\n\n // Find missing migrations (in disk but not in database)\n const appliedIdentifiers = new Set(applied.map((m) => m.identifier));\n const missing = allMigrations\n .filter((m) => !this.isMigrationApplied(m, appliedIdentifiers, format))\n .map((m) => m.name);\n\n // Find orphan records (in database but not in disk)\n const orphans = applied\n .filter((m) => {\n if (format.columns.identifier === 'name') {\n return !migrationNames.has(m.identifier);\n }\n // For hash-based formats, check both hash and name\n return !migrationHashes.has(m.identifier) && !migrationNames.has(m.identifier);\n })\n .map((m) => m.identifier);\n\n return {\n tenantId,\n schemaName,\n missing,\n orphans,\n inSync: missing.length === 0 && orphans.length === 0,\n format: format.format,\n };\n } catch (error) {\n return {\n tenantId,\n schemaName,\n missing: [],\n orphans: [],\n inSync: false,\n format: null,\n error: (error as Error).message,\n };\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Mark missing migrations as applied for a tenant\n */\n async markMissing(tenantId: string): Promise<TenantSyncResult> {\n const startTime = Date.now();\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n const markedMigrations: string[] = [];\n\n const pool = await this.createPool(schemaName);\n\n try {\n const syncStatus = await this.getTenantSyncStatus(tenantId);\n\n if (syncStatus.error) {\n return {\n tenantId,\n schemaName,\n success: false,\n markedMigrations: [],\n removedOrphans: [],\n error: syncStatus.error,\n durationMs: Date.now() - startTime,\n };\n }\n\n if (syncStatus.missing.length === 0) {\n return {\n tenantId,\n schemaName,\n success: true,\n markedMigrations: [],\n removedOrphans: [],\n durationMs: Date.now() - startTime,\n };\n }\n\n const format = await this.getOrDetectFormat(pool, schemaName);\n await this.ensureMigrationsTable(pool, schemaName, format);\n\n const allMigrations = await this.loadMigrations();\n const missingSet = new Set(syncStatus.missing);\n\n for (const migration of allMigrations) {\n if (missingSet.has(migration.name)) {\n await this.recordMigration(pool, schemaName, migration, format);\n markedMigrations.push(migration.name);\n }\n }\n\n return {\n tenantId,\n schemaName,\n success: true,\n markedMigrations,\n removedOrphans: [],\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n tenantId,\n schemaName,\n success: false,\n markedMigrations,\n removedOrphans: [],\n error: (error as Error).message,\n durationMs: Date.now() - startTime,\n };\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Mark missing migrations as applied for all tenants\n */\n async markAllMissing(options: SyncOptions = {}): Promise<SyncResults> {\n const { concurrency = 10, onProgress, onError } = options;\n\n const tenantIds = await this.migratorConfig.tenantDiscovery();\n const results: TenantSyncResult[] = [];\n let aborted = false;\n\n for (let i = 0; i < tenantIds.length && !aborted; i += concurrency) {\n const batch = tenantIds.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(async (tenantId) => {\n if (aborted) {\n return this.createSkippedSyncResult(tenantId);\n }\n\n try {\n onProgress?.(tenantId, 'starting');\n const result = await this.markMissing(tenantId);\n onProgress?.(tenantId, result.success ? 'completed' : 'failed');\n return result;\n } catch (error) {\n onProgress?.(tenantId, 'failed');\n const action = onError?.(tenantId, error as Error);\n if (action === 'abort') {\n aborted = true;\n }\n return this.createErrorSyncResult(tenantId, error as Error);\n }\n })\n );\n\n results.push(...batchResults);\n }\n\n return this.aggregateSyncResults(results);\n }\n\n /**\n * Remove orphan migration records for a tenant\n */\n async cleanOrphans(tenantId: string): Promise<TenantSyncResult> {\n const startTime = Date.now();\n const schemaName = this.tenantConfig.isolation.schemaNameTemplate(tenantId);\n const removedOrphans: string[] = [];\n\n const pool = await this.createPool(schemaName);\n\n try {\n const syncStatus = await this.getTenantSyncStatus(tenantId);\n\n if (syncStatus.error) {\n return {\n tenantId,\n schemaName,\n success: false,\n markedMigrations: [],\n removedOrphans: [],\n error: syncStatus.error,\n durationMs: Date.now() - startTime,\n };\n }\n\n if (syncStatus.orphans.length === 0) {\n return {\n tenantId,\n schemaName,\n success: true,\n markedMigrations: [],\n removedOrphans: [],\n durationMs: Date.now() - startTime,\n };\n }\n\n const format = await this.getOrDetectFormat(pool, schemaName);\n const identifierColumn = format.columns.identifier;\n\n for (const orphan of syncStatus.orphans) {\n await pool.query(\n `DELETE FROM \"${schemaName}\".\"${format.tableName}\" WHERE \"${identifierColumn}\" = $1`,\n [orphan]\n );\n removedOrphans.push(orphan);\n }\n\n return {\n tenantId,\n schemaName,\n success: true,\n markedMigrations: [],\n removedOrphans,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n tenantId,\n schemaName,\n success: false,\n markedMigrations: [],\n removedOrphans,\n error: (error as Error).message,\n durationMs: Date.now() - startTime,\n };\n } finally {\n await pool.end();\n }\n }\n\n /**\n * Remove orphan migration records for all tenants\n */\n async cleanAllOrphans(options: SyncOptions = {}): Promise<SyncResults> {\n const { concurrency = 10, onProgress, onError } = options;\n\n const tenantIds = await this.migratorConfig.tenantDiscovery();\n const results: TenantSyncResult[] = [];\n let aborted = false;\n\n for (let i = 0; i < tenantIds.length && !aborted; i += concurrency) {\n const batch = tenantIds.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(async (tenantId) => {\n if (aborted) {\n return this.createSkippedSyncResult(tenantId);\n }\n\n try {\n onProgress?.(tenantId, 'starting');\n const result = await this.cleanOrphans(tenantId);\n onProgress?.(tenantId, result.success ? 'completed' : 'failed');\n return result;\n } catch (error) {\n onProgress?.(tenantId, 'failed');\n const action = onError?.(tenantId, error as Error);\n if (action === 'abort') {\n aborted = true;\n }\n return this.createErrorSyncResult(tenantId, error as Error);\n }\n })\n );\n\n results.push(...batchResults);\n }\n\n return this.aggregateSyncResults(results);\n }\n\n /**\n * Load migration files from the migrations folder\n */\n private async loadMigrations(): Promise<MigrationFile[]> {\n const files = await readdir(this.migratorConfig.migrationsFolder);\n\n const migrations: MigrationFile[] = [];\n\n for (const file of files) {\n if (!file.endsWith('.sql')) continue;\n\n const filePath = join(this.migratorConfig.migrationsFolder, file);\n const content = await readFile(filePath, 'utf-8');\n\n // Extract timestamp from filename (e.g., 0001_migration_name.sql)\n const match = file.match(/^(\\d+)_/);\n const timestamp = match?.[1] ? parseInt(match[1], 10) : 0;\n\n // Compute SHA-256 hash for drizzle-kit compatibility\n const hash = createHash('sha256').update(content).digest('hex');\n\n migrations.push({\n name: basename(file, '.sql'),\n path: filePath,\n sql: content,\n timestamp,\n hash,\n });\n }\n\n // Sort by timestamp\n return migrations.sort((a, b) => a.timestamp - b.timestamp);\n }\n\n /**\n * Create a pool for a specific schema\n */\n private async createPool(schemaName: string): Promise<Pool> {\n return new Pool({\n connectionString: this.tenantConfig.connection.url,\n ...this.tenantConfig.connection.poolConfig,\n options: `-c search_path=\"${schemaName}\",public`,\n });\n }\n\n /**\n * Ensure migrations table exists with the correct format\n */\n private async ensureMigrationsTable(\n pool: Pool,\n schemaName: string,\n format: DetectedFormat\n ): Promise<void> {\n const { identifier, timestamp, timestampType } = format.columns;\n\n // Build column definitions based on format\n const identifierCol = identifier === 'name'\n ? 'name VARCHAR(255) NOT NULL UNIQUE'\n : 'hash TEXT NOT NULL';\n\n const timestampCol = timestampType === 'bigint'\n ? `${timestamp} BIGINT NOT NULL`\n : `${timestamp} TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP`;\n\n await pool.query(`\n CREATE TABLE IF NOT EXISTS \"${schemaName}\".\"${format.tableName}\" (\n id SERIAL PRIMARY KEY,\n ${identifierCol},\n ${timestampCol}\n )\n `);\n }\n\n /**\n * Check if migrations table exists\n */\n private async migrationsTableExists(pool: Pool, schemaName: string): Promise<boolean> {\n const result = await pool.query(\n `SELECT 1 FROM information_schema.tables\n WHERE table_schema = $1 AND table_name = $2`,\n [schemaName, this.migrationsTable]\n );\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Get applied migrations for a schema\n */\n private async getAppliedMigrations(\n pool: Pool,\n schemaName: string,\n format: DetectedFormat\n ): Promise<AppliedMigration[]> {\n const identifierColumn = format.columns.identifier;\n const timestampColumn = format.columns.timestamp;\n\n const result = await pool.query<{ id: number; identifier: string; applied_at: string | number }>(\n `SELECT id, \"${identifierColumn}\" as identifier, \"${timestampColumn}\" as applied_at\n FROM \"${schemaName}\".\"${format.tableName}\"\n ORDER BY id`\n );\n\n return result.rows.map((row) => {\n // Convert timestamp based on format\n const appliedAt = format.columns.timestampType === 'bigint'\n ? new Date(Number(row.applied_at))\n : new Date(row.applied_at);\n\n return {\n id: row.id,\n identifier: row.identifier,\n // Set name or hash based on format\n ...(format.columns.identifier === 'name'\n ? { name: row.identifier }\n : { hash: row.identifier }),\n appliedAt,\n };\n });\n }\n\n /**\n * Check if a migration has been applied\n */\n private isMigrationApplied(\n migration: MigrationFile,\n appliedIdentifiers: Set<string>,\n format: DetectedFormat\n ): boolean {\n if (format.columns.identifier === 'name') {\n return appliedIdentifiers.has(migration.name);\n }\n\n // Hash-based: check both hash AND name for backwards compatibility\n // This allows migration from name-based to hash-based tracking\n return appliedIdentifiers.has(migration.hash) || appliedIdentifiers.has(migration.name);\n }\n\n /**\n * Get or detect the format for a schema\n * Returns the configured format or auto-detects from existing table\n */\n private async getOrDetectFormat(\n pool: Pool,\n schemaName: string\n ): Promise<DetectedFormat> {\n const configuredFormat = this.migratorConfig.tableFormat ?? 'auto';\n\n // If not auto, return the configured format\n if (configuredFormat !== 'auto') {\n return getFormatConfig(configuredFormat, this.migrationsTable);\n }\n\n // Auto-detect from existing table\n const detected = await detectTableFormat(pool, schemaName, this.migrationsTable);\n\n if (detected) {\n return detected;\n }\n\n // No table exists, use default format\n const defaultFormat: TableFormat = this.migratorConfig.defaultFormat ?? 'name';\n return getFormatConfig(defaultFormat, this.migrationsTable);\n }\n\n /**\n * Apply a migration to a schema\n */\n private async applyMigration(\n pool: Pool,\n schemaName: string,\n migration: MigrationFile,\n format: DetectedFormat\n ): Promise<void> {\n const client = await pool.connect();\n\n try {\n await client.query('BEGIN');\n\n // Execute migration SQL\n await client.query(migration.sql);\n\n // Record migration using format-aware insert\n const { identifier, timestamp, timestampType } = format.columns;\n const identifierValue = identifier === 'name' ? migration.name : migration.hash;\n const timestampValue = timestampType === 'bigint' ? Date.now() : new Date();\n\n await client.query(\n `INSERT INTO \"${schemaName}\".\"${format.tableName}\" (\"${identifier}\", \"${timestamp}\") VALUES ($1, $2)`,\n [identifierValue, timestampValue]\n );\n\n await client.query('COMMIT');\n } catch (error) {\n await client.query('ROLLBACK');\n throw error;\n } finally {\n client.release();\n }\n }\n\n /**\n * Record a migration as applied without executing SQL\n * Used by markAsApplied to sync tracking state\n */\n private async recordMigration(\n pool: Pool,\n schemaName: string,\n migration: MigrationFile,\n format: DetectedFormat\n ): Promise<void> {\n const { identifier, timestamp, timestampType } = format.columns;\n const identifierValue = identifier === 'name' ? migration.name : migration.hash;\n const timestampValue = timestampType === 'bigint' ? Date.now() : new Date();\n\n await pool.query(\n `INSERT INTO \"${schemaName}\".\"${format.tableName}\" (\"${identifier}\", \"${timestamp}\") VALUES ($1, $2)`,\n [identifierValue, timestampValue]\n );\n }\n\n /**\n * Create a skipped result\n */\n private createSkippedResult(tenantId: string): TenantMigrationResult {\n return {\n tenantId,\n schemaName: this.tenantConfig.isolation.schemaNameTemplate(tenantId),\n success: false,\n appliedMigrations: [],\n error: 'Skipped due to abort',\n durationMs: 0,\n };\n }\n\n /**\n * Create an error result\n */\n private createErrorResult(tenantId: string, error: Error): TenantMigrationResult {\n return {\n tenantId,\n schemaName: this.tenantConfig.isolation.schemaNameTemplate(tenantId),\n success: false,\n appliedMigrations: [],\n error: error.message,\n durationMs: 0,\n };\n }\n\n /**\n * Aggregate migration results\n */\n private aggregateResults(results: TenantMigrationResult[]): MigrationResults {\n return {\n total: results.length,\n succeeded: results.filter((r) => r.success).length,\n failed: results.filter((r) => !r.success && r.error !== 'Skipped due to abort').length,\n skipped: results.filter((r) => r.error === 'Skipped due to abort').length,\n details: results,\n };\n }\n\n /**\n * Create a skipped sync result\n */\n private createSkippedSyncResult(tenantId: string): TenantSyncResult {\n return {\n tenantId,\n schemaName: this.tenantConfig.isolation.schemaNameTemplate(tenantId),\n success: false,\n markedMigrations: [],\n removedOrphans: [],\n error: 'Skipped due to abort',\n durationMs: 0,\n };\n }\n\n /**\n * Create an error sync result\n */\n private createErrorSyncResult(tenantId: string, error: Error): TenantSyncResult {\n return {\n tenantId,\n schemaName: this.tenantConfig.isolation.schemaNameTemplate(tenantId),\n success: false,\n markedMigrations: [],\n removedOrphans: [],\n error: error.message,\n durationMs: 0,\n };\n }\n\n /**\n * Aggregate sync results\n */\n private aggregateSyncResults(results: TenantSyncResult[]): SyncResults {\n return {\n total: results.length,\n succeeded: results.filter((r) => r.success).length,\n failed: results.filter((r) => !r.success).length,\n details: results,\n };\n }\n}\n\n/**\n * Create a migrator instance\n */\nexport function createMigrator<\n TTenantSchema extends Record<string, unknown>,\n TSharedSchema extends Record<string, unknown>,\n>(\n tenantConfig: Config<TTenantSchema, TSharedSchema>,\n migratorConfig: MigratorConfig\n): Migrator<TTenantSchema, TSharedSchema> {\n return new Migrator(tenantConfig, migratorConfig);\n}\n"]}