@kysera/migrations 0.3.0 ā 0.4.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 +1409 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import {sql}from'kysely';async function a(r){await r.schema.createTable("migrati
|
|
|
6
6
|
`);for(let o of t){let n=this.migrations.find(s=>s.name===o);if(!n){this.logger(`\u26A0\uFE0F Migration ${o} not found in codebase`);continue}if(!n.down){this.logger(`\u26A0\uFE0F Migration ${o} has no down method`);continue}try{this.logger(`\u2193 Rolling back ${o}...`),this.options.dryRun||(await n.down(this.db),await this.markAsRolledBack(o)),this.logger(`\u2713 ${o} rolled back`);}catch(s){throw this.logger(`\u2717 ${o} rollback failed: ${s}`),s}}this.options.dryRun||this.logger(`
|
|
7
7
|
\u2705 Rollback completed successfully`);}async status(){await a(this.db);let i=await this.getExecutedMigrations(),e=this.migrations.filter(t=>!i.includes(t.name)).map(t=>t.name);return this.logger(`
|
|
8
8
|
\u{1F4CA} Migration Status:`),this.logger(` \u2705 Executed: ${i.length}`),this.logger(` \u23F3 Pending: ${e.length}`),i.length>0&&(this.logger(`
|
|
9
|
-
Executed migrations:`),i.forEach(t=>this.logger(` \u2713 ${t}`))),e.length>0&&(this.logger(`
|
|
10
|
-
Pending migrations:`),e.forEach(t=>this.logger(` - ${t}`))),{executed:i,pending:e}}async reset(){if(this.options.dryRun){this.logger(`
|
|
9
|
+
Executed migrations:`),i.forEach(t=>{this.logger(` \u2713 ${t}`);})),e.length>0&&(this.logger(`
|
|
10
|
+
Pending migrations:`),e.forEach(t=>{this.logger(` - ${t}`);})),{executed:i,pending:e}}async reset(){if(this.options.dryRun){this.logger(`
|
|
11
11
|
\u{1F50D} DRY RUN - Would rollback all migrations`);return}let i=await this.getExecutedMigrations();this.logger(`
|
|
12
12
|
\u26A0\uFE0F Resetting ${i.length} migrations...`),await this.down(i.length),this.logger(`
|
|
13
13
|
\u2705 All migrations reset`);}async upTo(i){await a(this.db);let e=await this.getExecutedMigrations(),t=this.migrations.findIndex(n=>n.name===i);if(t===-1)throw new Error(`Migration ${i} not found`);let o=this.migrations.slice(0,t+1);for(let n of o){if(e.includes(n.name)){this.logger(`\u2713 ${n.name} (already executed)`);continue}try{this.logger(`\u2191 Running ${n.name}...`),this.options.dryRun||(await n.up(this.db),await this.markAsExecuted(n.name)),this.logger(`\u2713 ${n.name} completed`);}catch(s){throw this.logger(`\u2717 ${n.name} failed: ${s}`),s}}this.logger(`
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["setupMigrations","db","col","sql","MigrationRunner","migrations","options","r","name","executed","m","migration","error","steps","toRollback","pending","targetName","targetIndex","migrationsToRun","createMigrationRunner","createMigration","up","down"],"mappings":"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","file":"index.js","sourcesContent":["import type { Kysely } from 'kysely'\nimport { sql } from 'kysely'\n\n/**\n * Migration interface\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 metadata for tracking purposes\n */\nexport interface MigrationWithMeta extends Migration {\n /** Human-readable description */\n description?: string\n /** Whether this is a breaking change */\n breaking?: boolean\n /** Estimated duration in milliseconds */\n estimatedDuration?: number\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}\n\n/**\n * Migration runner options\n */\nexport interface MigrationRunnerOptions {\n /** Enable dry run mode (don't execute, just show what would run) */\n dryRun?: boolean\n /** Logger function */\n logger?: (message: string) => void\n}\n\n/**\n * Setup migrations table in database\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 =>\n col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)\n )\n .execute()\n}\n\n/**\n * Migration runner with state tracking\n */\nexport class MigrationRunner {\n private logger: (message: string) => void\n\n constructor(\n private db: Kysely<any>,\n private migrations: Migration[],\n private options: MigrationRunnerOptions = {}\n ) {\n this.logger = options.logger || console.log\n }\n\n /**\n * Get list of executed migrations from database\n */\n async getExecutedMigrations(): Promise<string[]> {\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 * Run all pending migrations\n */\n async up(): Promise<void> {\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('ā
No pending migrations')\n return\n }\n\n if (this.options.dryRun) {\n this.logger('\\nš DRY RUN - No changes will be made\\n')\n }\n\n for (const migration of this.migrations) {\n if (executed.includes(migration.name)) {\n this.logger(`ā ${migration.name} (already executed)`)\n continue\n }\n\n try {\n this.logger(`ā Running ${migration.name}...`)\n\n if (!this.options.dryRun) {\n await migration.up(this.db)\n await this.markAsExecuted(migration.name)\n }\n\n this.logger(`ā ${migration.name} completed`)\n } catch (error) {\n this.logger(`ā ${migration.name} failed: ${error}`)\n throw error\n }\n }\n\n if (!this.options.dryRun) {\n this.logger('\\nā
All migrations completed successfully')\n }\n }\n\n /**\n * Rollback last N migrations\n */\n async down(steps = 1): Promise<void> {\n const executed = await this.getExecutedMigrations()\n\n if (executed.length === 0) {\n this.logger('ā ļø No executed migrations to rollback')\n return\n }\n\n const toRollback = executed.slice(-steps).reverse()\n\n if (this.options.dryRun) {\n this.logger('\\nš DRY RUN - No changes will be made\\n')\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(`ā ļø Migration ${name} not found in codebase`)\n continue\n }\n\n if (!migration.down) {\n this.logger(`ā ļø Migration ${name} has no down method`)\n continue\n }\n\n try {\n this.logger(`ā Rolling back ${name}...`)\n\n if (!this.options.dryRun) {\n await migration.down(this.db)\n await this.markAsRolledBack(name)\n }\n\n this.logger(`ā ${name} rolled back`)\n } catch (error) {\n this.logger(`ā ${name} rollback failed: ${error}`)\n throw error\n }\n }\n\n if (!this.options.dryRun) {\n this.logger('\\nā
Rollback completed successfully')\n }\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\n .filter(m => !executed.includes(m.name))\n .map(m => m.name)\n\n this.logger('\\nš Migration Status:')\n this.logger(` ā
Executed: ${executed.length}`)\n this.logger(` ā³ Pending: ${pending.length}`)\n\n if (executed.length > 0) {\n this.logger('\\nExecuted migrations:')\n executed.forEach(name => this.logger(` ā ${name}`))\n }\n\n if (pending.length > 0) {\n this.logger('\\nPending migrations:')\n pending.forEach(name => this.logger(` - ${name}`))\n }\n\n return { executed, pending }\n }\n\n /**\n * Reset all migrations (dangerous!)\n */\n async reset(): Promise<void> {\n if (this.options.dryRun) {\n this.logger('\\nš DRY RUN - Would rollback all migrations')\n return\n }\n\n const executed = await this.getExecutedMigrations()\n this.logger(`\\nā ļø Resetting ${executed.length} migrations...`)\n\n await this.down(executed.length)\n this.logger('\\nā
All migrations reset')\n }\n\n /**\n * Run migrations up to a specific migration (inclusive)\n */\n async upTo(targetName: string): Promise<void> {\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 Error(`Migration ${targetName} not found`)\n }\n\n const migrationsToRun = this.migrations.slice(0, targetIndex + 1)\n\n for (const migration of migrationsToRun) {\n if (executed.includes(migration.name)) {\n this.logger(`ā ${migration.name} (already executed)`)\n continue\n }\n\n try {\n this.logger(`ā Running ${migration.name}...`)\n\n if (!this.options.dryRun) {\n await migration.up(this.db)\n await this.markAsExecuted(migration.name)\n }\n\n this.logger(`ā ${migration.name} completed`)\n } catch (error) {\n this.logger(`ā ${migration.name} failed: ${error}`)\n throw error\n }\n }\n\n this.logger(`\\nā
Migrated up to ${targetName}`)\n }\n}\n\n/**\n * Create a migration runner instance\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}"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["setupMigrations","db","col","sql","MigrationRunner","migrations","options","r","name","executed","m","migration","error","steps","toRollback","pending","targetName","targetIndex","migrationsToRun","createMigrationRunner","createMigration","up","down"],"mappings":"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","file":"index.js","sourcesContent":["import type { Kysely } from 'kysely'\nimport { sql } from 'kysely'\n\n/**\n * Migration interface\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 metadata for tracking purposes\n */\nexport interface MigrationWithMeta extends Migration {\n /** Human-readable description */\n description?: string\n /** Whether this is a breaking change */\n breaking?: boolean\n /** Estimated duration in milliseconds */\n estimatedDuration?: number\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}\n\n/**\n * Migration runner options\n */\nexport interface MigrationRunnerOptions {\n /** Enable dry run mode (don't execute, just show what would run) */\n dryRun?: boolean\n /** Logger function */\n logger?: (message: string) => void\n}\n\n/**\n * Setup migrations table in database\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 =>\n col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)\n )\n .execute()\n}\n\n/**\n * Migration runner with state tracking\n */\nexport class MigrationRunner {\n private logger: (message: string) => void\n\n constructor(\n private db: Kysely<any>,\n private migrations: Migration[],\n private options: MigrationRunnerOptions = {}\n ) {\n this.logger = options.logger || console.log\n }\n\n /**\n * Get list of executed migrations from database\n */\n async getExecutedMigrations(): Promise<string[]> {\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 * Run all pending migrations\n */\n async up(): Promise<void> {\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('ā
No pending migrations')\n return\n }\n\n if (this.options.dryRun) {\n this.logger('\\nš DRY RUN - No changes will be made\\n')\n }\n\n for (const migration of this.migrations) {\n if (executed.includes(migration.name)) {\n this.logger(`ā ${migration.name} (already executed)`)\n continue\n }\n\n try {\n this.logger(`ā Running ${migration.name}...`)\n\n if (!this.options.dryRun) {\n await migration.up(this.db)\n await this.markAsExecuted(migration.name)\n }\n\n this.logger(`ā ${migration.name} completed`)\n } catch (error) {\n this.logger(`ā ${migration.name} failed: ${error}`)\n throw error\n }\n }\n\n if (!this.options.dryRun) {\n this.logger('\\nā
All migrations completed successfully')\n }\n }\n\n /**\n * Rollback last N migrations\n */\n async down(steps = 1): Promise<void> {\n const executed = await this.getExecutedMigrations()\n\n if (executed.length === 0) {\n this.logger('ā ļø No executed migrations to rollback')\n return\n }\n\n const toRollback = executed.slice(-steps).reverse()\n\n if (this.options.dryRun) {\n this.logger('\\nš DRY RUN - No changes will be made\\n')\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(`ā ļø Migration ${name} not found in codebase`)\n continue\n }\n\n if (!migration.down) {\n this.logger(`ā ļø Migration ${name} has no down method`)\n continue\n }\n\n try {\n this.logger(`ā Rolling back ${name}...`)\n\n if (!this.options.dryRun) {\n await migration.down(this.db)\n await this.markAsRolledBack(name)\n }\n\n this.logger(`ā ${name} rolled back`)\n } catch (error) {\n this.logger(`ā ${name} rollback failed: ${error}`)\n throw error\n }\n }\n\n if (!this.options.dryRun) {\n this.logger('\\nā
Rollback completed successfully')\n }\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\n .filter(m => !executed.includes(m.name))\n .map(m => m.name)\n\n this.logger('\\nš Migration Status:')\n this.logger(` ā
Executed: ${executed.length}`)\n this.logger(` ā³ Pending: ${pending.length}`)\n\n if (executed.length > 0) {\n this.logger('\\nExecuted migrations:')\n executed.forEach(name => { this.logger(` ā ${name}`); })\n }\n\n if (pending.length > 0) {\n this.logger('\\nPending migrations:')\n pending.forEach(name => { this.logger(` - ${name}`); })\n }\n\n return { executed, pending }\n }\n\n /**\n * Reset all migrations (dangerous!)\n */\n async reset(): Promise<void> {\n if (this.options.dryRun) {\n this.logger('\\nš DRY RUN - Would rollback all migrations')\n return\n }\n\n const executed = await this.getExecutedMigrations()\n this.logger(`\\nā ļø Resetting ${executed.length} migrations...`)\n\n await this.down(executed.length)\n this.logger('\\nā
All migrations reset')\n }\n\n /**\n * Run migrations up to a specific migration (inclusive)\n */\n async upTo(targetName: string): Promise<void> {\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 Error(`Migration ${targetName} not found`)\n }\n\n const migrationsToRun = this.migrations.slice(0, targetIndex + 1)\n\n for (const migration of migrationsToRun) {\n if (executed.includes(migration.name)) {\n this.logger(`ā ${migration.name} (already executed)`)\n continue\n }\n\n try {\n this.logger(`ā Running ${migration.name}...`)\n\n if (!this.options.dryRun) {\n await migration.up(this.db)\n await this.markAsExecuted(migration.name)\n }\n\n this.logger(`ā ${migration.name} completed`)\n } catch (error) {\n this.logger(`ā ${migration.name} failed: ${error}`)\n throw error\n }\n }\n\n this.logger(`\\nā
Migrated up to ${targetName}`)\n }\n}\n\n/**\n * Create a migration runner instance\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}"]}
|