@sebspark/spanner-migrate 0.1.1 → 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.
- package/README.md +155 -49
- package/dist/{chunk-K5WX6ESL.mjs → chunk-SZDH364K.mjs} +94 -60
- package/dist/cli.js +254 -98
- package/dist/cli.mjs +160 -38
- package/dist/index.d.mts +13 -7
- package/dist/index.d.ts +13 -7
- package/dist/index.js +93 -59
- package/dist/index.mjs +1 -1
- package/package.json +14 -9
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
28
28
|
var import_node_path2 = require("path");
|
|
29
|
-
var
|
|
29
|
+
var import_prompts = require("@inquirer/prompts");
|
|
30
30
|
var import_yargs = __toESM(require("yargs"));
|
|
31
31
|
var import_helpers = require("yargs/helpers");
|
|
32
32
|
|
|
@@ -70,7 +70,7 @@ var applyDown = async (db) => {
|
|
|
70
70
|
json: true
|
|
71
71
|
};
|
|
72
72
|
const [rows] = await db.run(req);
|
|
73
|
-
const lastMigration = rows
|
|
73
|
+
const lastMigration = rows?.[0];
|
|
74
74
|
if (!lastMigration) {
|
|
75
75
|
throw new Error("No migrations found to roll back.");
|
|
76
76
|
}
|
|
@@ -102,12 +102,11 @@ var runScript = async (db, script) => {
|
|
|
102
102
|
}
|
|
103
103
|
for (const statement of statements) {
|
|
104
104
|
console.log(`Executing statement: ${statement}`);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
await db.updateSchema(sql);
|
|
105
|
+
if (isSchemaChange(statement)) {
|
|
106
|
+
await db.updateSchema(statement);
|
|
108
107
|
} else {
|
|
109
108
|
await db.runTransactionAsync(async (transaction) => {
|
|
110
|
-
await transaction.runUpdate(
|
|
109
|
+
await transaction.runUpdate(statement);
|
|
111
110
|
await transaction.commit();
|
|
112
111
|
});
|
|
113
112
|
}
|
|
@@ -133,12 +132,12 @@ var SQL_CREATE_TABLE_MIGRATIONS = `
|
|
|
133
132
|
down STRING(1024)
|
|
134
133
|
) PRIMARY KEY (id)
|
|
135
134
|
`;
|
|
136
|
-
var ensureMigrationTable = async (
|
|
137
|
-
const [rows] = await
|
|
135
|
+
var ensureMigrationTable = async (db) => {
|
|
136
|
+
const [rows] = await db.run(SQL_SELECT_TABLE_MIGRATIONS);
|
|
138
137
|
if (rows.length) return;
|
|
139
138
|
console.log("Creating migration table");
|
|
140
139
|
try {
|
|
141
|
-
await
|
|
140
|
+
await db.updateSchema(SQL_CREATE_TABLE_MIGRATIONS);
|
|
142
141
|
} catch (err) {
|
|
143
142
|
console.error("Failed to create migrations table");
|
|
144
143
|
throw err;
|
|
@@ -169,7 +168,7 @@ var import_node_path = require("path");
|
|
|
169
168
|
var getMigrationFiles = async (path) => {
|
|
170
169
|
try {
|
|
171
170
|
const files = await (0, import_promises.readdir)(path);
|
|
172
|
-
const migrationFileIds = files.filter((file) => file.endsWith(".
|
|
171
|
+
const migrationFileIds = files.filter((file) => file.endsWith(".sql")).map((file) => file.replace(/\.sql$/, ""));
|
|
173
172
|
return migrationFileIds;
|
|
174
173
|
} catch (error) {
|
|
175
174
|
throw new Error(
|
|
@@ -179,35 +178,39 @@ var getMigrationFiles = async (path) => {
|
|
|
179
178
|
};
|
|
180
179
|
var getMigration = async (path, id) => {
|
|
181
180
|
try {
|
|
182
|
-
const filePath = (0, import_node_path.resolve)(process.cwd(), (0, import_node_path.join)(path, `${id}.
|
|
181
|
+
const filePath = (0, import_node_path.resolve)(process.cwd(), (0, import_node_path.join)(path, `${id}.sql`));
|
|
183
182
|
try {
|
|
184
183
|
await (0, import_promises.access)(filePath);
|
|
185
184
|
} catch (err) {
|
|
186
185
|
throw new Error(`Migration file not found: ${filePath}`);
|
|
187
186
|
}
|
|
188
|
-
const
|
|
189
|
-
|
|
187
|
+
const migrationText = await (0, import_promises.readFile)(filePath, "utf8");
|
|
188
|
+
const up2 = getSql(migrationText, "up");
|
|
189
|
+
const down2 = getSql(migrationText, "down");
|
|
190
|
+
const description = getDescription(migrationText);
|
|
191
|
+
if (!up2 || !down2) {
|
|
190
192
|
throw new Error(
|
|
191
193
|
`Migration file ${filePath} does not export required scripts (up, down).`
|
|
192
194
|
);
|
|
193
195
|
}
|
|
194
|
-
return {
|
|
195
|
-
id,
|
|
196
|
-
description: id.split("_").slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
|
|
197
|
-
// Generate a human-readable description
|
|
198
|
-
up: migrationModule.up,
|
|
199
|
-
down: migrationModule.down
|
|
200
|
-
};
|
|
196
|
+
return { id, description, up: up2, down: down2 };
|
|
201
197
|
} catch (error) {
|
|
202
198
|
throw new Error(
|
|
203
199
|
`Failed to get migration ${id}: ${error.message}`
|
|
204
200
|
);
|
|
205
201
|
}
|
|
206
202
|
};
|
|
203
|
+
var getDescription = (text) => text?.match(/^--\s*Description:\s*(.+)$/m)?.[1]?.trim() || "";
|
|
204
|
+
var getSql = (text, direction) => {
|
|
205
|
+
const rx = {
|
|
206
|
+
up: /---- UP ----\n([\s\S]*?)\n---- DOWN ----/,
|
|
207
|
+
down: /---- DOWN ----\n([\s\S]*)$/
|
|
208
|
+
};
|
|
209
|
+
return text?.match(rx[direction])?.[1]?.replace(/--.*$/gm, "").trim();
|
|
210
|
+
};
|
|
207
211
|
var getNewMigrations = (applied, files) => {
|
|
208
212
|
const sortedFiles = files.sort();
|
|
209
213
|
for (let ix = 0; ix < applied.length; ix++) {
|
|
210
|
-
console.log(sortedFiles[ix], applied[ix].id);
|
|
211
214
|
if (sortedFiles[ix] !== applied[ix].id) {
|
|
212
215
|
throw new Error(
|
|
213
216
|
`Mismatch between applied migrations and files. Found '${sortedFiles[ix]}' but expected '${applied[ix].id}' at position ${ix}.`
|
|
@@ -215,25 +218,24 @@ var getNewMigrations = (applied, files) => {
|
|
|
215
218
|
}
|
|
216
219
|
}
|
|
217
220
|
const newMigrations = sortedFiles.slice(applied.length);
|
|
218
|
-
console.log(`Found ${newMigrations.length} new migrations.`);
|
|
219
221
|
return newMigrations;
|
|
220
222
|
};
|
|
221
223
|
var createMigration = async (path, description) => {
|
|
222
224
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
223
225
|
const compactTimestamp = timestamp.replace(/[-:.TZ]/g, "");
|
|
224
226
|
const parsedDescription = description.replace(/\s+/g, "_").toLowerCase();
|
|
225
|
-
const filename = `${compactTimestamp}_${parsedDescription}.
|
|
227
|
+
const filename = `${compactTimestamp}_${parsedDescription}.sql`;
|
|
226
228
|
const filePath = (0, import_node_path.join)(path, filename);
|
|
227
|
-
const template =
|
|
228
|
-
|
|
229
|
+
const template = `-- Created: ${timestamp}
|
|
230
|
+
-- Description: ${description}
|
|
231
|
+
|
|
232
|
+
---- UP ----
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
---- DOWN ----
|
|
229
237
|
|
|
230
|
-
export const up = \`
|
|
231
|
-
-- SQL for migrate up
|
|
232
|
-
\`
|
|
233
238
|
|
|
234
|
-
export const down = \`
|
|
235
|
-
-- SQL for migrate down
|
|
236
|
-
\`
|
|
237
239
|
`;
|
|
238
240
|
try {
|
|
239
241
|
await (0, import_promises.mkdir)(path, { recursive: true });
|
|
@@ -266,86 +268,116 @@ var init = async (config, configPath) => {
|
|
|
266
268
|
var create = async (config, description) => {
|
|
267
269
|
await createMigration(config.migrationsPath, description);
|
|
268
270
|
};
|
|
269
|
-
var up = async (config, max
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
271
|
+
var up = async (config, database, max) => {
|
|
272
|
+
if (max && !database) {
|
|
273
|
+
throw new Error("Max number of migrations requires specifying a database");
|
|
274
|
+
}
|
|
275
|
+
const databases = database ? [database] : config.instance.databases;
|
|
276
|
+
for (const databaseConfig of databases) {
|
|
277
|
+
const path = {
|
|
278
|
+
projectId: config.projectId,
|
|
279
|
+
instanceName: config.instance.name,
|
|
280
|
+
databaseName: databaseConfig.name
|
|
281
|
+
};
|
|
282
|
+
const db = getDb(path);
|
|
283
|
+
await ensureMigrationTable(db);
|
|
284
|
+
const appliedMigrations = await getAppliedMigrations(db);
|
|
285
|
+
const migrationFiles = await getMigrationFiles(
|
|
286
|
+
databaseConfig.migrationsPath
|
|
287
|
+
);
|
|
288
|
+
const newMigrations = getNewMigrations(appliedMigrations, migrationFiles);
|
|
289
|
+
console.log(`Found ${newMigrations.length} new migrations.`);
|
|
290
|
+
console.log(newMigrations.map((mig) => ` ${mig}`).join("\n"));
|
|
291
|
+
const newMigrationsToApply = max ? newMigrations.slice(0, max) : newMigrations;
|
|
292
|
+
for (const id of newMigrationsToApply) {
|
|
293
|
+
const migration = await getMigration(databaseConfig.migrationsPath, id);
|
|
294
|
+
await applyUp(db, migration);
|
|
295
|
+
}
|
|
280
296
|
}
|
|
281
297
|
};
|
|
282
|
-
var down = async (config) => {
|
|
283
|
-
const
|
|
298
|
+
var down = async (config, database) => {
|
|
299
|
+
const path = {
|
|
300
|
+
projectId: config.projectId,
|
|
301
|
+
instanceName: config.instance.name,
|
|
302
|
+
databaseName: database.name
|
|
303
|
+
};
|
|
304
|
+
const db = getDb(path);
|
|
284
305
|
await ensureMigrationTable(db);
|
|
285
306
|
await applyDown(db);
|
|
286
307
|
};
|
|
287
|
-
var status = async (config) => {
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
308
|
+
var status = async (config, databases) => {
|
|
309
|
+
const statuses = [];
|
|
310
|
+
for (const databaseConfig of databases || config.instance.databases) {
|
|
311
|
+
const path = {
|
|
312
|
+
projectId: config.projectId,
|
|
313
|
+
instanceName: config.instance.name,
|
|
314
|
+
databaseName: databaseConfig.name
|
|
315
|
+
};
|
|
316
|
+
const db = getDb(path);
|
|
317
|
+
await ensureMigrationTable(db);
|
|
318
|
+
const appliedMigrations = await getAppliedMigrations(db);
|
|
319
|
+
const migrationFiles = await getMigrationFiles(
|
|
320
|
+
databaseConfig.migrationsPath
|
|
321
|
+
);
|
|
322
|
+
const newMigrations = getNewMigrations(appliedMigrations, migrationFiles);
|
|
323
|
+
statuses.push(
|
|
324
|
+
[
|
|
325
|
+
`Migrations [${databaseConfig.name}]`,
|
|
326
|
+
"",
|
|
327
|
+
"Applied",
|
|
328
|
+
"--------------------------------------------------------------------------------",
|
|
329
|
+
`${appliedMigrations.map((m) => m.id).join("\n")}
|
|
299
330
|
`,
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
331
|
+
"New",
|
|
332
|
+
"--------------------------------------------------------------------------------",
|
|
333
|
+
`${newMigrations.join("\n")}
|
|
303
334
|
`
|
|
304
|
-
|
|
335
|
+
].join("\n")
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
return statuses.join("\n\n");
|
|
305
339
|
};
|
|
306
340
|
|
|
307
341
|
// src/cli.ts
|
|
308
342
|
var CONFIG_FILE = "./.spanner-migrate.config.json";
|
|
309
|
-
async function loadConfig() {
|
|
310
|
-
try {
|
|
311
|
-
const configContent = await import_promises2.default.readFile(CONFIG_FILE, "utf8");
|
|
312
|
-
return JSON.parse(configContent);
|
|
313
|
-
} catch {
|
|
314
|
-
console.error('Config file not found. Run "spanner-migrate init" first.');
|
|
315
|
-
process.exit(1);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
343
|
(0, import_yargs.default)((0, import_helpers.hideBin)(process.argv)).scriptName("spanner-migrate").usage("$0 <command>").command(
|
|
319
344
|
"init",
|
|
320
345
|
"Initialize a .spanner-migrate.config.json file",
|
|
321
346
|
async () => {
|
|
322
|
-
const
|
|
323
|
-
message: "Enter the path for your migrations",
|
|
324
|
-
required: true,
|
|
325
|
-
default: "./migrations"
|
|
326
|
-
});
|
|
327
|
-
const instanceName = await (0, import_input.default)({
|
|
347
|
+
const instanceName = await (0, import_prompts.input)({
|
|
328
348
|
message: "Enter Spanner instance name",
|
|
329
349
|
required: true
|
|
330
350
|
});
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
351
|
+
const databases = [
|
|
352
|
+
await getDatabaseConfig(true)
|
|
353
|
+
];
|
|
354
|
+
while (true) {
|
|
355
|
+
const dbConfig = await getDatabaseConfig(false);
|
|
356
|
+
if (!dbConfig) break;
|
|
357
|
+
databases.push(dbConfig);
|
|
358
|
+
}
|
|
359
|
+
const projectId = await (0, import_prompts.input)({
|
|
336
360
|
message: "Enter Google Cloud project name",
|
|
337
361
|
required: false
|
|
338
362
|
});
|
|
339
|
-
const config = {
|
|
363
|
+
const config = {
|
|
364
|
+
instance: {
|
|
365
|
+
name: instanceName,
|
|
366
|
+
databases
|
|
367
|
+
}
|
|
368
|
+
};
|
|
340
369
|
if (projectId) config.projectId = projectId;
|
|
341
370
|
await init(config, CONFIG_FILE);
|
|
342
|
-
console.log(`Configuration written to ${CONFIG_FILE}`);
|
|
343
371
|
}
|
|
344
372
|
).command(
|
|
345
373
|
"create <description ...>",
|
|
346
374
|
"Create a new migration file",
|
|
347
375
|
(yargs2) => {
|
|
348
|
-
yargs2.
|
|
376
|
+
yargs2.option("database", {
|
|
377
|
+
alias: "d",
|
|
378
|
+
type: "string",
|
|
379
|
+
describe: "Database name"
|
|
380
|
+
}).positional("description", {
|
|
349
381
|
type: "string",
|
|
350
382
|
describe: "Description of the migration",
|
|
351
383
|
demandOption: true
|
|
@@ -354,33 +386,157 @@ async function loadConfig() {
|
|
|
354
386
|
async (args) => {
|
|
355
387
|
const config = await loadConfig();
|
|
356
388
|
const fullDescription = args.description.join(" ");
|
|
357
|
-
|
|
389
|
+
let databaseConfig;
|
|
390
|
+
if (args.database) {
|
|
391
|
+
databaseConfig = config.instance.databases.find(
|
|
392
|
+
(db) => db.name === args.database
|
|
393
|
+
);
|
|
394
|
+
if (!databaseConfig) {
|
|
395
|
+
throw new Error(`Unknown database name "${args.database}"`);
|
|
396
|
+
}
|
|
397
|
+
} else {
|
|
398
|
+
if (config.instance.databases.length === 1) {
|
|
399
|
+
databaseConfig = config.instance.databases[0];
|
|
400
|
+
} else {
|
|
401
|
+
databaseConfig = await (0, import_prompts.select)({
|
|
402
|
+
message: "Select database",
|
|
403
|
+
choices: config.instance.databases.map((dbConfig) => ({
|
|
404
|
+
name: dbConfig.name,
|
|
405
|
+
value: dbConfig
|
|
406
|
+
}))
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (!databaseConfig) throw new Error("No database config found");
|
|
411
|
+
await create(databaseConfig, fullDescription);
|
|
358
412
|
console.log(
|
|
359
|
-
`Migration file created: '${(0, import_node_path2.join)(
|
|
413
|
+
`Migration file created: '${(0, import_node_path2.join)(databaseConfig.migrationsPath, args.description.join("_"))}.sql'`
|
|
360
414
|
);
|
|
361
415
|
}
|
|
362
416
|
).command(
|
|
363
417
|
"up",
|
|
364
418
|
"Apply migrations",
|
|
365
419
|
(yargs2) => {
|
|
366
|
-
yargs2.option("
|
|
420
|
+
yargs2.option("database", {
|
|
421
|
+
alias: "d",
|
|
422
|
+
type: "string",
|
|
423
|
+
describe: "Database name",
|
|
424
|
+
requiresArg: false
|
|
425
|
+
}).option("max", {
|
|
367
426
|
alias: "m",
|
|
368
427
|
type: "number",
|
|
369
|
-
describe: "Maximum number of migrations to apply",
|
|
370
|
-
|
|
428
|
+
describe: "Maximum number of migrations to apply (requires --database)",
|
|
429
|
+
requiresArg: false
|
|
371
430
|
});
|
|
372
431
|
},
|
|
373
432
|
async (args) => {
|
|
374
433
|
const config = await loadConfig();
|
|
375
|
-
|
|
434
|
+
if (args.max !== void 0) {
|
|
435
|
+
if (!args.database) {
|
|
436
|
+
throw new Error("The --max option requires a specified --database");
|
|
437
|
+
}
|
|
438
|
+
if (!Number.isInteger(args.max) || args.max <= 0) {
|
|
439
|
+
throw new Error("The --max option must be an integer greater than 0");
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (args.database) {
|
|
443
|
+
const databaseConfig = config.instance.databases.find(
|
|
444
|
+
(db) => db.name === args.database
|
|
445
|
+
);
|
|
446
|
+
if (!databaseConfig) {
|
|
447
|
+
throw new Error(`Unknown database name "${args.database}"`);
|
|
448
|
+
}
|
|
449
|
+
if (args.max !== void 0) {
|
|
450
|
+
await up(config, databaseConfig, args.max);
|
|
451
|
+
} else {
|
|
452
|
+
await up(config, databaseConfig);
|
|
453
|
+
}
|
|
454
|
+
} else {
|
|
455
|
+
await up(config);
|
|
456
|
+
}
|
|
376
457
|
console.log("Migrations applied successfully.");
|
|
377
458
|
}
|
|
378
|
-
).command(
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
})
|
|
459
|
+
).command(
|
|
460
|
+
"down",
|
|
461
|
+
"Roll back the last applied migration",
|
|
462
|
+
(yargs2) => {
|
|
463
|
+
yargs2.option("database", {
|
|
464
|
+
alias: "d",
|
|
465
|
+
type: "string",
|
|
466
|
+
describe: "Specify the database to roll back (required if multiple databases exist)"
|
|
467
|
+
});
|
|
468
|
+
},
|
|
469
|
+
async (args) => {
|
|
470
|
+
const config = await loadConfig();
|
|
471
|
+
let databaseConfig;
|
|
472
|
+
if (args.database) {
|
|
473
|
+
databaseConfig = config.instance.databases.find(
|
|
474
|
+
(dbConfig) => dbConfig.name === args.database
|
|
475
|
+
);
|
|
476
|
+
if (!databaseConfig) {
|
|
477
|
+
throw new Error(`Unknown database name "${args.database}"`);
|
|
478
|
+
}
|
|
479
|
+
} else if (config.instance.databases.length === 1) {
|
|
480
|
+
databaseConfig = config.instance.databases[0];
|
|
481
|
+
} else {
|
|
482
|
+
throw new Error(
|
|
483
|
+
"Multiple databases detected. Use --database to specify which one to roll back."
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
if (!databaseConfig) throw new Error("No database config found");
|
|
487
|
+
await down(config, databaseConfig);
|
|
488
|
+
console.log("Last migration rolled back successfully.");
|
|
489
|
+
}
|
|
490
|
+
).command(
|
|
491
|
+
"status",
|
|
492
|
+
"Show the migration status",
|
|
493
|
+
(yargs2) => {
|
|
494
|
+
yargs2.option("database", {
|
|
495
|
+
alias: "d",
|
|
496
|
+
type: "string",
|
|
497
|
+
describe: "Specify a database to check status (optional, runs on all databases if omitted)"
|
|
498
|
+
});
|
|
499
|
+
},
|
|
500
|
+
async (args) => {
|
|
501
|
+
const config = await loadConfig();
|
|
502
|
+
let migrationStatus;
|
|
503
|
+
if (args.database) {
|
|
504
|
+
const databaseConfig = config.instance.databases.find(
|
|
505
|
+
(db) => db.name === args.database
|
|
506
|
+
);
|
|
507
|
+
if (!databaseConfig) {
|
|
508
|
+
throw new Error(`Unknown database name "${args.database}"`);
|
|
509
|
+
}
|
|
510
|
+
migrationStatus = await status(config, [databaseConfig]);
|
|
511
|
+
} else {
|
|
512
|
+
migrationStatus = await status(config);
|
|
513
|
+
}
|
|
514
|
+
console.log(migrationStatus);
|
|
515
|
+
}
|
|
516
|
+
).demandCommand().help().parse();
|
|
517
|
+
async function loadConfig() {
|
|
518
|
+
try {
|
|
519
|
+
const configContent = await import_promises2.default.readFile(CONFIG_FILE, "utf8");
|
|
520
|
+
return JSON.parse(configContent);
|
|
521
|
+
} catch {
|
|
522
|
+
console.error('Config file not found. Run "spanner-migrate init" first.');
|
|
523
|
+
process.exit(1);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
var getDatabaseConfig = async (required) => {
|
|
527
|
+
const message = required ? "Enter Spanner database name" : "Enter another Spanner database name [Enter to continue]";
|
|
528
|
+
const name = await (0, import_prompts.input)({
|
|
529
|
+
message,
|
|
530
|
+
required
|
|
531
|
+
});
|
|
532
|
+
if (!name) return;
|
|
533
|
+
const migrationsPath = await (0, import_prompts.input)({
|
|
534
|
+
message: "Enter the path for your migrations",
|
|
535
|
+
required: true,
|
|
536
|
+
default: `./migrations/${name}`
|
|
537
|
+
});
|
|
538
|
+
return {
|
|
539
|
+
name,
|
|
540
|
+
migrationsPath
|
|
541
|
+
};
|
|
542
|
+
};
|