@ftschopp/dynatable-migrations 1.0.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.
Files changed (73) hide show
  1. package/.gitkeep +0 -0
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +421 -0
  4. package/USAGE.md +557 -0
  5. package/bin/dynatable-migrate.js +30 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +104 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/create.d.ts +2 -0
  11. package/dist/commands/create.d.ts.map +1 -0
  12. package/dist/commands/create.js +123 -0
  13. package/dist/commands/create.js.map +1 -0
  14. package/dist/commands/down.d.ts +3 -0
  15. package/dist/commands/down.d.ts.map +1 -0
  16. package/dist/commands/down.js +37 -0
  17. package/dist/commands/down.js.map +1 -0
  18. package/dist/commands/init.d.ts +2 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +70 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/status.d.ts +3 -0
  23. package/dist/commands/status.d.ts.map +1 -0
  24. package/dist/commands/status.js +84 -0
  25. package/dist/commands/status.js.map +1 -0
  26. package/dist/commands/up.d.ts +3 -0
  27. package/dist/commands/up.d.ts.map +1 -0
  28. package/dist/commands/up.js +37 -0
  29. package/dist/commands/up.js.map +1 -0
  30. package/dist/core/config.d.ts +29 -0
  31. package/dist/core/config.d.ts.map +1 -0
  32. package/dist/core/config.js +160 -0
  33. package/dist/core/config.js.map +1 -0
  34. package/dist/core/loader.d.ts +47 -0
  35. package/dist/core/loader.d.ts.map +1 -0
  36. package/dist/core/loader.js +226 -0
  37. package/dist/core/loader.js.map +1 -0
  38. package/dist/core/runner.d.ts +38 -0
  39. package/dist/core/runner.d.ts.map +1 -0
  40. package/dist/core/runner.js +166 -0
  41. package/dist/core/runner.js.map +1 -0
  42. package/dist/core/tracker.d.ts +19 -0
  43. package/dist/core/tracker.d.ts.map +1 -0
  44. package/dist/core/tracker.js +172 -0
  45. package/dist/core/tracker.js.map +1 -0
  46. package/dist/index.d.ts +16 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +48 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/templates/migration.d.ts +5 -0
  51. package/dist/templates/migration.d.ts.map +1 -0
  52. package/dist/templates/migration.js +96 -0
  53. package/dist/templates/migration.js.map +1 -0
  54. package/dist/types/index.d.ts +159 -0
  55. package/dist/types/index.d.ts.map +1 -0
  56. package/dist/types/index.js +3 -0
  57. package/dist/types/index.js.map +1 -0
  58. package/migrations/.gitkeep +0 -0
  59. package/package.json +43 -0
  60. package/src/cli.ts +106 -0
  61. package/src/commands/create.ts +110 -0
  62. package/src/commands/down.ts +42 -0
  63. package/src/commands/init.ts +37 -0
  64. package/src/commands/status.ts +92 -0
  65. package/src/commands/up.ts +39 -0
  66. package/src/core/config.ts +140 -0
  67. package/src/core/loader.ts +233 -0
  68. package/src/core/runner.ts +223 -0
  69. package/src/core/tracker.ts +219 -0
  70. package/src/index.ts +23 -0
  71. package/src/templates/migration.ts +92 -0
  72. package/src/types/index.ts +196 -0
  73. package/tsconfig.json +19 -0
