@kysera/migrations 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -225,7 +225,7 @@ interface MigrationResult {
225
225
  ```typescript
226
226
  interface MigrationRunnerOptions {
227
227
  dryRun?: boolean // Preview only (default: false)
228
- logger?: (msg: string) => void // Custom logger
228
+ logger?: KyseraLogger // Logger instance from @kysera/core (default: silentLogger)
229
229
  useTransactions?: boolean // Wrap in transactions (default: false)
230
230
  stopOnError?: boolean // Stop on first error (default: true)
231
231
  verbose?: boolean // Show metadata (default: true)
package/dist/index.d.ts CHANGED
@@ -6,19 +6,23 @@ import 'zod';
6
6
 
7
7
  /**
8
8
  * Migration interface - the core building block
9
+ * Generic DB type allows type-safe migrations when schema is known,
10
+ * defaults to unknown for maximum flexibility
9
11
  */
10
- interface Migration {
12
+ interface Migration<DB = unknown> {
11
13
  /** Unique migration name (e.g., '001_create_users') */
12
14
  name: string;
13
15
  /** Migration up function - creates/modifies schema */
14
- up: (db: Kysely<any>) => Promise<void>;
16
+ up: (db: Kysely<DB>) => Promise<void>;
15
17
  /** Optional migration down function - reverts changes */
16
- down?: (db: Kysely<any>) => Promise<void>;
18
+ down?: (db: Kysely<DB>) => Promise<void>;
17
19
  }
18
20
  /**
19
21
  * Migration with metadata for enhanced logging and tracking
22
+ * Generic DB type allows type-safe migrations when schema is known,
23
+ * defaults to unknown for maximum flexibility
20
24
  */
21
- interface MigrationWithMeta extends Migration {
25
+ interface MigrationWithMeta<DB = unknown> extends Migration<DB> {
22
26
  /** Human-readable description shown during migration */
23
27
  description?: string;
24
28
  /** Whether this is a breaking change - shows warning before execution */
@@ -61,10 +65,12 @@ interface MigrationRunnerOptions {
61
65
  }
62
66
  /**
63
67
  * Object-based migration definition for Level 2 DX
68
+ * Generic DB type allows type-safe migrations when schema is known,
69
+ * defaults to unknown for maximum flexibility
64
70
  */
65
- interface MigrationDefinition {
66
- up: (db: Kysely<any>) => Promise<void>;
67
- down?: (db: Kysely<any>) => Promise<void>;
71
+ interface MigrationDefinition<DB = unknown> {
72
+ up: (db: Kysely<DB>) => Promise<void>;
73
+ down?: (db: Kysely<DB>) => Promise<void>;
68
74
  description?: string;
69
75
  breaking?: boolean;
70
76
  estimatedDuration?: number;
@@ -72,8 +78,10 @@ interface MigrationDefinition {
72
78
  }
73
79
  /**
74
80
  * Migration definitions map for defineMigrations()
81
+ * Generic DB type allows type-safe migrations when schema is known,
82
+ * defaults to unknown for maximum flexibility
75
83
  */
76
- type MigrationDefinitions = Record<string, MigrationDefinition>;
84
+ type MigrationDefinitions<DB = unknown> = Record<string, MigrationDefinition<DB>>;
77
85
  /**
78
86
  * Result of a migration run
79
87
  */
@@ -104,27 +112,33 @@ declare class MigrationError extends DatabaseError {
104
112
  /**
105
113
  * Setup migrations table in database
106
114
  * Idempotent - safe to run multiple times
115
+ * Uses Kysely<unknown> as migrations work with any database schema
107
116
  */
108
- declare function setupMigrations(db: Kysely<any>): Promise<void>;
117
+ declare function setupMigrations(db: Kysely<unknown>): Promise<void>;
109
118
  /**
110
119
  * Migration runner with state tracking and metadata support
120
+ * Generic DB type allows type-safe migrations when schema is known,
121
+ * defaults to unknown for maximum flexibility
111
122
  */
112
- declare class MigrationRunner {
123
+ declare class MigrationRunner<DB = unknown> {
113
124
  private db;
114
125
  private migrations;
115
126
  private logger;
116
127
  private options;
117
- constructor(db: Kysely<any>, migrations: Migration[], options?: MigrationRunnerOptions);
128
+ constructor(db: Kysely<DB>, migrations: Migration<DB>[], options?: MigrationRunnerOptions);
118
129
  /**
119
130
  * Get list of executed migrations from database
131
+ * Note: Uses type assertions for migrations table as it's not part of the user schema
120
132
  */
121
133
  getExecutedMigrations(): Promise<string[]>;
122
134
  /**
123
135
  * Mark a migration as executed
136
+ * Note: Uses type assertions for migrations table as it's not part of the user schema
124
137
  */
125
138
  markAsExecuted(name: string): Promise<void>;
126
139
  /**
127
140
  * Mark a migration as rolled back (remove from executed list)
141
+ * Note: Uses type assertions for migrations table as it's not part of the user schema
128
142
  */
129
143
  markAsRolledBack(name: string): Promise<void>;
130
144
  /**
@@ -160,103 +174,127 @@ declare class MigrationRunner {
160
174
  /**
161
175
  * Create a migration runner instance
162
176
  * Options are validated using Zod schema
177
+ * Generic DB type allows type-safe migrations when schema is known,
178
+ * defaults to unknown for maximum flexibility
163
179
  */
164
- declare function createMigrationRunner(db: Kysely<any>, migrations: Migration[], options?: MigrationRunnerOptions): MigrationRunner;
180
+ declare function createMigrationRunner<DB = unknown>(db: Kysely<DB>, migrations: Migration<DB>[], options?: MigrationRunnerOptions): MigrationRunner<DB>;
165
181
  /**
166
182
  * Helper to create a simple migration
183
+ * Generic DB type allows type-safe migrations when schema is known,
184
+ * defaults to unknown for maximum flexibility
167
185
  */
168
- declare function createMigration(name: string, up: (db: Kysely<any>) => Promise<void>, down?: (db: Kysely<any>) => Promise<void>): Migration;
186
+ declare function createMigration<DB = unknown>(name: string, up: (db: Kysely<DB>) => Promise<void>, down?: (db: Kysely<DB>) => Promise<void>): Migration<DB>;
169
187
  /**
170
188
  * Helper to create a migration with metadata
189
+ * Generic DB type allows type-safe migrations when schema is known,
190
+ * defaults to unknown for maximum flexibility
171
191
  */
172
- declare function createMigrationWithMeta(name: string, options: {
173
- up: (db: Kysely<any>) => Promise<void>;
174
- down?: (db: Kysely<any>) => Promise<void>;
192
+ declare function createMigrationWithMeta<DB = unknown>(name: string, options: {
193
+ up: (db: Kysely<DB>) => Promise<void>;
194
+ down?: (db: Kysely<DB>) => Promise<void>;
175
195
  description?: string;
176
196
  breaking?: boolean;
177
197
  estimatedDuration?: number;
178
198
  tags?: string[];
179
- }): MigrationWithMeta;
199
+ }): MigrationWithMeta<DB>;
180
200
  /**
181
201
  * Define migrations using an object-based syntax for cleaner code
202
+ * Generic DB type allows type-safe migrations when schema is known,
203
+ * defaults to unknown for maximum flexibility
182
204
  */
183
- declare function defineMigrations(definitions: MigrationDefinitions): MigrationWithMeta[];
205
+ declare function defineMigrations<DB = unknown>(definitions: MigrationDefinitions<DB>): MigrationWithMeta<DB>[];
184
206
  /**
185
207
  * Run all pending migrations - one-liner convenience function
208
+ * Generic DB type allows type-safe migrations when schema is known,
209
+ * defaults to unknown for maximum flexibility
186
210
  */
187
- declare function runMigrations(db: Kysely<any>, migrations: Migration[], options?: MigrationRunnerOptions): Promise<MigrationResult>;
211
+ declare function runMigrations<DB = unknown>(db: Kysely<DB>, migrations: Migration<DB>[], options?: MigrationRunnerOptions): Promise<MigrationResult>;
188
212
  /**
189
213
  * Rollback migrations - one-liner convenience function
214
+ * Generic DB type allows type-safe migrations when schema is known,
215
+ * defaults to unknown for maximum flexibility
190
216
  */
191
- declare function rollbackMigrations(db: Kysely<any>, migrations: Migration[], steps?: number, options?: MigrationRunnerOptions): Promise<MigrationResult>;
217
+ declare function rollbackMigrations<DB = unknown>(db: Kysely<DB>, migrations: Migration<DB>[], steps?: number, options?: MigrationRunnerOptions): Promise<MigrationResult>;
192
218
  /**
193
219
  * Get migration status - one-liner convenience function
220
+ * Generic DB type allows type-safe migrations when schema is known,
221
+ * defaults to unknown for maximum flexibility
194
222
  */
195
- declare function getMigrationStatus(db: Kysely<any>, migrations: Migration[], options?: Pick<MigrationRunnerOptions, 'logger' | 'verbose'>): Promise<MigrationStatus>;
223
+ declare function getMigrationStatus<DB = unknown>(db: Kysely<DB>, migrations: Migration<DB>[], options?: Pick<MigrationRunnerOptions, 'logger' | 'verbose'>): Promise<MigrationStatus>;
196
224
  /**
197
225
  * Migration plugin interface - consistent with @kysera/repository Plugin
198
226
  * Provides lifecycle hooks for migration execution
227
+ * Generic DB type allows type-safe plugins when schema is known,
228
+ * defaults to unknown for maximum flexibility
199
229
  */
200
- interface MigrationPlugin {
230
+ interface MigrationPlugin<DB = unknown> {
201
231
  /** Plugin name */
202
232
  name: string;
203
233
  /** Plugin version */
204
234
  version: string;
205
235
  /** Called once when the runner is initialized (consistent with repository Plugin.onInit) */
206
- onInit?(runner: MigrationRunner): Promise<void> | void;
236
+ onInit?(runner: MigrationRunner<DB>): Promise<void> | void;
207
237
  /** Called before migration execution */
208
- beforeMigration?(migration: Migration, operation: 'up' | 'down'): Promise<void> | void;
238
+ beforeMigration?(migration: Migration<DB>, operation: 'up' | 'down'): Promise<void> | void;
209
239
  /** Called after successful migration execution */
210
- afterMigration?(migration: Migration, operation: 'up' | 'down', duration: number): Promise<void> | void;
240
+ afterMigration?(migration: Migration<DB>, operation: 'up' | 'down', duration: number): Promise<void> | void;
211
241
  /** Called on migration error (unknown type for consistency with repository Plugin.onError) */
212
- onMigrationError?(migration: Migration, operation: 'up' | 'down', error: unknown): Promise<void> | void;
242
+ onMigrationError?(migration: Migration<DB>, operation: 'up' | 'down', error: unknown): Promise<void> | void;
213
243
  }
214
244
  /**
215
245
  * Extended migration runner options with plugin support
246
+ * Generic DB type allows type-safe plugins when schema is known,
247
+ * defaults to unknown for maximum flexibility
216
248
  */
217
- interface MigrationRunnerWithPluginsOptions extends MigrationRunnerOptions {
249
+ interface MigrationRunnerWithPluginsOptions<DB = unknown> extends MigrationRunnerOptions {
218
250
  /** Plugins to apply */
219
- plugins?: MigrationPlugin[];
251
+ plugins?: MigrationPlugin<DB>[];
220
252
  }
221
253
  /**
222
254
  * Create a migration runner with plugin support
223
255
  * Async factory to properly initialize plugins (consistent with @kysera/repository createORM)
256
+ * Generic DB type allows type-safe migrations when schema is known,
257
+ * defaults to unknown for maximum flexibility
224
258
  */
225
- declare function createMigrationRunnerWithPlugins(db: Kysely<any>, migrations: Migration[], options?: MigrationRunnerWithPluginsOptions): Promise<MigrationRunnerWithPlugins>;
259
+ declare function createMigrationRunnerWithPlugins<DB = unknown>(db: Kysely<DB>, migrations: Migration<DB>[], options?: MigrationRunnerWithPluginsOptions<DB>): Promise<MigrationRunnerWithPlugins<DB>>;
226
260
  /**
227
261
  * Extended migration runner with plugin support
262
+ * Generic DB type allows type-safe migrations when schema is known,
263
+ * defaults to unknown for maximum flexibility
228
264
  */
229
- declare class MigrationRunnerWithPlugins extends MigrationRunner {
265
+ declare class MigrationRunnerWithPlugins<DB = unknown> extends MigrationRunner<DB> {
230
266
  private plugins;
231
- constructor(db: Kysely<any>, migrations: Migration[], options?: MigrationRunnerWithPluginsOptions);
267
+ constructor(db: Kysely<DB>, migrations: Migration<DB>[], options?: MigrationRunnerWithPluginsOptions<DB>);
232
268
  /**
233
269
  * Execute plugin hooks before migration
234
270
  * Can be called by consumers extending this class
235
271
  */
236
- protected runBeforeHooks(migration: Migration, operation: 'up' | 'down'): Promise<void>;
272
+ protected runBeforeHooks(migration: Migration<DB>, operation: 'up' | 'down'): Promise<void>;
237
273
  /**
238
274
  * Execute plugin hooks after migration
239
275
  * Can be called by consumers extending this class
240
276
  */
241
- protected runAfterHooks(migration: Migration, operation: 'up' | 'down', duration: number): Promise<void>;
277
+ protected runAfterHooks(migration: Migration<DB>, operation: 'up' | 'down', duration: number): Promise<void>;
242
278
  /**
243
279
  * Execute plugin hooks on error
244
280
  * Can be called by consumers extending this class
245
281
  */
246
- protected runErrorHooks(migration: Migration, operation: 'up' | 'down', error: unknown): Promise<void>;
282
+ protected runErrorHooks(migration: Migration<DB>, operation: 'up' | 'down', error: unknown): Promise<void>;
247
283
  /**
248
284
  * Get the list of registered plugins
249
285
  */
250
- getPlugins(): MigrationPlugin[];
286
+ getPlugins(): MigrationPlugin<DB>[];
251
287
  }
252
288
  /**
253
289
  * Logging plugin - logs migration events with timing
290
+ * Works with any DB type (generic plugin)
254
291
  */
255
- declare function createLoggingPlugin(logger?: KyseraLogger): MigrationPlugin;
292
+ declare function createLoggingPlugin<DB = unknown>(logger?: KyseraLogger): MigrationPlugin<DB>;
256
293
  /**
257
294
  * Metrics plugin - collects migration metrics
295
+ * Works with any DB type (generic plugin)
258
296
  */
259
- declare function createMetricsPlugin(): MigrationPlugin & {
297
+ declare function createMetricsPlugin<DB = unknown>(): MigrationPlugin<DB> & {
260
298
  getMetrics(): {
261
299
  migrations: Array<{
262
300
  name: string;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import {sql}from'kysely';import {silentLogger,DatabaseError,BadRequestError,NotFoundError}from'@kysera/core';export{BadRequestError,DatabaseError,NotFoundError,silentLogger}from'@kysera/core';import {z}from'zod';var d=z.object({dryRun:z.boolean().default(false),logger:z.any().optional(),useTransactions:z.boolean().default(false),stopOnError:z.boolean().default(true),verbose:z.boolean().default(true)}),m=z.object({name:z.string().min(1,"Migration name is required"),description:z.string().optional(),breaking:z.boolean().default(false),tags:z.array(z.string()).default([]),estimatedDuration:z.string().optional()}),b=z.object({logger:z.any().optional()}),w=z.object({name:z.string().min(1,"Plugin name is required"),version:z.string().min(1,"Plugin version is required"),onInit:z.any().optional(),beforeMigration:z.any().optional(),afterMigration:z.any().optional(),onMigrationError:z.any().optional()}),P=z.object({executed:z.array(z.string()),pending:z.array(z.string()),total:z.number().int().nonnegative()}),O=z.object({executed:z.array(z.string()),skipped:z.array(z.string()),failed:z.array(z.string()),duration:z.number().nonnegative(),dryRun:z.boolean()}),k=d.extend({plugins:z.array(w).optional()});function D(e){return d.parse(e)}function E(e){return d.safeParse(e)}function v(e){return m.parse(e)}function $(e){return m.safeParse(e)}var f=class extends DatabaseError{migrationName;operation;constructor(n,i,t,o){let a=t==="up"?"MIGRATION_UP_FAILED":"MIGRATION_DOWN_FAILED";super(n,a,i),this.name="MigrationError",this.migrationName=i,this.operation=t,o&&(this.cause=o);}toJSON(){let n=this.cause instanceof Error?this.cause:void 0;return {...super.toJSON(),migrationName:this.migrationName,operation:this.operation,cause:n?.message}}};async function c(e){await e.schema.createTable("migrations").ifNotExists().addColumn("name","varchar(255)",n=>n.primaryKey()).addColumn("executed_at","timestamp",n=>n.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)).execute();}function h(e){return "description"in e||"breaking"in e||"tags"in e}function M(e){return e instanceof Error?e.message:String(e)}function T(e){let n=new Set;for(let i of e){if(n.has(i.name))throw new BadRequestError(`Duplicate migration name: ${i.name}`);n.add(i.name);}}var p=class{constructor(n,i,t={}){this.db=n;this.migrations=i;let o=d.safeParse(t);if(!o.success)throw new BadRequestError(`Invalid migration runner options: ${o.error.message}`);this.logger=t.logger??silentLogger,this.options={dryRun:o.data.dryRun,logger:this.logger,useTransactions:o.data.useTransactions,stopOnError:o.data.stopOnError,verbose:o.data.verbose},T(i);}logger;options;async getExecutedMigrations(){return await c(this.db),(await this.db.selectFrom("migrations").select("name").orderBy("executed_at","asc").execute()).map(i=>i.name)}async markAsExecuted(n){await this.db.insertInto("migrations").values({name:n}).execute();}async markAsRolledBack(n){await this.db.deleteFrom("migrations").where("name","=",n).execute();}logMigrationMeta(n){if(!this.options.verbose||!h(n))return;let i=n;if(i.description&&this.logger.info(` Description: ${i.description}`),i.breaking&&this.logger.warn(" BREAKING CHANGE - Review carefully before proceeding"),i.tags&&i.tags.length>0&&this.logger.info(` Tags: ${i.tags.join(", ")}`),i.estimatedDuration){let t=(i.estimatedDuration/1e3).toFixed(1);this.logger.info(` Estimated: ${t}s`);}}async executeMigration(n,i){let t=i==="up"?n.up:n.down;t&&(this.options.useTransactions?await this.db.transaction().execute(async o=>{await t(o);}):await t(this.db));}async up(){let n=Date.now(),i={executed:[],skipped:[],failed:[],duration:0,dryRun:this.options.dryRun};await c(this.db);let t=await this.getExecutedMigrations();if(this.migrations.filter(a=>!t.includes(a.name)).length===0)return this.logger.info("No pending migrations"),i.skipped=t,i.duration=Date.now()-n,i;this.options.dryRun&&this.logger.info("DRY RUN - No changes will be made");for(let a of this.migrations){if(t.includes(a.name)){this.logger.info(`${a.name} (already executed)`),i.skipped.push(a.name);continue}try{this.logger.info(`Running ${a.name}...`),this.logMigrationMeta(a),this.options.dryRun||(await this.executeMigration(a,"up"),await this.markAsExecuted(a.name)),this.logger.info(`${a.name} completed`),i.executed.push(a.name);}catch(g){let s=M(g);if(this.logger.error(`${a.name} failed: ${s}`),i.failed.push(a.name),this.options.stopOnError)throw new f(`Migration ${a.name} failed: ${s}`,a.name,"up",g instanceof Error?g:void 0)}}return this.options.dryRun?this.logger.info("Dry run completed - no changes made"):this.logger.info("All migrations completed successfully"),i.duration=Date.now()-n,i}async down(n=1){let i=Date.now(),t={executed:[],skipped:[],failed:[],duration:0,dryRun:this.options.dryRun};await c(this.db);let o=await this.getExecutedMigrations();if(o.length===0)return this.logger.warn("No executed migrations to rollback"),t.duration=Date.now()-i,t;let a=o.slice(-n).reverse();this.options.dryRun&&this.logger.info("DRY RUN - No changes will be made");for(let g of a){let s=this.migrations.find(u=>u.name===g);if(!s){this.logger.warn(`Migration ${g} not found in codebase`),t.skipped.push(g);continue}if(!s.down){this.logger.warn(`Migration ${g} has no down method - skipping`),t.skipped.push(g);continue}try{this.logger.info(`Rolling back ${g}...`),this.logMigrationMeta(s),this.options.dryRun||(await this.executeMigration(s,"down"),await this.markAsRolledBack(g)),this.logger.info(`${g} rolled back`),t.executed.push(g);}catch(u){let l=M(u);if(this.logger.error(`${g} rollback failed: ${l}`),t.failed.push(g),this.options.stopOnError)throw new f(`Rollback of ${g} failed: ${l}`,g,"down",u instanceof Error?u:void 0)}}return this.options.dryRun?this.logger.info("Dry run completed - no changes made"):this.logger.info("Rollback completed successfully"),t.duration=Date.now()-i,t}async status(){await c(this.db);let n=await this.getExecutedMigrations(),i=this.migrations.filter(t=>!n.includes(t.name)).map(t=>t.name);if(this.logger.info("Migration Status:"),this.logger.info(` Executed: ${n.length}`),this.logger.info(` Pending: ${i.length}`),this.logger.info(` Total: ${this.migrations.length}`),n.length>0){this.logger.info("Executed migrations:");for(let t of n){let o=this.migrations.find(a=>a.name===t);o&&h(o)&&o.description?this.logger.info(` ${t} - ${o.description}`):this.logger.info(` ${t}`);}}if(i.length>0){this.logger.info("Pending migrations:");for(let t of i){let o=this.migrations.find(a=>a.name===t);if(o&&h(o)){let a=o,g=a.breaking?" BREAKING":"",s=a.description?` - ${a.description}`:"";this.logger.info(` ${t}${s}${g}`);}else this.logger.info(` ${t}`);}}return {executed:n,pending:i,total:this.migrations.length}}async reset(){let n=Date.now();await c(this.db);let i=await this.getExecutedMigrations();if(i.length===0)return this.logger.warn("No migrations to reset"),{executed:[],skipped:[],failed:[],duration:Date.now()-n,dryRun:this.options.dryRun};if(this.logger.warn(`Resetting ${i.length} migrations...`),this.options.dryRun){this.logger.info("DRY RUN - Would rollback the following migrations:");for(let o of [...i].reverse())this.migrations.find(g=>g.name===o)?.down?this.logger.info(` ${o}`):this.logger.warn(` ${o} (no down method - would be skipped)`);return this.logger.info("Dry run completed - no changes made"),{executed:[],skipped:i,failed:[],duration:Date.now()-n,dryRun:true}}let t=await this.down(i.length);return this.logger.info("All migrations reset"),t}async upTo(n){let i=Date.now(),t={executed:[],skipped:[],failed:[],duration:0,dryRun:this.options.dryRun};await c(this.db);let o=await this.getExecutedMigrations(),a=this.migrations.findIndex(s=>s.name===n);if(a===-1)throw new NotFoundError("Migration",{name:n});let g=this.migrations.slice(0,a+1);this.options.dryRun&&this.logger.info("DRY RUN - No changes will be made");for(let s of g){if(o.includes(s.name)){this.logger.info(`${s.name} (already executed)`),t.skipped.push(s.name);continue}try{this.logger.info(`Running ${s.name}...`),this.logMigrationMeta(s),this.options.dryRun||(await this.executeMigration(s,"up"),await this.markAsExecuted(s.name)),this.logger.info(`${s.name} completed`),t.executed.push(s.name);}catch(u){let l=M(u);throw this.logger.error(`${s.name} failed: ${l}`),t.failed.push(s.name),new f(`Migration ${s.name} failed: ${l}`,s.name,"up",u instanceof Error?u:void 0)}}return this.options.dryRun?this.logger.info(`Dry run completed - would migrate up to ${n}`):this.logger.info(`Migrated up to ${n}`),t.duration=Date.now()-i,t}};function _(e,n,i){return new p(e,n,i)}function F(e,n,i){let t={name:e,up:n};return i!==void 0&&(t.down=i),t}function j(e,n){let i={name:e,up:n.up};return n.down!==void 0&&(i.down=n.down),n.description!==void 0&&(i.description=n.description),n.breaking!==void 0&&(i.breaking=n.breaking),n.estimatedDuration!==void 0&&(i.estimatedDuration=n.estimatedDuration),n.tags!==void 0&&(i.tags=n.tags),i}function B(e){return Object.entries(e).map(([n,i])=>{let t={name:n,up:i.up};return i.down!==void 0&&(t.down=i.down),i.description!==void 0&&(t.description=i.description),i.breaking!==void 0&&(t.breaking=i.breaking),i.estimatedDuration!==void 0&&(t.estimatedDuration=i.estimatedDuration),i.tags!==void 0&&(t.tags=i.tags),t})}async function G(e,n,i){return new p(e,n,i).up()}async function q(e,n,i=1,t){return new p(e,n,t).down(i)}async function C(e,n,i){return new p(e,n,i).status()}async function U(e,n,i){let t=new y(e,n,i);if(i?.plugins){for(let o of i.plugins)if(o.onInit){let a=o.onInit(t);a instanceof Promise&&await a;}}return t}var y=class extends p{plugins;constructor(n,i,t={}){super(n,i,t),this.plugins=t.plugins??[];}async runBeforeHooks(n,i){for(let t of this.plugins)t.beforeMigration&&await t.beforeMigration(n,i);}async runAfterHooks(n,i,t){for(let o of this.plugins)o.afterMigration&&await o.afterMigration(n,i,t);}async runErrorHooks(n,i,t){for(let o of this.plugins)o.onMigrationError&&await o.onMigrationError(n,i,t);}getPlugins(){return [...this.plugins]}};function H(e=silentLogger){return {name:"@kysera/migrations/logging",version:"0.5.1",beforeMigration(n,i){e.info(`Starting ${i} for ${n.name}`);},afterMigration(n,i,t){e.info(`Completed ${i} for ${n.name} in ${t}ms`);},onMigrationError(n,i,t){let o=t instanceof Error?t.message:String(t);e.error(`Error during ${i} for ${n.name}: ${o}`);}}}function Y(){let e=[];return {name:"@kysera/migrations/metrics",version:"0.5.1",afterMigration(n,i,t){e.push({name:n.name,operation:i,duration:t,success:true});},onMigrationError(n,i){e.push({name:n.name,operation:i,duration:0,success:false});},getMetrics(){return {migrations:[...e]}}}}export{m as MigrationDefinitionSchema,f as MigrationError,b as MigrationPluginOptionsSchema,w as MigrationPluginSchema,O as MigrationResultSchema,p as MigrationRunner,d as MigrationRunnerOptionsSchema,y as MigrationRunnerWithPlugins,k as MigrationRunnerWithPluginsOptionsSchema,P as MigrationStatusSchema,H as createLoggingPlugin,Y as createMetricsPlugin,F as createMigration,_ as createMigrationRunner,U as createMigrationRunnerWithPlugins,j as createMigrationWithMeta,B as defineMigrations,C as getMigrationStatus,v as parseMigrationDefinition,D as parseMigrationRunnerOptions,q as rollbackMigrations,G as runMigrations,$ as safeParseMigrationDefinition,E as safeParseMigrationRunnerOptions,c as setupMigrations};//# sourceMappingURL=index.js.map
1
+ import {sql}from'kysely';import {silentLogger,DatabaseError,BadRequestError,NotFoundError}from'@kysera/core';export{BadRequestError,DatabaseError,NotFoundError,silentLogger}from'@kysera/core';import {z as z$1}from'zod';var d=z$1.object({dryRun:z$1.boolean().default(false),logger:z$1.any().optional(),useTransactions:z$1.boolean().default(false),stopOnError:z$1.boolean().default(true),verbose:z$1.boolean().default(true)}),m=z$1.object({name:z$1.string().min(1,"Migration name is required"),description:z$1.string().optional(),breaking:z$1.boolean().default(false),tags:z$1.array(z$1.string()).default([]),estimatedDuration:z$1.string().optional()}),x=z$1.object({logger:z$1.any().optional()}),D=z$1.object({name:z$1.string().min(1,"Plugin name is required"),version:z$1.string().min(1,"Plugin version is required"),onInit:z$1.any().optional(),beforeMigration:z$1.any().optional(),afterMigration:z$1.any().optional(),onMigrationError:z$1.any().optional()}),b=z$1.object({executed:z$1.array(z$1.string()),pending:z$1.array(z$1.string()),total:z$1.number().int().nonnegative()}),P=z$1.object({executed:z$1.array(z$1.string()),skipped:z$1.array(z$1.string()),failed:z$1.array(z$1.string()),duration:z$1.number().nonnegative(),dryRun:z$1.boolean()}),B=d.extend({plugins:z$1.array(D).optional()});function k(e){return d.parse(e)}function O(e){return d.safeParse(e)}function E(e){return m.parse(e)}function v(e){return m.safeParse(e)}var f=class extends DatabaseError{migrationName;operation;constructor(n,i,t,o){let a=t==="up"?"MIGRATION_UP_FAILED":"MIGRATION_DOWN_FAILED";super(n,a,i),this.name="MigrationError",this.migrationName=i,this.operation=t,o&&(this.cause=o);}toJSON(){let n=this.cause instanceof Error?this.cause:void 0;return {...super.toJSON(),migrationName:this.migrationName,operation:this.operation,cause:n?.message}}};async function c(e){await e.schema.createTable("migrations").ifNotExists().addColumn("name","varchar(255)",n=>n.primaryKey()).addColumn("executed_at","timestamp",n=>n.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)).execute();}function h(e){return "description"in e||"breaking"in e||"tags"in e}function M(e){return e instanceof Error?e.message:String(e)}function N(e){let n=new Set;for(let i of e){if(n.has(i.name))throw new BadRequestError(`Duplicate migration name: ${i.name}`);n.add(i.name);}}var p=class{constructor(n,i,t={}){this.db=n;this.migrations=i;let o=d.safeParse(t);if(!o.success)throw new BadRequestError(`Invalid migration runner options: ${o.error.message}`);this.logger=t.logger??silentLogger,this.options={dryRun:o.data.dryRun,logger:this.logger,useTransactions:o.data.useTransactions,stopOnError:o.data.stopOnError,verbose:o.data.verbose},N(i);}logger;options;async getExecutedMigrations(){return await c(this.db),(await this.db.selectFrom("migrations").select("name").orderBy("executed_at","asc").execute()).map(i=>i.name)}async markAsExecuted(n){await this.db.insertInto("migrations").values({name:n}).execute();}async markAsRolledBack(n){await this.db.deleteFrom("migrations").where("name","=",n).execute();}logMigrationMeta(n){if(!this.options.verbose||!h(n))return;let i=n;if(i.description&&this.logger.info(` Description: ${i.description}`),i.breaking&&this.logger.warn(" BREAKING CHANGE - Review carefully before proceeding"),i.tags&&i.tags.length>0&&this.logger.info(` Tags: ${i.tags.join(", ")}`),i.estimatedDuration){let t=(i.estimatedDuration/1e3).toFixed(1);this.logger.info(` Estimated: ${t}s`);}}async executeMigration(n,i){let t=i==="up"?n.up:n.down;t&&(this.options.useTransactions?await this.db.transaction().execute(async o=>{await t(o);}):await t(this.db));}async up(){let n=Date.now(),i={executed:[],skipped:[],failed:[],duration:0,dryRun:this.options.dryRun};await c(this.db);let t=await this.getExecutedMigrations();if(this.migrations.filter(a=>!t.includes(a.name)).length===0)return this.logger.info("No pending migrations"),i.skipped=t,i.duration=Date.now()-n,i;this.options.dryRun&&this.logger.info("DRY RUN - No changes will be made");for(let a of this.migrations){if(t.includes(a.name)){this.logger.info(`${a.name} (already executed)`),i.skipped.push(a.name);continue}try{this.logger.info(`Running ${a.name}...`),this.logMigrationMeta(a),this.options.dryRun||(await this.executeMigration(a,"up"),await this.markAsExecuted(a.name)),this.logger.info(`${a.name} completed`),i.executed.push(a.name);}catch(g){let s=M(g);if(this.logger.error(`${a.name} failed: ${s}`),i.failed.push(a.name),this.options.stopOnError)throw new f(`Migration ${a.name} failed: ${s}`,a.name,"up",g instanceof Error?g:void 0)}}return this.options.dryRun?this.logger.info("Dry run completed - no changes made"):this.logger.info("All migrations completed successfully"),i.duration=Date.now()-n,i}async down(n=1){let i=Date.now(),t={executed:[],skipped:[],failed:[],duration:0,dryRun:this.options.dryRun};await c(this.db);let o=await this.getExecutedMigrations();if(o.length===0)return this.logger.warn("No executed migrations to rollback"),t.duration=Date.now()-i,t;let a=o.slice(-n).reverse();this.options.dryRun&&this.logger.info("DRY RUN - No changes will be made");for(let g of a){let s=this.migrations.find(u=>u.name===g);if(!s){this.logger.warn(`Migration ${g} not found in codebase`),t.skipped.push(g);continue}if(!s.down){this.logger.warn(`Migration ${g} has no down method - skipping`),t.skipped.push(g);continue}try{this.logger.info(`Rolling back ${g}...`),this.logMigrationMeta(s),this.options.dryRun||(await this.executeMigration(s,"down"),await this.markAsRolledBack(g)),this.logger.info(`${g} rolled back`),t.executed.push(g);}catch(u){let l=M(u);if(this.logger.error(`${g} rollback failed: ${l}`),t.failed.push(g),this.options.stopOnError)throw new f(`Rollback of ${g} failed: ${l}`,g,"down",u instanceof Error?u:void 0)}}return this.options.dryRun?this.logger.info("Dry run completed - no changes made"):this.logger.info("Rollback completed successfully"),t.duration=Date.now()-i,t}async status(){await c(this.db);let n=await this.getExecutedMigrations(),i=this.migrations.filter(t=>!n.includes(t.name)).map(t=>t.name);if(this.logger.info("Migration Status:"),this.logger.info(` Executed: ${n.length}`),this.logger.info(` Pending: ${i.length}`),this.logger.info(` Total: ${this.migrations.length}`),n.length>0){this.logger.info("Executed migrations:");for(let t of n){let o=this.migrations.find(a=>a.name===t);o&&h(o)&&o.description?this.logger.info(` ${t} - ${o.description}`):this.logger.info(` ${t}`);}}if(i.length>0){this.logger.info("Pending migrations:");for(let t of i){let o=this.migrations.find(a=>a.name===t);if(o&&h(o)){let a=o,g=a.breaking?" BREAKING":"",s=a.description?` - ${a.description}`:"";this.logger.info(` ${t}${s}${g}`);}else this.logger.info(` ${t}`);}}return {executed:n,pending:i,total:this.migrations.length}}async reset(){let n=Date.now();await c(this.db);let i=await this.getExecutedMigrations();if(i.length===0)return this.logger.warn("No migrations to reset"),{executed:[],skipped:[],failed:[],duration:Date.now()-n,dryRun:this.options.dryRun};if(this.logger.warn(`Resetting ${i.length} migrations...`),this.options.dryRun){this.logger.info("DRY RUN - Would rollback the following migrations:");for(let o of [...i].reverse())this.migrations.find(g=>g.name===o)?.down?this.logger.info(` ${o}`):this.logger.warn(` ${o} (no down method - would be skipped)`);return this.logger.info("Dry run completed - no changes made"),{executed:[],skipped:i,failed:[],duration:Date.now()-n,dryRun:true}}let t=await this.down(i.length);return this.logger.info("All migrations reset"),t}async upTo(n){let i=Date.now(),t={executed:[],skipped:[],failed:[],duration:0,dryRun:this.options.dryRun};await c(this.db);let o=await this.getExecutedMigrations(),a=this.migrations.findIndex(s=>s.name===n);if(a===-1)throw new NotFoundError("Migration",{name:n});let g=this.migrations.slice(0,a+1);this.options.dryRun&&this.logger.info("DRY RUN - No changes will be made");for(let s of g){if(o.includes(s.name)){this.logger.info(`${s.name} (already executed)`),t.skipped.push(s.name);continue}try{this.logger.info(`Running ${s.name}...`),this.logMigrationMeta(s),this.options.dryRun||(await this.executeMigration(s,"up"),await this.markAsExecuted(s.name)),this.logger.info(`${s.name} completed`),t.executed.push(s.name);}catch(u){let l=M(u);throw this.logger.error(`${s.name} failed: ${l}`),t.failed.push(s.name),new f(`Migration ${s.name} failed: ${l}`,s.name,"up",u instanceof Error?u:void 0)}}return this.options.dryRun?this.logger.info(`Dry run completed - would migrate up to ${n}`):this.logger.info(`Migrated up to ${n}`),t.duration=Date.now()-i,t}};function z(e,n,i){return new p(e,n,i)}function _(e,n,i){let t={name:e,up:n};return i!==void 0&&(t.down=i),t}function F(e,n){let i={name:e,up:n.up};return n.down!==void 0&&(i.down=n.down),n.description!==void 0&&(i.description=n.description),n.breaking!==void 0&&(i.breaking=n.breaking),n.estimatedDuration!==void 0&&(i.estimatedDuration=n.estimatedDuration),n.tags!==void 0&&(i.tags=n.tags),i}function j(e){return Object.entries(e).map(([n,i])=>{let t={name:n,up:i.up};return i.down!==void 0&&(t.down=i.down),i.description!==void 0&&(t.description=i.description),i.breaking!==void 0&&(t.breaking=i.breaking),i.estimatedDuration!==void 0&&(t.estimatedDuration=i.estimatedDuration),i.tags!==void 0&&(t.tags=i.tags),t})}async function G(e,n,i){return new p(e,n,i).up()}async function q(e,n,i=1,t){return new p(e,n,t).down(i)}async function C(e,n,i){return new p(e,n,i).status()}async function U(e,n,i){let t=new y(e,n,i);if(i?.plugins){for(let o of i.plugins)if(o.onInit){let a=o.onInit(t);a instanceof Promise&&await a;}}return t}var y=class extends p{plugins;constructor(n,i,t={}){super(n,i,t),this.plugins=t.plugins??[];}async runBeforeHooks(n,i){for(let t of this.plugins)t.beforeMigration&&await t.beforeMigration(n,i);}async runAfterHooks(n,i,t){for(let o of this.plugins)o.afterMigration&&await o.afterMigration(n,i,t);}async runErrorHooks(n,i,t){for(let o of this.plugins)o.onMigrationError&&await o.onMigrationError(n,i,t);}getPlugins(){return [...this.plugins]}};function H(e=silentLogger){return {name:"@kysera/migrations/logging",version:"0.5.1",beforeMigration(n,i){e.info(`Starting ${i} for ${n.name}`);},afterMigration(n,i,t){e.info(`Completed ${i} for ${n.name} in ${t}ms`);},onMigrationError(n,i,t){let o=t instanceof Error?t.message:String(t);e.error(`Error during ${i} for ${n.name}: ${o}`);}}}function Y(){let e=[];return {name:"@kysera/migrations/metrics",version:"0.5.1",afterMigration(n,i,t){e.push({name:n.name,operation:i,duration:t,success:true});},onMigrationError(n,i){e.push({name:n.name,operation:i,duration:0,success:false});},getMetrics(){return {migrations:[...e]}}}}export{m as MigrationDefinitionSchema,f as MigrationError,x as MigrationPluginOptionsSchema,D as MigrationPluginSchema,P as MigrationResultSchema,p as MigrationRunner,d as MigrationRunnerOptionsSchema,y as MigrationRunnerWithPlugins,B as MigrationRunnerWithPluginsOptionsSchema,b as MigrationStatusSchema,H as createLoggingPlugin,Y as createMetricsPlugin,_ as createMigration,z as createMigrationRunner,U as createMigrationRunnerWithPlugins,F as createMigrationWithMeta,j as defineMigrations,C as getMigrationStatus,E as parseMigrationDefinition,k as parseMigrationRunnerOptions,q as rollbackMigrations,G as runMigrations,v as safeParseMigrationDefinition,O as safeParseMigrationRunnerOptions,c as setupMigrations};//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas.ts","../src/index.ts"],"names":["MigrationRunnerOptionsSchema","z","MigrationDefinitionSchema","MigrationPluginOptionsSchema","MigrationPluginSchema","MigrationStatusSchema","MigrationResultSchema","MigrationRunnerWithPluginsOptionsSchema","parseMigrationRunnerOptions","options","safeParseMigrationRunnerOptions","parseMigrationDefinition","definition","safeParseMigrationDefinition","MigrationError","DatabaseError","message","migrationName","operation","cause","code","causeError","setupMigrations","db","col","sql","hasMeta","migration","formatError","error","validateMigrations","migrations","names","BadRequestError","MigrationRunner","parsed","silentLogger","r","name","meta","seconds","fn","trx","startTime","result","executed","m","errorMsg","steps","toRollback","pending","suffix","desc","targetName","targetIndex","NotFoundError","migrationsToRun","createMigrationRunner","createMigration","up","down","createMigrationWithMeta","defineMigrations","definitions","def","runMigrations","rollbackMigrations","getMigrationStatus","createMigrationRunnerWithPlugins","runner","MigrationRunnerWithPlugins","plugin","duration","createLoggingPlugin","logger","createMetricsPlugin","metrics"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\n// ============================================================================\n// Migration Runner Options Schema\n// ============================================================================\n\n/**\n * Schema for MigrationRunnerOptions\n * Validates configuration options for the migration runner\n */\nexport const MigrationRunnerOptionsSchema = z.object({\n /** Enable dry run mode (preview only, no changes) */\n dryRun: z.boolean().default(false),\n /** Logger function - validated as any since function schemas are complex in Zod v4 */\n logger: z.any().optional(),\n /** Wrap each migration in a transaction */\n useTransactions: z.boolean().default(false),\n /** Stop on first error */\n stopOnError: z.boolean().default(true),\n /** Show detailed metadata in logs */\n verbose: z.boolean().default(true),\n});\n\n// ============================================================================\n// Migration Definition Schema\n// ============================================================================\n\n/**\n * Schema for MigrationDefinition\n * Validates migration definition objects used with defineMigrations()\n */\nexport const MigrationDefinitionSchema = z.object({\n /** Migration name - must be non-empty */\n name: z.string().min(1, 'Migration name is required'),\n /** Human-readable description shown during migration */\n description: z.string().optional(),\n /** Whether this is a breaking change - shows warning before execution */\n breaking: z.boolean().default(false),\n /** Tags for categorization (e.g., ['schema', 'data', 'index']) */\n tags: z.array(z.string()).default([]),\n /** Estimated duration as human-readable string (e.g., '30s', '2m') */\n estimatedDuration: z.string().optional(),\n});\n\n// ============================================================================\n// Migration Plugin Options Schema\n// ============================================================================\n\n/**\n * Schema for MigrationPluginOptions\n * Validates options passed to migration plugins\n */\nexport const MigrationPluginOptionsSchema = z.object({\n /** Optional logger for the plugin */\n logger: z.any().optional(),\n});\n\n// ============================================================================\n// Migration Plugin Schema\n// ============================================================================\n\n/**\n * Schema for MigrationPlugin\n * Validates migration plugin structure\n */\nexport const MigrationPluginSchema = z.object({\n /** Plugin name */\n name: z.string().min(1, 'Plugin name is required'),\n /** Plugin version */\n version: z.string().min(1, 'Plugin version is required'),\n /** Called once when the runner is initialized */\n onInit: z.any().optional(),\n /** Called before migration execution */\n beforeMigration: z.any().optional(),\n /** Called after successful migration execution */\n afterMigration: z.any().optional(),\n /** Called on migration error */\n onMigrationError: z.any().optional(),\n});\n\n// ============================================================================\n// Migration Status Schema\n// ============================================================================\n\n/**\n * Schema for MigrationStatus\n * Validates migration status results\n */\nexport const MigrationStatusSchema = z.object({\n /** List of executed migration names */\n executed: z.array(z.string()),\n /** List of pending migration names */\n pending: z.array(z.string()),\n /** Total migration count */\n total: z.number().int().nonnegative(),\n});\n\n// ============================================================================\n// Migration Result Schema\n// ============================================================================\n\n/**\n * Schema for MigrationResult\n * Validates results from migration runs\n */\nexport const MigrationResultSchema = z.object({\n /** Successfully executed migrations */\n executed: z.array(z.string()),\n /** Migrations that were skipped (already executed) */\n skipped: z.array(z.string()),\n /** Migrations that failed */\n failed: z.array(z.string()),\n /** Total duration in milliseconds */\n duration: z.number().nonnegative(),\n /** Whether the run was in dry-run mode */\n dryRun: z.boolean(),\n});\n\n// ============================================================================\n// Extended Runner Options Schema (with plugins)\n// ============================================================================\n\n/**\n * Schema for MigrationRunnerWithPluginsOptions\n * Extends MigrationRunnerOptionsSchema with plugin support\n */\nexport const MigrationRunnerWithPluginsOptionsSchema = MigrationRunnerOptionsSchema.extend({\n /** Plugins to apply */\n plugins: z.array(MigrationPluginSchema).optional(),\n});\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\n/** Input type for MigrationRunnerOptions - before defaults are applied */\nexport type MigrationRunnerOptionsInput = z.input<typeof MigrationRunnerOptionsSchema>;\n\n/** Output type for MigrationRunnerOptions - after defaults are applied */\nexport type MigrationRunnerOptionsOutput = z.output<typeof MigrationRunnerOptionsSchema>;\n\n/** Input type for MigrationDefinition - before defaults are applied */\nexport type MigrationDefinitionInput = z.input<typeof MigrationDefinitionSchema>;\n\n/** Output type for MigrationDefinition - after defaults are applied */\nexport type MigrationDefinitionOutput = z.output<typeof MigrationDefinitionSchema>;\n\n/** Input type for MigrationPluginOptions */\nexport type MigrationPluginOptionsInput = z.input<typeof MigrationPluginOptionsSchema>;\n\n/** Output type for MigrationPluginOptions */\nexport type MigrationPluginOptionsOutput = z.output<typeof MigrationPluginOptionsSchema>;\n\n/** Input type for MigrationPlugin */\nexport type MigrationPluginInput = z.input<typeof MigrationPluginSchema>;\n\n/** Output type for MigrationPlugin */\nexport type MigrationPluginOutput = z.output<typeof MigrationPluginSchema>;\n\n/** Type for MigrationStatus */\nexport type MigrationStatusType = z.infer<typeof MigrationStatusSchema>;\n\n/** Type for MigrationResult */\nexport type MigrationResultType = z.infer<typeof MigrationResultSchema>;\n\n/** Input type for MigrationRunnerWithPluginsOptions */\nexport type MigrationRunnerWithPluginsOptionsInput = z.input<typeof MigrationRunnerWithPluginsOptionsSchema>;\n\n/** Output type for MigrationRunnerWithPluginsOptions */\nexport type MigrationRunnerWithPluginsOptionsOutput = z.output<typeof MigrationRunnerWithPluginsOptionsSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\n/**\n * Validate and parse MigrationRunnerOptions with defaults\n */\nexport function parseMigrationRunnerOptions(\n options: unknown\n): MigrationRunnerOptionsOutput {\n return MigrationRunnerOptionsSchema.parse(options);\n}\n\n/**\n * Safely validate MigrationRunnerOptions without throwing\n * Returns result with success boolean and either data or error\n */\nexport function safeParseMigrationRunnerOptions(options: unknown) {\n return MigrationRunnerOptionsSchema.safeParse(options);\n}\n\n/**\n * Validate and parse MigrationDefinition with defaults\n */\nexport function parseMigrationDefinition(\n definition: unknown\n): MigrationDefinitionOutput {\n return MigrationDefinitionSchema.parse(definition);\n}\n\n/**\n * Safely validate MigrationDefinition without throwing\n * Returns result with success boolean and either data or error\n */\nexport function safeParseMigrationDefinition(definition: unknown) {\n return MigrationDefinitionSchema.safeParse(definition);\n}\n","import type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport type { KyseraLogger } from '@kysera/core';\nimport { DatabaseError, NotFoundError, BadRequestError, silentLogger } from '@kysera/core';\n\n// ============================================================================\n// Schema Exports\n// ============================================================================\n\nexport {\n // Schemas\n MigrationRunnerOptionsSchema,\n MigrationDefinitionSchema,\n MigrationPluginOptionsSchema,\n MigrationPluginSchema,\n MigrationStatusSchema,\n MigrationResultSchema,\n MigrationRunnerWithPluginsOptionsSchema,\n // Type exports\n type MigrationRunnerOptionsInput,\n type MigrationRunnerOptionsOutput,\n type MigrationDefinitionInput,\n type MigrationDefinitionOutput,\n type MigrationPluginOptionsInput,\n type MigrationPluginOptionsOutput,\n type MigrationPluginInput,\n type MigrationPluginOutput,\n type MigrationStatusType,\n type MigrationResultType,\n type MigrationRunnerWithPluginsOptionsInput,\n type MigrationRunnerWithPluginsOptionsOutput,\n // Validation helpers\n parseMigrationRunnerOptions,\n safeParseMigrationRunnerOptions,\n parseMigrationDefinition,\n safeParseMigrationDefinition,\n} from './schemas.js';\n\nimport { MigrationRunnerOptionsSchema } from './schemas.js';\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\n/**\n * Migration interface - the core building block\n */\nexport interface Migration {\n /** Unique migration name (e.g., '001_create_users') */\n name: string;\n /** Migration up function - creates/modifies schema */\n up: (db: Kysely<any>) => Promise<void>;\n /** Optional migration down function - reverts changes */\n down?: (db: Kysely<any>) => Promise<void>;\n}\n\n/**\n * Migration with metadata for enhanced logging and tracking\n */\nexport interface MigrationWithMeta extends Migration {\n /** Human-readable description shown during migration */\n description?: string;\n /** Whether this is a breaking change - shows warning before execution */\n breaking?: boolean;\n /** Estimated duration in milliseconds for progress indication */\n estimatedDuration?: number;\n /** Tags for categorization (e.g., ['schema', 'data', 'index']) */\n tags?: string[];\n}\n\n/**\n * Migration status result\n */\nexport interface MigrationStatus {\n /** List of executed migration names */\n executed: string[];\n /** List of pending migration names */\n pending: string[];\n /** Total migration count */\n total: number;\n}\n\n/**\n * Migration runner options\n */\nexport interface MigrationRunnerOptions {\n /** Enable dry run mode (preview only, no changes) */\n dryRun?: boolean;\n /**\n * Logger for migration operations.\n * Uses KyseraLogger interface from @kysera/core.\n *\n * @default silentLogger (no output)\n */\n logger?: KyseraLogger;\n /** Wrap each migration in a transaction (default: false) */\n useTransactions?: boolean;\n /** Stop on first error (default: true) */\n stopOnError?: boolean;\n /** Show detailed metadata in logs (default: true) */\n verbose?: boolean;\n}\n\n/**\n * Object-based migration definition for Level 2 DX\n */\nexport interface MigrationDefinition {\n up: (db: Kysely<any>) => Promise<void>;\n down?: (db: Kysely<any>) => Promise<void>;\n description?: string;\n breaking?: boolean;\n estimatedDuration?: number;\n tags?: string[];\n}\n\n/**\n * Migration definitions map for defineMigrations()\n */\nexport type MigrationDefinitions = Record<string, MigrationDefinition>;\n\n/**\n * Result of a migration run\n */\nexport interface MigrationResult {\n /** Successfully executed migrations */\n executed: string[];\n /** Migrations that were skipped (already executed) */\n skipped: string[];\n /** Migrations that failed */\n failed: string[];\n /** Total duration in milliseconds */\n duration: number;\n /** Whether the run was in dry-run mode */\n dryRun: boolean;\n}\n\n// ============================================================================\n// Error Classes (extending @kysera/core)\n// ============================================================================\n\n/** Error codes for migration operations */\nexport type MigrationErrorCode = 'MIGRATION_UP_FAILED' | 'MIGRATION_DOWN_FAILED' | 'MIGRATION_VALIDATION_FAILED';\n\n/**\n * Migration-specific error extending DatabaseError from @kysera/core\n * Provides structured error information with code, migration context, and cause tracking\n */\nexport class MigrationError extends DatabaseError {\n public readonly migrationName: string;\n public readonly operation: 'up' | 'down';\n\n constructor(\n message: string,\n migrationName: string,\n operation: 'up' | 'down',\n cause?: Error\n ) {\n const code: MigrationErrorCode = operation === 'up' ? 'MIGRATION_UP_FAILED' : 'MIGRATION_DOWN_FAILED';\n super(message, code, migrationName);\n this.name = 'MigrationError';\n this.migrationName = migrationName;\n this.operation = operation;\n if (cause) {\n this.cause = cause;\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const causeError = this.cause instanceof Error ? this.cause : undefined;\n return {\n ...super.toJSON(),\n migrationName: this.migrationName,\n operation: this.operation,\n cause: causeError?.message,\n };\n }\n}\n\n// ============================================================================\n// Setup Functions\n// ============================================================================\n\n/**\n * Setup migrations table in database\n * Idempotent - safe to run multiple times\n */\nexport async function setupMigrations(db: Kysely<any>): Promise<void> {\n await db.schema\n .createTable('migrations')\n .ifNotExists()\n .addColumn('name', 'varchar(255)', (col) => col.primaryKey())\n .addColumn('executed_at', 'timestamp', (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`))\n .execute();\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if migration has metadata\n */\nfunction hasMeta(migration: Migration): migration is MigrationWithMeta {\n return 'description' in migration || 'breaking' in migration || 'tags' in migration;\n}\n\n/**\n * Format error message for logging\n */\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\n/**\n * Validate migrations for duplicate names\n * @throws {BadRequestError} When duplicate migration names are found\n */\nfunction validateMigrations(migrations: Migration[]): void {\n const names = new Set<string>();\n for (const migration of migrations) {\n if (names.has(migration.name)) {\n throw new BadRequestError(`Duplicate migration name: ${migration.name}`);\n }\n names.add(migration.name);\n }\n}\n\n// ============================================================================\n// Migration Runner Class\n// ============================================================================\n\n/**\n * Migration runner with state tracking and metadata support\n */\nexport class MigrationRunner {\n private logger: KyseraLogger;\n private options: Required<Omit<MigrationRunnerOptions, 'logger'>> & { logger: KyseraLogger };\n\n constructor(\n private db: Kysely<any>,\n private migrations: Migration[],\n options: MigrationRunnerOptions = {}\n ) {\n // Validate and apply defaults using Zod schema\n const parsed = MigrationRunnerOptionsSchema.safeParse(options);\n if (!parsed.success) {\n throw new BadRequestError(`Invalid migration runner options: ${parsed.error.message}`);\n }\n\n this.logger = options.logger ?? silentLogger;\n this.options = {\n dryRun: parsed.data.dryRun,\n logger: this.logger,\n useTransactions: parsed.data.useTransactions,\n stopOnError: parsed.data.stopOnError,\n verbose: parsed.data.verbose,\n };\n\n // Validate migrations on construction\n validateMigrations(migrations);\n }\n\n /**\n * Get list of executed migrations from database\n */\n async getExecutedMigrations(): Promise<string[]> {\n await setupMigrations(this.db);\n const rows = await this.db\n .selectFrom('migrations' as any)\n .select('name' as any)\n .orderBy('executed_at' as any, 'asc')\n .execute();\n\n return rows.map((r: any) => r.name);\n }\n\n /**\n * Mark a migration as executed\n */\n async markAsExecuted(name: string): Promise<void> {\n await this.db\n .insertInto('migrations' as any)\n .values({ name } as any)\n .execute();\n }\n\n /**\n * Mark a migration as rolled back (remove from executed list)\n */\n async markAsRolledBack(name: string): Promise<void> {\n await this.db\n .deleteFrom('migrations' as any)\n .where('name' as any, '=', name)\n .execute();\n }\n\n /**\n * Log migration metadata if available\n */\n private logMigrationMeta(migration: Migration): void {\n if (!this.options.verbose || !hasMeta(migration)) return;\n\n const meta = migration as MigrationWithMeta;\n\n if (meta.description) {\n this.logger.info(` Description: ${meta.description}`);\n }\n\n if (meta.breaking) {\n this.logger.warn(` BREAKING CHANGE - Review carefully before proceeding`);\n }\n\n if (meta.tags && meta.tags.length > 0) {\n this.logger.info(` Tags: ${meta.tags.join(', ')}`);\n }\n\n if (meta.estimatedDuration) {\n const seconds = (meta.estimatedDuration / 1000).toFixed(1);\n this.logger.info(` Estimated: ${seconds}s`);\n }\n }\n\n /**\n * Execute a single migration with optional transaction wrapping\n */\n private async executeMigration(\n migration: Migration,\n operation: 'up' | 'down'\n ): Promise<void> {\n const fn = operation === 'up' ? migration.up : migration.down;\n if (!fn) return;\n\n if (this.options.useTransactions) {\n await this.db.transaction().execute(async (trx) => {\n await fn(trx);\n });\n } else {\n await fn(this.db);\n }\n }\n\n /**\n * Run all pending migrations\n */\n async up(): Promise<MigrationResult> {\n const startTime = Date.now();\n const result: MigrationResult = {\n executed: [],\n skipped: [],\n failed: [],\n duration: 0,\n dryRun: this.options.dryRun,\n };\n\n await setupMigrations(this.db);\n const executed = await this.getExecutedMigrations();\n\n const pending = this.migrations.filter((m) => !executed.includes(m.name));\n\n if (pending.length === 0) {\n this.logger.info('No pending migrations');\n result.skipped = executed;\n result.duration = Date.now() - startTime;\n return result;\n }\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - No changes will be made');\n }\n\n for (const migration of this.migrations) {\n if (executed.includes(migration.name)) {\n this.logger.info(`${migration.name} (already executed)`);\n result.skipped.push(migration.name);\n continue;\n }\n\n try {\n this.logger.info(`Running ${migration.name}...`);\n this.logMigrationMeta(migration);\n\n if (!this.options.dryRun) {\n await this.executeMigration(migration, 'up');\n await this.markAsExecuted(migration.name);\n }\n\n this.logger.info(`${migration.name} completed`);\n result.executed.push(migration.name);\n } catch (error) {\n const errorMsg = formatError(error);\n this.logger.error(`${migration.name} failed: ${errorMsg}`);\n result.failed.push(migration.name);\n\n if (this.options.stopOnError) {\n throw new MigrationError(\n `Migration ${migration.name} failed: ${errorMsg}`,\n migration.name,\n 'up',\n error instanceof Error ? error : undefined\n );\n }\n }\n }\n\n if (!this.options.dryRun) {\n this.logger.info('All migrations completed successfully');\n } else {\n this.logger.info('Dry run completed - no changes made');\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n\n /**\n * Rollback last N migrations\n */\n async down(steps = 1): Promise<MigrationResult> {\n const startTime = Date.now();\n const result: MigrationResult = {\n executed: [],\n skipped: [],\n failed: [],\n duration: 0,\n dryRun: this.options.dryRun,\n };\n\n await setupMigrations(this.db);\n const executed = await this.getExecutedMigrations();\n\n if (executed.length === 0) {\n this.logger.warn('No executed migrations to rollback');\n result.duration = Date.now() - startTime;\n return result;\n }\n\n const toRollback = executed.slice(-steps).reverse();\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - No changes will be made');\n }\n\n for (const name of toRollback) {\n const migration = this.migrations.find((m) => m.name === name);\n\n if (!migration) {\n this.logger.warn(`Migration ${name} not found in codebase`);\n result.skipped.push(name);\n continue;\n }\n\n if (!migration.down) {\n this.logger.warn(`Migration ${name} has no down method - skipping`);\n result.skipped.push(name);\n continue;\n }\n\n try {\n this.logger.info(`Rolling back ${name}...`);\n this.logMigrationMeta(migration);\n\n if (!this.options.dryRun) {\n await this.executeMigration(migration, 'down');\n await this.markAsRolledBack(name);\n }\n\n this.logger.info(`${name} rolled back`);\n result.executed.push(name);\n } catch (error) {\n const errorMsg = formatError(error);\n this.logger.error(`${name} rollback failed: ${errorMsg}`);\n result.failed.push(name);\n\n if (this.options.stopOnError) {\n throw new MigrationError(\n `Rollback of ${name} failed: ${errorMsg}`,\n name,\n 'down',\n error instanceof Error ? error : undefined\n );\n }\n }\n }\n\n if (!this.options.dryRun) {\n this.logger.info('Rollback completed successfully');\n } else {\n this.logger.info('Dry run completed - no changes made');\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n\n /**\n * Show migration status\n */\n async status(): Promise<MigrationStatus> {\n await setupMigrations(this.db);\n const executed = await this.getExecutedMigrations();\n const pending = this.migrations.filter((m) => !executed.includes(m.name)).map((m) => m.name);\n\n this.logger.info('Migration Status:');\n this.logger.info(` Executed: ${executed.length}`);\n this.logger.info(` Pending: ${pending.length}`);\n this.logger.info(` Total: ${this.migrations.length}`);\n\n if (executed.length > 0) {\n this.logger.info('Executed migrations:');\n for (const name of executed) {\n const migration = this.migrations.find((m) => m.name === name);\n if (migration && hasMeta(migration) && (migration as MigrationWithMeta).description) {\n this.logger.info(` ${name} - ${(migration as MigrationWithMeta).description}`);\n } else {\n this.logger.info(` ${name}`);\n }\n }\n }\n\n if (pending.length > 0) {\n this.logger.info('Pending migrations:');\n for (const name of pending) {\n const migration = this.migrations.find((m) => m.name === name);\n if (migration && hasMeta(migration)) {\n const meta = migration as MigrationWithMeta;\n const suffix = meta.breaking ? ' BREAKING' : '';\n const desc = meta.description ? ` - ${meta.description}` : '';\n this.logger.info(` ${name}${desc}${suffix}`);\n } else {\n this.logger.info(` ${name}`);\n }\n }\n }\n\n return { executed, pending, total: this.migrations.length };\n }\n\n /**\n * Reset all migrations (dangerous!)\n * In dry run mode, shows what would be rolled back\n */\n async reset(): Promise<MigrationResult> {\n const startTime = Date.now();\n\n await setupMigrations(this.db);\n const executed = await this.getExecutedMigrations();\n\n if (executed.length === 0) {\n this.logger.warn('No migrations to reset');\n return {\n executed: [],\n skipped: [],\n failed: [],\n duration: Date.now() - startTime,\n dryRun: this.options.dryRun,\n };\n }\n\n this.logger.warn(`Resetting ${executed.length} migrations...`);\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - Would rollback the following migrations:');\n for (const name of [...executed].reverse()) {\n const migration = this.migrations.find((m) => m.name === name);\n if (!migration?.down) {\n this.logger.warn(` ${name} (no down method - would be skipped)`);\n } else {\n this.logger.info(` ${name}`);\n }\n }\n this.logger.info('Dry run completed - no changes made');\n return {\n executed: [],\n skipped: executed,\n failed: [],\n duration: Date.now() - startTime,\n dryRun: true,\n };\n }\n\n const result = await this.down(executed.length);\n this.logger.info('All migrations reset');\n return result;\n }\n\n /**\n * Run migrations up to a specific migration (inclusive)\n */\n async upTo(targetName: string): Promise<MigrationResult> {\n const startTime = Date.now();\n const result: MigrationResult = {\n executed: [],\n skipped: [],\n failed: [],\n duration: 0,\n dryRun: this.options.dryRun,\n };\n\n await setupMigrations(this.db);\n const executed = await this.getExecutedMigrations();\n\n const targetIndex = this.migrations.findIndex((m) => m.name === targetName);\n if (targetIndex === -1) {\n throw new NotFoundError('Migration', { name: targetName });\n }\n\n const migrationsToRun = this.migrations.slice(0, targetIndex + 1);\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - No changes will be made');\n }\n\n for (const migration of migrationsToRun) {\n if (executed.includes(migration.name)) {\n this.logger.info(`${migration.name} (already executed)`);\n result.skipped.push(migration.name);\n continue;\n }\n\n try {\n this.logger.info(`Running ${migration.name}...`);\n this.logMigrationMeta(migration);\n\n if (!this.options.dryRun) {\n await this.executeMigration(migration, 'up');\n await this.markAsExecuted(migration.name);\n }\n\n this.logger.info(`${migration.name} completed`);\n result.executed.push(migration.name);\n } catch (error) {\n const errorMsg = formatError(error);\n this.logger.error(`${migration.name} failed: ${errorMsg}`);\n result.failed.push(migration.name);\n\n throw new MigrationError(\n `Migration ${migration.name} failed: ${errorMsg}`,\n migration.name,\n 'up',\n error instanceof Error ? error : undefined\n );\n }\n }\n\n if (!this.options.dryRun) {\n this.logger.info(`Migrated up to ${targetName}`);\n } else {\n this.logger.info(`Dry run completed - would migrate up to ${targetName}`);\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a migration runner instance\n * Options are validated using Zod schema\n */\nexport function createMigrationRunner(\n db: Kysely<any>,\n migrations: Migration[],\n options?: MigrationRunnerOptions\n): MigrationRunner {\n return new MigrationRunner(db, migrations, options);\n}\n\n/**\n * Helper to create a simple migration\n */\nexport function createMigration(\n name: string,\n up: (db: Kysely<any>) => Promise<void>,\n down?: (db: Kysely<any>) => Promise<void>\n): Migration {\n const migration: Migration = { name, up };\n if (down !== undefined) {\n migration.down = down;\n }\n return migration;\n}\n\n/**\n * Helper to create a migration with metadata\n */\nexport function createMigrationWithMeta(\n name: string,\n options: {\n up: (db: Kysely<any>) => Promise<void>;\n down?: (db: Kysely<any>) => Promise<void>;\n description?: string;\n breaking?: boolean;\n estimatedDuration?: number;\n tags?: string[];\n }\n): MigrationWithMeta {\n const migration: MigrationWithMeta = {\n name,\n up: options.up,\n };\n if (options.down !== undefined) {\n migration.down = options.down;\n }\n if (options.description !== undefined) {\n migration.description = options.description;\n }\n if (options.breaking !== undefined) {\n migration.breaking = options.breaking;\n }\n if (options.estimatedDuration !== undefined) {\n migration.estimatedDuration = options.estimatedDuration;\n }\n if (options.tags !== undefined) {\n migration.tags = options.tags;\n }\n return migration;\n}\n\n// ============================================================================\n// Level 2: Developer Experience APIs\n// ============================================================================\n\n/**\n * Define migrations using an object-based syntax for cleaner code\n */\nexport function defineMigrations(definitions: MigrationDefinitions): MigrationWithMeta[] {\n return Object.entries(definitions).map(([name, def]) => {\n const migration: MigrationWithMeta = {\n name,\n up: def.up,\n };\n if (def.down !== undefined) {\n migration.down = def.down;\n }\n if (def.description !== undefined) {\n migration.description = def.description;\n }\n if (def.breaking !== undefined) {\n migration.breaking = def.breaking;\n }\n if (def.estimatedDuration !== undefined) {\n migration.estimatedDuration = def.estimatedDuration;\n }\n if (def.tags !== undefined) {\n migration.tags = def.tags;\n }\n return migration;\n });\n}\n\n/**\n * Run all pending migrations - one-liner convenience function\n */\nexport async function runMigrations(\n db: Kysely<any>,\n migrations: Migration[],\n options?: MigrationRunnerOptions\n): Promise<MigrationResult> {\n const runner = new MigrationRunner(db, migrations, options);\n return runner.up();\n}\n\n/**\n * Rollback migrations - one-liner convenience function\n */\nexport async function rollbackMigrations(\n db: Kysely<any>,\n migrations: Migration[],\n steps = 1,\n options?: MigrationRunnerOptions\n): Promise<MigrationResult> {\n const runner = new MigrationRunner(db, migrations, options);\n return runner.down(steps);\n}\n\n/**\n * Get migration status - one-liner convenience function\n */\nexport async function getMigrationStatus(\n db: Kysely<any>,\n migrations: Migration[],\n options?: Pick<MigrationRunnerOptions, 'logger' | 'verbose'>\n): Promise<MigrationStatus> {\n const runner = new MigrationRunner(db, migrations, options);\n return runner.status();\n}\n\n// ============================================================================\n// Level 3: Ecosystem Integration\n// ============================================================================\n\n/**\n * Migration plugin interface - consistent with @kysera/repository Plugin\n * Provides lifecycle hooks for migration execution\n */\nexport interface MigrationPlugin {\n /** Plugin name */\n name: string;\n /** Plugin version */\n version: string;\n /** Called once when the runner is initialized (consistent with repository Plugin.onInit) */\n onInit?(runner: MigrationRunner): Promise<void> | void;\n /** Called before migration execution */\n beforeMigration?(migration: Migration, operation: 'up' | 'down'): Promise<void> | void;\n /** Called after successful migration execution */\n afterMigration?(migration: Migration, operation: 'up' | 'down', duration: number): Promise<void> | void;\n /** Called on migration error (unknown type for consistency with repository Plugin.onError) */\n onMigrationError?(migration: Migration, operation: 'up' | 'down', error: unknown): Promise<void> | void;\n}\n\n/**\n * Extended migration runner options with plugin support\n */\nexport interface MigrationRunnerWithPluginsOptions extends MigrationRunnerOptions {\n /** Plugins to apply */\n plugins?: MigrationPlugin[];\n}\n\n/**\n * Create a migration runner with plugin support\n * Async factory to properly initialize plugins (consistent with @kysera/repository createORM)\n */\nexport async function createMigrationRunnerWithPlugins(\n db: Kysely<any>,\n migrations: Migration[],\n options?: MigrationRunnerWithPluginsOptions\n): Promise<MigrationRunnerWithPlugins> {\n const runner = new MigrationRunnerWithPlugins(db, migrations, options);\n\n // Initialize plugins (consistent with repository Plugin.onInit pattern)\n if (options?.plugins) {\n for (const plugin of options.plugins) {\n if (plugin.onInit) {\n const result = plugin.onInit(runner);\n if (result instanceof Promise) {\n await result;\n }\n }\n }\n }\n\n return runner;\n}\n\n/**\n * Extended migration runner with plugin support\n */\nexport class MigrationRunnerWithPlugins extends MigrationRunner {\n private plugins: MigrationPlugin[];\n\n constructor(\n db: Kysely<any>,\n migrations: Migration[],\n options: MigrationRunnerWithPluginsOptions = {}\n ) {\n super(db, migrations, options);\n this.plugins = options.plugins ?? [];\n }\n\n /**\n * Execute plugin hooks before migration\n * Can be called by consumers extending this class\n */\n protected async runBeforeHooks(migration: Migration, operation: 'up' | 'down'): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.beforeMigration) {\n await plugin.beforeMigration(migration, operation);\n }\n }\n }\n\n /**\n * Execute plugin hooks after migration\n * Can be called by consumers extending this class\n */\n protected async runAfterHooks(\n migration: Migration,\n operation: 'up' | 'down',\n duration: number\n ): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.afterMigration) {\n await plugin.afterMigration(migration, operation, duration);\n }\n }\n }\n\n /**\n * Execute plugin hooks on error\n * Can be called by consumers extending this class\n */\n protected async runErrorHooks(\n migration: Migration,\n operation: 'up' | 'down',\n error: unknown\n ): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.onMigrationError) {\n await plugin.onMigrationError(migration, operation, error);\n }\n }\n }\n\n /**\n * Get the list of registered plugins\n */\n getPlugins(): MigrationPlugin[] {\n return [...this.plugins];\n }\n}\n\n// ============================================================================\n// Built-in Plugins\n// ============================================================================\n\n/**\n * Logging plugin - logs migration events with timing\n */\nexport function createLoggingPlugin(\n logger: KyseraLogger = silentLogger\n): MigrationPlugin {\n return {\n name: '@kysera/migrations/logging',\n version: '0.5.1',\n beforeMigration(migration, operation) {\n logger.info(`Starting ${operation} for ${migration.name}`);\n },\n afterMigration(migration, operation, duration) {\n logger.info(`Completed ${operation} for ${migration.name} in ${duration}ms`);\n },\n onMigrationError(migration, operation, error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Error during ${operation} for ${migration.name}: ${message}`);\n },\n };\n}\n\n/**\n * Metrics plugin - collects migration metrics\n */\nexport function createMetricsPlugin(): MigrationPlugin & {\n getMetrics(): { migrations: Array<{ name: string; operation: string; duration: number; success: boolean }> };\n} {\n const metrics: Array<{ name: string; operation: string; duration: number; success: boolean }> = [];\n\n return {\n name: '@kysera/migrations/metrics',\n version: '0.5.1',\n afterMigration(migration, operation, duration) {\n metrics.push({ name: migration.name, operation, duration, success: true });\n },\n onMigrationError(migration, operation) {\n metrics.push({ name: migration.name, operation, duration: 0, success: false });\n },\n getMetrics() {\n return { migrations: [...metrics] };\n },\n };\n}\n\n// ============================================================================\n// Re-exports from @kysera/core for convenience\n// ============================================================================\n\nexport { DatabaseError, NotFoundError, BadRequestError, silentLogger } from '@kysera/core';\nexport type { KyseraLogger } from '@kysera/core';\n"]}
1
+ {"version":3,"sources":["../src/schemas.ts","../src/index.ts"],"names":["MigrationRunnerOptionsSchema","z","MigrationDefinitionSchema","MigrationPluginOptionsSchema","MigrationPluginSchema","MigrationStatusSchema","MigrationResultSchema","MigrationRunnerWithPluginsOptionsSchema","parseMigrationRunnerOptions","options","safeParseMigrationRunnerOptions","parseMigrationDefinition","definition","safeParseMigrationDefinition","MigrationError","DatabaseError","message","migrationName","operation","cause","code","causeError","setupMigrations","db","col","sql","hasMeta","migration","formatError","error","validateMigrations","migrations","names","BadRequestError","MigrationRunner","parsed","silentLogger","r","name","meta","seconds","fn","trx","startTime","result","executed","m","errorMsg","steps","toRollback","pending","suffix","desc","targetName","targetIndex","NotFoundError","migrationsToRun","createMigrationRunner","createMigration","up","down","createMigrationWithMeta","defineMigrations","definitions","def","runMigrations","rollbackMigrations","getMigrationStatus","createMigrationRunnerWithPlugins","runner","MigrationRunnerWithPlugins","plugin","duration","createLoggingPlugin","logger","createMetricsPlugin","metrics"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\n// ============================================================================\n// Migration Runner Options Schema\n// ============================================================================\n\n/**\n * Schema for MigrationRunnerOptions\n * Validates configuration options for the migration runner\n */\nexport const MigrationRunnerOptionsSchema = z.object({\n /** Enable dry run mode (preview only, no changes) */\n dryRun: z.boolean().default(false),\n /** Logger function - validated as any since function schemas are complex in Zod v4 */\n logger: z.any().optional(),\n /** Wrap each migration in a transaction */\n useTransactions: z.boolean().default(false),\n /** Stop on first error */\n stopOnError: z.boolean().default(true),\n /** Show detailed metadata in logs */\n verbose: z.boolean().default(true),\n});\n\n// ============================================================================\n// Migration Definition Schema\n// ============================================================================\n\n/**\n * Schema for MigrationDefinition\n * Validates migration definition objects used with defineMigrations()\n */\nexport const MigrationDefinitionSchema = z.object({\n /** Migration name - must be non-empty */\n name: z.string().min(1, 'Migration name is required'),\n /** Human-readable description shown during migration */\n description: z.string().optional(),\n /** Whether this is a breaking change - shows warning before execution */\n breaking: z.boolean().default(false),\n /** Tags for categorization (e.g., ['schema', 'data', 'index']) */\n tags: z.array(z.string()).default([]),\n /** Estimated duration as human-readable string (e.g., '30s', '2m') */\n estimatedDuration: z.string().optional(),\n});\n\n// ============================================================================\n// Migration Plugin Options Schema\n// ============================================================================\n\n/**\n * Schema for MigrationPluginOptions\n * Validates options passed to migration plugins\n */\nexport const MigrationPluginOptionsSchema = z.object({\n /** Optional logger for the plugin */\n logger: z.any().optional(),\n});\n\n// ============================================================================\n// Migration Plugin Schema\n// ============================================================================\n\n/**\n * Schema for MigrationPlugin\n * Validates migration plugin structure\n */\nexport const MigrationPluginSchema = z.object({\n /** Plugin name */\n name: z.string().min(1, 'Plugin name is required'),\n /** Plugin version */\n version: z.string().min(1, 'Plugin version is required'),\n /** Called once when the runner is initialized */\n onInit: z.any().optional(),\n /** Called before migration execution */\n beforeMigration: z.any().optional(),\n /** Called after successful migration execution */\n afterMigration: z.any().optional(),\n /** Called on migration error */\n onMigrationError: z.any().optional(),\n});\n\n// ============================================================================\n// Migration Status Schema\n// ============================================================================\n\n/**\n * Schema for MigrationStatus\n * Validates migration status results\n */\nexport const MigrationStatusSchema = z.object({\n /** List of executed migration names */\n executed: z.array(z.string()),\n /** List of pending migration names */\n pending: z.array(z.string()),\n /** Total migration count */\n total: z.number().int().nonnegative(),\n});\n\n// ============================================================================\n// Migration Result Schema\n// ============================================================================\n\n/**\n * Schema for MigrationResult\n * Validates results from migration runs\n */\nexport const MigrationResultSchema = z.object({\n /** Successfully executed migrations */\n executed: z.array(z.string()),\n /** Migrations that were skipped (already executed) */\n skipped: z.array(z.string()),\n /** Migrations that failed */\n failed: z.array(z.string()),\n /** Total duration in milliseconds */\n duration: z.number().nonnegative(),\n /** Whether the run was in dry-run mode */\n dryRun: z.boolean(),\n});\n\n// ============================================================================\n// Extended Runner Options Schema (with plugins)\n// ============================================================================\n\n/**\n * Schema for MigrationRunnerWithPluginsOptions\n * Extends MigrationRunnerOptionsSchema with plugin support\n */\nexport const MigrationRunnerWithPluginsOptionsSchema = MigrationRunnerOptionsSchema.extend({\n /** Plugins to apply */\n plugins: z.array(MigrationPluginSchema).optional(),\n});\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\n/** Input type for MigrationRunnerOptions - before defaults are applied */\nexport type MigrationRunnerOptionsInput = z.input<typeof MigrationRunnerOptionsSchema>;\n\n/** Output type for MigrationRunnerOptions - after defaults are applied */\nexport type MigrationRunnerOptionsOutput = z.output<typeof MigrationRunnerOptionsSchema>;\n\n/** Input type for MigrationDefinition - before defaults are applied */\nexport type MigrationDefinitionInput = z.input<typeof MigrationDefinitionSchema>;\n\n/** Output type for MigrationDefinition - after defaults are applied */\nexport type MigrationDefinitionOutput = z.output<typeof MigrationDefinitionSchema>;\n\n/** Input type for MigrationPluginOptions */\nexport type MigrationPluginOptionsInput = z.input<typeof MigrationPluginOptionsSchema>;\n\n/** Output type for MigrationPluginOptions */\nexport type MigrationPluginOptionsOutput = z.output<typeof MigrationPluginOptionsSchema>;\n\n/** Input type for MigrationPlugin */\nexport type MigrationPluginInput = z.input<typeof MigrationPluginSchema>;\n\n/** Output type for MigrationPlugin */\nexport type MigrationPluginOutput = z.output<typeof MigrationPluginSchema>;\n\n/** Type for MigrationStatus */\nexport type MigrationStatusType = z.infer<typeof MigrationStatusSchema>;\n\n/** Type for MigrationResult */\nexport type MigrationResultType = z.infer<typeof MigrationResultSchema>;\n\n/** Input type for MigrationRunnerWithPluginsOptions */\nexport type MigrationRunnerWithPluginsOptionsInput = z.input<typeof MigrationRunnerWithPluginsOptionsSchema>;\n\n/** Output type for MigrationRunnerWithPluginsOptions */\nexport type MigrationRunnerWithPluginsOptionsOutput = z.output<typeof MigrationRunnerWithPluginsOptionsSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\n/**\n * Validate and parse MigrationRunnerOptions with defaults\n */\nexport function parseMigrationRunnerOptions(\n options: unknown\n): MigrationRunnerOptionsOutput {\n return MigrationRunnerOptionsSchema.parse(options);\n}\n\n/**\n * Safely validate MigrationRunnerOptions without throwing\n * Returns result with success boolean and either data or error\n */\nexport function safeParseMigrationRunnerOptions(options: unknown) {\n return MigrationRunnerOptionsSchema.safeParse(options);\n}\n\n/**\n * Validate and parse MigrationDefinition with defaults\n */\nexport function parseMigrationDefinition(\n definition: unknown\n): MigrationDefinitionOutput {\n return MigrationDefinitionSchema.parse(definition);\n}\n\n/**\n * Safely validate MigrationDefinition without throwing\n * Returns result with success boolean and either data or error\n */\nexport function safeParseMigrationDefinition(definition: unknown) {\n return MigrationDefinitionSchema.safeParse(definition);\n}\n","import type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport type { KyseraLogger } from '@kysera/core';\nimport { DatabaseError, NotFoundError, BadRequestError, silentLogger } from '@kysera/core';\n\n// ============================================================================\n// Schema Exports\n// ============================================================================\n\nexport {\n // Schemas\n MigrationRunnerOptionsSchema,\n MigrationDefinitionSchema,\n MigrationPluginOptionsSchema,\n MigrationPluginSchema,\n MigrationStatusSchema,\n MigrationResultSchema,\n MigrationRunnerWithPluginsOptionsSchema,\n // Type exports\n type MigrationRunnerOptionsInput,\n type MigrationRunnerOptionsOutput,\n type MigrationDefinitionInput,\n type MigrationDefinitionOutput,\n type MigrationPluginOptionsInput,\n type MigrationPluginOptionsOutput,\n type MigrationPluginInput,\n type MigrationPluginOutput,\n type MigrationStatusType,\n type MigrationResultType,\n type MigrationRunnerWithPluginsOptionsInput,\n type MigrationRunnerWithPluginsOptionsOutput,\n // Validation helpers\n parseMigrationRunnerOptions,\n safeParseMigrationRunnerOptions,\n parseMigrationDefinition,\n safeParseMigrationDefinition,\n} from './schemas.js';\n\nimport { MigrationRunnerOptionsSchema } from './schemas.js';\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\n/**\n * Migration interface - the core building block\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport interface Migration<DB = unknown> {\n /** Unique migration name (e.g., '001_create_users') */\n name: string;\n /** Migration up function - creates/modifies schema */\n up: (db: Kysely<DB>) => Promise<void>;\n /** Optional migration down function - reverts changes */\n down?: (db: Kysely<DB>) => Promise<void>;\n}\n\n/**\n * Migration with metadata for enhanced logging and tracking\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport interface MigrationWithMeta<DB = unknown> extends Migration<DB> {\n /** Human-readable description shown during migration */\n description?: string;\n /** Whether this is a breaking change - shows warning before execution */\n breaking?: boolean;\n /** Estimated duration in milliseconds for progress indication */\n estimatedDuration?: number;\n /** Tags for categorization (e.g., ['schema', 'data', 'index']) */\n tags?: string[];\n}\n\n/**\n * Migration status result\n */\nexport interface MigrationStatus {\n /** List of executed migration names */\n executed: string[];\n /** List of pending migration names */\n pending: string[];\n /** Total migration count */\n total: number;\n}\n\n/**\n * Migration runner options\n */\nexport interface MigrationRunnerOptions {\n /** Enable dry run mode (preview only, no changes) */\n dryRun?: boolean;\n /**\n * Logger for migration operations.\n * Uses KyseraLogger interface from @kysera/core.\n *\n * @default silentLogger (no output)\n */\n logger?: KyseraLogger;\n /** Wrap each migration in a transaction (default: false) */\n useTransactions?: boolean;\n /** Stop on first error (default: true) */\n stopOnError?: boolean;\n /** Show detailed metadata in logs (default: true) */\n verbose?: boolean;\n}\n\n/**\n * Object-based migration definition for Level 2 DX\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport interface MigrationDefinition<DB = unknown> {\n up: (db: Kysely<DB>) => Promise<void>;\n down?: (db: Kysely<DB>) => Promise<void>;\n description?: string;\n breaking?: boolean;\n estimatedDuration?: number;\n tags?: string[];\n}\n\n/**\n * Migration definitions map for defineMigrations()\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport type MigrationDefinitions<DB = unknown> = Record<string, MigrationDefinition<DB>>;\n\n/**\n * Result of a migration run\n */\nexport interface MigrationResult {\n /** Successfully executed migrations */\n executed: string[];\n /** Migrations that were skipped (already executed) */\n skipped: string[];\n /** Migrations that failed */\n failed: string[];\n /** Total duration in milliseconds */\n duration: number;\n /** Whether the run was in dry-run mode */\n dryRun: boolean;\n}\n\n// ============================================================================\n// Error Classes (extending @kysera/core)\n// ============================================================================\n\n/** Error codes for migration operations */\nexport type MigrationErrorCode = 'MIGRATION_UP_FAILED' | 'MIGRATION_DOWN_FAILED' | 'MIGRATION_VALIDATION_FAILED';\n\n/**\n * Migration-specific error extending DatabaseError from @kysera/core\n * Provides structured error information with code, migration context, and cause tracking\n */\nexport class MigrationError extends DatabaseError {\n public readonly migrationName: string;\n public readonly operation: 'up' | 'down';\n\n constructor(\n message: string,\n migrationName: string,\n operation: 'up' | 'down',\n cause?: Error\n ) {\n const code: MigrationErrorCode = operation === 'up' ? 'MIGRATION_UP_FAILED' : 'MIGRATION_DOWN_FAILED';\n super(message, code, migrationName);\n this.name = 'MigrationError';\n this.migrationName = migrationName;\n this.operation = operation;\n if (cause) {\n this.cause = cause;\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const causeError = this.cause instanceof Error ? this.cause : undefined;\n return {\n ...super.toJSON(),\n migrationName: this.migrationName,\n operation: this.operation,\n cause: causeError?.message,\n };\n }\n}\n\n// ============================================================================\n// Setup Functions\n// ============================================================================\n\n/**\n * Setup migrations table in database\n * Idempotent - safe to run multiple times\n * Uses Kysely<unknown> as migrations work with any database schema\n */\nexport async function setupMigrations(db: Kysely<unknown>): Promise<void> {\n await db.schema\n .createTable('migrations')\n .ifNotExists()\n .addColumn('name', 'varchar(255)', (col) => col.primaryKey())\n .addColumn('executed_at', 'timestamp', (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`))\n .execute();\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if migration has metadata\n * Type guard to narrow Migration<DB> to MigrationWithMeta<DB>\n */\nfunction hasMeta<DB>(migration: Migration<DB>): migration is MigrationWithMeta<DB> {\n return 'description' in migration || 'breaking' in migration || 'tags' in migration;\n}\n\n/**\n * Format error message for logging\n */\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\n/**\n * Validate migrations for duplicate names\n * @throws {BadRequestError} When duplicate migration names are found\n */\nfunction validateMigrations<DB>(migrations: Migration<DB>[]): void {\n const names = new Set<string>();\n for (const migration of migrations) {\n if (names.has(migration.name)) {\n throw new BadRequestError(`Duplicate migration name: ${migration.name}`);\n }\n names.add(migration.name);\n }\n}\n\n// ============================================================================\n// Migration Runner Class\n// ============================================================================\n\n/**\n * Migration runner with state tracking and metadata support\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport class MigrationRunner<DB = unknown> {\n private logger: KyseraLogger;\n private options: Required<Omit<MigrationRunnerOptions, 'logger'>> & { logger: KyseraLogger };\n\n constructor(\n private db: Kysely<DB>,\n private migrations: Migration<DB>[],\n options: MigrationRunnerOptions = {}\n ) {\n // Validate and apply defaults using Zod schema\n const parsed = MigrationRunnerOptionsSchema.safeParse(options);\n if (!parsed.success) {\n throw new BadRequestError(`Invalid migration runner options: ${parsed.error.message}`);\n }\n\n this.logger = options.logger ?? silentLogger;\n this.options = {\n dryRun: parsed.data.dryRun,\n logger: this.logger,\n useTransactions: parsed.data.useTransactions,\n stopOnError: parsed.data.stopOnError,\n verbose: parsed.data.verbose,\n };\n\n // Validate migrations on construction\n validateMigrations(migrations);\n }\n\n /**\n * Get list of executed migrations from database\n * Note: Uses type assertions for migrations table as it's not part of the user schema\n */\n async getExecutedMigrations(): Promise<string[]> {\n // Cast to any for migrations table operations - it's internal and not part of user schema\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setupMigrations(this.db as any);\n\n // The migrations table is internal and not part of the generic DB schema\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const rows = await (this.db as any)\n .selectFrom('migrations')\n .select('name')\n .orderBy('executed_at', 'asc')\n .execute() as Array<{ name: string }>;\n\n return rows.map((r) => r.name);\n }\n\n /**\n * Mark a migration as executed\n * Note: Uses type assertions for migrations table as it's not part of the user schema\n */\n async markAsExecuted(name: string): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await (this.db as any)\n .insertInto('migrations')\n .values({ name })\n .execute();\n }\n\n /**\n * Mark a migration as rolled back (remove from executed list)\n * Note: Uses type assertions for migrations table as it's not part of the user schema\n */\n async markAsRolledBack(name: string): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await (this.db as any)\n .deleteFrom('migrations')\n .where('name', '=', name)\n .execute();\n }\n\n /**\n * Log migration metadata if available\n */\n private logMigrationMeta(migration: Migration<DB>): void {\n if (!this.options.verbose || !hasMeta(migration)) return;\n\n const meta = migration;\n\n if (meta.description) {\n this.logger.info(` Description: ${meta.description}`);\n }\n\n if (meta.breaking) {\n this.logger.warn(` BREAKING CHANGE - Review carefully before proceeding`);\n }\n\n if (meta.tags && meta.tags.length > 0) {\n this.logger.info(` Tags: ${meta.tags.join(', ')}`);\n }\n\n if (meta.estimatedDuration) {\n const seconds = (meta.estimatedDuration / 1000).toFixed(1);\n this.logger.info(` Estimated: ${seconds}s`);\n }\n }\n\n /**\n * Execute a single migration with optional transaction wrapping\n */\n private async executeMigration(\n migration: Migration<DB>,\n operation: 'up' | 'down'\n ): Promise<void> {\n const fn = operation === 'up' ? migration.up : migration.down;\n if (!fn) return;\n\n if (this.options.useTransactions) {\n await this.db.transaction().execute(async (trx) => {\n await fn(trx);\n });\n } else {\n await fn(this.db);\n }\n }\n\n /**\n * Run all pending migrations\n */\n async up(): Promise<MigrationResult> {\n const startTime = Date.now();\n const result: MigrationResult = {\n executed: [],\n skipped: [],\n failed: [],\n duration: 0,\n dryRun: this.options.dryRun,\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setupMigrations(this.db as any);\n const executed = await this.getExecutedMigrations();\n\n const pending = this.migrations.filter((m) => !executed.includes(m.name));\n\n if (pending.length === 0) {\n this.logger.info('No pending migrations');\n result.skipped = executed;\n result.duration = Date.now() - startTime;\n return result;\n }\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - No changes will be made');\n }\n\n for (const migration of this.migrations) {\n if (executed.includes(migration.name)) {\n this.logger.info(`${migration.name} (already executed)`);\n result.skipped.push(migration.name);\n continue;\n }\n\n try {\n this.logger.info(`Running ${migration.name}...`);\n this.logMigrationMeta(migration);\n\n if (!this.options.dryRun) {\n await this.executeMigration(migration, 'up');\n await this.markAsExecuted(migration.name);\n }\n\n this.logger.info(`${migration.name} completed`);\n result.executed.push(migration.name);\n } catch (error) {\n const errorMsg = formatError(error);\n this.logger.error(`${migration.name} failed: ${errorMsg}`);\n result.failed.push(migration.name);\n\n if (this.options.stopOnError) {\n throw new MigrationError(\n `Migration ${migration.name} failed: ${errorMsg}`,\n migration.name,\n 'up',\n error instanceof Error ? error : undefined\n );\n }\n }\n }\n\n if (!this.options.dryRun) {\n this.logger.info('All migrations completed successfully');\n } else {\n this.logger.info('Dry run completed - no changes made');\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n\n /**\n * Rollback last N migrations\n */\n async down(steps = 1): Promise<MigrationResult> {\n const startTime = Date.now();\n const result: MigrationResult = {\n executed: [],\n skipped: [],\n failed: [],\n duration: 0,\n dryRun: this.options.dryRun,\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setupMigrations(this.db as any);\n const executed = await this.getExecutedMigrations();\n\n if (executed.length === 0) {\n this.logger.warn('No executed migrations to rollback');\n result.duration = Date.now() - startTime;\n return result;\n }\n\n const toRollback = executed.slice(-steps).reverse();\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - No changes will be made');\n }\n\n for (const name of toRollback) {\n const migration = this.migrations.find((m) => m.name === name);\n\n if (!migration) {\n this.logger.warn(`Migration ${name} not found in codebase`);\n result.skipped.push(name);\n continue;\n }\n\n if (!migration.down) {\n this.logger.warn(`Migration ${name} has no down method - skipping`);\n result.skipped.push(name);\n continue;\n }\n\n try {\n this.logger.info(`Rolling back ${name}...`);\n this.logMigrationMeta(migration);\n\n if (!this.options.dryRun) {\n await this.executeMigration(migration, 'down');\n await this.markAsRolledBack(name);\n }\n\n this.logger.info(`${name} rolled back`);\n result.executed.push(name);\n } catch (error) {\n const errorMsg = formatError(error);\n this.logger.error(`${name} rollback failed: ${errorMsg}`);\n result.failed.push(name);\n\n if (this.options.stopOnError) {\n throw new MigrationError(\n `Rollback of ${name} failed: ${errorMsg}`,\n name,\n 'down',\n error instanceof Error ? error : undefined\n );\n }\n }\n }\n\n if (!this.options.dryRun) {\n this.logger.info('Rollback completed successfully');\n } else {\n this.logger.info('Dry run completed - no changes made');\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n\n /**\n * Show migration status\n */\n async status(): Promise<MigrationStatus> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setupMigrations(this.db as any);\n const executed = await this.getExecutedMigrations();\n const pending = this.migrations.filter((m) => !executed.includes(m.name)).map((m) => m.name);\n\n this.logger.info('Migration Status:');\n this.logger.info(` Executed: ${executed.length}`);\n this.logger.info(` Pending: ${pending.length}`);\n this.logger.info(` Total: ${this.migrations.length}`);\n\n if (executed.length > 0) {\n this.logger.info('Executed migrations:');\n for (const name of executed) {\n const migration = this.migrations.find((m) => m.name === name);\n if (migration && hasMeta(migration) && (migration as MigrationWithMeta).description) {\n this.logger.info(` ${name} - ${(migration as MigrationWithMeta).description}`);\n } else {\n this.logger.info(` ${name}`);\n }\n }\n }\n\n if (pending.length > 0) {\n this.logger.info('Pending migrations:');\n for (const name of pending) {\n const migration = this.migrations.find((m) => m.name === name);\n if (migration && hasMeta(migration)) {\n const meta = migration as MigrationWithMeta;\n const suffix = meta.breaking ? ' BREAKING' : '';\n const desc = meta.description ? ` - ${meta.description}` : '';\n this.logger.info(` ${name}${desc}${suffix}`);\n } else {\n this.logger.info(` ${name}`);\n }\n }\n }\n\n return { executed, pending, total: this.migrations.length };\n }\n\n /**\n * Reset all migrations (dangerous!)\n * In dry run mode, shows what would be rolled back\n */\n async reset(): Promise<MigrationResult> {\n const startTime = Date.now();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setupMigrations(this.db as any);\n const executed = await this.getExecutedMigrations();\n\n if (executed.length === 0) {\n this.logger.warn('No migrations to reset');\n return {\n executed: [],\n skipped: [],\n failed: [],\n duration: Date.now() - startTime,\n dryRun: this.options.dryRun,\n };\n }\n\n this.logger.warn(`Resetting ${executed.length} migrations...`);\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - Would rollback the following migrations:');\n for (const name of [...executed].reverse()) {\n const migration = this.migrations.find((m) => m.name === name);\n if (!migration?.down) {\n this.logger.warn(` ${name} (no down method - would be skipped)`);\n } else {\n this.logger.info(` ${name}`);\n }\n }\n this.logger.info('Dry run completed - no changes made');\n return {\n executed: [],\n skipped: executed,\n failed: [],\n duration: Date.now() - startTime,\n dryRun: true,\n };\n }\n\n const result = await this.down(executed.length);\n this.logger.info('All migrations reset');\n return result;\n }\n\n /**\n * Run migrations up to a specific migration (inclusive)\n */\n async upTo(targetName: string): Promise<MigrationResult> {\n const startTime = Date.now();\n const result: MigrationResult = {\n executed: [],\n skipped: [],\n failed: [],\n duration: 0,\n dryRun: this.options.dryRun,\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setupMigrations(this.db as any);\n const executed = await this.getExecutedMigrations();\n\n const targetIndex = this.migrations.findIndex((m) => m.name === targetName);\n if (targetIndex === -1) {\n throw new NotFoundError('Migration', { name: targetName });\n }\n\n const migrationsToRun = this.migrations.slice(0, targetIndex + 1);\n\n if (this.options.dryRun) {\n this.logger.info('DRY RUN - No changes will be made');\n }\n\n for (const migration of migrationsToRun) {\n if (executed.includes(migration.name)) {\n this.logger.info(`${migration.name} (already executed)`);\n result.skipped.push(migration.name);\n continue;\n }\n\n try {\n this.logger.info(`Running ${migration.name}...`);\n this.logMigrationMeta(migration);\n\n if (!this.options.dryRun) {\n await this.executeMigration(migration, 'up');\n await this.markAsExecuted(migration.name);\n }\n\n this.logger.info(`${migration.name} completed`);\n result.executed.push(migration.name);\n } catch (error) {\n const errorMsg = formatError(error);\n this.logger.error(`${migration.name} failed: ${errorMsg}`);\n result.failed.push(migration.name);\n\n throw new MigrationError(\n `Migration ${migration.name} failed: ${errorMsg}`,\n migration.name,\n 'up',\n error instanceof Error ? error : undefined\n );\n }\n }\n\n if (!this.options.dryRun) {\n this.logger.info(`Migrated up to ${targetName}`);\n } else {\n this.logger.info(`Dry run completed - would migrate up to ${targetName}`);\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a migration runner instance\n * Options are validated using Zod schema\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport function createMigrationRunner<DB = unknown>(\n db: Kysely<DB>,\n migrations: Migration<DB>[],\n options?: MigrationRunnerOptions\n): MigrationRunner<DB> {\n return new MigrationRunner(db, migrations, options);\n}\n\n/**\n * Helper to create a simple migration\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport function createMigration<DB = unknown>(\n name: string,\n up: (db: Kysely<DB>) => Promise<void>,\n down?: (db: Kysely<DB>) => Promise<void>\n): Migration<DB> {\n const migration: Migration<DB> = { name, up };\n if (down !== undefined) {\n migration.down = down;\n }\n return migration;\n}\n\n/**\n * Helper to create a migration with metadata\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport function createMigrationWithMeta<DB = unknown>(\n name: string,\n options: {\n up: (db: Kysely<DB>) => Promise<void>;\n down?: (db: Kysely<DB>) => Promise<void>;\n description?: string;\n breaking?: boolean;\n estimatedDuration?: number;\n tags?: string[];\n }\n): MigrationWithMeta<DB> {\n const migration: MigrationWithMeta<DB> = {\n name,\n up: options.up,\n };\n if (options.down !== undefined) {\n migration.down = options.down;\n }\n if (options.description !== undefined) {\n migration.description = options.description;\n }\n if (options.breaking !== undefined) {\n migration.breaking = options.breaking;\n }\n if (options.estimatedDuration !== undefined) {\n migration.estimatedDuration = options.estimatedDuration;\n }\n if (options.tags !== undefined) {\n migration.tags = options.tags;\n }\n return migration;\n}\n\n// ============================================================================\n// Level 2: Developer Experience APIs\n// ============================================================================\n\n/**\n * Define migrations using an object-based syntax for cleaner code\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport function defineMigrations<DB = unknown>(definitions: MigrationDefinitions<DB>): MigrationWithMeta<DB>[] {\n return Object.entries(definitions).map(([name, def]) => {\n const migration: MigrationWithMeta<DB> = {\n name,\n up: def.up,\n };\n if (def.down !== undefined) {\n migration.down = def.down;\n }\n if (def.description !== undefined) {\n migration.description = def.description;\n }\n if (def.breaking !== undefined) {\n migration.breaking = def.breaking;\n }\n if (def.estimatedDuration !== undefined) {\n migration.estimatedDuration = def.estimatedDuration;\n }\n if (def.tags !== undefined) {\n migration.tags = def.tags;\n }\n return migration;\n });\n}\n\n/**\n * Run all pending migrations - one-liner convenience function\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport async function runMigrations<DB = unknown>(\n db: Kysely<DB>,\n migrations: Migration<DB>[],\n options?: MigrationRunnerOptions\n): Promise<MigrationResult> {\n const runner = new MigrationRunner(db, migrations, options);\n return runner.up();\n}\n\n/**\n * Rollback migrations - one-liner convenience function\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport async function rollbackMigrations<DB = unknown>(\n db: Kysely<DB>,\n migrations: Migration<DB>[],\n steps = 1,\n options?: MigrationRunnerOptions\n): Promise<MigrationResult> {\n const runner = new MigrationRunner(db, migrations, options);\n return runner.down(steps);\n}\n\n/**\n * Get migration status - one-liner convenience function\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport async function getMigrationStatus<DB = unknown>(\n db: Kysely<DB>,\n migrations: Migration<DB>[],\n options?: Pick<MigrationRunnerOptions, 'logger' | 'verbose'>\n): Promise<MigrationStatus> {\n const runner = new MigrationRunner(db, migrations, options);\n return runner.status();\n}\n\n// ============================================================================\n// Level 3: Ecosystem Integration\n// ============================================================================\n\n/**\n * Migration plugin interface - consistent with @kysera/repository Plugin\n * Provides lifecycle hooks for migration execution\n * Generic DB type allows type-safe plugins when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport interface MigrationPlugin<DB = unknown> {\n /** Plugin name */\n name: string;\n /** Plugin version */\n version: string;\n /** Called once when the runner is initialized (consistent with repository Plugin.onInit) */\n onInit?(runner: MigrationRunner<DB>): Promise<void> | void;\n /** Called before migration execution */\n beforeMigration?(migration: Migration<DB>, operation: 'up' | 'down'): Promise<void> | void;\n /** Called after successful migration execution */\n afterMigration?(migration: Migration<DB>, operation: 'up' | 'down', duration: number): Promise<void> | void;\n /** Called on migration error (unknown type for consistency with repository Plugin.onError) */\n onMigrationError?(migration: Migration<DB>, operation: 'up' | 'down', error: unknown): Promise<void> | void;\n}\n\n/**\n * Extended migration runner options with plugin support\n * Generic DB type allows type-safe plugins when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport interface MigrationRunnerWithPluginsOptions<DB = unknown> extends MigrationRunnerOptions {\n /** Plugins to apply */\n plugins?: MigrationPlugin<DB>[];\n}\n\n/**\n * Create a migration runner with plugin support\n * Async factory to properly initialize plugins (consistent with @kysera/repository createORM)\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport async function createMigrationRunnerWithPlugins<DB = unknown>(\n db: Kysely<DB>,\n migrations: Migration<DB>[],\n options?: MigrationRunnerWithPluginsOptions<DB>\n): Promise<MigrationRunnerWithPlugins<DB>> {\n const runner = new MigrationRunnerWithPlugins(db, migrations, options);\n\n // Initialize plugins (consistent with repository Plugin.onInit pattern)\n if (options?.plugins) {\n for (const plugin of options.plugins) {\n if (plugin.onInit) {\n const result = plugin.onInit(runner);\n if (result instanceof Promise) {\n await result;\n }\n }\n }\n }\n\n return runner;\n}\n\n/**\n * Extended migration runner with plugin support\n * Generic DB type allows type-safe migrations when schema is known,\n * defaults to unknown for maximum flexibility\n */\nexport class MigrationRunnerWithPlugins<DB = unknown> extends MigrationRunner<DB> {\n private plugins: MigrationPlugin<DB>[];\n\n constructor(\n db: Kysely<DB>,\n migrations: Migration<DB>[],\n options: MigrationRunnerWithPluginsOptions<DB> = {}\n ) {\n super(db, migrations, options);\n this.plugins = options.plugins ?? [];\n }\n\n /**\n * Execute plugin hooks before migration\n * Can be called by consumers extending this class\n */\n protected async runBeforeHooks(migration: Migration<DB>, operation: 'up' | 'down'): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.beforeMigration) {\n await plugin.beforeMigration(migration, operation);\n }\n }\n }\n\n /**\n * Execute plugin hooks after migration\n * Can be called by consumers extending this class\n */\n protected async runAfterHooks(\n migration: Migration<DB>,\n operation: 'up' | 'down',\n duration: number\n ): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.afterMigration) {\n await plugin.afterMigration(migration, operation, duration);\n }\n }\n }\n\n /**\n * Execute plugin hooks on error\n * Can be called by consumers extending this class\n */\n protected async runErrorHooks(\n migration: Migration<DB>,\n operation: 'up' | 'down',\n error: unknown\n ): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.onMigrationError) {\n await plugin.onMigrationError(migration, operation, error);\n }\n }\n }\n\n /**\n * Get the list of registered plugins\n */\n getPlugins(): MigrationPlugin<DB>[] {\n return [...this.plugins];\n }\n}\n\n// ============================================================================\n// Built-in Plugins\n// ============================================================================\n\n/**\n * Logging plugin - logs migration events with timing\n * Works with any DB type (generic plugin)\n */\nexport function createLoggingPlugin<DB = unknown>(\n logger: KyseraLogger = silentLogger\n): MigrationPlugin<DB> {\n return {\n name: '@kysera/migrations/logging',\n version: '0.5.1',\n beforeMigration(migration, operation) {\n logger.info(`Starting ${operation} for ${migration.name}`);\n },\n afterMigration(migration, operation, duration) {\n logger.info(`Completed ${operation} for ${migration.name} in ${duration}ms`);\n },\n onMigrationError(migration, operation, error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Error during ${operation} for ${migration.name}: ${message}`);\n },\n };\n}\n\n/**\n * Metrics plugin - collects migration metrics\n * Works with any DB type (generic plugin)\n */\nexport function createMetricsPlugin<DB = unknown>(): MigrationPlugin<DB> & {\n getMetrics(): { migrations: Array<{ name: string; operation: string; duration: number; success: boolean }> };\n} {\n const metrics: Array<{ name: string; operation: string; duration: number; success: boolean }> = [];\n\n return {\n name: '@kysera/migrations/metrics',\n version: '0.5.1',\n afterMigration(migration, operation, duration) {\n metrics.push({ name: migration.name, operation, duration, success: true });\n },\n onMigrationError(migration, operation) {\n metrics.push({ name: migration.name, operation, duration: 0, success: false });\n },\n getMetrics() {\n return { migrations: [...metrics] };\n },\n };\n}\n\n// ============================================================================\n// Re-exports from @kysera/core for convenience\n// ============================================================================\n\nexport { DatabaseError, NotFoundError, BadRequestError, silentLogger } from '@kysera/core';\nexport type { KyseraLogger } from '@kysera/core';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kysera/migrations",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Database migration management for Kysera ORM with dry-run support and flexible rollback capabilities",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "author": "Kysera Team",
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
- "@kysera/core": "0.5.1"
29
+ "@kysera/core": "0.6.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/better-sqlite3": "^7.6.13",