rake-db 2.30.9 → 2.31.1

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.mjs CHANGED
@@ -1,247 +1,9 @@
1
- import { colors, singleQuote, isRawSQL, escapeForMigration, ArrayColumn, toSnakeCase, toCamelCase, DomainColumn, toArray, EnumColumn, defaultSchemaConfig, snakeCaseKey, getColumnTypes, parseTableData, emptyObject, escapeString, tableDataMethods, setCurrentColumnName, consumeColumnName, Column, parseTableDataInput, UnknownColumn, setDefaultLanguage, deepCompare, raw, logParamToLogObject, createDbWithAdapter, getImportPath, pathToLog, emptyArray, exhaustive, codeToString, addCode, quoteObjectKey, pushTableDataCode, rawSqlToCode, primaryKeyInnerToCode, indexInnerToCode, excludeInnerToCode, constraintInnerToCode, referencesArgsToCode, backtickQuote, TimestampTZColumn, TimestampColumn, makeColumnsByType, RawSql, CustomTypeColumn, assignDbDataToColumn, PostgisGeographyPointColumn, makeColumnTypes, getStackTrace } from 'pqb';
1
+ import { singleQuote, makeColumnTypes, defaultSchemaConfig, isRawSQL, escapeForMigration, ArrayColumn, toSnakeCase, toCamelCase, DomainColumn, toArray, EnumColumn, snakeCaseKey, getColumnTypes, parseTableData, emptyObject, escapeString, tableDataMethods, setDefaultLanguage, consumeColumnName, setCurrentColumnName, Column, parseTableDataInput, UnknownColumn, deepCompare, raw, logParamToLogObject, getImportPath, pathToLog, emptyArray, colors, exhaustive, codeToString, addCode, backtickQuote, rawSqlToCode, referencesArgsToCode, quoteObjectKey, primaryKeyInnerToCode, indexInnerToCode, excludeInnerToCode, constraintInnerToCode, pushTableDataCode, TimestampTZColumn, TimestampColumn, RawSql, CustomTypeColumn, assignDbDataToColumn, makeColumnsByType, PostgisGeographyPointColumn, getStackTrace } from 'pqb/internal';
2
2
  import path, { join } from 'path';
3
3
  import { pathToFileURL, fileURLToPath } from 'node:url';
4
+ import { createDbWithAdapter } from 'pqb';
4
5
  import fs, { mkdir, writeFile, readdir, stat, readFile } from 'fs/promises';