package/USAGE.md ADDED
@@ -0,0 +1,557 @@
1
+ # Usage Guide - @ftschopp/dynatable-migrations
2
+
3
+ ## Quick Start Guide
4
+
5
+ ### 1. Install in your project
6
+
7
+ ```bash
8
+ npm install @ftschopp/dynatable-migrations
9
+ # or
10
+ yarn add @ftschopp/dynatable-migrations
11
+ ```
12
+
13
+ ### 2. Initialize migrations
14
+
15
+ ```bash
16
+ npx dynatable-migrate init
17
+ ```
18
+
19
+ This creates:
20
+
21
+ - `migrations/` directory
22
+ - `dynatable.config.js` configuration file
23
+
24
+ ### 3. Configure DynamoDB connection
25
+
26
+ Edit `dynatable.config.js`:
27
+
28
+ **For Local DynamoDB:**
29
+
30
+ ```javascript
31
+ module.exports = {
32
+ tableName: 'MyTable',
33
+ client: {
34
+ region: 'us-east-1',
35
+ endpoint: 'http://localhost:8000',
36
+ credentials: {
37
+ accessKeyId: 'local',
38
+ secretAccessKey: 'local',
39
+ },
40
+ },
41
+ };
42
+ ```
43
+
44
+ **For AWS DynamoDB:**
45
+
46
+ ```javascript
47
+ module.exports = {
48
+ tableName: 'MyTable',
49
+ client: {
50
+ region: 'us-east-1',
51
+ // Uses AWS_PROFILE or IAM role automatically
52
+ },
53
+ };
54
+ ```
55
+
56
+ ### 4. Create your first migration
57
+
58
+ ```bash
59
+ npx dynatable-migrate create add_user_email
60
+ ```
61
+
62
+ Creates: `migrations/v0001_add_user_email.ts`
63
+
64
+ ### 5. Edit the migration
65
+
66
+ ```typescript
67
+ import { Migration } from '@ftschopp/dynatable-migrations';
68
+
69
+ export const migration: Migration = {
70
+ version: 'v0001',
71
+ name: 'add_user_email',
72
+
73
+ async up({ client, tableName, tracker }) {
74
+ // Your migration code here
75
+ },
76
+
77
+ async down({ client, tableName, dynamodb }) {
78
+ // Rollback code here
79
+ },
80
+ };
81
+ ```
82
+
83
+ ### 6. Run migrations
84
+
85
+ ```bash
86
+ # Check status first
87
+ npx dynatable-migrate status
88
+
89
+ # Apply all pending migrations
90
+ npx dynatable-migrate up
91
+
92
+ # Rollback last migration
93
+ npx dynatable-migrate down
94
+ ```
95
+
96
+ ## Common Migration Patterns
97
+
98
+ ### Pattern 1: Add Field to Existing Items
99
+
100
+ ```typescript
101
+ export const migration: Migration = {
102
+ version: 'v0001',
103
+ name: 'add_user_bio',
104
+
105
+ async up({ client, tableName }) {
106
+ const { ScanCommand, UpdateCommand } = dynamodb;
107
+
108
+ // Find all users
109
+ const result = await client.send(
110
+ new ScanCommand({
111
+ TableName: tableName,
112
+ FilterExpression: 'begins_with(PK, :pk)',
113
+ ExpressionAttributeValues: { ':pk': 'USER#' },
114
+ })
115
+ );
116
+
117
+ // Add bio field with default value
118
+ for (const user of result.Items || []) {
119
+ await client.send(
120
+ new UpdateCommand({
121
+ TableName: tableName,
122
+ Key: { PK: user.PK, SK: user.SK },
123
+ UpdateExpression: 'SET bio = :bio',
124
+ ExpressionAttributeValues: { ':bio': '' },
125
+ })
126
+ );
127
+ }
128
+ },
129
+
130
+ async down({ client, tableName, dynamodb }) {
131
+ // Remove the field
132
+ const { ScanCommand, UpdateCommand } = dynamodb;
133
+
134
+ const result = await client.send(
135
+ new ScanCommand({
136
+ TableName: tableName,
137
+ FilterExpression: 'begins_with(PK, :pk)',
138
+ ExpressionAttributeValues: { ':pk': 'USER#' },
139
+ })
140
+ );
141
+
142
+ for (const user of result.Items || []) {
143
+ await client.send(
144
+ new UpdateCommand({
145
+ TableName: tableName,
146
+ Key: { PK: user.PK, SK: user.SK },
147
+ UpdateExpression: 'REMOVE bio',
148
+ })
149
+ );
150
+ }
151
+ },
152
+ };
153
+ ```
154
+
155
+ ### Pattern 2: Transform Data
156
+
157
+ ```typescript
158
+ export const migration: Migration = {
159
+ version: 'v0002',
160
+ name: 'normalize_usernames',
161
+
162
+ async up({ client, tableName }) {
163
+ const { ScanCommand, UpdateCommand } = dynamodb;
164
+
165
+ const result = await client.send(
166
+ new ScanCommand({
167
+ TableName: tableName,
168
+ FilterExpression: 'begins_with(PK, :pk)',
169
+ ExpressionAttributeValues: { ':pk': 'USER#' },
170
+ })
171
+ );
172
+
173
+ for (const user of result.Items || []) {
174
+ const normalizedUsername = user.username.toLowerCase();
175
+
176
+ if (user.username !== normalizedUsername) {
177
+ await client.send(
178
+ new UpdateCommand({
179
+ TableName: tableName,
180
+ Key: { PK: user.PK, SK: user.SK },
181
+ UpdateExpression: 'SET username = :username',
182
+ ExpressionAttributeValues: { ':username': normalizedUsername },
183
+ })
184
+ );
185
+ }
186
+ }
187
+ },
188
+
189
+ async down({ client, tableName, dynamodb }) {
190
+ console.log('Cannot revert username normalization');
191
+ },
192
+ };
193
+ ```
194
+
195
+ ### Pattern 3: Change Key Structure (Advanced)
196
+
197
+ ```typescript
198
+ export const migration: Migration = {
199
+ version: 'v0003',
200
+ name: 'change_photo_sort_key',
201
+
202
+ async up({ client, tableName }) {
203
+ const { ScanCommand, TransactWriteCommand } = dynamodb;
204
+
205
+ const result = await client.send(
206
+ new ScanCommand({
207
+ TableName: tableName,
208
+ FilterExpression: 'begins_with(SK, :sk)',
209
+ ExpressionAttributeValues: { ':sk': 'PHOTO#' },
210
+ })
211
+ );
212
+
213
+ // Batch process to avoid rate limits
214
+ const batchSize = 25; // DynamoDB transaction limit
215
+ const items = result.Items || [];
216
+
217
+ for (let i = 0; i < items.length; i += batchSize) {
218
+ const batch = items.slice(i, i + batchSize);
219
+ const transactItems = [];
220
+
221
+ for (const photo of batch) {
222
+ const timestamp = new Date(photo.createdAt).getTime();
223
+ const photoId = photo.SK.replace('PHOTO#', '');
224
+
225
+ transactItems.push(
226
+ {
227
+ Delete: {
228
+ TableName: tableName,
229
+ Key: { PK: photo.PK, SK: photo.SK },
230
+ },
231
+ },
232
+ {
233
+ Put: {
234
+ TableName: tableName,
235
+ Item: {
236
+ ...photo,
237
+ SK: `PHOTO#${timestamp}#${photoId}`,
238
+ },
239
+ },
240
+ }
241
+ );
242
+ }
243
+
244
+ await client.send(
245
+ new TransactWriteCommand({
246
+ TransactItems: transactItems,
247
+ })
248
+ );
249
+ }
250
+ },
251
+
252
+ async down({ client, tableName, dynamodb }) {
253
+ // Similar logic but reverse
254
+ },
255
+ };
256
+ ```
257
+
258
+ ### Pattern 4: Add New Entity Type (No Data Migration)
259
+
260
+ ```typescript
261
+ export const migration: Migration = {
262
+ version: 'v0004',
263
+ name: 'add_notification_entity',
264
+
265
+ schema: {
266
+ Notification: {
267
+ key: {
268
+ PK: 'USER#${userId}',
269
+ SK: 'NOTIFICATION#${notificationId}',
270
+ },
271
+ attributes: {
272
+ userId: { type: String, required: true },
273
+ notificationId: { type: String, generate: 'ulid' },
274
+ message: { type: String, required: true },
275
+ read: { type: Boolean, default: false },
276
+ },
277
+ },
278
+ },
279
+
280
+ async up({ tracker }) {
281
+ // In Single Table Design, adding a new entity type
282
+ // doesn't require data migration, just schema documentation
283
+ await tracker.recordSchemaChange({
284
+ entity: 'Notification',
285
+ changes: {
286
+ added: ['userId', 'notificationId', 'message', 'read'],
287
+ },
288
+ });
289
+
290
+ console.log('✅ Notification entity added to schema');
291
+ },
292
+
293
+ async down({ client, tableName, dynamodb }) {
294
+ // Delete all notifications if rolling back
295
+ const { ScanCommand, DeleteCommand } = dynamodb;
296
+
297
+ const result = await client.send(
298
+ new ScanCommand({
299
+ TableName: tableName,
300
+ FilterExpression: 'begins_with(SK, :sk)',
301
+ ExpressionAttributeValues: { ':sk': 'NOTIFICATION#' },
302
+ })
303
+ );
304
+
305
+ for (const notification of result.Items || []) {
306
+ await client.send(
307
+ new DeleteCommand({
308
+ TableName: tableName,
309
+ Key: { PK: notification.PK, SK: notification.SK },
310
+ })
311
+ );
312
+ }
313
+ },
314
+ };
315
+ ```
316
+
317
+ ## CLI Commands Reference
318
+
319
+ ### `dynatable-migrate init`
320
+
321
+ Initialize migrations in current project.
322
+
323
+ ### `dynatable-migrate create <name>`
324
+
325
+ Create a new migration file.
326
+
327
+ **Options:**
328
+
329
+ - `-c, --config <path>` - Custom config file path
330
+
331
+ **Example:**
332
+
333
+ ```bash
334
+ dynatable-migrate create add_user_profile
335
+ ```
336
+
337
+ ### `dynatable-migrate up`
338
+
339
+ Run all pending migrations.
340
+
341
+ **Options:**
342
+
343
+ - `-c, --config <path>` - Custom config file path
344
+ - `-l, --limit <number>` - Limit migrations to run
345
+
346
+ **Examples:**
347
+
348
+ ```bash
349
+ # Run all pending
350
+ dynatable-migrate up
351
+
352
+ # Run only next migration
353
+ dynatable-migrate up --limit 1
354
+
355
+ # Use custom config
356
+ dynatable-migrate up --config ./my-config.js
357
+ ```
358
+
359
+ ### `dynatable-migrate down`
360
+
361
+ Rollback migrations.
362
+
363
+ **Options:**
364
+
365
+ - `-c, --config <path>` - Custom config file path
366
+ - `-s, --steps <number>` - Number of migrations to rollback (default: 1)
367
+
368
+ **Examples:**
369
+
370
+ ```bash
371
+ # Rollback last migration
372
+ dynatable-migrate down
373
+
374
+ # Rollback last 3 migrations
375
+ dynatable-migrate down --steps 3
376
+ ```
377
+
378
+ ### `dynatable-migrate status`
379
+
380
+ Show migration status.
381
+
382
+ **Example:**
383
+
384
+ ```bash
385
+ dynatable-migrate status
386
+ ```
387
+
388
+ **Output:**
389
+
390
+ ```
391
+ 📊 Migration Status
392
+
393
+ Table: InstagramClone
394
+ Current version: v0002
395
+ Migrations directory: ./migrations
396
+
397
+ ✅ Applied (2):
398
+ v0001 - add_user_email (2025-03-29 10:00:00)
399
+ v0002 - normalize_usernames (2025-03-29 11:00:00)
400
+
401
+ ⏳ Pending (1):
402
+ v0003 - change_photo_sort_key
403
+
404
+ Total: 3 migration(s)
405
+ ```
406
+
407
+ ## Integration with package.json
408
+
409
+ Add scripts to your `package.json`:
410
+
411
+ ```json
412
+ {
413
+ "scripts": {
414
+ "migrate": "dynatable-migrate",
415
+ "migrate:create": "dynatable-migrate create",
416
+ "migrate:up": "dynatable-migrate up",
417
+ "migrate:down": "dynatable-migrate down",
418
+ "migrate:status": "dynatable-migrate status"
419
+ }
420
+ }
421
+ ```
422
+
423
+ Then use:
424
+
425
+ ```bash
426
+ npm run migrate:status
427
+ npm run migrate:create add_feature
428
+ npm run migrate:up
429
+ npm run migrate:down
430
+ ```
431
+
432
+ ## Best Practices
433
+
434
+ ### 1. Always Write Down Functions
435
+
436
+ Even if you think you won't need to rollback, always implement the `down()` function.
437
+
438
+ ### 2. Test Locally First
439
+
440
+ Use DynamoDB Local to test migrations before running on production:
441
+
442
+ ```bash
443
+ docker run -p 8000:8000 amazon/dynamodb-local
444
+ ```
445
+
446
+ ### 3. Backup Before Running
447
+
448
+ Enable point-in-time recovery on your production tables.
449
+
450
+ ### 4. Keep Migrations Focused
451
+
452
+ One migration = one change. Don't combine multiple unrelated changes.
453
+
454
+ ### 5. Never Modify Applied Migrations
455
+
456
+ Once a migration is applied, don't change it. Create a new migration instead.
457
+
458
+ ### 6. Use Transactions for Atomic Operations
459
+
460
+ For multi-step changes that must succeed or fail together:
461
+
462
+ ```typescript
463
+ await client.send(new TransactWriteCommand({
464
+ TransactItems: [
465
+ { Put: { ... } },
466
+ { Update: { ... } },
467
+ { Delete: { ... } }
468
+ ]
469
+ }));
470
+ ```
471
+
472
+ ### 7. Handle Large Datasets Carefully
473
+
474
+ For tables with many items:
475
+
476
+ - Process in batches
477
+ - Add delays between batches to avoid throttling
478
+ - Consider using DynamoDB Streams for background processing
479
+
480
+ ### 8. Document Your Changes
481
+
482
+ Use the `schema` field to document what changed:
483
+
484
+ ```typescript
485
+ export const migration: Migration = {
486
+ schema: {
487
+ User: {
488
+ attributes: {
489
+ // ... document your schema here
490
+ },
491
+ },
492
+ },
493
+ // ...
494
+ };
495
+ ```
496
+
497
+ ## Troubleshooting
498
+
499
+ ### Migration Failed Mid-Execution
500
+
501
+ If a migration fails partway through:
502
+
503
+ 1. Check the error message
504
+ 2. Fix the issue manually in DynamoDB if needed
505
+ 3. Fix the migration code
506
+ 4. The migration will be marked as "failed" - you may need to manually update the status or create a fix migration
507
+
508
+ ### Can't Find Migration File
509
+
510
+ Make sure:
511
+
512
+ - Migration file follows naming convention: `v0001_name.ts`
513
+ - File is in the `migrationsDir` specified in config
514
+ - File exports a `migration` object
515
+
516
+ ### Permission Errors
517
+
518
+ Ensure your AWS credentials have permissions for:
519
+
520
+ - `dynamodb:Scan`
521
+ - `dynamodb:Query`
522
+ - `dynamodb:GetItem`
523
+ - `dynamodb:PutItem`
524
+ - `dynamodb:UpdateItem`
525
+ - `dynamodb:DeleteItem`
526
+
527
+ ## Advanced: Programmatic Usage
528
+
529
+ You can also use the migration runner in your code:
530
+
531
+ ```typescript
532
+ import { MigrationRunner, loadConfig } from '@ftschopp/dynatable-migrations';
533
+ import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
534
+ import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
535
+
536
+ async function runMigrations() {
537
+ const config = await loadConfig();
538
+
539
+ const ddbClient = new DynamoDBClient({
540
+ region: config.client.region,
541
+ endpoint: config.client.endpoint,
542
+ });
543
+
544
+ const client = DynamoDBDocumentClient.from(ddbClient);
545
+ const runner = new MigrationRunner(client, config);
546
+
547
+ // Get status
548
+ const status = await runner.status();
549
+ console.log('Migration status:', status);
550
+
551
+ // Run migrations
552
+ await runner.up();
553
+
554
+ // Rollback
555
+ await runner.down(1);
556
+ }
557
+ ```
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * DynamoDB Migration CLI
5
+ * Executable entry point
6
+ */
7
+
8
+ // Register ts-node for TypeScript support in development
9
+ const path = require('path');
10
+ const fs = require('fs');
11
+
12
+ // Check if we're running from source (development) or compiled (production)
13
+ const sourceFile = path.join(__dirname, '../src/cli.ts');
14
+ const compiledFile = path.join(__dirname, '../dist/cli.js');
15
+
16
+ if (fs.existsSync(compiledFile)) {
17
+ // Production: use compiled JavaScript
18
+ require(compiledFile);
19
+ } else if (fs.existsSync(sourceFile)) {
20
+ // Development: use ts-node to run TypeScript directly
21
+ require('ts-node').register({
22
+ project: path.join(__dirname, '../tsconfig.json'),
23
+ transpileOnly: true,
24
+ });
25
+ require(sourceFile);
26
+ } else {
27
+ console.error('Error: CLI files not found. Please build the project first.');
28
+ console.error('Run: npm run build');
29
+ process.exit(1);
30
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const config_1 = require("./core/config");
6
+ const create_1 = require("./commands/create");
7
+ const up_1 = require("./commands/up");
8
+ const down_1 = require("./commands/down");
9
+ const status_1 = require("./commands/status");
10
+ const init_1 = require("./commands/init");
11
+ const program = new commander_1.Command();
12
+ program
13
+ .name('dynatable-migrate')
14
+ .description('DynamoDB migration tool for single table design')
15
+ .version('0.1.0');
16
+ // Init command
17
+ program
18
+ .command('init')
19
+ .description('Initialize migrations in current project')
20
+ .action(async () => {
21
+ try {
22
+ await (0, init_1.initProject)();
23
+ }
24
+ catch (error) {
25
+ console.error(`Error: ${error.message}`);
26
+ process.exit(1);
27
+ }
28
+ });
29
+ // Create command
30
+ program
31
+ .command('create <name>')
32
+ .description('Create a new migration file')
33
+ .option('-c, --config <path>', 'Path to config file')
34
+ .option('-t, --type <type>', 'Version bump type: major, minor, or patch (default: patch)')
35
+ .option('-e, --explicit <version>', 'Explicit version (e.g., 2.0.0)')
36
+ .action(async (name, options) => {
37
+ try {
38
+ let migrationsDir = './migrations';
39
+ // Try to load config to get migrations directory
40
+ try {
41
+ const config = await (0, config_1.loadConfig)(options.config);
42
+ migrationsDir = config.migrationsDir || './migrations';
43
+ }
44
+ catch {
45
+ // If config doesn't exist, use default
46
+ }
47
+ await (0, create_1.createMigration)(name, migrationsDir, options.type, options.explicit);
48
+ }
49
+ catch (error) {
50
+ console.error(`Error: ${error.message}`);
51
+ process.exit(1);
52
+ }
53
+ });
54
+ // Up command
55
+ program
56
+ .command('up')
57
+ .description('Run pending migrations')
58
+ .option('-c, --config <path>', 'Path to config file')
59
+ .option('-l, --limit <number>', 'Limit number of migrations to run')
60
+ .action(async (options) => {
61
+ try {
62
+ const config = await (0, config_1.loadConfig)(options.config);
63
+ const limit = options.limit ? parseInt(options.limit, 10) : undefined;
64
+ await (0, up_1.runMigrations)(config, limit);
65
+ }
66
+ catch (error) {
67
+ console.error(`Error: ${error.message}`);
68
+ process.exit(1);
69
+ }
70
+ });
71
+ // Down command
72
+ program
73
+ .command('down')
74
+ .description('Rollback migrations')
75
+ .option('-c, --config <path>', 'Path to config file')
76
+ .option('-s, --steps <number>', 'Number of migrations to rollback', '1')
77
+ .action(async (options) => {
78
+ try {
79
+ const config = await (0, config_1.loadConfig)(options.config);
80
+ const steps = parseInt(options.steps, 10);
81
+ await (0, down_1.rollbackMigrations)(config, steps);
82
+ }
83
+ catch (error) {
84
+ console.error(`Error: ${error.message}`);
85
+ process.exit(1);
86
+ }
87
+ });
88
+ // Status command
89
+ program
90
+ .command('status')
91
+ .description('Show migration status')
92
+ .option('-c, --config <path>', 'Path to config file')
93
+ .action(async (options) => {
94
+ try {
95
+ const config = await (0, config_1.loadConfig)(options.config);
96
+ await (0, status_1.showStatus)(config);
97
+ }
98
+ catch (error) {
99
+ console.error(`Error: ${error.message}`);
100
+ process.exit(1);
101
+ }
102
+ });
103
+ program.parse(process.argv);
104
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function createMigration(name: string, migrationsDir?: string, bumpType?: string, explicitVersion?: string): Promise<void>;
2
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AA6CA,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,MAAuB,EACtC,QAAQ,CAAC,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CA2Df"}