rake-db 2.27.12 → 2.27.14

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/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import * as orchid_core from 'orchid-core';
2
- import { MaybeArray, RawSQLBase, ColumnDataCheckBase, RecordString, ColumnTypeBase, EmptyObject, ColumnSchemaConfig, QueryLogOptions, AdapterBase, MaybePromise, QueryLogObject, QueryBase } from 'orchid-core';
3
1
  import * as pqb from 'pqb';
4
2
  import { ColumnsShape, Db, TableData, NoPrimaryKeyOption, ColumnType, EnumColumn, DefaultColumnTypes, DefaultSchemaConfig, DbResult, TableDataFn, TableDataItem, DbDomainArg, raw, SearchWeight, ColumnsByType, DbStructureDomainsMap } from 'pqb';
3
+ import * as orchid_core from 'orchid-core';
4
+ import { MaybeArray, RawSQLBase, ColumnDataCheckBase, RecordString, ColumnTypeBase, EmptyObject, ColumnSchemaConfig, QueryLogOptions, AdapterBase, MaybePromise, QueryLogObject, QueryBase } from 'orchid-core';
5
5
 
6
6
  interface CreateTableResult<Table extends string, Shape extends ColumnsShape> {
7
7
  table: Db<Table, Shape>;
@@ -1495,17 +1495,6 @@ interface RakeDbChangeFnWithPromise<CT> extends RakeDbChangeFn<CT> {
1495
1495
  */
1496
1496
  declare const rakeDbWithAdapters: RakeDbFn<AdapterBase[]>;
1497
1497
  declare const makeChange: (config: RakeDbConfig<ColumnSchemaConfig, unknown>) => (fn: ChangeCallback<unknown>) => MigrationChange;
1498
- declare const runCommand: <SchemaConfig extends ColumnSchemaConfig<orchid_core.ColumnTypeBase<orchid_core.ColumnTypeSchemaArg, unknown, any, any, unknown, unknown, any, unknown, any, orchid_core.ColumnDataBase>>, CT>(adapters: AdapterBase[], config: RakeDbConfig<SchemaConfig, CT>, args?: string[]) => Promise<RakeDbResult>;
1499
- interface RakeDbCommand {
1500
- run(adapters: AdapterBase[], config: AnyRakeDbConfig, args: string[]): MaybePromise<unknown>;
1501
- help: string;
1502
- helpArguments?: RecordString;
1503
- helpAfter?: string;
1504
- }
1505
- interface RakeDbCommands {
1506
- [K: string]: RakeDbCommand;
1507
- }
1508
- declare const rakeDbCommands: RakeDbCommands;
1509
1498
 
1510
1499
  declare const encodeColumnDefault: (def: unknown, values: unknown[], column?: ColumnTypeBase) => string | null;
1511
1500
  declare const getConstraintName: (table: string, constraint: {
@@ -1764,4 +1753,16 @@ declare const makeMigrateAdapter: (config?: Partial<MigrateFnConfig>) => ((adapt
1764
1753
  declare class RakeDbError extends Error {
1765
1754
  }
1766
1755
 
1756
+ declare const runCommand: <SchemaConfig extends ColumnSchemaConfig<orchid_core.ColumnTypeBase<orchid_core.ColumnTypeSchemaArg, unknown, any, any, unknown, unknown, any, unknown, any, orchid_core.ColumnDataBase>>, CT>(adapters: AdapterBase[], config: RakeDbConfig<SchemaConfig, CT>, args?: string[]) => Promise<RakeDbResult>;
1757
+ interface RakeDbCommand {
1758
+ run(adapters: AdapterBase[], config: AnyRakeDbConfig, args: string[]): MaybePromise<unknown>;
1759
+ help: string;
1760
+ helpArguments?: RecordString;
1761
+ helpAfter?: string;
1762
+ }
1763
+ interface RakeDbCommands {
1764
+ [K: string]: RakeDbCommand;
1765
+ }
1766
+ declare const rakeDbCommands: RakeDbCommands;
1767
+
1767
1768
  export { type AnyRakeDbConfig, type ChangeCallback, type DbMigration, DbStructure, type InputRakeDbConfig, type InputRakeDbConfigBase, type IntrospectedStructure, type MigrateFnConfig, RakeDbAst, type RakeDbChangeFn, type RakeDbChangeFnWithPromise, type RakeDbConfig, RakeDbError, type RakeDbFn, type SilentQueries, type StructureToAstCtx, type StructureToAstTableData, astToMigration, concatSchemaAndName, createMigrationInterface, dbColumnToAst, encodeColumnDefault, getConstraintName, getDbStructureTableData, getDbTableColumnsChecks, getExcludeName, getIndexName, getSchemaAndTableFromName, instantiateDbColumn, introspectDbSchema, makeChange, makeDomainsMap, makeFileVersion, makeMigrateAdapter, makeStructureToAstCtx, migrate, migrateAndClose, migrateFiles, migrationConfigDefaults, processRakeDbConfig, promptSelect, rakeDbCommands, rakeDbWithAdapters, runCommand, saveMigratedVersion, structureToAst, tableToAst, writeMigrationFile };
package/dist/index.js CHANGED
@@ -8,6 +8,99 @@ var fs = require('fs/promises');
8
8
  require('url');
9
9
  require('node:path');
10
10
 
11
+ class RakeDbError extends Error {
12
+ }
13
+ class NoPrimaryKey extends RakeDbError {
14
+ }
15
+
16
+ let currentChanges = [];
17
+ const clearChanges = () => {
18
+ currentChanges = [];
19
+ };
20
+ const getCurrentChanges = () => currentChanges;
21
+ const pushChange = (change) => currentChanges.push(change);
22
+
23
+ const migrationConfigDefaults = {
24
+ schemaConfig: pqb.defaultSchemaConfig,
25
+ migrationsPath: path.join("src", "db", "migrations"),
26
+ migrationId: { serial: 4 },
27
+ migrationsTable: "schemaMigrations",
28
+ snakeCase: false,
29
+ commands: {},
30
+ log: true,
31
+ logger: console,
32
+ import() {
33
+ throw new Error(
34
+ "Add `import: (path) => import(path),` setting to `rakeDb` config"
35
+ );
36
+ }
37
+ };
38
+ const ensureMigrationsPath = (config) => {
39
+ if (!config.migrationsPath) {
40
+ config.migrationsPath = migrationConfigDefaults.migrationsPath;
41
+ }
42
+ if (!path.isAbsolute(config.migrationsPath)) {
43
+ config.migrationsPath = path.resolve(
44
+ config.basePath,
45
+ config.migrationsPath
46
+ );
47
+ }
48
+ return config;
49
+ };
50
+ const ensureBasePathAndDbScript = (config, intermediateCallers = 0) => {
51
+ if (config.basePath && config.dbScript) return config;
52
+ let filePath = orchidCore.getStackTrace()?.[3 + intermediateCallers].getFileName();
53
+ if (!filePath) {
54
+ throw new Error(
55
+ "Failed to determine path to db script. Please set basePath option of rakeDb"
56
+ );
57
+ }
58
+ if (filePath.startsWith("file://")) {
59
+ filePath = node_url.fileURLToPath(filePath);
60
+ }
61
+ const ext = path.extname(filePath);
62
+ if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
63
+ throw new Error(
64
+ `Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
65
+ );
66
+ }
67
+ config.basePath = path.dirname(filePath);
68
+ config.dbScript = path.basename(filePath);
69
+ return config;
70
+ };
71
+ const processRakeDbConfig = (config) => {
72
+ const result = { ...migrationConfigDefaults, ...config };
73
+ if (!result.log) {
74
+ delete result.logger;
75
+ }
76
+ ensureBasePathAndDbScript(result, 1);
77
+ ensureMigrationsPath(result);
78
+ if (!result.recurrentPath) {
79
+ result.recurrentPath = path.join(
80
+ result.migrationsPath,
81
+ "recurrent"
82
+ );
83
+ }
84
+ if ("recurrentPath" in result && !path.isAbsolute(result.recurrentPath)) {
85
+ result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
86
+ }
87
+ if ("baseTable" in config && config.baseTable) {
88
+ const { types, snakeCase, language } = config.baseTable.prototype;
89
+ result.columnTypes = types || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
90
+ if (snakeCase) result.snakeCase = true;
91
+ if (language) result.language = language;
92
+ } else {
93
+ const ct = "columnTypes" in config && config.columnTypes;
94
+ result.columnTypes = (typeof ct === "function" ? ct(
95
+ pqb.makeColumnTypes(pqb.defaultSchemaConfig)
96
+ ) : ct) || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
97
+ }
98
+ if (config.migrationId === "serial") {
99
+ result.migrationId = { serial: 4 };
100
+ }
101
+ return result;
102
+ };
103
+
11
104
  const getFirstWordAndRest = (input) => {
12
105
  const i = input.search(/(?=[A-Z])|[-_ ]/);
13
106
  if (i !== -1) {
@@ -75,13 +168,6 @@ const transaction = (adapter, fn) => {
75
168
  };
76
169
  const queryLock = (trx) => trx.query(`SELECT pg_advisory_xact_lock('${RAKE_DB_LOCK_KEY}')`);
77
170
 
78
- let currentChanges = [];
79
- const clearChanges = () => {
80
- currentChanges = [];
81
- };
82
- const getCurrentChanges = () => currentChanges;
83
- const pushChange = (change) => currentChanges.push(change);
84
-
85
171
  const versionToString = (config, version) => config.migrationId === "timestamp" ? `${version}` : `${version}`.padStart(config.migrationId.serial, "0");
86
172
  const columnTypeToSql = (item) => {
87
173
  return item.data.isOfCustomType ? item instanceof pqb.DomainColumn ? quoteNameFromString(item.dataType) : quoteCustomType(item.toSQL()) : item.toSQL();
@@ -465,11 +551,6 @@ const tableMethods = {
465
551
  }
466
552
  };
467
553
 
468
- class RakeDbError extends Error {
469
- }
470
- class NoPrimaryKey extends RakeDbError {
471
- }
472
-
473
554
  const createTable = async (migration, up, tableName, first, second, third) => {
474
555
  let options;
475
556
  let fn;
@@ -3053,7 +3134,6 @@ const makeMigrateCommand = (migrateFn, defaultCount) => {
3053
3134
  }
3054
3135
  for (const adapter of adapters) {
3055
3136
  await migrateFn({ ctx: {}, adapter, config, count, force });
3056
- await adapter.close();
3057
3137
  }
3058
3138
  };
3059
3139
  };
@@ -3523,7 +3603,7 @@ const resetDb = async (adapters, config) => {
3523
3603
  await dropDb(adapters, config);
3524
3604
  await createDb(adapters, config);
3525
3605
  for (const adapter of adapters) {
3526
- await migrateAndClose({ adapter, config });
3606
+ await migrate({ adapter, config });
3527
3607
  }
3528
3608
  };
3529
3609
  const askForAdminCredentials = async (create) => {
@@ -3548,6 +3628,44 @@ const askForAdminCredentials = async (create) => {
3548
3628
  };
3549
3629
  };
3550
3630
 
3631
+ const runRecurrentMigrations = async (adapters, config) => {
3632
+ let dbs;
3633
+ let files = 0;
3634
+ await readdirRecursive(config.recurrentPath, async (path) => {
3635
+ files++;
3636
+ dbs ?? (dbs = adapters.map((adapter) => pqb.createDbWithAdapter({ adapter })));
3637
+ const sql = await fs.readFile(path, "utf-8");
3638
+ await Promise.all(
3639
+ dbs.map(async (db) => {
3640
+ await db.adapter.arrays(sql);
3641
+ })
3642
+ );
3643
+ });
3644
+ if (files > 0) {
3645
+ config.logger?.log(
3646
+ `Applied ${files} recurrent migration file${files > 1 ? "s" : ""}`
3647
+ );
3648
+ }
3649
+ };
3650
+ const readdirRecursive = async (dirPath, cb) => {
3651
+ const list = await fs.readdir(dirPath).catch((err) => {
3652
+ if (err.code !== "ENOENT") throw err;
3653
+ return;
3654
+ });
3655
+ if (!list) return;
3656
+ await Promise.all(
3657
+ list.map(async (item) => {
3658
+ const path$1 = path.join(dirPath, item);
3659
+ const info = await fs.stat(path$1);
3660
+ if (info.isDirectory()) {
3661
+ await readdirRecursive(path$1, cb);
3662
+ } else if (info.isFile() && path$1.endsWith(".sql")) {
3663
+ await cb(path$1);
3664
+ }
3665
+ })
3666
+ );
3667
+ };
3668
+
3551
3669
  const filterSchema = (table) => `${table} !~ '^pg_' AND ${table} != 'information_schema'`;
3552
3670
  const jsonAgg = (sql2, as) => `(SELECT coalesce(json_agg(t.*), '[]') FROM (${sql2}) t) AS "${as}"`;
3553
3671
  const columnsSql = ({
@@ -5259,7 +5377,6 @@ const pullDbStructure = async (adapter, config) => {
5259
5377
  const currentSchema = adapter.schema || "public";
5260
5378
  const ctx = makeStructureToAstCtx(config, currentSchema);
5261
5379
  const ast = await structureToAst(ctx, adapter, config);
5262
- await adapter.close();
5263
5380
  const result = astToMigration(currentSchema, config, ast);
5264
5381
  if (!result) return;
5265
5382
  const version = await makeFileVersion({}, config);
@@ -5283,220 +5400,6 @@ Append \`as\` method manually to ${count > 1 ? "these" : "this"} column${count >
5283
5400
  );
5284
5401
  }
5285
5402
  config.logger?.log("Database pulled successfully");
5286
- adapter.close();
5287
- };
5288
-
5289
- const runRecurrentMigrations = async (adapters, config) => {
5290
- let dbs;
5291
- let files = 0;
5292
- await readdirRecursive(config.recurrentPath, async (path) => {
5293
- files++;
5294
- dbs ?? (dbs = adapters.map((adapter) => pqb.createDbWithAdapter({ adapter })));
5295
- const sql = await fs.readFile(path, "utf-8");
5296
- await Promise.all(
5297
- dbs.map(async (db) => {
5298
- await db.adapter.arrays(sql);
5299
- })
5300
- );
5301
- });
5302
- if (dbs) {
5303
- await Promise.all(dbs.map((db) => db.close()));
5304
- if (files > 0) {
5305
- config.logger?.log(
5306
- `Applied ${files} recurrent migration file${files > 1 ? "s" : ""}`
5307
- );
5308
- }
5309
- }
5310
- };
5311
- const readdirRecursive = async (dirPath, cb) => {
5312
- const list = await fs.readdir(dirPath).catch((err) => {
5313
- if (err.code !== "ENOENT") throw err;
5314
- return;
5315
- });
5316
- if (!list) return;
5317
- await Promise.all(
5318
- list.map(async (item) => {
5319
- const path$1 = path.join(dirPath, item);
5320
- const info = await fs.stat(path$1);
5321
- if (info.isDirectory()) {
5322
- await readdirRecursive(path$1, cb);
5323
- } else if (info.isFile() && path$1.endsWith(".sql")) {
5324
- await cb(path$1);
5325
- }
5326
- })
5327
- );
5328
- };
5329
-
5330
- const listMigrationsStatuses = async (adapters, config, args) => {
5331
- const ctx = {};
5332
- const [{ migrations }, ...migrated] = await Promise.all([
5333
- getMigrations(ctx, config, true),
5334
- ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
5335
- ]);
5336
- const map = {};
5337
- let maxVersionLength = 12;
5338
- let maxNameLength = 4;
5339
- for (let i = 0; i < adapters.length; i++) {
5340
- const list = migrated[i];
5341
- const key = Object.entries(list.map).map(([version, up]) => `${version}${up ? "t" : "f"}`).join("");
5342
- const database = adapters[i].getDatabase();
5343
- if (map[key]) {
5344
- map[key].databases.push(database);
5345
- continue;
5346
- }
5347
- map[key] = {
5348
- databases: [database],
5349
- migrations: migrations.map((item) => {
5350
- if (item.version.length > maxVersionLength) {
5351
- maxVersionLength = item.version.length;
5352
- }
5353
- const name = path.parse(item.path).name.slice(item.version.length + 1).replace(
5354
- /([a-z])([A-Z])/g,
5355
- (_, a, b) => `${a} ${b.toLocaleLowerCase()}`
5356
- ).replace(/[-_](.)/g, (_, char) => ` ${char.toLocaleLowerCase()}`).replace(/^\w/, (match) => match.toLocaleUpperCase());
5357
- if (name.length > maxNameLength) {
5358
- maxNameLength = name.length;
5359
- }
5360
- return {
5361
- up: !!list.map[item.version],
5362
- version: item.version,
5363
- name,
5364
- url: node_url.pathToFileURL(item.path)
5365
- };
5366
- })
5367
- };
5368
- }
5369
- const showUrl = args.includes("p") || args.includes("path");
5370
- const asIs = (s) => s;
5371
- const c = typeof config.log === "object" && config.log.colors === false ? {
5372
- yellow: asIs,
5373
- green: asIs,
5374
- red: asIs,
5375
- blue: asIs
5376
- } : colors;
5377
- const log = Object.values(map).map(({ databases, migrations: migrations2 }) => {
5378
- let log2 = ` ${c.yellow("Database:")} ${databases.join(", ")}`;
5379
- if (migrations2.length === 0) {
5380
- return log2 + `
5381
-
5382
- No migrations available`;
5383
- }
5384
- const lineSeparator = c.yellow(
5385
- makeChars(14 + maxVersionLength + maxNameLength, "-")
5386
- );
5387
- const columnSeparator = c.yellow("|");
5388
- log2 += "\n\n " + c.yellow(
5389
- `Status | Migration ID${makeChars(
5390
- maxVersionLength - 12,
5391
- " "
5392
- )} | Name
5393
- ${lineSeparator}`
5394
- );
5395
- for (const migration of migrations2) {
5396
- log2 += `
5397
- ${migration.up ? ` ${c.green("Up")} ` : c.red("Down")} ${columnSeparator} ${c.blue(migration.version)}${makeChars(
5398
- maxVersionLength - migration.version.length,
5399
- " "
5400
- )} ${columnSeparator} ${migration.name}`;
5401
- if (showUrl) {
5402
- log2 += `
5403
- ${migration.url}
5404
- `;
5405
- }
5406
- }
5407
- return log2 += showUrl ? lineSeparator : `
5408
- ${lineSeparator}`;
5409
- }).join("\n\n");
5410
- (config.logger ?? console).log(log);
5411
- await Promise.all(adapters.map((adapter) => adapter.close()));
5412
- };
5413
- const makeChars = (count, char) => {
5414
- let chars = "";
5415
- for (let i = 0; i < count; i++) {
5416
- chars += char;
5417
- }
5418
- return chars;
5419
- };
5420
-
5421
- const migrationConfigDefaults = {
5422
- schemaConfig: pqb.defaultSchemaConfig,
5423
- migrationsPath: path.join("src", "db", "migrations"),
5424
- migrationId: { serial: 4 },
5425
- migrationsTable: "schemaMigrations",
5426
- snakeCase: false,
5427
- commands: {},
5428
- log: true,
5429
- logger: console,
5430
- import() {
5431
- throw new Error(
5432
- "Add `import: (path) => import(path),` setting to `rakeDb` config"
5433
- );
5434
- }
5435
- };
5436
- const ensureMigrationsPath = (config) => {
5437
- if (!config.migrationsPath) {
5438
- config.migrationsPath = migrationConfigDefaults.migrationsPath;
5439
- }
5440
- if (!path.isAbsolute(config.migrationsPath)) {
5441
- config.migrationsPath = path.resolve(
5442
- config.basePath,
5443
- config.migrationsPath
5444
- );
5445
- }
5446
- return config;
5447
- };
5448
- const ensureBasePathAndDbScript = (config, intermediateCallers = 0) => {
5449
- if (config.basePath && config.dbScript) return config;
5450
- let filePath = orchidCore.getStackTrace()?.[3 + intermediateCallers].getFileName();
5451
- if (!filePath) {
5452
- throw new Error(
5453
- "Failed to determine path to db script. Please set basePath option of rakeDb"
5454
- );
5455
- }
5456
- if (filePath.startsWith("file://")) {
5457
- filePath = node_url.fileURLToPath(filePath);
5458
- }
5459
- const ext = path.extname(filePath);
5460
- if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
5461
- throw new Error(
5462
- `Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
5463
- );
5464
- }
5465
- config.basePath = path.dirname(filePath);
5466
- config.dbScript = path.basename(filePath);
5467
- return config;
5468
- };
5469
- const processRakeDbConfig = (config) => {
5470
- const result = { ...migrationConfigDefaults, ...config };
5471
- if (!result.log) {
5472
- delete result.logger;
5473
- }
5474
- ensureBasePathAndDbScript(result, 1);
5475
- ensureMigrationsPath(result);
5476
- if (!result.recurrentPath) {
5477
- result.recurrentPath = path.join(
5478
- result.migrationsPath,
5479
- "recurrent"
5480
- );
5481
- }
5482
- if ("recurrentPath" in result && !path.isAbsolute(result.recurrentPath)) {
5483
- result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
5484
- }
5485
- if ("baseTable" in config && config.baseTable) {
5486
- const { types, snakeCase, language } = config.baseTable.prototype;
5487
- result.columnTypes = types || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
5488
- if (snakeCase) result.snakeCase = true;
5489
- if (language) result.language = language;
5490
- } else {
5491
- const ct = "columnTypes" in config && config.columnTypes;
5492
- result.columnTypes = (typeof ct === "function" ? ct(
5493
- pqb.makeColumnTypes(pqb.defaultSchemaConfig)
5494
- ) : ct) || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
5495
- }
5496
- if (config.migrationId === "serial") {
5497
- result.migrationId = { serial: 4 };
5498
- }
5499
- return result;
5500
5403
  };
5501
5404
 
5502
5405
  const rebase = async (adapters, config) => {
@@ -5513,7 +5416,6 @@ const rebase = async (adapters, config) => {
5513
5416
  await getMigrations(ctx, config, true, true),
5514
5417
  ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
5515
5418
  ]);
5516
- await Promise.all(adapters.map((adapter) => adapter.close()));
5517
5419
  const files = set.migrations.map((file) => ({
5518
5420
  ...file,
5519
5421
  name: path.basename(file.path),
@@ -5643,7 +5545,6 @@ const rebase = async (adapters, config) => {
5643
5545
  adapter,
5644
5546
  config: redoConfig
5645
5547
  });
5646
- await adapter.close();
5647
5548
  }
5648
5549
  for (let i = renames.length - 1; i >= 0; i--) {
5649
5550
  const [from, version] = renames[i];
@@ -5658,37 +5559,97 @@ const rebase = async (adapters, config) => {
5658
5559
  }
5659
5560
  };
5660
5561
 
5661
- const rakeDbWithAdapters = (adapters, partialConfig, args = process.argv.slice(2)) => {
5662
- const config = processRakeDbConfig(partialConfig);
5663
- const promise = runCommand(
5664
- adapters,
5665
- config,
5666
- args
5667
- ).catch((err) => {
5668
- if (err instanceof RakeDbError) {
5669
- config.logger?.error(err.message);
5670
- process.exit(1);
5562
+ const listMigrationsStatuses = async (adapters, config, args) => {
5563
+ const ctx = {};
5564
+ const [{ migrations }, ...migrated] = await Promise.all([
5565
+ getMigrations(ctx, config, true),
5566
+ ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
5567
+ ]);
5568
+ const map = {};
5569
+ let maxVersionLength = 12;
5570
+ let maxNameLength = 4;
5571
+ for (let i = 0; i < adapters.length; i++) {
5572
+ const list = migrated[i];
5573
+ const key = Object.entries(list.map).map(([version, up]) => `${version}${up ? "t" : "f"}`).join("");
5574
+ const database = adapters[i].getDatabase();
5575
+ if (map[key]) {
5576
+ map[key].databases.push(database);
5577
+ continue;
5671
5578
  }
5672
- throw err;
5673
- });
5674
- return Object.assign(makeChange(config), {
5675
- promise
5676
- });
5677
- };
5678
- rakeDbWithAdapters.lazy = (adapters, partialConfig) => {
5679
- const config = processRakeDbConfig(partialConfig);
5680
- return {
5681
- change: makeChange(config),
5682
- run(args, conf) {
5683
- return runCommand(adapters, conf ? { ...config, ...conf } : config, args);
5579
+ map[key] = {
5580
+ databases: [database],
5581
+ migrations: migrations.map((item) => {
5582
+ if (item.version.length > maxVersionLength) {
5583
+ maxVersionLength = item.version.length;
5584
+ }
5585
+ const name = path.parse(item.path).name.slice(item.version.length + 1).replace(
5586
+ /([a-z])([A-Z])/g,
5587
+ (_, a, b) => `${a} ${b.toLocaleLowerCase()}`
5588
+ ).replace(/[-_](.)/g, (_, char) => ` ${char.toLocaleLowerCase()}`).replace(/^\w/, (match) => match.toLocaleUpperCase());
5589
+ if (name.length > maxNameLength) {
5590
+ maxNameLength = name.length;
5591
+ }
5592
+ return {
5593
+ up: !!list.map[item.version],
5594
+ version: item.version,
5595
+ name,
5596
+ url: node_url.pathToFileURL(item.path)
5597
+ };
5598
+ })
5599
+ };
5600
+ }
5601
+ const showUrl = args.includes("p") || args.includes("path");
5602
+ const asIs = (s) => s;
5603
+ const c = typeof config.log === "object" && config.log.colors === false ? {
5604
+ yellow: asIs,
5605
+ green: asIs,
5606
+ red: asIs,
5607
+ blue: asIs
5608
+ } : colors;
5609
+ const log = Object.values(map).map(({ databases, migrations: migrations2 }) => {
5610
+ let log2 = ` ${c.yellow("Database:")} ${databases.join(", ")}`;
5611
+ if (migrations2.length === 0) {
5612
+ return log2 + `
5613
+
5614
+ No migrations available`;
5684
5615
  }
5685
- };
5616
+ const lineSeparator = c.yellow(
5617
+ makeChars(14 + maxVersionLength + maxNameLength, "-")
5618
+ );
5619
+ const columnSeparator = c.yellow("|");
5620
+ log2 += "\n\n " + c.yellow(
5621
+ `Status | Migration ID${makeChars(
5622
+ maxVersionLength - 12,
5623
+ " "
5624
+ )} | Name
5625
+ ${lineSeparator}`
5626
+ );
5627
+ for (const migration of migrations2) {
5628
+ log2 += `
5629
+ ${migration.up ? ` ${c.green("Up")} ` : c.red("Down")} ${columnSeparator} ${c.blue(migration.version)}${makeChars(
5630
+ maxVersionLength - migration.version.length,
5631
+ " "
5632
+ )} ${columnSeparator} ${migration.name}`;
5633
+ if (showUrl) {
5634
+ log2 += `
5635
+ ${migration.url}
5636
+ `;
5637
+ }
5638
+ }
5639
+ return log2 += showUrl ? lineSeparator : `
5640
+ ${lineSeparator}`;
5641
+ }).join("\n\n");
5642
+ (config.logger ?? console).log(log);
5643
+ await Promise.all(adapters.map((adapter) => adapter.close()));
5686
5644
  };
5687
- const makeChange = (config) => (fn) => {
5688
- const change = { fn, config };
5689
- pushChange(change);
5690
- return change;
5645
+ const makeChars = (count, char) => {
5646
+ let chars = "";
5647
+ for (let i = 0; i < count; i++) {
5648
+ chars += char;
5649
+ }
5650
+ return chars;
5691
5651
  };
5652
+
5692
5653
  const rakeDbAliases = {
5693
5654
  migrate: "up",
5694
5655
  rollback: "down",
@@ -5764,10 +5725,9 @@ ${Object.entries(helpArguments).map(
5764
5725
  args
5765
5726
  };
5766
5727
  };
5728
+ const close = (adapters) => Promise.all(adapters.map((adapter) => adapter.close()));
5767
5729
  const upCommand = {
5768
- run: (adapters, config, args) => migrateCommand(adapters, config, args).then(
5769
- () => runRecurrentMigrations(adapters, config)
5770
- ),
5730
+ run: (adapters, config, args) => migrateCommand(adapters, config, args).then(() => runRecurrentMigrations(adapters, config)).then(() => close(adapters)),
5771
5731
  help: "migrate pending migrations",
5772
5732
  helpArguments: {
5773
5733
  "no arguments": "migrate all pending",
@@ -5776,7 +5736,7 @@ const upCommand = {
5776
5736
  }
5777
5737
  };
5778
5738
  const downCommand = {
5779
- run: (adapters, config, args) => rollbackCommand(adapters, config, args),
5739
+ run: (adapters, config, args) => rollbackCommand(adapters, config, args).then(() => close(adapters)),
5780
5740
  help: "rollback migrated migrations",
5781
5741
  helpArguments: {
5782
5742
  "no arguments": "rollback one last migration",
@@ -5793,7 +5753,7 @@ const statusCommand = {
5793
5753
  }
5794
5754
  };
5795
5755
  const recurrentCommand = {
5796
- run: runRecurrentMigrations,
5756
+ run: (adapters, config) => runRecurrentMigrations(adapters, config).then(() => close(adapters)),
5797
5757
  help: "run recurrent migrations"
5798
5758
  };
5799
5759
  const rakeDbCommands = {
@@ -5806,9 +5766,7 @@ const rakeDbCommands = {
5806
5766
  help: "drop databases"
5807
5767
  },
5808
5768
  reset: {
5809
- run: (adapters, config) => resetDb(adapters, config).then(
5810
- () => runRecurrentMigrations(adapters, config)
5811
- ),
5769
+ run: (adapters, config) => resetDb(adapters, config).then(() => runRecurrentMigrations(adapters, config)).then(() => close(adapters)),
5812
5770
  help: "drop, create and migrate databases"
5813
5771
  },
5814
5772
  up: upCommand,
@@ -5816,13 +5774,11 @@ const rakeDbCommands = {
5816
5774
  down: downCommand,
5817
5775
  rollback: downCommand,
5818
5776
  redo: {
5819
- run: (adapters, config, args) => redoCommand(adapters, config, args).then(
5820
- () => runRecurrentMigrations(adapters, config)
5821
- ),
5777
+ run: (adapters, config, args) => redoCommand(adapters, config, args).then(() => runRecurrentMigrations(adapters, config)).then(() => close(adapters)),
5822
5778
  help: "rollback and migrate, run recurrent"
5823
5779
  },
5824
5780
  pull: {
5825
- run: ([adapter], config) => pullDbStructure(adapter, config),
5781
+ run: ([adapter], config) => pullDbStructure(adapter, config).then(() => close([adapter])),
5826
5782
  help: "generate a combined migration for an existing database"
5827
5783
  },
5828
5784
  new: {
@@ -5834,7 +5790,7 @@ const rakeDbCommands = {
5834
5790
  rec: recurrentCommand,
5835
5791
  recurrent: recurrentCommand,
5836
5792
  rebase: {
5837
- run: rebase,
5793
+ run: (adapters, config) => rebase(adapters, config).then(() => close(adapters)),
5838
5794
  help: "move local migrations below the new ones from upstream"
5839
5795
  },
5840
5796
  "change-ids": {
@@ -5848,6 +5804,38 @@ const rakeDbCommands = {
5848
5804
  }
5849
5805
  };
5850
5806
 
5807
+ const rakeDbWithAdapters = (adapters, partialConfig, args = process.argv.slice(2)) => {
5808
+ const config = processRakeDbConfig(partialConfig);
5809
+ const promise = runCommand(
5810
+ adapters,
5811
+ config,
5812
+ args
5813
+ ).catch((err) => {
5814
+ if (err instanceof RakeDbError) {
5815
+ config.logger?.error(err.message);
5816
+ process.exit(1);
5817
+ }
5818
+ throw err;
5819
+ });
5820
+ return Object.assign(makeChange(config), {
5821
+ promise
5822
+ });
5823
+ };
5824
+ rakeDbWithAdapters.lazy = (adapters, partialConfig) => {
5825
+ const config = processRakeDbConfig(partialConfig);
5826
+ return {
5827
+ change: makeChange(config),
5828
+ run(args, conf) {
5829
+ return runCommand(adapters, conf ? { ...config, ...conf } : config, args);
5830
+ }
5831
+ };
5832
+ };
5833
+ const makeChange = (config) => (fn) => {
5834
+ const change = { fn, config };
5835
+ pushChange(change);
5836
+ return change;
5837
+ };
5838
+
5851
5839
  const migrateFiles = async (db, files) => {
5852
5840
  const qb = db.$qb;
5853
5841
  await qb.ensureTransaction(async () => {