5
-
6
- const ESC = "\x1B";
7
- const CSI = `${ESC}[`;
8
- const cursorShow = `${CSI}?25h`;
9
- const cursorHide = `${CSI}?25l`;
10
- const { stdin, stdout } = process;
11
- const visibleChars = (s) => s.replace(
12
- // eslint-disable-next-line no-control-regex
13
- /[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d/#&.:=?%@~_]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PRZcf-ntqry=><~]))/g,
14
- ""
15
- ).length;
16
- const clear = (text) => {
17
- const rows = text.split(/\r?\n/).reduce(
18
- (rows2, line) => rows2 + 1 + Math.floor(Math.max(visibleChars(line) - 1, 0) / stdout.columns),
19
- 0
20
- );
21
- let clear2 = "";
22
- for (let i = 0; i < rows; i++) {
23
- clear2 += `${CSI}2K`;
24
- if (i < rows - 1) {
25
- clear2 += `${CSI}${i < rows - 1 ? "1A" : "G"}`;
26
- }
27
- }
28
- return clear2;
29
- };
30
- const prompt = async ({
31
- render,
32
- onKeyPress,
33
- validate,
34
- value,
35
- cursor: showCursor
36
- }) => {
37
- stdin.resume();
38
- if (stdin.isTTY) stdin.setRawMode(true);
39
- stdin.setEncoding("utf-8");
40
- if (!showCursor) stdout.write(cursorHide);
41
- return new Promise((res) => {
42
- let prevText;
43
- const ctx = {
44
- value,
45
- submitted: false,
46
- render() {
47
- let text = (ctx.submitted ? colors.greenBold("\u2714") : colors.yellowBold("?")) + " " + render(ctx);
48
- if (ctx.submitted) text += "\n";
49
- stdout.write(prevText ? clear(prevText) + "\r" + text : text);
50
- prevText = text;
51
- },
52
- submit(value2) {
53
- if (value2 !== void 0) ctx.value = value2;
54
- if (ctx.value === void 0 || validate && !validate?.(ctx)) return;
55
- ctx.submitted = true;
56
- ctx.render();
57
- close();
58
- res(ctx.value);
59
- }
60
- };
61
- const close = () => {
62
- if (!showCursor) stdout.write(cursorShow);
63
- if (stdin.isTTY) stdin.setRawMode(false);
64
- stdin.off("data", keypress);
65
- stdin.pause();
66
- };
67
- const keypress = (s) => {
68
- if (s === "" || s === "") {
69
- close?.();
70
- process.exit(0);
71
- }
72
- if (s === "\r" || s === "\n" || s === "\r\n") {
73
- ctx.submit();
74
- } else {
75
- onKeyPress(ctx, s);
76
- }
77
- };
78
- stdin.on("data", keypress);
79
- ctx.render();
80
- });
81
- };
82
- const defaultActive = (s) => `${colors.blueBold("\u276F")} ${s}`;
83
- const defaultInactive = (s) => ` ${s}`;
84
- const promptSelect = ({
85
- message,
86
- options,
87
- active = defaultActive,
88
- inactive = defaultInactive
89
- }) => prompt({
90
- value: 0,
91
- render(ctx) {
92
- let text = `${message} ${colors.pale(
93
- "Use arrows or jk. Press enter to submit."
94
- )}
95
- `;
96
- for (let i = 0; i < options.length; i++) {
97
- text += (ctx.value === i ? active : inactive)(options[i]) + "\n";
98
- }
99
- return text;
100
- },
101
- onKeyPress(ctx, s) {
102
- ctx.value = s === "\x1B[H" ? 0 : s === "\x1B[F" ? options.length - 1 : s === "\x1B[A" || s === "k" ? ctx.value === 0 ? options.length - 1 : ctx.value - 1 : s === "\x1B[B" || s === "j" || s === " " ? ctx.value === options.length - 1 ? 0 : ctx.value + 1 : ctx.value;
103
- ctx.render();
104
- }
105
- });
106
- const promptConfirm = ({
107
- message
108
- }) => prompt({
109
- value: true,
110
- render(ctx) {
111
- return `${colors.bright(message)}
112
- ${ctx.submitted ? `> ${ctx.value ? colors.greenBold("Yes") : colors.yellowBold("No")}` : colors.pale(`> (Y/n)`)}
113
- `;
114
- },
115
- onKeyPress(ctx, s) {
116
- let ok;
117
- if (s === "y" || s === "Y") ok = true;
118
- else if (s === "n" || s === "N") ok = false;
119
- if (ok !== void 0) {
120
- ctx.submit(ok);
121
- }
122
- }
123
- });
124
- const promptText = ({
125
- message,
126
- default: def = "",
127
- password,
128
- min
129
- }) => {
130
- let showDefault = true;
131
- let x = 0;
132
- const renderValue = (ctx) => password ? "*".repeat(ctx.value.length) : ctx.value;
133
- return prompt({
134
- value: def,
135
- cursor: true,
136
- validate: (ctx) => !min || ctx.value.length >= min,
137
- render(ctx) {
138
- let text = `${colors.bright(message)}
139
- > ${ctx.submitted ? renderValue(ctx) : showDefault ? colors.pale(def) + "\b".repeat(def.length) : ctx.value}`;
140
- if (ctx.submitted) text += "\n";
141
- return text;
142
- },
143
- onKeyPress(ctx, s) {
144
- let value = showDefault ? "" : ctx.value;
145
- if (s === "\x1B[D" && x > 0) {
146
- x--;
147
- stdout.write("\b");
148
- } else if (s === "\x1B[C" && x < value.length) {
149
- stdout.write(value[x]);
150
- x++;
151
- }
152
- if (s !== "\x7F" && s !== "\x1B[3~" && !visibleChars(s)) return;
153
- if (showDefault) {
154
- showDefault = false;
155
- stdout.write(" ".repeat(def.length) + "\b".repeat(def.length));
156
- }
157
- const prev = value;
158
- const prevX = x;
159
- if (s === "\x7F") {
160
- if (x > 0) {
161
- value = value.slice(0, x - 1) + value.slice(x);
162
- x--;
163
- }
164
- } else if (s === "\x1B[3~") {
165
- if (x < value.length) {
166
- value = value.slice(0, x) + value.slice(x + 1);
167
- }
168
- } else {
169
- value = value.slice(0, x) + s + value.slice(x);
170
- x++;
171
- }
172
- ctx.value = value;
173
- const spaces = prev.length - value.length;
174
- stdout.write(
175
- "\b".repeat(prevX) + renderValue(ctx) + (spaces > 0 ? " ".repeat(spaces) + "\b".repeat(spaces) : "") + "\b".repeat(value.length - x)
176
- );
177
- }
178
- });
179
- };
180
-
181
- const getMaybeTransactionAdapter = (db) => "$getAdapter" in db ? db.$getAdapter() : db;
182
- const runSqlInSavePoint = async (db, sql, code) => {
183
- const adapter = getMaybeTransactionAdapter(db);
184
- try {
185
- await adapter.query(
186
- adapter.isInTransaction() ? `SAVEPOINT s; ${sql}; RELEASE SAVEPOINT s` : sql
187
- );
188
- return "done";
189
- } catch (err) {
190
- if (err.code === code) {
191
- if (adapter.isInTransaction()) {
192
- await adapter.query(`ROLLBACK TO SAVEPOINT s`);
193
- }
194
- return "already";
195
- }
196
- throw err;
197
- }
198
- };
199
-
200
- class CreateOrDropError extends Error {
201
- constructor(message, status, cause) {
202
- super(message);
203
- this.status = status;
204
- this.cause = cause;
205
- }
206
- }
207
- const createDatabase = async (db, {
208
- database,
209
- owner
210
- }) => {
211
- return createOrDrop(
212
- db,
213
- `CREATE DATABASE "${database}"${owner ? ` OWNER "${owner}"` : ""}`
214
- );
215
- };
216
- const dropDatabase = async (db, { database }) => {
217
- return createOrDrop(db, `DROP DATABASE "${database}"`);
218
- };
219
- const createOrDrop = async (db, sql) => {
220
- try {
221
- const adapter = getMaybeTransactionAdapter(db);
222
- await adapter.query(sql);
223
- return "done";
224
- } catch (error) {
225
- const err = error;
226
- if (typeof err.message === "string" && err.message.includes("sslmode=require")) {
227
- throw new CreateOrDropError("SSL required", "ssl-required", err);
228
- }
229
- if (err.code === "42P04" || err.code === "3D000") {
230
- return "already";
231
- }
232
- if (err.code === "42501") {
233
- throw new CreateOrDropError("Insufficient privilege", "forbidden", err);
234
- }
235
- if (typeof err.message === "string" && err.message.includes("password authentication failed")) {
236
- throw new CreateOrDropError("Authentication failed", "auth-failed", err);
237
- }
238
- throw err;
239
- }
240
- };
241
- const createSchema$1 = async (db, sql) => runSqlInSavePoint(db, `CREATE SCHEMA ${sql}`, "42P06");
242
- const dropSchema = async (db, sql) => runSqlInSavePoint(db, `DROP SCHEMA ${sql}`, "3F000");
243
- const createTable$1 = async (db, sql) => runSqlInSavePoint(db, `CREATE TABLE ${sql}`, "42P07");
244
- const dropTable = async (db, sql) => runSqlInSavePoint(db, `DROP TABLE ${sql}`, "42P01");
6
+ import path$1 from 'node:path';
245
7
 
246
8
  const RAKE_DB_LOCK_KEY = "8582141715823621641";
247
9
  const getFirstWordAndRest = (input) => {
@@ -330,10 +92,13 @@ const getCliParam = (args, name) => {
330
92
  return;
331
93
  };
332
94
 
333
- const makeChange = (config) => (fn) => {
334
- const change = { fn, config };
335
- pushChange(change);
336
- return change;
95
+ const createMigrationChangeFn = (config) => {
96
+ const conf = config.columnTypes ? config : { columnTypes: makeColumnTypes(defaultSchemaConfig) };
97
+ return (fn) => {
98
+ const change = { fn, config: conf };
99
+ pushChange(change);
100
+ return change;
101
+ };
337
102
  };
338
103
  let currentChanges = [];
339
104
  const clearChanges = () => {
@@ -394,7 +159,6 @@ const columnToSql = (schema, name, item, values, hasMultiplePrimaryKeys, snakeCa
394
159
  referencesToSql(
395
160
  schema,
396
161
  {
397
- columns: [name],
398
162
  ...foreignKey
399
163
  },
400
164
  snakeCase
@@ -750,7 +514,7 @@ class RakeDbError extends Error {
750
514
  class NoPrimaryKey extends RakeDbError {
751
515
  }
752
516
 
753
- const createTable = async (migration, up, tableName, first, second, third) => {
517
+ const createTable$1 = async (migration, up, tableName, first, second, third) => {
754
518
  let options;
755
519
  let fn;
756
520
  let dataFn;
@@ -1979,27 +1743,37 @@ const createMigrationInterface = (tx, up, config) => {
1979
1743
  );
1980
1744
  };
1981
1745
  Object.assign(adapter, { silentQuery: query, silentArrays: arrays });
1982
- const db = createDbWithAdapter({
1983
- adapter,
1984
- columnTypes: config.columnTypes
1985
- });
1986
- const { prototype: proto } = Migration;
1987
- for (const key of Object.getOwnPropertyNames(proto)) {
1988
- db[key] = proto[key];
1989
- }
1990
- return Object.assign(db, {
1746
+ const dbPerColumnTypes = /* @__PURE__ */ new Map();
1747
+ return {
1991
1748
  adapter,
1992
- log,
1993
- up,
1994
- options: config
1995
- });
1749
+ getDb(columnTypes) {
1750
+ let db = dbPerColumnTypes.get(columnTypes);
1751
+ if (!db) {
1752
+ db = createDbWithAdapter({
1753
+ adapter,
1754
+ columnTypes
1755
+ });
1756
+ const { prototype: proto } = Migration;
1757
+ for (const key of Object.getOwnPropertyNames(proto)) {
1758
+ db[key] = proto[key];
1759
+ }
1760
+ return Object.assign(db, {
1761
+ adapter,
1762
+ log,
1763
+ up,
1764
+ options: config
1765
+ });
1766
+ }
1767
+ return db;
1768
+ }
1769
+ };
1996
1770
  };
1997
1771
  class Migration {
1998
1772
  createTable(tableName, first, second, third) {
1999
- return createTable(this, this.up, tableName, first, second, third);
1773
+ return createTable$1(this, this.up, tableName, first, second, third);
2000
1774
  }
2001
1775
  dropTable(tableName, first, second, third) {
2002
- return createTable(this, !this.up, tableName, first, second, third);
1776
+ return createTable$1(this, !this.up, tableName, first, second, third);
2003
1777
  }
2004
1778
  changeTable(tableName, cbOrOptions, cb) {
2005
1779
  const [fn, options] = typeof cbOrOptions === "function" ? [cbOrOptions, {}] : [cb, cbOrOptions];
@@ -2332,7 +2106,7 @@ class Migration {
2332
2106
  * @param schemaName - name of the schema
2333
2107
  */
2334
2108
  createSchema(schemaName) {
2335
- return createSchema(this, this.up, schemaName);
2109
+ return createSchema$1(this, this.up, schemaName);
2336
2110
  }
2337
2111
  /**
2338
2112
  * Renames a database schema, renames it backwards on roll back.
@@ -2359,7 +2133,7 @@ class Migration {
2359
2133
  * @param schemaName - name of the schema
2360
2134
  */
2361
2135
  dropSchema(schemaName) {
2362
- return createSchema(this, !this.up, schemaName);
2136
+ return createSchema$1(this, !this.up, schemaName);
2363
2137
  }
2364
2138
  /**
2365
2139
  * `createExtension` creates a database extension, and removes it on rollback.
@@ -2506,7 +2280,6 @@ class Migration {
2506
2280
  enumName
2507
2281
  );
2508
2282
  const ast = {
2509
- type: "renameEnumValues",
2510
2283
  schema,
2511
2284
  name,
2512
2285
  values
@@ -2920,12 +2693,9 @@ const addCheck = (migration, up, tableName, check) => {
2920
2693
  ...t.add(t.check(check))
2921
2694
  }));
2922
2695
  };
2923
- const createSchema = async (migration, up, name) => {
2696
+ const createSchema$1 = async (migration, up, name) => {
2924
2697
  const ast = {
2925
- type: "schema",
2926
- action: up ? "create" : "drop",
2927
- name
2928
- };
2698
+ action: up ? "create" : "drop"};
2929
2699
  await migration.adapter.query(
2930
2700
  `${ast.action === "create" ? "CREATE" : "DROP"} SCHEMA "${name}"`
2931
2701
  );
@@ -2936,7 +2706,6 @@ const createExtension = async (migration, up, fullName, options) => {
2936
2706
  fullName
2937
2707
  );
2938
2708
  const ast = {
2939
- type: "extension",
2940
2709
  action: up ? "create" : "drop",
2941
2710
  schema,
2942
2711
  name,
@@ -2956,11 +2725,9 @@ const createEnum = async (migration, up, name, values, options = {}) => {
2956
2725
  name
2957
2726
  );
2958
2727
  const ast = {
2959
- type: "enum",
2960
2728
  action: up ? "create" : "drop",
2961
2729
  schema,
2962
2730
  name: enumName,
2963
- values,
2964
2731
  ...options
2965
2732
  };
2966
2733
  let query;
@@ -2978,7 +2745,6 @@ const createDomain = async (migration, up, name, fn) => {
2978
2745
  name
2979
2746
  );
2980
2747
  const ast = {
2981
- type: "domain",
2982
2748
  action: up ? "create" : "drop",
2983
2749
  schema,
2984
2750
  name: domainName,
@@ -3011,7 +2777,6 @@ const createCollation = async (migration, up, name, options) => {
3011
2777
  name
3012
2778
  );
3013
2779
  const ast = {
3014
- type: "collation",
3015
2780
  action: up ? "create" : "drop",
3016
2781
  schema,
3017
2782
  name: collationName,
@@ -3057,7 +2822,6 @@ const renameType = async (migration, from, to, kind) => {
3057
2822
  migration.up ? to : from
3058
2823
  );
3059
2824
  const ast = {
3060
- type: "renameType",
3061
2825
  kind,
3062
2826
  fromSchema,
3063
2827
  from: f,
@@ -3096,7 +2860,6 @@ const addOrDropEnumValues = async (migration, up, enumName, values, options) =>
3096
2860
  );
3097
2861
  const quotedName = quoteTable(schema, name);
3098
2862
  const ast = {
3099
- type: "enumValues",
3100
2863
  action: up ? "add" : "drop",
3101
2864
  schema,
3102
2865
  name,
@@ -3139,10 +2902,8 @@ const changeEnumValues = async (migration, enumName, fromValues, toValues) => {
3139
2902
  toValues = values;
3140
2903
  }
3141
2904
  const ast = {
3142
- type: "changeEnumValues",
3143
2905
  schema,
3144
2906
  name,
3145
- fromValues,
3146
2907
  toValues
3147
2908
  };
3148
2909
  await recreateEnum(
@@ -3406,7 +3167,7 @@ const getMigrations = async (ctx, config, up, allowDuplicates, getVersion = getM
3406
3167
  function getMigrationsFromConfig(config, allowDuplicates, getVersion = getMigrationVersionOrThrow) {
3407
3168
  const result = [];
3408
3169
  const versions = {};
3409
- const { migrations, basePath } = config;
3170
+ const { migrations } = config;
3410
3171
  for (const key in migrations) {
3411
3172
  const version = getVersion(config, path.basename(key));
3412
3173
  if (versions[version] && !allowDuplicates) {
@@ -3416,7 +3177,7 @@ function getMigrationsFromConfig(config, allowDuplicates, getVersion = getMigrat
3416
3177
  }
3417
3178
  versions[version] = key;
3418
3179
  result.push({
3419
- path: path.resolve(basePath, key),
3180
+ path: key,
3420
3181
  version,
3421
3182
  load: migrations[key]
3422
3183
  });
@@ -3466,7 +3227,7 @@ async function getMigrationsFromFiles(config, allowDuplicates, getVersion = getM
3466
3227
  }
3467
3228
  data.renameTo = {
3468
3229
  to: config.migrationId,
3469
- map: () => renameMigrationsMap(config, file.name)
3230
+ map: () => renameMigrationsMap(migrationsPath, file.name)
3470
3231
  };
3471
3232
  return data;
3472
3233
  } else {
@@ -3505,8 +3266,8 @@ Run \`**db command** rebase\` to reorganize files with duplicated versions.`
3505
3266
  result.migrations.sort(sortMigrationsAsc);
3506
3267
  return result;
3507
3268
  }
3508
- const renameMigrationsMap = async (config, fileName) => {
3509
- const filePath = path.join(config.migrationsPath, fileName);
3269
+ const renameMigrationsMap = async (migrationsPath, fileName) => {
3270
+ const filePath = path.join(migrationsPath, fileName);
3510
3271
  const json = await fs.readFile(filePath, "utf-8");
3511
3272
  let data;
3512
3273
  try {
@@ -3557,6 +3318,71 @@ function getDigitsPrefix(name) {
3557
3318
  return value;
3558
3319
  }
3559
3320
 
3321
+ const getMaybeTransactionAdapter = (db) => "$getAdapter" in db ? db.$getAdapter() : db;
3322
+ const runSqlInSavePoint = async (db, sql, code) => {
3323
+ const adapter = getMaybeTransactionAdapter(db);
3324
+ try {
3325
+ await adapter.query(
3326
+ adapter.isInTransaction() ? `SAVEPOINT s; ${sql}; RELEASE SAVEPOINT s` : sql
3327
+ );
3328
+ return "done";
3329
+ } catch (err) {
3330
+ if (err.code === code) {
3331
+ if (adapter.isInTransaction()) {
3332
+ await adapter.query(`ROLLBACK TO SAVEPOINT s`);
3333
+ }
3334
+ return "already";
3335
+ }
3336
+ throw err;
3337
+ }
3338
+ };
3339
+
3340
+ class CreateOrDropError extends Error {
3341
+ constructor(message, status, cause) {
3342
+ super(message);
3343
+ this.status = status;
3344
+ this.cause = cause;
3345
+ }
3346
+ }
3347
+ const createDatabase = async (db, {
3348
+ database,
3349
+ owner
3350
+ }) => {
3351
+ return createOrDrop(
3352
+ db,
3353
+ `CREATE DATABASE "${database}"${owner ? ` OWNER "${owner}"` : ""}`
3354
+ );
3355
+ };
3356
+ const dropDatabase = async (db, { database }) => {
3357
+ return createOrDrop(db, `DROP DATABASE "${database}"`);
3358
+ };
3359
+ const createOrDrop = async (db, sql) => {
3360
+ try {
3361
+ const adapter = getMaybeTransactionAdapter(db);
3362
+ await adapter.query(sql);
3363
+ return "done";
3364
+ } catch (error) {
3365
+ const err = error;
3366
+ if (typeof err.message === "string" && err.message.includes("sslmode=require")) {
3367
+ throw new CreateOrDropError("SSL required", "ssl-required", err);
3368
+ }
3369
+ if (err.code === "42P04" || err.code === "3D000") {
3370
+ return "already";
3371
+ }
3372
+ if (err.code === "42501") {
3373
+ throw new CreateOrDropError("Insufficient privilege", "forbidden", err);
3374
+ }
3375
+ if (typeof err.message === "string" && err.message.includes("password authentication failed")) {
3376
+ throw new CreateOrDropError("Authentication failed", "auth-failed", err);
3377
+ }
3378
+ throw err;
3379
+ }
3380
+ };
3381
+ const createSchema = async (db, sql) => runSqlInSavePoint(db, `CREATE SCHEMA ${sql}`, "42P06");
3382
+ const dropSchema = async (db, sql) => runSqlInSavePoint(db, `DROP SCHEMA ${sql}`, "3F000");
3383
+ const createTable = async (db, sql) => runSqlInSavePoint(db, `CREATE TABLE ${sql}`, "42P07");
3384
+ const dropTable = async (db, sql) => runSqlInSavePoint(db, `DROP TABLE ${sql}`, "42P01");
3385
+
3560
3386
  const saveMigratedVersion = async (db, version, name, config) => {
3561
3387
  await db.silentArrays(
3562
3388
  `INSERT INTO ${migrationsSchemaTableSql(
@@ -3570,12 +3396,12 @@ const createMigrationsSchemaAndTable = async (db, config) => {
3570
3396
  const adapter = getMaybeTransactionAdapter(db);
3571
3397
  const { schema, table } = getMigrationsSchemaAndTable(adapter, config);
3572
3398
  if (schema) {
3573
- const res2 = await createSchema$1(db, schema);
3399
+ const res2 = await createSchema(db, schema);
3574
3400
  if (res2 === "done") {
3575
3401
  config.logger?.log(`Created schema "${schema}"`);
3576
3402
  }
3577
3403
  }
3578
- const res = await createTable$1(
3404
+ const res = await createTable(
3579
3405
  db,
3580
3406
  `${schema ? `"${schema}"."${table}"` : `"${table}"`} (version TEXT NOT NULL, name TEXT NOT NULL)`
3581
3407
  );
@@ -3600,53 +3426,62 @@ const deleteMigratedVersion = async (adapter, version, name, config) => {
3600
3426
  class NoMigrationsTableError extends Error {
3601
3427
  }
3602
3428
  const getMigratedVersionsMap = async (ctx, adapter, config, renameTo) => {
3429
+ const table = migrationsSchemaTableSql(adapter, config);
3430
+ const inTransaction = "isInTransaction" in adapter && adapter.isInTransaction();
3431
+ let result;
3603
3432
  try {
3604
- const table = migrationsSchemaTableSql(adapter, config);
3605
- const result = await adapter.arrays(
3433
+ if (inTransaction) {
3434
+ await adapter.query(`SAVEPOINT check_migrations_table`);
3435
+ }
3436
+ result = await adapter.arrays(
3606
3437
  `SELECT * FROM ${table} ORDER BY version`
3607
3438
  );
3608
- if (!result.fields[1]) {
3609
- const { migrations } = await getMigrations(ctx, config, true);
3610
- const map = {};
3611
- for (const item of migrations) {
3612
- const name = path.basename(item.path);
3613
- map[item.version] = name.slice(getDigitsPrefix(name).length + 1);
3614
- }
3615
- for (const row of result.rows) {
3616
- const [version] = row;
3617
- const name = map[version];
3618
- if (!name) {
3619
- throw new Error(
3620
- `Migration for version ${version} is stored in db but is not found among available migrations`
3621
- );
3622
- }
3623
- row[1] = name;
3624
- }
3625
- await adapter.arrays(`ALTER TABLE ${table} ADD COLUMN name TEXT`);
3626
- await Promise.all(
3627
- result.rows.map(
3628
- ([version, name]) => adapter.arrays(`UPDATE ${table} SET name = $2 WHERE version = $1`, [
3629
- version,
3630
- name
3631
- ])
3632
- )
3633
- );
3634
- await adapter.arrays(
3635
- `ALTER TABLE ${table} ALTER COLUMN name SET NOT NULL`
3636
- );
3439
+ if (inTransaction) {
3440
+ await adapter.query(`RELEASE SAVEPOINT check_migrations_table`);
3637
3441
  }
3638
- let versions = Object.fromEntries(result.rows);
3639
- if (renameTo) {
3640
- versions = await renameMigrations(config, adapter, versions, renameTo);
3641
- }
3642
- return { map: versions, sequence: result.rows.map((row) => +row[0]) };
3643
3442
  } catch (err) {
3644
3443
  if (err.code === "42P01") {
3444
+ if (inTransaction) {
3445
+ await adapter.query(`ROLLBACK TO SAVEPOINT check_migrations_table`);
3446
+ }
3645
3447
  throw new NoMigrationsTableError();
3646
3448
  } else {
3647
3449
  throw err;
3648
3450
  }
3649
3451
  }
3452
+ if (!result.fields[1]) {
3453
+ const { migrations } = await getMigrations(ctx, config, true);
3454
+ const map = {};
3455
+ for (const item of migrations) {
3456
+ const name = path.basename(item.path);
3457
+ map[item.version] = name.slice(getDigitsPrefix(name).length + 1);
3458
+ }
3459
+ for (const row of result.rows) {
3460
+ const [version] = row;
3461
+ const name = map[version];
3462
+ if (!name) {
3463
+ throw new Error(
3464
+ `Migration for version ${version} is stored in db but is not found among available migrations`
3465
+ );
3466
+ }
3467
+ row[1] = name;
3468
+ }
3469
+ await adapter.arrays(`ALTER TABLE ${table} ADD COLUMN name TEXT`);
3470
+ await Promise.all(
3471
+ result.rows.map(
3472
+ ([version, name]) => adapter.arrays(`UPDATE ${table} SET name = $2 WHERE version = $1`, [
3473
+ version,
3474
+ name
3475
+ ])
3476
+ )
3477
+ );
3478
+ await adapter.arrays(`ALTER TABLE ${table} ALTER COLUMN name SET NOT NULL`);
3479
+ }
3480
+ let versions = Object.fromEntries(result.rows);
3481
+ if (renameTo) {
3482
+ versions = await renameMigrations(config, adapter, versions, renameTo);
3483
+ }
3484
+ return { map: versions, sequence: result.rows.map((row) => +row[0]) };
3650
3485
  };
3651
3486
  async function renameMigrations(config, trx, versions, renameTo) {
3652
3487
  let first;
@@ -3677,11 +3512,35 @@ async function renameMigrations(config, trx, versions, renameTo) {
3677
3512
  return updatedVersions;
3678
3513
  }
3679
3514
 
3515
+ const migrateConfigDefaults = {
3516
+ migrationId: { serial: 4 },
3517
+ migrationsTable: "schemaMigrations",
3518
+ transaction: "single"
3519
+ };
3520
+ const handleConfigLogger = (config) => {
3521
+ return config.log === true ? config.logger || console : config.log === false ? void 0 : config.logger;
3522
+ };
3523
+ const processMigrateConfig = (config) => {
3524
+ let migrationsPath;
3525
+ if (!("migrations" in config)) {
3526
+ migrationsPath = config.migrationsPath ? config.migrationsPath : path$1.join("src", "db", "migrations");
3527
+ if (config.basePath && !path$1.isAbsolute(migrationsPath)) {
3528
+ migrationsPath = path$1.resolve(config.basePath, migrationsPath);
3529
+ }
3530
+ }
3531
+ return {
3532
+ ...migrateConfigDefaults,
3533
+ ...config,
3534
+ migrationsPath,
3535
+ logger: handleConfigLogger(config)
3536
+ };
3537
+ };
3680
3538
  const transactionIfSingle = (adapter, config, fn) => {
3681
3539
  return config.transaction === "single" ? transaction(adapter, config, fn) : fn(adapter);
3682
3540
  };
3683
3541
  function makeMigrateFn(up, defaultCount, fn) {
3684
- return async (db, config, params) => {
3542
+ return async (db, publicConfig, params) => {
3543
+ const config = processMigrateConfig(publicConfig);
3685
3544
  const ctx = params?.ctx || {};
3686
3545
  const set = await getMigrations(ctx, config, up);
3687
3546
  const count = params?.count ?? defaultCount;
@@ -3724,7 +3583,16 @@ function makeMigrateFn(up, defaultCount, fn) {
3724
3583
  const migrate = makeMigrateFn(
3725
3584
  true,
3726
3585
  Infinity,
3727
- (trx, config, set, versions, count, force) => migrateOrRollback(trx, config, set, versions, count, true, false, force)
3586
+ (trx, config, set, versions, count, force) => migrateOrRollback(
3587
+ trx,
3588
+ config,
3589
+ set,
3590
+ versions,
3591
+ count,
3592
+ true,
3593
+ false,
3594
+ force
3595
+ )
3728
3596
  );
3729
3597
  const migrateAndClose = async (db, config, params) => {
3730
3598
  const adapter = getMaybeTransactionAdapter(db);
@@ -3732,26 +3600,46 @@ const migrateAndClose = async (db, config, params) => {
3732
3600
  await adapter.close();
3733
3601
  };
3734
3602
  async function runMigration(db, ...args) {
3735
- const [config, migration] = args.length === 1 ? [{}, args[0]] : [args[0], args[1]];
3603
+ const [rawConfig, migration] = args.length === 1 ? [{}, args[0]] : [args[0], args[1]];
3604
+ const config = {
3605
+ ...rawConfig,
3606
+ logger: handleConfigLogger(rawConfig)
3607
+ };
3736
3608
  const adapter = getMaybeTransactionAdapter(db);
3737
3609
  await transaction(adapter, config, async (trx) => {
3738
3610
  clearChanges();
3739
3611
  const changes = await getChanges({ load: migration });
3740
- const config2 = changes[0]?.config;
3741
- await applyMigration(trx, true, changes, config2);
3612
+ await applyMigration(trx, true, changes, config);
3742
3613
  });
3743
3614
  }
3744
3615
  const rollback = makeMigrateFn(
3745
3616
  false,
3746
3617
  1,
3747
- (trx, config, set, versions, count, force) => migrateOrRollback(trx, config, set, versions, count, false, false, force)
3618
+ (trx, config, set, versions, count, force) => migrateOrRollback(
3619
+ trx,
3620
+ config,
3621
+ set,
3622
+ versions,
3623
+ count,
3624
+ false,
3625
+ false,
3626
+ force
3627
+ )
3748
3628
  );
3749
3629
  const redo = makeMigrateFn(
3750
3630
  true,
3751
3631
  1,
3752
3632
  async (trx, config, set, versions, count, force) => {
3753
3633
  set.migrations.reverse();
3754
- await migrateOrRollback(trx, config, set, versions, count, false, true);
3634
+ await migrateOrRollback(
3635
+ trx,
3636
+ config,
3637
+ set,
3638
+ versions,
3639
+ count,
3640
+ false,
3641
+ true
3642
+ );
3755
3643
  set.migrations.reverse();
3756
3644
  return migrateOrRollback(
3757
3645
  trx,
@@ -3822,7 +3710,7 @@ const migrateOrRollback = async (trx, config, set, versions, count, up, redo2, f
3822
3710
  await changeMigratedVersion(adapter, up, file, config);
3823
3711
  (migrations ?? (migrations = [])).push(file);
3824
3712
  if (up) {
3825
- const name = path.basename(file.path);
3713
+ const name = path$1.basename(file.path);
3826
3714
  versionsMap[file.version] = name;
3827
3715
  sequence.push(+file.version);
3828
3716
  } else {
@@ -3869,7 +3757,7 @@ const checkMigrationOrder = (config, set, { sequence, map }, force) => {
3869
3757
  if (version > last || map[file.version]) continue;
3870
3758
  if (!force) {
3871
3759
  throw new Error(
3872
- `Cannot migrate ${path.basename(
3760
+ `Cannot migrate ${path$1.basename(
3873
3761
  file.path
3874
3762
  )} because the higher position ${map[versionToString(config, last)]} was already migrated.
3875
3763
  Run \`**db command** up force\` to rollback the above migrations and migrate all`
@@ -3905,105 +3793,296 @@ const runMigrationInOwnTransaction = (adapter, up, changes, config) => {
3905
3793
  );
3906
3794
  };
3907
3795
  const applyMigration = async (trx, up, changes, config) => {
3908
- const db = createMigrationInterface(trx, up, config);
3796
+ const { adapter, getDb: getDb2 } = createMigrationInterface(trx, up, config);
3909
3797
  if (changes.length) {
3910
3798
  const from = up ? 0 : changes.length - 1;
3911
3799
  const to = up ? changes.length : -1;
3912
3800
  const step = up ? 1 : -1;
3913
3801
  for (let i = from; i !== to; i += step) {
3914
- await changes[i].fn(db, up);
3802
+ const change = changes[i];
3803
+ const db = getDb2(change.config.columnTypes);
3804
+ await change.fn(db, up);
3915
3805
  }
3916
3806
  }
3917
- return db.adapter;
3807
+ return adapter;
3918
3808
  };
3919
3809
  const changeMigratedVersion = async (adapter, up, file, config) => {
3920
3810
  await (up ? saveMigratedVersion : deleteMigratedVersion)(
3921
3811
  adapter,
3922
3812
  file.version,
3923
- path.basename(file.path).slice(file.version.length + 1),
3813
+ path$1.basename(file.path).slice(file.version.length + 1),
3924
3814
  config
3925
3815
  );
3926
3816
  };
3927
3817
 
3928
- const runRecurrentMigrations = async (adapters, config) => {
3929
- let dbs;
3930
- let files = 0;
3931
- await readdirRecursive(config.recurrentPath, async (path) => {
3932
- files++;
3933
- dbs ?? (dbs = adapters.map((adapter) => createDbWithAdapter({ adapter })));
3934
- const sql = await readFile(path, "utf-8");
3935
- await Promise.all(
3936
- dbs.map(async (db) => {
3937
- await db.adapter.arrays(sql);
3938
- })
3939
- );
3940
- });
3941
- if (files > 0) {
3942
- config.logger?.log(
3943
- `Applied ${files} recurrent migration file${files > 1 ? "s" : ""}`
3818
+ const rakeDbConfigDefaults = {
3819
+ ...migrateConfigDefaults,
3820
+ schemaConfig: defaultSchemaConfig,
3821
+ snakeCase: false,
3822
+ commands: {},
3823
+ log: true,
3824
+ logger: console,
3825
+ import() {
3826
+ throw new Error(
3827
+ "Add `import: (path) => import(path),` setting to `rakeDb` config"
3944
3828
  );
3945
3829
  }
3946
3830
  };
3947
- const readdirRecursive = async (dirPath, cb) => {
3948
- const list = await readdir(dirPath).catch((err) => {
3949
- if (err.code !== "ENOENT") throw err;
3950
- return;
3951
- });
3952
- if (!list) return;
3953
- await Promise.all(
3954
- list.map(async (item) => {
3955
- const path = join(dirPath, item);
3956
- const info = await stat(path);
3957
- if (info.isDirectory()) {
3958
- await readdirRecursive(path, cb);
3959
- } else if (info.isFile() && path.endsWith(".sql")) {
3960
- await cb(path);
3961
- }
3962
- })
3831
+
3832
+ const ESC = "\x1B";
3833
+ const CSI = `${ESC}[`;
3834
+ const cursorShow = `${CSI}?25h`;
3835
+ const cursorHide = `${CSI}?25l`;
3836
+ const { stdin, stdout } = process;
3837
+ const visibleChars = (s) => s.replace(
3838
+ // eslint-disable-next-line no-control-regex
3839
+ /[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d/#&.:=?%@~_]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PRZcf-ntqry=><~]))/g,
3840
+ ""
3841
+ ).length;
3842
+ const clear = (text) => {
3843
+ const rows = text.split(/\r?\n/).reduce(
3844
+ (rows2, line) => rows2 + 1 + Math.floor(Math.max(visibleChars(line) - 1, 0) / stdout.columns),
3845
+ 0
3963
3846
  );
3847
+ let clear2 = "";
3848
+ for (let i = 0; i < rows; i++) {
3849
+ clear2 += `${CSI}2K`;
3850
+ if (i < rows - 1) {
3851
+ clear2 += `${CSI}${i < rows - 1 ? "1A" : "G"}`;
3852
+ }
3853
+ }
3854
+ return clear2;
3964
3855
  };
3965
-
3966
- const createDatabaseCommand = (adapters, config, dontClose) => createOrDropDatabase("create", adapters, config, dontClose);
3967
- const dropDatabaseCommand = (adapters, config) => createOrDropDatabase("drop", adapters, config);
3968
- const createOrDropDatabase = async (action, adapters, config, dontClose) => {
3969
- const fn = action === "create" ? createDatabase : dropDatabase;
3970
- for (const adapter of adapters) {
3971
- const database = adapter.getDatabase();
3972
- const owner = adapter.getUser();
3973
- const res = await run(
3974
- adapter.reconfigure({ database: "postgres" }),
3975
- config,
3976
- {
3977
- command: (adapter2) => fn(adapter2, {
3978
- database,
3979
- owner
3980
- }),
3981
- doneMessage: () => `Database ${database} successfully ${action === "create" ? "created" : "dropped"}`,
3982
- alreadyMessage: () => `Database ${database} ${action === "create" ? "already exists" : "does not exist"}`,
3983
- deniedMessage: () => `Permission denied to ${action} database.`,
3984
- askAdminCreds: () => askForAdminCredentials(action === "create")
3856
+ const prompt = async ({
3857
+ render,
3858
+ onKeyPress,
3859
+ validate,
3860
+ value,
3861
+ cursor: showCursor
3862
+ }) => {
3863
+ stdin.resume();
3864
+ if (stdin.isTTY) stdin.setRawMode(true);
3865
+ stdin.setEncoding("utf-8");
3866
+ if (!showCursor) stdout.write(cursorHide);
3867
+ return new Promise((res) => {
3868
+ let prevText;
3869
+ const ctx = {
3870
+ value,
3871
+ submitted: false,
3872
+ render() {
3873
+ let text = (ctx.submitted ? colors.greenBold("\u2714") : colors.yellowBold("?")) + " " + render(ctx);
3874
+ if (ctx.submitted) text += "\n";
3875
+ stdout.write(prevText ? clear(prevText) + "\r" + text : text);
3876
+ prevText = text;
3877
+ },
3878
+ submit(value2) {
3879
+ if (value2 !== void 0) ctx.value = value2;
3880
+ if (ctx.value === void 0 || validate && !validate?.(ctx)) return;
3881
+ ctx.submitted = true;
3882
+ ctx.render();
3883
+ close();
3884
+ res(ctx.value);
3985
3885
  }
3986
- );
3987
- if (!res) continue;
3988
- if (action === "create") {
3989
- await adapter.transaction(async (tx) => {
3990
- const schema = tx.getSchema();
3991
- if (schema) {
3992
- const quoted = `"${typeof schema === "function" ? schema() : schema}"`;
3993
- const res2 = await createSchema$1(tx, quoted);
3994
- if (res2 === "done") {
3995
- config.logger?.log(`Created schema ${quoted}`);
3996
- }
3997
- }
3998
- await createMigrationsSchemaAndTable(tx, config);
3999
- });
4000
- if (!dontClose) {
4001
- await adapter.close();
3886
+ };
3887
+ const close = () => {
3888
+ if (!showCursor) stdout.write(cursorShow);
3889
+ if (stdin.isTTY) stdin.setRawMode(false);
3890
+ stdin.off("data", keypress);
3891
+ stdin.pause();
3892
+ };
3893
+ const keypress = (s) => {
3894
+ if (s === "" || s === "") {
3895
+ close?.();
3896
+ process.exit(0);
4002
3897
  }
4003
- }
4004
- }
3898
+ if (s === "\r" || s === "\n" || s === "\r\n") {
3899
+ ctx.submit();
3900
+ } else {
3901
+ onKeyPress(ctx, s);
3902
+ }
3903
+ };
3904
+ stdin.on("data", keypress);
3905
+ ctx.render();
3906
+ });
4005
3907
  };
4006
- const resetDatabaseCommand = async (adapters, config) => {
3908
+ const defaultActive = (s) => `${colors.blueBold("\u276F")} ${s}`;
3909
+ const defaultInactive = (s) => ` ${s}`;
3910
+ const promptSelect = ({
3911
+ message,
3912
+ options,
3913
+ active = defaultActive,
3914
+ inactive = defaultInactive
3915
+ }) => prompt({
3916
+ value: 0,
3917
+ render(ctx) {
3918
+ let text = `${message} ${colors.pale(
3919
+ "Use arrows or jk. Press enter to submit."
3920
+ )}
3921
+ `;
3922
+ for (let i = 0; i < options.length; i++) {
3923
+ text += (ctx.value === i ? active : inactive)(options[i]) + "\n";
3924
+ }
3925
+ return text;
3926
+ },
3927
+ onKeyPress(ctx, s) {
3928
+ ctx.value = s === "\x1B[H" ? 0 : s === "\x1B[F" ? options.length - 1 : s === "\x1B[A" || s === "k" ? ctx.value === 0 ? options.length - 1 : ctx.value - 1 : s === "\x1B[B" || s === "j" || s === " " ? ctx.value === options.length - 1 ? 0 : ctx.value + 1 : ctx.value;
3929
+ ctx.render();
3930
+ }
3931
+ });
3932
+ const promptConfirm = ({
3933
+ message
3934
+ }) => prompt({
3935
+ value: true,
3936
+ render(ctx) {
3937
+ return `${colors.bright(message)}
3938
+ ${ctx.submitted ? `> ${ctx.value ? colors.greenBold("Yes") : colors.yellowBold("No")}` : colors.pale(`> (Y/n)`)}
3939
+ `;
3940
+ },
3941
+ onKeyPress(ctx, s) {
3942
+ let ok;
3943
+ if (s === "y" || s === "Y") ok = true;
3944
+ else if (s === "n" || s === "N") ok = false;
3945
+ if (ok !== void 0) {
3946
+ ctx.submit(ok);
3947
+ }
3948
+ }
3949
+ });
3950
+ const promptText = ({
3951
+ message,
3952
+ default: def = "",
3953
+ password,
3954
+ min
3955
+ }) => {
3956
+ let showDefault = true;
3957
+ let x = 0;
3958
+ const renderValue = (ctx) => password ? "*".repeat(ctx.value.length) : ctx.value;
3959
+ return prompt({
3960
+ value: def,
3961
+ cursor: true,
3962
+ validate: (ctx) => !min || ctx.value.length >= min,
3963
+ render(ctx) {
3964
+ let text = `${colors.bright(message)}
3965
+ > ${ctx.submitted ? renderValue(ctx) : showDefault ? colors.pale(def) + "\b".repeat(def.length) : ctx.value}`;
3966
+ if (ctx.submitted) text += "\n";
3967
+ return text;
3968
+ },
3969
+ onKeyPress(ctx, s) {
3970
+ let value = showDefault ? "" : ctx.value;
3971
+ if (s === "\x1B[D" && x > 0) {
3972
+ x--;
3973
+ stdout.write("\b");
3974
+ } else if (s === "\x1B[C" && x < value.length) {
3975
+ stdout.write(value[x]);
3976
+ x++;
3977
+ }
3978
+ if (s !== "\x7F" && s !== "\x1B[3~" && !visibleChars(s)) return;
3979
+ if (showDefault) {
3980
+ showDefault = false;
3981
+ stdout.write(" ".repeat(def.length) + "\b".repeat(def.length));
3982
+ }
3983
+ const prev = value;
3984
+ const prevX = x;
3985
+ if (s === "\x7F") {
3986
+ if (x > 0) {
3987
+ value = value.slice(0, x - 1) + value.slice(x);
3988
+ x--;
3989
+ }
3990
+ } else if (s === "\x1B[3~") {
3991
+ if (x < value.length) {
3992
+ value = value.slice(0, x) + value.slice(x + 1);
3993
+ }
3994
+ } else {
3995
+ value = value.slice(0, x) + s + value.slice(x);
3996
+ x++;
3997
+ }
3998
+ ctx.value = value;
3999
+ const spaces = prev.length - value.length;
4000
+ stdout.write(
4001
+ "\b".repeat(prevX) + renderValue(ctx) + (spaces > 0 ? " ".repeat(spaces) + "\b".repeat(spaces) : "") + "\b".repeat(value.length - x)
4002
+ );
4003
+ }
4004
+ });
4005
+ };
4006
+
4007
+ const runRecurrentMigrations = async (adapters, config) => {
4008
+ let dbs;
4009
+ let files = 0;
4010
+ await readdirRecursive(config.recurrentPath, async (path) => {
4011
+ files++;
4012
+ dbs ?? (dbs = adapters.map((adapter) => createDbWithAdapter({ adapter })));
4013
+ const sql = await readFile(path, "utf-8");
4014
+ await Promise.all(
4015
+ dbs.map(async (db) => {
4016
+ await db.adapter.arrays(sql);
4017
+ })
4018
+ );
4019
+ });
4020
+ if (files > 0) {
4021
+ config.logger?.log(
4022
+ `Applied ${files} recurrent migration file${files > 1 ? "s" : ""}`
4023
+ );
4024
+ }
4025
+ };
4026
+ const readdirRecursive = async (dirPath, cb) => {
4027
+ const list = await readdir(dirPath).catch((err) => {
4028
+ if (err.code !== "ENOENT") throw err;
4029
+ return;
4030
+ });
4031
+ if (!list) return;
4032
+ await Promise.all(
4033
+ list.map(async (item) => {
4034
+ const path = join(dirPath, item);
4035
+ const info = await stat(path);
4036
+ if (info.isDirectory()) {
4037
+ await readdirRecursive(path, cb);
4038
+ } else if (info.isFile() && path.endsWith(".sql")) {
4039
+ await cb(path);
4040
+ }
4041
+ })
4042
+ );
4043
+ };
4044
+
4045
+ const createDatabaseCommand = (adapters, config, dontClose) => createOrDropDatabase("create", adapters, config, dontClose);
4046
+ const dropDatabaseCommand = (adapters, config) => createOrDropDatabase("drop", adapters, config);
4047
+ const createOrDropDatabase = async (action, adapters, config, dontClose) => {
4048
+ const fn = action === "create" ? createDatabase : dropDatabase;
4049
+ for (const adapter of adapters) {
4050
+ const database = adapter.getDatabase();
4051
+ const owner = adapter.getUser();
4052
+ const res = await run(
4053
+ adapter.reconfigure({ database: "postgres" }),
4054
+ config,
4055
+ {
4056
+ command: (adapter2) => fn(adapter2, {
4057
+ database,
4058
+ owner
4059
+ }),
4060
+ doneMessage: () => `Database ${database} successfully ${action === "create" ? "created" : "dropped"}`,
4061
+ alreadyMessage: () => `Database ${database} ${action === "create" ? "already exists" : "does not exist"}`,
4062
+ deniedMessage: () => `Permission denied to ${action} database.`,
4063
+ askAdminCreds: () => askForAdminCredentials(action === "create")
4064
+ }
4065
+ );
4066
+ if (!res) continue;
4067
+ if (action === "create") {
4068
+ await adapter.transaction(async (tx) => {
4069
+ const schema = tx.getSchema();
4070
+ if (schema) {
4071
+ const quoted = `"${typeof schema === "function" ? schema() : schema}"`;
4072
+ const res2 = await createSchema(tx, quoted);
4073
+ if (res2 === "done") {
4074
+ config.logger?.log(`Created schema ${quoted}`);
4075
+ }
4076
+ }
4077
+ await createMigrationsSchemaAndTable(tx, config);
4078
+ });
4079
+ if (!dontClose) {
4080
+ await adapter.close();
4081
+ }
4082
+ }
4083
+ }
4084
+ };
4085
+ const resetDatabaseCommand = async (adapters, config) => {
4007
4086
  await createOrDropDatabase("drop", adapters, config);
4008
4087
  await createOrDropDatabase("create", adapters, config, true);
4009
4088
  for (const adapter of adapters) {
@@ -6083,174 +6162,62 @@ Append \`as\` method manually to ${count > 1 ? "these" : "this"} column${count >
6083
6162
  config.logger?.log("Database pulled successfully");
6084
6163
  };
6085
6164
 
6086
- const migrationConfigDefaults = {
6087
- schemaConfig: defaultSchemaConfig,
6088
- migrationsPath: path.join("src", "db", "migrations"),
6089
- migrationId: { serial: 4 },
6090
- migrationsTable: "schemaMigrations",
6091
- snakeCase: false,
6092
- commands: {},
6093
- log: true,
6094
- logger: console,
6095
- import() {
6096
- throw new Error(
6097
- "Add `import: (path) => import(path),` setting to `rakeDb` config"
6098
- );
6099
- }
6100
- };
6101
- const ensureMigrationsPath = (config) => {
6102
- if (!config.migrationsPath) {
6103
- config.migrationsPath = migrationConfigDefaults.migrationsPath;
6104
- }
6105
- if (!path.isAbsolute(config.migrationsPath)) {
6106
- config.migrationsPath = path.resolve(
6107
- config.basePath,
6108
- config.migrationsPath
6109
- );
6165
+ const listMigrationsStatuses = async (adapters, config, params) => {
6166
+ const ctx = {};
6167
+ const [{ migrations }, ...migrated] = await Promise.all([
6168
+ getMigrations(ctx, config, true),
6169
+ ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
6170
+ ]);
6171
+ const map = {};
6172
+ let maxVersionLength = 12;
6173
+ let maxNameLength = 4;
6174
+ for (let i = 0; i < adapters.length; i++) {
6175
+ const list = migrated[i];
6176
+ const key = Object.entries(list.map).map(([version, up]) => `${version}${up ? "t" : "f"}`).join("");
6177
+ const database = adapters[i].getDatabase();
6178
+ if (map[key]) {
6179
+ map[key].databases.push(database);
6180
+ continue;
6181
+ }
6182
+ map[key] = {
6183
+ databases: [database],
6184
+ migrations: migrations.map((item) => {
6185
+ if (item.version.length > maxVersionLength) {
6186
+ maxVersionLength = item.version.length;
6187
+ }
6188
+ const name = path.parse(item.path).name.slice(item.version.length + 1).replace(
6189
+ /([a-z])([A-Z])/g,
6190
+ (_, a, b) => `${a} ${b.toLocaleLowerCase()}`
6191
+ ).replace(/[-_](.)/g, (_, char) => ` ${char.toLocaleLowerCase()}`).replace(/^\w/, (match) => match.toLocaleUpperCase());
6192
+ if (name.length > maxNameLength) {
6193
+ maxNameLength = name.length;
6194
+ }
6195
+ return {
6196
+ up: !!list.map[item.version],
6197
+ version: item.version,
6198
+ name,
6199
+ url: pathToFileURL(item.path)
6200
+ };
6201
+ })
6202
+ };
6110
6203
  }
6111
- return config;
6112
- };
6113
- const ensureBasePathAndDbScript = (config, intermediateCallers2 = 0) => {
6114
- if (config.basePath && config.dbScript) return config;
6115
- let filePath = getStackTrace()?.[3 + intermediateCallers2]?.getFileName();
6116
- if (!filePath) {
6117
- throw new Error(
6118
- "Failed to determine path to db script. Please set basePath option of rakeDb"
6119
- );
6120
- }
6121
- if (filePath.startsWith("file://")) {
6122
- filePath = fileURLToPath(filePath);
6123
- }
6124
- const ext = path.extname(filePath);
6125
- if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
6126
- throw new Error(
6127
- `Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
6128
- );
6129
- }
6130
- config.basePath = path.dirname(filePath);
6131
- config.dbScript = path.basename(filePath);
6132
- return config;
6133
- };
6134
- let intermediateCallers = 0;
6135
- const incrementIntermediateCaller = () => {
6136
- intermediateCallers++;
6137
- };
6138
- const makeRakeDbConfig = (config, args) => {
6139
- const ic = intermediateCallers;
6140
- intermediateCallers = 0;
6141
- const result = {
6142
- ...migrationConfigDefaults,
6143
- ...config,
6144
- __rakeDbConfig: true
6145
- };
6146
- if (!result.log) {
6147
- delete result.logger;
6148
- }
6149
- ensureBasePathAndDbScript(result, ic);
6150
- ensureMigrationsPath(result);
6151
- if (!result.recurrentPath) {
6152
- result.recurrentPath = path.join(
6153
- result.migrationsPath,
6154
- "recurrent"
6155
- );
6156
- }
6157
- if ("recurrentPath" in result && !path.isAbsolute(result.recurrentPath)) {
6158
- result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
6159
- }
6160
- if ("baseTable" in config && config.baseTable) {
6161
- const { types, snakeCase, language } = config.baseTable.prototype;
6162
- result.columnTypes = types || makeColumnTypes(defaultSchemaConfig);
6163
- if (snakeCase) result.snakeCase = true;
6164
- if (language) result.language = language;
6165
- } else {
6166
- const ct = "columnTypes" in config && config.columnTypes;
6167
- result.columnTypes = (typeof ct === "function" ? ct(
6168
- makeColumnTypes(defaultSchemaConfig)
6169
- ) : ct) || makeColumnTypes(defaultSchemaConfig);
6170
- }
6171
- if (config.migrationId === "serial") {
6172
- result.migrationId = { serial: 4 };
6173
- }
6174
- const transaction = getCliParam(args, "transaction");
6175
- if (transaction) {
6176
- if (transaction !== "single" && transaction !== "per-migration") {
6177
- throw new Error(
6178
- `Unsupported transaction param ${transaction}, expected single or per-migration`
6179
- );
6180
- }
6181
- result.transaction = transaction;
6182
- } else if (!result.transaction) {
6183
- result.transaction = "single";
6184
- }
6185
- let c = rakeDbCommands;
6186
- if (config.commands) {
6187
- c = { ...c };
6188
- const commands = config.commands;
6189
- for (const key in commands) {
6190
- const command = commands[key];
6191
- c[key] = typeof command === "function" ? { run: command } : command;
6192
- }
6193
- }
6194
- result.commands = c;
6195
- return result;
6196
- };
6197
-
6198
- const listMigrationsStatuses = async (adapters, config, params) => {
6199
- const ctx = {};
6200
- const [{ migrations }, ...migrated] = await Promise.all([
6201
- getMigrations(ctx, config, true),
6202
- ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
6203
- ]);
6204
- const map = {};
6205
- let maxVersionLength = 12;
6206
- let maxNameLength = 4;
6207
- for (let i = 0; i < adapters.length; i++) {
6208
- const list = migrated[i];
6209
- const key = Object.entries(list.map).map(([version, up]) => `${version}${up ? "t" : "f"}`).join("");
6210
- const database = adapters[i].getDatabase();
6211
- if (map[key]) {
6212
- map[key].databases.push(database);
6213
- continue;
6214
- }
6215
- map[key] = {
6216
- databases: [database],
6217
- migrations: migrations.map((item) => {
6218
- if (item.version.length > maxVersionLength) {
6219
- maxVersionLength = item.version.length;
6220
- }
6221
- const name = path.parse(item.path).name.slice(item.version.length + 1).replace(
6222
- /([a-z])([A-Z])/g,
6223
- (_, a, b) => `${a} ${b.toLocaleLowerCase()}`
6224
- ).replace(/[-_](.)/g, (_, char) => ` ${char.toLocaleLowerCase()}`).replace(/^\w/, (match) => match.toLocaleUpperCase());
6225
- if (name.length > maxNameLength) {
6226
- maxNameLength = name.length;
6227
- }
6228
- return {
6229
- up: !!list.map[item.version],
6230
- version: item.version,
6231
- name,
6232
- url: pathToFileURL(item.path)
6233
- };
6234
- })
6235
- };
6236
- }
6237
- const showUrl = params?.showUrl;
6238
- const asIs = (s) => s;
6239
- const c = typeof config.log === "object" && config.log.colors === false ? {
6240
- yellow: asIs,
6241
- green: asIs,
6242
- red: asIs,
6243
- blue: asIs
6244
- } : colors;
6245
- const log = Object.values(map).map(({ databases, migrations: migrations2 }) => {
6246
- let log2 = ` ${c.yellow("Database:")} ${databases.join(", ")}`;
6247
- if (migrations2.length === 0) {
6248
- return log2 + `
6249
-
6250
- No migrations available`;
6251
- }
6252
- const lineSeparator = c.yellow(
6253
- makeChars(14 + maxVersionLength + maxNameLength, "-")
6204
+ const showUrl = params?.showUrl;
6205
+ const asIs = (s) => s;
6206
+ const c = typeof config.log === "object" && config.log.colors === false ? {
6207
+ yellow: asIs,
6208
+ green: asIs,
6209
+ red: asIs,
6210
+ blue: asIs
6211
+ } : colors;
6212
+ const log = Object.values(map).map(({ databases, migrations: migrations2 }) => {
6213
+ let log2 = ` ${c.yellow("Database:")} ${databases.join(", ")}`;
6214
+ if (migrations2.length === 0) {
6215
+ return log2 + `
6216
+
6217
+ No migrations available`;
6218
+ }
6219
+ const lineSeparator = c.yellow(
6220
+ makeChars(14 + maxVersionLength + maxNameLength, "-")
6254
6221
  );
6255
6222
  const columnSeparator = c.yellow("|");
6256
6223
  log2 += "\n\n " + c.yellow(
@@ -6439,6 +6406,196 @@ const rebase = async (adapters, config) => {
6439
6406
  }
6440
6407
  };
6441
6408
 
6409
+ const close = (adapters) => Promise.all(adapters.map((adapter) => adapter.close()));
6410
+ const maybeRunRecurrent = async (adapters, config) => {
6411
+ config.recurrentPath && await runRecurrentMigrations(
6412
+ adapters,
6413
+ config
6414
+ );
6415
+ };
6416
+ const rakeDbAliases$1 = {
6417
+ migrate: "up",
6418
+ rollback: "down",
6419
+ s: "status",
6420
+ rec: "recurrent"
6421
+ };
6422
+ const upCommand = {
6423
+ run: (adapters, config, args) => migrateCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
6424
+ help: "migrate pending migrations",
6425
+ helpArguments: {
6426
+ "no arguments": "migrate all pending",
6427
+ "a number": "run a specific number of pending migrations",
6428
+ force: "enforce migrating a pending file in the middle"
6429
+ }
6430
+ };
6431
+ const downCommand = {
6432
+ run: (adapters, config, args) => rollbackCommand(adapters, config, args).then(() => close(adapters)),
6433
+ help: "rollback migrated migrations",
6434
+ helpArguments: {
6435
+ "no arguments": "rollback one last migration",
6436
+ "a number": "rollback a specified number",
6437
+ all: "rollback all migrations"
6438
+ }
6439
+ };
6440
+ const statusCommand = {
6441
+ run(adapters, config, args) {
6442
+ const showUrl = args.includes("p") || args.includes("path");
6443
+ return listMigrationsStatuses(adapters, config, { showUrl });
6444
+ },
6445
+ help: "list migrations statuses",
6446
+ helpArguments: {
6447
+ "no arguments": `does not print file paths`,
6448
+ "p, path": "also print file paths"
6449
+ }
6450
+ };
6451
+ const recurrent = {
6452
+ async run(adapters, config) {
6453
+ if (!config.recurrentPath) return;
6454
+ await maybeRunRecurrent(adapters, config).then(() => close(adapters));
6455
+ },
6456
+ help: "run recurrent migrations"
6457
+ };
6458
+ const rakeDbCommands = {
6459
+ create: {
6460
+ run: (adapters, config) => createDatabaseCommand(adapters, config),
6461
+ help: "create databases"
6462
+ },
6463
+ drop: {
6464
+ run: dropDatabaseCommand,
6465
+ help: "drop databases"
6466
+ },
6467
+ reset: {
6468
+ run: (adapters, config) => resetDatabaseCommand(adapters, config),
6469
+ help: "drop, create and migrate databases"
6470
+ },
6471
+ up: upCommand,
6472
+ down: downCommand,
6473
+ redo: {
6474
+ run: (adapters, config, args) => redoCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
6475
+ help: "rollback and migrate, run recurrent"
6476
+ },
6477
+ pull: {
6478
+ run: ([adapter], config) => pullDbStructure(adapter, config).then(() => close([adapter])),
6479
+ help: "generate a combined migration for an existing database"
6480
+ },
6481
+ new: {
6482
+ run(_, config, args) {
6483
+ const [name] = args;
6484
+ if (!name) throw new Error("Migration name is missing");
6485
+ return newMigration(config, name);
6486
+ },
6487
+ help: "create new migration file"
6488
+ },
6489
+ status: statusCommand,
6490
+ recurrent,
6491
+ rebase: {
6492
+ run: (adapters, config) => rebase(adapters, config).then(() => close(adapters)),
6493
+ help: "move local migrations below the new ones from upstream"
6494
+ },
6495
+ "change-ids": {
6496
+ run(adapters, config, [format, digitsArg]) {
6497
+ if (format !== "serial" && format !== "timestamp") {
6498
+ throw new Error(
6499
+ `Pass "serial" or "timestamp" argument to the "change-ids" command`
6500
+ );
6501
+ }
6502
+ const digits = digitsArg ? parseInt(digitsArg) : void 0;
6503
+ if (digits && isNaN(digits)) {
6504
+ throw new Error(`Second argument is optional and must be an integer`);
6505
+ }
6506
+ return changeIds(adapters, config, { format, digits });
6507
+ },
6508
+ help: "change migrations ids format",
6509
+ helpArguments: {
6510
+ serial: "change ids to 4 digit serial",
6511
+ "serial *number*": "change ids to serial number of custom length",
6512
+ timestamp: "change timestamps"
6513
+ }
6514
+ }
6515
+ };
6516
+ for (const key in rakeDbAliases$1) {
6517
+ const command = rakeDbAliases$1[key];
6518
+ if (command) rakeDbCommands[key] = rakeDbCommands[command];
6519
+ }
6520
+ let intermediateCallers = 0;
6521
+ const incrementIntermediateCaller = () => {
6522
+ intermediateCallers++;
6523
+ };
6524
+ const ensureBasePathAndDbScript = (config, intermediateCallers2 = 0) => {
6525
+ if (config.basePath && config.dbScript) return config;
6526
+ let filePath = getStackTrace()?.[3 + intermediateCallers2]?.getFileName();
6527
+ if (!filePath) {
6528
+ throw new Error(
6529
+ "Failed to determine path to db script. Please set basePath option of rakeDb"
6530
+ );
6531
+ }
6532
+ if (filePath.startsWith("file://")) {
6533
+ filePath = fileURLToPath(filePath);
6534
+ }
6535
+ const ext = path.extname(filePath);
6536
+ if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
6537
+ throw new Error(
6538
+ `Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
6539
+ );
6540
+ }
6541
+ config.basePath = path.dirname(filePath);
6542
+ config.dbScript = path.basename(filePath);
6543
+ return config;
6544
+ };
6545
+ const makeRakeDbConfig = (config, args) => {
6546
+ const ic = intermediateCallers;
6547
+ intermediateCallers = 0;
6548
+ const result = {
6549
+ ...rakeDbConfigDefaults,
6550
+ ...config,
6551
+ __rakeDbConfig: true
6552
+ };
6553
+ ensureBasePathAndDbScript(result, ic);
6554
+ Object.assign(result, processMigrateConfig(result));
6555
+ if (!result.recurrentPath && result.migrationsPath) {
6556
+ result.recurrentPath = path.join(result.migrationsPath, "recurrent");
6557
+ }
6558
+ if (result.recurrentPath && !path.isAbsolute(result.recurrentPath)) {
6559
+ result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
6560
+ }
6561
+ if ("baseTable" in config && config.baseTable) {
6562
+ const { types, snakeCase, language } = config.baseTable.prototype;
6563
+ result.columnTypes = types || makeColumnTypes(defaultSchemaConfig);
6564
+ if (snakeCase) result.snakeCase = true;
6565
+ if (language) result.language = language;
6566
+ } else {
6567
+ const ct = "columnTypes" in config && config.columnTypes;
6568
+ result.columnTypes = (typeof ct === "function" ? ct(
6569
+ makeColumnTypes(defaultSchemaConfig)
6570
+ ) : ct) || makeColumnTypes(defaultSchemaConfig);
6571
+ }
6572
+ if (config.migrationId === "serial") {
6573
+ result.migrationId = { serial: 4 };
6574
+ }
6575
+ const transaction = getCliParam(args, "transaction");
6576
+ if (transaction) {
6577
+ if (transaction !== "single" && transaction !== "per-migration") {
6578
+ throw new Error(
6579
+ `Unsupported transaction param ${transaction}, expected single or per-migration`
6580
+ );
6581
+ }
6582
+ result.transaction = transaction;
6583
+ } else if (!result.transaction) {
6584
+ result.transaction = "single";
6585
+ }
6586
+ let c = rakeDbCommands;
6587
+ if (config.commands) {
6588
+ c = { ...c };
6589
+ const commands = config.commands;
6590
+ for (const key in commands) {
6591
+ const command = commands[key];
6592
+ c[key] = typeof command === "function" ? { run: command } : command;
6593
+ }
6594
+ }
6595
+ result.commands = c;
6596
+ return result;
6597
+ };
6598
+
6442
6599
  const rakeDbAliases = {
6443
6600
  migrate: "up",
6444
6601
  rollback: "down",
@@ -6454,7 +6611,7 @@ const rakeDbCliWithAdapter = (inputConfig, args = process.argv.slice(2)) => {
6454
6611
  config = makeRakeDbConfig(inputConfig, args);
6455
6612
  }
6456
6613
  return {
6457
- change: makeChange(config),
6614
+ change: createMigrationChangeFn(config),
6458
6615
  async run(adapter, runArgs) {
6459
6616
  const adapters = toArray(adapter);
6460
6617
  try {
@@ -6548,111 +6705,6 @@ ${Object.entries(helpArguments).map(
6548
6705
  `);
6549
6706
  }
6550
6707
  };
6551
- const close = (adapters) => Promise.all(adapters.map((adapter) => adapter.close()));
6552
- const maybeRunRecurrent = async (adapters, config) => {
6553
- config.recurrentPath && await runRecurrentMigrations(
6554
- adapters,
6555
- config
6556
- );
6557
- };
6558
- const upCommand = {
6559
- run: (adapters, config, args) => migrateCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
6560
- help: "migrate pending migrations",
6561
- helpArguments: {
6562
- "no arguments": "migrate all pending",
6563
- "a number": "run a specific number of pending migrations",
6564
- force: "enforce migrating a pending file in the middle"
6565
- }
6566
- };
6567
- const downCommand = {
6568
- run: (adapters, config, args) => rollbackCommand(adapters, config, args).then(() => close(adapters)),
6569
- help: "rollback migrated migrations",
6570
- helpArguments: {
6571
- "no arguments": "rollback one last migration",
6572
- "a number": "rollback a specified number",
6573
- all: "rollback all migrations"
6574
- }
6575
- };
6576
- const statusCommand = {
6577
- run(adapters, config, args) {
6578
- const showUrl = args.includes("p") || args.includes("path");
6579
- return listMigrationsStatuses(adapters, config, { showUrl });
6580
- },
6581
- help: "list migrations statuses",
6582
- helpArguments: {
6583
- "no arguments": `does not print file paths`,
6584
- "p, path": "also print file paths"
6585
- }
6586
- };
6587
- const recurrent = {
6588
- async run(adapters, config) {
6589
- if (!config.recurrentPath) return;
6590
- await maybeRunRecurrent(adapters, config).then(() => close(adapters));
6591
- },
6592
- help: "run recurrent migrations"
6593
- };
6594
- const rakeDbCommands = {
6595
- create: {
6596
- run: (adapters, config) => createDatabaseCommand(adapters, config),
6597
- help: "create databases"
6598
- },
6599
- drop: {
6600
- run: dropDatabaseCommand,
6601
- help: "drop databases"
6602
- },
6603
- reset: {
6604
- run: (adapters, config) => resetDatabaseCommand(adapters, config),
6605
- help: "drop, create and migrate databases"
6606
- },
6607
- up: upCommand,
6608
- down: downCommand,
6609
- redo: {
6610
- run: (adapters, config, args) => redoCommand(adapters, config, args).then(() => maybeRunRecurrent(adapters, config)).then(() => close(adapters)),
6611
- help: "rollback and migrate, run recurrent"
6612
- },
6613
- pull: {
6614
- run: ([adapter], config) => pullDbStructure(adapter, config).then(() => close([adapter])),
6615
- help: "generate a combined migration for an existing database"
6616
- },
6617
- new: {
6618
- run(_, config, args) {
6619
- const [name] = args;
6620
- if (!name) throw new Error("Migration name is missing");
6621
- return newMigration(config, name);
6622
- },
6623
- help: "create new migration file"
6624
- },
6625
- status: statusCommand,
6626
- recurrent,
6627
- rebase: {
6628
- run: (adapters, config) => rebase(adapters, config).then(() => close(adapters)),
6629
- help: "move local migrations below the new ones from upstream"
6630
- },
6631
- "change-ids": {
6632
- run(adapters, config, [format, digitsArg]) {
6633
- if (format !== "serial" && format !== "timestamp") {
6634
- throw new Error(
6635
- `Pass "serial" or "timestamp" argument to the "change-ids" command`
6636
- );
6637
- }
6638
- const digits = digitsArg ? parseInt(digitsArg) : void 0;
6639
- if (digits && isNaN(digits)) {
6640
- throw new Error(`Second argument is optional and must be an integer`);
6641
- }
6642
- return changeIds(adapters, config, { format, digits });
6643
- },
6644
- help: "change migrations ids format",
6645
- helpArguments: {
6646
- serial: "change ids to 4 digit serial",
6647
- "serial *number*": "change ids to serial number of custom length",
6648
- timestamp: "change ids to timestamps"
6649
- }
6650
- }
6651
- };
6652
- for (const key in rakeDbAliases) {
6653
- const command = rakeDbAliases[key];
6654
- if (command) rakeDbCommands[key] = rakeDbCommands[command];
6655
- }
6656
6708
 
6657
- export { RakeDbError, astToMigration, concatSchemaAndName, createDatabase, createMigrationInterface, createMigrationsSchemaAndTable, createSchema$1 as createSchema, createTable$1 as createTable, dbColumnToAst, dropDatabase, dropSchema, dropTable, encodeColumnDefault, getConstraintName, getDbStructureTableData, getDbTableColumnsChecks, getDbVersion, getExcludeName, getIndexName, getMigrationsSchemaAndTable, getSchemaAndTableFromName, incrementIntermediateCaller, instantiateDbColumn, introspectDbSchema, makeDomainsMap, makeFileVersion, makeRakeDbConfig, makeStructureToAstCtx, migrate, migrateAndClose, migrationConfigDefaults, promptSelect, rakeDbCliWithAdapter, rakeDbCommands, redo, rollback, runMigration, saveMigratedVersion, setRakeDbCliRunFn, structureToAst, tableToAst, writeMigrationFile };
6709
+ export { RakeDbError, astToMigration, concatSchemaAndName, createDatabase, createMigrationChangeFn, createMigrationInterface, createMigrationsSchemaAndTable, createSchema, createTable, dbColumnToAst, dropDatabase, dropSchema, dropTable, encodeColumnDefault, getConstraintName, getDbStructureTableData, getDbTableColumnsChecks, getDbVersion, getExcludeName, getIndexName, getMigrationsSchemaAndTable, getSchemaAndTableFromName, incrementIntermediateCaller, instantiateDbColumn, introspectDbSchema, makeDomainsMap, makeFileVersion, makeStructureToAstCtx, migrate, migrateAndClose, promptSelect, rakeDbCliWithAdapter, rakeDbCommands, rakeDbConfigDefaults, redo, rollback, runMigration, saveMigratedVersion, setRakeDbCliRunFn, structureToAst, tableToAst, writeMigrationFile };
6658
6710
  //# sourceMappingURL=index.mjs.map