rake-db 2.14.4 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,206 +3,11 @@
3
3
  var pqb = require('pqb');
4
4
  var orchidCore = require('orchid-core');
5
5
  var path = require('path');
6
- var promises = require('fs/promises');
7
- var prompts = require('prompts');
8
6
  var node_url = require('node:url');
7
+ var fs = require('fs/promises');
8
+ var prompts = require('prompts');
9
+ var rakeDb$1 = require('rake-db');
9
10
 
10
- var __defProp$7 = Object.defineProperty;
11
- var __defProps$5 = Object.defineProperties;
12
- var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors;
13
- var __getOwnPropSymbols$7 = Object.getOwnPropertySymbols;
14
- var __hasOwnProp$7 = Object.prototype.hasOwnProperty;
15
- var __propIsEnum$7 = Object.prototype.propertyIsEnumerable;
16
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
17
- var __spreadValues$7 = (a, b) => {
18
- for (var prop in b || (b = {}))
19
- if (__hasOwnProp$7.call(b, prop))
20
- __defNormalProp$7(a, prop, b[prop]);
21
- if (__getOwnPropSymbols$7)
22
- for (var prop of __getOwnPropSymbols$7(b)) {
23
- if (__propIsEnum$7.call(b, prop))
24
- __defNormalProp$7(a, prop, b[prop]);
25
- }
26
- return a;
27
- };
28
- var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
29
- var __objRest$2 = (source, exclude) => {
30
- var target = {};
31
- for (var prop in source)
32
- if (__hasOwnProp$7.call(source, prop) && exclude.indexOf(prop) < 0)
33
- target[prop] = source[prop];
34
- if (source != null && __getOwnPropSymbols$7)
35
- for (var prop of __getOwnPropSymbols$7(source)) {
36
- if (exclude.indexOf(prop) < 0 && __propIsEnum$7.call(source, prop))
37
- target[prop] = source[prop];
38
- }
39
- return target;
40
- };
41
- const migrationConfigDefaults = {
42
- schemaConfig: pqb.defaultSchemaConfig,
43
- migrationsPath: path.join("src", "db", "migrations"),
44
- migrationsTable: "schemaMigrations",
45
- snakeCase: false,
46
- commands: {},
47
- import: (path2) => {
48
- return import(path2).catch((err) => {
49
- if (err.code === "ERR_UNKNOWN_FILE_EXTENSION") {
50
- require(path2);
51
- } else {
52
- throw err;
53
- }
54
- });
55
- },
56
- log: true,
57
- logger: console,
58
- useCodeUpdater: true
59
- };
60
- const processRakeDbConfig = (config) => {
61
- var _a, _b;
62
- const result = __spreadValues$7(__spreadValues$7({}, migrationConfigDefaults), config);
63
- if (!result.recurrentPath) {
64
- result.recurrentPath = path.join(result.migrationsPath, "recurrent");
65
- }
66
- if (config.appCodeUpdater && (!("baseTable" in config) || !config.baseTable)) {
67
- throw new Error(
68
- "`baseTable` option is required in `rakeDb` for `appCodeUpdater`"
69
- );
70
- }
71
- if (!result.log) {
72
- delete result.logger;
73
- }
74
- if (!result.basePath || !result.dbScript) {
75
- let filePath = (_a = orchidCore.getStackTrace()) == null ? void 0 : _a[3].getFileName();
76
- if (!filePath) {
77
- throw new Error(
78
- "Failed to determine path to db script. Please set basePath option of rakeDb"
79
- );
80
- }
81
- if (filePath.startsWith("file://")) {
82
- filePath = node_url.fileURLToPath(filePath);
83
- }
84
- const ext = path.extname(filePath);
85
- if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
86
- throw new Error(
87
- `Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
88
- );
89
- }
90
- result.basePath = path.dirname(filePath);
91
- result.dbScript = path.basename(filePath);
92
- }
93
- if ("migrationsPath" in result && !path.isAbsolute(result.migrationsPath)) {
94
- result.migrationsPath = path.resolve(
95
- result.basePath,
96
- result.migrationsPath
97
- );
98
- }
99
- if ("recurrentPath" in result && !path.isAbsolute(result.recurrentPath)) {
100
- result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
101
- }
102
- if ("baseTable" in config) {
103
- const proto = (_b = config.baseTable) == null ? void 0 : _b.prototype;
104
- result.columnTypes = proto.types || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
105
- if (proto.snakeCase)
106
- result.snakeCase = true;
107
- if (proto.language)
108
- result.language = proto.language;
109
- } else {
110
- const ct = "columnTypes" in config && config.columnTypes;
111
- result.columnTypes = (typeof ct === "function" ? ct(
112
- pqb.makeColumnTypes(pqb.defaultSchemaConfig)
113
- ) : ct) || pqb.makeColumnTypes;
114
- }
115
- return result;
116
- };
117
- const getDatabaseAndUserFromOptions = (options) => {
118
- if (options.databaseURL) {
119
- const url = new URL(options.databaseURL);
120
- return {
121
- database: url.pathname.slice(1),
122
- user: url.username
123
- };
124
- } else {
125
- return {
126
- database: options.database,
127
- user: options.user
128
- };
129
- }
130
- };
131
- const setAdapterOptions = (options, set) => {
132
- if (options.databaseURL) {
133
- const url = new URL(options.databaseURL);
134
- if ("database" in set) {
135
- url.pathname = `/${set.database}`;
136
- }
137
- if (set.user !== void 0) {
138
- url.username = set.user;
139
- }
140
- if (set.password !== void 0) {
141
- url.password = set.password;
142
- }
143
- return __spreadProps$5(__spreadValues$7({}, options), { databaseURL: url.toString() });
144
- } else {
145
- return __spreadValues$7(__spreadValues$7({}, options), set);
146
- }
147
- };
148
- const setAdminCredentialsToOptions = async (options, create) => {
149
- const confirm = await prompts([
150
- {
151
- message: `Would you like to share admin credentials to ${create ? "create" : "drop"} a database`,
152
- type: "confirm",
153
- name: "confirm",
154
- initial: true
155
- }
156
- ]);
157
- if (!confirm.confirm) {
158
- return;
159
- }
160
- const values = await prompts([
161
- {
162
- message: "Enter admin user:",
163
- type: "text",
164
- name: "user",
165
- initial: "postgres",
166
- min: 1
167
- },
168
- {
169
- message: "Enter admin password:",
170
- type: "password",
171
- name: "password"
172
- }
173
- ]);
174
- return setAdapterOptions(options, __spreadProps$5(__spreadValues$7({}, values), {
175
- password: values.password || void 0
176
- }));
177
- };
178
- const createSchemaMigrations = async (db, config) => {
179
- var _a, _b, _c;
180
- const { schema } = db;
181
- if (schema && schema !== "public") {
182
- try {
183
- await db.query(`CREATE SCHEMA "${schema}"`);
184
- (_a = config.logger) == null ? void 0 : _a.log(`Created schema ${schema}`);
185
- } catch (err) {
186
- if (err.code !== "42P06") {
187
- throw err;
188
- }
189
- }
190
- }
191
- try {
192
- await db.query(
193
- `CREATE TABLE ${quoteWithSchema({
194
- name: config.migrationsTable
195
- })} ( version TEXT NOT NULL )`
196
- );
197
- (_b = config.logger) == null ? void 0 : _b.log("Created versions table");
198
- } catch (err) {
199
- if (err.code === "42P07") {
200
- (_c = config.logger) == null ? void 0 : _c.log("Versions table exists");
201
- } else {
202
- throw err;
203
- }
204
- }
205
- };
206
11
  const getFirstWordAndRest = (input) => {
207
12
  const index = input.search(/(?=[A-Z])|[-_]/);
208
13
  if (index !== -1) {
@@ -230,73 +35,6 @@ const getTextAfterTo = (input) => {
230
35
  const getTextAfterFrom = (input) => {
231
36
  return getTextAfterRegExp(input, /(From|-from|_from)[A-Z-_]/, 4);
232
37
  };
233
- const getMigrations = async (_a, up) => {
234
- var _b = _a, {
235
- migrations
236
- } = _b, config = __objRest$2(_b, [
237
- "migrations"
238
- ]);
239
- return migrations ? getMigrationsFromConfig(__spreadProps$5(__spreadValues$7({}, config), { migrations }), up) : getMigrationsFromFiles(config, up);
240
- };
241
- function getMigrationsFromConfig(config, up) {
242
- const result = [];
243
- const { migrations, basePath } = config;
244
- for (const key in migrations) {
245
- result.push({
246
- path: path.resolve(basePath, key),
247
- version: getVersion(path.basename(key)),
248
- load: migrations[key]
249
- });
250
- }
251
- return up ? result : result.reverse();
252
- }
253
- async function getMigrationsFromFiles(config, up) {
254
- const { migrationsPath, import: imp } = config;
255
- let files;
256
- try {
257
- files = await promises.readdir(migrationsPath);
258
- } catch (_) {
259
- return [];
260
- }
261
- files = files.filter((file) => path.basename(file).includes("."));
262
- files = (up ? sortAsc : sortDesc)(files);
263
- return files.map((file) => {
264
- checkExt(file);
265
- const filePath = path.resolve(migrationsPath, file);
266
- return {
267
- path: filePath,
268
- version: getVersion(file),
269
- async load() {
270
- try {
271
- await imp(filePath);
272
- } catch (err) {
273
- if (err.code !== "ERR_UNSUPPORTED_ESM_URL_SCHEME")
274
- throw err;
275
- await imp(node_url.pathToFileURL(filePath).pathname);
276
- }
277
- }
278
- };
279
- });
280
- }
281
- function checkExt(filePath) {
282
- const ext = path.extname(filePath);
283
- if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
284
- throw new Error(
285
- `Only .ts, .js, and .mjs files are supported for migration, received: ${path}`
286
- );
287
- }
288
- }
289
- function getVersion(path2) {
290
- const timestampMatch = path2.match(/^(\d{14})\D/);
291
- if (!timestampMatch) {
292
- throw new Error(
293
- `Migration file name should start with 14 digit version, received ${path2}`
294
- );
295
- }
296
- return timestampMatch[1];
297
- }
298
- const sortAsc = (arr) => arr.sort();
299
- const sortDesc = (arr) => arr.sort((a, b) => a > b ? -1 : 1);
300
38
  const joinColumns = (columns) => {
301
39
  return columns.map((column) => `"${column}"`).join(", ");
302
40
  };
@@ -332,6 +70,14 @@ const makePopulateEnumQuery = (item) => {
332
70
  }
333
71
  };
334
72
  };
73
+ const begin = {
74
+ text: "BEGIN",
75
+ values: orchidCore.emptyArray
76
+ };
77
+ const transaction = (adapter, fn) => {
78
+ return adapter.transaction(begin, fn);
79
+ };
80
+ const queryLock = (trx) => trx.query(`SELECT pg_advisory_xact_lock('${RAKE_DB_LOCK_KEY}')`);
335
81
 
336
82
  let currentChanges = [];
337
83
  const clearChanges = () => {
@@ -340,25 +86,25 @@ const clearChanges = () => {
340
86
  const getCurrentChanges = () => currentChanges;
341
87
  const pushChange = (fn) => currentChanges.push(fn);
342
88
 
343
- var __defProp$6 = Object.defineProperty;
344
- var __defProps$4 = Object.defineProperties;
345
- var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
346
- var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
347
- var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
348
- var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
349
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
350
- var __spreadValues$6 = (a, b) => {
89
+ var __defProp$a = Object.defineProperty;
90
+ var __defProps$7 = Object.defineProperties;
91
+ var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors;
92
+ var __getOwnPropSymbols$a = Object.getOwnPropertySymbols;
93
+ var __hasOwnProp$a = Object.prototype.hasOwnProperty;
94
+ var __propIsEnum$a = Object.prototype.propertyIsEnumerable;
95
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
96
+ var __spreadValues$a = (a, b) => {
351
97
  for (var prop in b || (b = {}))
352
- if (__hasOwnProp$6.call(b, prop))
353
- __defNormalProp$6(a, prop, b[prop]);
354
- if (__getOwnPropSymbols$6)
355
- for (var prop of __getOwnPropSymbols$6(b)) {
356
- if (__propIsEnum$6.call(b, prop))
357
- __defNormalProp$6(a, prop, b[prop]);
98
+ if (__hasOwnProp$a.call(b, prop))
99
+ __defNormalProp$a(a, prop, b[prop]);
100
+ if (__getOwnPropSymbols$a)
101
+ for (var prop of __getOwnPropSymbols$a(b)) {
102
+ if (__propIsEnum$a.call(b, prop))
103
+ __defNormalProp$a(a, prop, b[prop]);
358
104
  }
359
105
  return a;
360
106
  };
361
- var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
107
+ var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
362
108
  const columnTypeToSql = (item) => {
363
109
  return item.data.isOfCustomType ? `"${item.toSQL()}"` : item.toSQL();
364
110
  };
@@ -452,7 +198,7 @@ const addColumnIndex = (indexes, name, item) => {
452
198
  if (item.data.indexes) {
453
199
  indexes.push(
454
200
  ...item.data.indexes.map((index) => ({
455
- columns: [__spreadProps$4(__spreadValues$6({}, index), { column: name })],
201
+ columns: [__spreadProps$7(__spreadValues$a({}, index), { column: name })],
456
202
  options: index
457
203
  }))
458
204
  );
@@ -634,33 +380,33 @@ class RakeDbError extends Error {
634
380
  class NoPrimaryKey extends RakeDbError {
635
381
  }
636
382
 
637
- var __defProp$5 = Object.defineProperty;
638
- var __defProps$3 = Object.defineProperties;
639
- var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
640
- var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
641
- var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
642
- var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
643
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
644
- var __spreadValues$5 = (a, b) => {
383
+ var __defProp$9 = Object.defineProperty;
384
+ var __defProps$6 = Object.defineProperties;
385
+ var __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors;
386
+ var __getOwnPropSymbols$9 = Object.getOwnPropertySymbols;
387
+ var __hasOwnProp$9 = Object.prototype.hasOwnProperty;
388
+ var __propIsEnum$9 = Object.prototype.propertyIsEnumerable;
389
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
390
+ var __spreadValues$9 = (a, b) => {
645
391
  for (var prop in b || (b = {}))
646
- if (__hasOwnProp$5.call(b, prop))
647
- __defNormalProp$5(a, prop, b[prop]);
648
- if (__getOwnPropSymbols$5)
649
- for (var prop of __getOwnPropSymbols$5(b)) {
650
- if (__propIsEnum$5.call(b, prop))
651
- __defNormalProp$5(a, prop, b[prop]);
392
+ if (__hasOwnProp$9.call(b, prop))
393
+ __defNormalProp$9(a, prop, b[prop]);
394
+ if (__getOwnPropSymbols$9)
395
+ for (var prop of __getOwnPropSymbols$9(b)) {
396
+ if (__propIsEnum$9.call(b, prop))
397
+ __defNormalProp$9(a, prop, b[prop]);
652
398
  }
653
399
  return a;
654
400
  };
655
- var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
401
+ var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
656
402
  var __objRest$1 = (source, exclude) => {
657
403
  var target = {};
658
404
  for (var prop in source)
659
- if (__hasOwnProp$5.call(source, prop) && exclude.indexOf(prop) < 0)
405
+ if (__hasOwnProp$9.call(source, prop) && exclude.indexOf(prop) < 0)
660
406
  target[prop] = source[prop];
661
- if (source != null && __getOwnPropSymbols$5)
662
- for (var prop of __getOwnPropSymbols$5(source)) {
663
- if (exclude.indexOf(prop) < 0 && __propIsEnum$5.call(source, prop))
407
+ if (source != null && __getOwnPropSymbols$9)
408
+ for (var prop of __getOwnPropSymbols$9(source)) {
409
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$9.call(source, prop))
664
410
  target[prop] = source[prop];
665
411
  }
666
412
  return target;
@@ -712,14 +458,14 @@ const makeAst$2 = (up, tableName, shape, tableData, options, noPrimaryKey) => {
712
458
  }
713
459
  const { primaryKey } = tableData;
714
460
  const [schema, table] = getSchemaAndTableFromName(tableName);
715
- return __spreadProps$3(__spreadValues$5(__spreadProps$3(__spreadValues$5({
461
+ return __spreadProps$6(__spreadValues$9(__spreadProps$6(__spreadValues$9({
716
462
  type: "table",
717
463
  action: up ? "create" : "drop",
718
464
  schema,
719
465
  name: table,
720
466
  shape
721
467
  }, tableData), {
722
- primaryKey: shapePKeys.length <= 1 ? primaryKey : primaryKey ? __spreadProps$3(__spreadValues$5({}, primaryKey), { columns: [...shapePKeys, ...primaryKey.columns] }) : { columns: shapePKeys }
468
+ primaryKey: shapePKeys.length <= 1 ? primaryKey : primaryKey ? __spreadProps$6(__spreadValues$9({}, primaryKey), { columns: [...shapePKeys, ...primaryKey.columns] }) : { columns: shapePKeys }
723
469
  }), options), {
724
470
  noPrimaryKey: options.noPrimaryKey ? "ignore" : noPrimaryKey || "error"
725
471
  });
@@ -796,8 +542,8 @@ const astToQueries$1 = (ast, snakeCase, language) => {
796
542
  ${constraintToSql(
797
543
  ast,
798
544
  true,
799
- __spreadProps$3(__spreadValues$5({}, item), {
800
- references: item.references ? __spreadProps$3(__spreadValues$5({}, item.references), {
545
+ __spreadProps$6(__spreadValues$9({}, item), {
546
+ references: item.references ? __spreadProps$6(__spreadValues$9({}, item.references), {
801
547
  columns: item.references.columns.map(
802
548
  (column) => getColumnName(shape[column], column, snakeCase)
803
549
  )
@@ -809,8 +555,8 @@ const astToQueries$1 = (ast, snakeCase, language) => {
809
555
  );
810
556
  });
811
557
  indexes.push(
812
- ...((_b = ast.indexes) == null ? void 0 : _b.map((index) => __spreadProps$3(__spreadValues$5({}, index), {
813
- columns: index.columns.map((item) => __spreadValues$5(__spreadValues$5({}, item), "column" in item ? {
558
+ ...((_b = ast.indexes) == null ? void 0 : _b.map((index) => __spreadProps$6(__spreadValues$9({}, index), {
559
+ columns: index.columns.map((item) => __spreadValues$9(__spreadValues$9({}, item), "column" in item ? {
814
560
  column: getColumnName(shape[item.column], item.column, snakeCase)
815
561
  } : {}))
816
562
  }))) || []
@@ -832,25 +578,25 @@ const astToQueries$1 = (ast, snakeCase, language) => {
832
578
  return queries;
833
579
  };
834
580
 
835
- var __defProp$4 = Object.defineProperty;
836
- var __defProps$2 = Object.defineProperties;
837
- var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
838
- var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
839
- var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
840
- var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
841
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
842
- var __spreadValues$4 = (a, b) => {
581
+ var __defProp$8 = Object.defineProperty;
582
+ var __defProps$5 = Object.defineProperties;
583
+ var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors;
584
+ var __getOwnPropSymbols$8 = Object.getOwnPropertySymbols;
585
+ var __hasOwnProp$8 = Object.prototype.hasOwnProperty;
586
+ var __propIsEnum$8 = Object.prototype.propertyIsEnumerable;
587
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
588
+ var __spreadValues$8 = (a, b) => {
843
589
  for (var prop in b || (b = {}))
844
- if (__hasOwnProp$4.call(b, prop))
845
- __defNormalProp$4(a, prop, b[prop]);
846
- if (__getOwnPropSymbols$4)
847
- for (var prop of __getOwnPropSymbols$4(b)) {
848
- if (__propIsEnum$4.call(b, prop))
849
- __defNormalProp$4(a, prop, b[prop]);
590
+ if (__hasOwnProp$8.call(b, prop))
591
+ __defNormalProp$8(a, prop, b[prop]);
592
+ if (__getOwnPropSymbols$8)
593
+ for (var prop of __getOwnPropSymbols$8(b)) {
594
+ if (__propIsEnum$8.call(b, prop))
595
+ __defNormalProp$8(a, prop, b[prop]);
850
596
  }
851
597
  return a;
852
598
  };
853
- var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
599
+ var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
854
600
  const newChangeTableData = () => ({
855
601
  add: {},
856
602
  drop: {}
@@ -866,7 +612,7 @@ const mergeTableData = (a, b) => {
866
612
  } else {
867
613
  a.primaryKey = {
868
614
  columns: [...a.primaryKey.columns, ...b.primaryKey.columns],
869
- options: __spreadValues$4(__spreadValues$4({}, a.primaryKey.options), b.primaryKey.options)
615
+ options: __spreadValues$8(__spreadValues$8({}, a.primaryKey.options), b.primaryKey.options)
870
616
  };
871
617
  }
872
618
  }
@@ -929,7 +675,7 @@ const addOrDrop = (type, item, options) => {
929
675
  check: item.data.check
930
676
  }
931
677
  });
932
- return __spreadValues$4({
678
+ return __spreadValues$8({
933
679
  type: "change",
934
680
  from: type === "add" ? empty : add2,
935
681
  to: type === "add" ? add2 : empty
@@ -947,7 +693,7 @@ const columnTypeToColumnChange = (item) => {
947
693
  if (foreignKeys == null ? void 0 : foreignKeys.some((it) => "fn" in it)) {
948
694
  throw new Error("Callback in foreignKey is not allowed in migration");
949
695
  }
950
- return __spreadProps$2(__spreadValues$4({
696
+ return __spreadProps$5(__spreadValues$8({
951
697
  column: item,
952
698
  type: item.toSQL(),
953
699
  nullable: item.data.isNullable,
@@ -959,7 +705,7 @@ const columnTypeToColumnChange = (item) => {
959
705
  return item.to;
960
706
  };
961
707
  const nameKey = Symbol("name");
962
- const tableChangeMethods = __spreadProps$2(__spreadValues$4({}, tableMethods), {
708
+ const tableChangeMethods = __spreadProps$5(__spreadValues$8({}, tableMethods), {
963
709
  name(name) {
964
710
  orchidCore.setCurrentColumnName(name);
965
711
  const types = Object.create(this);
@@ -969,7 +715,7 @@ const tableChangeMethods = __spreadProps$2(__spreadValues$4({}, tableMethods), {
969
715
  add,
970
716
  drop,
971
717
  change(from, to, options) {
972
- return __spreadValues$4({
718
+ return __spreadValues$8({
973
719
  type: "change",
974
720
  name: this[nameKey],
975
721
  from: columnTypeToColumnChange(from),
@@ -1031,18 +777,18 @@ const makeAst$1 = (up, name, changeData, changeTableData2, options) => {
1031
777
  }
1032
778
  if ("type" in item) {
1033
779
  if (up) {
1034
- shape[key] = item.type === "change" && item.usingUp ? __spreadProps$2(__spreadValues$4({}, item), { using: item.usingUp }) : item;
780
+ shape[key] = item.type === "change" && item.usingUp ? __spreadProps$5(__spreadValues$8({}, item), { using: item.usingUp }) : item;
1035
781
  } else {
1036
782
  if (item.type === "rename") {
1037
- shape[item.name] = __spreadProps$2(__spreadValues$4({}, item), { name: key });
783
+ shape[item.name] = __spreadProps$5(__spreadValues$8({}, item), { name: key });
1038
784
  } else {
1039
- shape[key] = item.type === "add" ? __spreadProps$2(__spreadValues$4({}, item), { type: "drop" }) : item.type === "drop" ? __spreadProps$2(__spreadValues$4({}, item), { type: "add" }) : item.type === "change" ? __spreadProps$2(__spreadValues$4({}, item), { from: item.to, to: item.from, using: item.usingDown }) : item;
785
+ shape[key] = item.type === "add" ? __spreadProps$5(__spreadValues$8({}, item), { type: "drop" }) : item.type === "drop" ? __spreadProps$5(__spreadValues$8({}, item), { type: "add" }) : item.type === "change" ? __spreadProps$5(__spreadValues$8({}, item), { from: item.to, to: item.from, using: item.usingDown }) : item;
1040
786
  }
1041
787
  }
1042
788
  }
1043
789
  }
1044
790
  const [schema, table] = getSchemaAndTableFromName(name);
1045
- return __spreadValues$4({
791
+ return __spreadValues$8({
1046
792
  type: "changeTable",
1047
793
  schema,
1048
794
  name: table,
@@ -1236,7 +982,7 @@ const astToQueries = (ast, snakeCase, language) => {
1236
982
  if (fromIndex) {
1237
983
  dropIndexes.push({
1238
984
  columns: [
1239
- __spreadValues$4({
985
+ __spreadValues$8({
1240
986
  column: name
1241
987
  }, fromIndex)
1242
988
  ],
@@ -1246,7 +992,7 @@ const astToQueries = (ast, snakeCase, language) => {
1246
992
  if (toIndex) {
1247
993
  addIndexes.push({
1248
994
  columns: [
1249
- __spreadValues$4({
995
+ __spreadValues$8({
1250
996
  column: name
1251
997
  }, toIndex)
1252
998
  ],
@@ -1311,13 +1057,13 @@ const mapIndexesForSnakeCase = (indexes, snakeCase) => {
1311
1057
  return (indexes == null ? void 0 : indexes.map((index) => ({
1312
1058
  options: index.options,
1313
1059
  columns: snakeCase ? index.columns.map(
1314
- (item) => "column" in item ? __spreadProps$2(__spreadValues$4({}, item), { column: orchidCore.toSnakeCase(item.column) }) : item
1060
+ (item) => "column" in item ? __spreadProps$5(__spreadValues$8({}, item), { column: orchidCore.toSnakeCase(item.column) }) : item
1315
1061
  ) : index.columns
1316
1062
  }))) || [];
1317
1063
  };
1318
1064
  const mapConstraintsToSnakeCase = (foreignKeys, snakeCase) => {
1319
- return (foreignKeys == null ? void 0 : foreignKeys.map((item) => __spreadProps$2(__spreadValues$4({}, item), {
1320
- references: item.references ? snakeCase ? __spreadProps$2(__spreadValues$4({}, item.references), {
1065
+ return (foreignKeys == null ? void 0 : foreignKeys.map((item) => __spreadProps$5(__spreadValues$8({}, item), {
1066
+ references: item.references ? snakeCase ? __spreadProps$5(__spreadValues$8({}, item.references), {
1321
1067
  columns: item.references.columns.map(orchidCore.toSnakeCase)
1322
1068
  }) : item.references : void 0
1323
1069
  }))) || [];
@@ -1385,25 +1131,25 @@ const astToQuery = (ast) => {
1385
1131
  };
1386
1132
  };
1387
1133
 
1388
- var __defProp$3 = Object.defineProperty;
1389
- var __defProps$1 = Object.defineProperties;
1390
- var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
1391
- var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
1392
- var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
1393
- var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
1394
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1395
- var __spreadValues$3 = (a, b) => {
1134
+ var __defProp$7 = Object.defineProperty;
1135
+ var __defProps$4 = Object.defineProperties;
1136
+ var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
1137
+ var __getOwnPropSymbols$7 = Object.getOwnPropertySymbols;
1138
+ var __hasOwnProp$7 = Object.prototype.hasOwnProperty;
1139
+ var __propIsEnum$7 = Object.prototype.propertyIsEnumerable;
1140
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1141
+ var __spreadValues$7 = (a, b) => {
1396
1142
  for (var prop in b || (b = {}))
1397
- if (__hasOwnProp$3.call(b, prop))
1398
- __defNormalProp$3(a, prop, b[prop]);
1399
- if (__getOwnPropSymbols$3)
1400
- for (var prop of __getOwnPropSymbols$3(b)) {
1401
- if (__propIsEnum$3.call(b, prop))
1402
- __defNormalProp$3(a, prop, b[prop]);
1143
+ if (__hasOwnProp$7.call(b, prop))
1144
+ __defNormalProp$7(a, prop, b[prop]);
1145
+ if (__getOwnPropSymbols$7)
1146
+ for (var prop of __getOwnPropSymbols$7(b)) {
1147
+ if (__propIsEnum$7.call(b, prop))
1148
+ __defNormalProp$7(a, prop, b[prop]);
1403
1149
  }
1404
1150
  return a;
1405
1151
  };
1406
- var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
1152
+ var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
1407
1153
  const createMigrationInterface = (tx, up, config, asts) => {
1408
1154
  const adapter = new pqb.TransactionAdapter(tx, tx.client, tx.types);
1409
1155
  const { query, arrays } = adapter;
@@ -2042,7 +1788,7 @@ const wrapWithLog = async (log, query, fn) => {
2042
1788
  if (!log) {
2043
1789
  return fn();
2044
1790
  } else {
2045
- const sql = typeof query === "string" ? { text: query, values: [] } : query.values ? query : __spreadProps$1(__spreadValues$3({}, query), { values: [] });
1791
+ const sql = typeof query === "string" ? { text: query, values: [] } : query.values ? query : __spreadProps$4(__spreadValues$7({}, query), { values: [] });
2046
1792
  const logData = log.beforeQuery(sql);
2047
1793
  try {
2048
1794
  const result = await fn();
@@ -2060,19 +1806,19 @@ const addColumn = (migration, up, tableName, columnName, fn) => {
2060
1806
  }));
2061
1807
  };
2062
1808
  const addIndex = (migration, up, tableName, columns, options) => {
2063
- return changeTable(migration, up, tableName, {}, (t) => __spreadValues$3({}, t.add(t.index(columns, options))));
1809
+ return changeTable(migration, up, tableName, {}, (t) => __spreadValues$7({}, t.add(t.index(columns, options))));
2064
1810
  };
2065
1811
  const addForeignKey = (migration, up, tableName, columns, foreignTable, foreignColumns, options) => {
2066
- return changeTable(migration, up, tableName, {}, (t) => __spreadValues$3({}, t.add(t.foreignKey(columns, foreignTable, foreignColumns, options))));
1812
+ return changeTable(migration, up, tableName, {}, (t) => __spreadValues$7({}, t.add(t.foreignKey(columns, foreignTable, foreignColumns, options))));
2067
1813
  };
2068
1814
  const addPrimaryKey = (migration, up, tableName, columns, options) => {
2069
- return changeTable(migration, up, tableName, {}, (t) => __spreadValues$3({}, t.add(t.primaryKey(columns, options))));
1815
+ return changeTable(migration, up, tableName, {}, (t) => __spreadValues$7({}, t.add(t.primaryKey(columns, options))));
2070
1816
  };
2071
1817
  const addCheck = (migration, up, tableName, check) => {
2072
- return changeTable(migration, up, tableName, {}, (t) => __spreadValues$3({}, t.add(t.check(check))));
1818
+ return changeTable(migration, up, tableName, {}, (t) => __spreadValues$7({}, t.add(t.check(check))));
2073
1819
  };
2074
1820
  const addConstraint = (migration, up, tableName, constraint) => {
2075
- return changeTable(migration, up, tableName, {}, (t) => __spreadValues$3({}, t.add(t.constraint(constraint))));
1821
+ return changeTable(migration, up, tableName, {}, (t) => __spreadValues$7({}, t.add(t.constraint(constraint))));
2076
1822
  };
2077
1823
  const createSchema$1 = async (migration, up, name) => {
2078
1824
  const ast = {
@@ -2086,7 +1832,7 @@ const createSchema$1 = async (migration, up, name) => {
2086
1832
  migration.migratedAsts.push(ast);
2087
1833
  };
2088
1834
  const createExtension$1 = async (migration, up, name, options) => {
2089
- const ast = __spreadValues$3({
1835
+ const ast = __spreadValues$7({
2090
1836
  type: "extension",
2091
1837
  action: up ? "create" : "drop",
2092
1838
  name
@@ -2102,7 +1848,7 @@ const createExtension$1 = async (migration, up, name, options) => {
2102
1848
  };
2103
1849
  const createEnum$1 = async (migration, up, name, values, options = {}) => {
2104
1850
  const [schema, enumName] = getSchemaAndTableFromName(name);
2105
- const ast = __spreadValues$3({
1851
+ const ast = __spreadValues$7({
2106
1852
  type: "enum",
2107
1853
  action: up ? "create" : "drop",
2108
1854
  schema,
@@ -2121,7 +1867,7 @@ const createEnum$1 = async (migration, up, name, values, options = {}) => {
2121
1867
  };
2122
1868
  const createDomain$1 = async (migration, up, name, fn, options) => {
2123
1869
  const [schema, domainName] = getSchemaAndTableFromName(name);
2124
- const ast = __spreadValues$3({
1870
+ const ast = __spreadValues$7({
2125
1871
  type: "domain",
2126
1872
  action: up ? "create" : "drop",
2127
1873
  schema,
@@ -2149,7 +1895,7 @@ DEFAULT ${ast.default.toSQL({ values })}` : ""}${ast.notNull || ast.check ? "\n"
2149
1895
  };
2150
1896
  const createCollation$1 = async (migration, up, name, options) => {
2151
1897
  const [schema, collationName] = getSchemaAndTableFromName(name);
2152
- const ast = __spreadValues$3({
1898
+ const ast = __spreadValues$7({
2153
1899
  type: "collation",
2154
1900
  action: up ? "create" : "drop",
2155
1901
  schema,
@@ -2191,28 +1937,357 @@ const queryExists = (db, sql) => {
2191
1937
  return db.adapter.query(sql).then(({ rowCount }) => rowCount > 0);
2192
1938
  };
2193
1939
 
2194
- const saveMigratedVersion = async (db, version, config) => {
2195
- await db.silentArrays(
2196
- `INSERT INTO ${quoteWithSchema({
2197
- name: config.migrationsTable
2198
- })} VALUES ('${version}')`
1940
+ const writeMigrationFile = async (config, version, name, content) => {
1941
+ var _a;
1942
+ await fs.mkdir(config.migrationsPath, { recursive: true });
1943
+ const filePath = path.resolve(config.migrationsPath, `${version}_${name}.ts`);
1944
+ const importPath = orchidCore.getImportPath(
1945
+ filePath,
1946
+ path.join(config.basePath, config.dbScript)
1947
+ );
1948
+ await fs.writeFile(filePath, content(importPath, name));
1949
+ (_a = config.logger) == null ? void 0 : _a.log(`Created ${orchidCore.pathToLog(filePath)}`);
1950
+ };
1951
+ const generate = async (config, [name]) => {
1952
+ if (!name)
1953
+ throw new Error("Migration name is missing");
1954
+ const version = await makeFileVersion({}, config);
1955
+ await writeMigrationFile(config, version, name, makeContent);
1956
+ };
1957
+ const makeFileVersion = async (ctx, config) => {
1958
+ if (config.migrationId === "timestamp") {
1959
+ return generateTimeStamp();
1960
+ } else {
1961
+ const {
1962
+ migrations: [first]
1963
+ } = await getMigrations(ctx, config, false);
1964
+ return first ? String(parseInt(first.version) + 1).padStart(4, "0") : "0001";
1965
+ }
1966
+ };
1967
+ const generateTimeStamp = () => {
1968
+ const now = /* @__PURE__ */ new Date();
1969
+ return [
1970
+ now.getUTCFullYear(),
1971
+ now.getUTCMonth() + 1,
1972
+ now.getUTCDate(),
1973
+ now.getUTCHours(),
1974
+ now.getUTCMinutes(),
1975
+ now.getUTCSeconds()
1976
+ ].map((value) => value < 10 ? `0${value}` : value).join("");
1977
+ };
1978
+ const makeContent = (importPath, name) => {
1979
+ let content = `import { change } from '${importPath}';
1980
+
1981
+ change(async (db) => {`;
1982
+ const [first, rest] = getFirstWordAndRest(name);
1983
+ if (rest) {
1984
+ if (first === "create" || first === "drop") {
1985
+ content += `
1986
+ await db.${first === "create" ? "createTable" : "dropTable"}('${rest}', (t) => ({
1987
+
1988
+ }));`;
1989
+ } else if (first === "change") {
1990
+ content += `
1991
+ await db.changeTable('${rest}', (t) => ({
1992
+
1993
+ }));`;
1994
+ } else if (first === "add" || first === "remove") {
1995
+ const table = first === "add" ? getTextAfterTo(rest) : getTextAfterFrom(rest);
1996
+ content += `
1997
+ await db.changeTable(${table ? `'${table}'` : "tableName"}, (t) => ({
1998
+
1999
+ }));`;
2000
+ }
2001
+ }
2002
+ return content + "\n});\n";
2003
+ };
2004
+
2005
+ const fileNamesToChangeMigrationId = {
2006
+ serial: ".rename-to-serial.json",
2007
+ timestamp: ".rename-to-timestamp.json"
2008
+ };
2009
+ const fileNamesToChangeMigrationIdMap = Object.fromEntries(
2010
+ Object.entries(fileNamesToChangeMigrationId).map(([_, name]) => [name, true])
2011
+ );
2012
+ const changeIds = async (options, config, [arg]) => {
2013
+ var _a;
2014
+ if (arg !== "serial" && arg !== "timestamp") {
2015
+ throw new Error(
2016
+ `Pass "serial" or "timestamp" argument to the "change-ids" command`
2017
+ );
2018
+ }
2019
+ if (config.migrations) {
2020
+ throw new Error(
2021
+ `Cannot change migrations ids when migrations set is defined in the config`
2022
+ );
2023
+ }
2024
+ const data = await getMigrationsFromFiles(config, false, (_, filePath) => {
2025
+ const fileName = path.basename(filePath);
2026
+ const match = fileName.match(/^(\d+)\D/);
2027
+ if (!match) {
2028
+ throw new Error(
2029
+ `Migration file name should start digits, received ${fileName}`
2030
+ );
2031
+ }
2032
+ return match[1];
2033
+ });
2034
+ if (data.renameTo) {
2035
+ if (data.renameTo === arg) {
2036
+ (_a = config.logger) == null ? void 0 : _a.log(`${fileNamesToChangeMigrationId[arg]} already exists`);
2037
+ return;
2038
+ }
2039
+ await fs.unlink(
2040
+ path.join(
2041
+ config.migrationsPath,
2042
+ fileNamesToChangeMigrationId[data.renameTo]
2043
+ )
2044
+ );
2045
+ }
2046
+ const version = arg === "timestamp" ? parseInt(generateTimeStamp()) : 1;
2047
+ const rename = Object.fromEntries(
2048
+ data.migrations.map((item, i) => [path.basename(item.path), version + i])
2049
+ );
2050
+ await fs.writeFile(
2051
+ path.join(config.migrationsPath, fileNamesToChangeMigrationId[arg]),
2052
+ JSON.stringify(rename, null, 2)
2053
+ );
2054
+ const values = [];
2055
+ await Promise.all(
2056
+ data.migrations.map(async (item, i) => {
2057
+ let newVersion = String(version + i);
2058
+ if (arg === "serial")
2059
+ newVersion = newVersion.padStart(4, "0");
2060
+ const name = path.basename(item.path).slice(item.version.length + 1);
2061
+ await fs.rename(
2062
+ item.path,
2063
+ path.join(path.dirname(item.path), `${newVersion}_${name}`)
2064
+ );
2065
+ values.push([item.version, name, newVersion]);
2066
+ })
2199
2067
  );
2068
+ if (!values.length)
2069
+ return;
2070
+ await options.map((opts) => {
2071
+ const adapter = new pqb.Adapter(opts);
2072
+ renameMigrationVersionsInDb(config, adapter, values).then(
2073
+ () => adapter.close()
2074
+ );
2075
+ });
2200
2076
  };
2201
- const removeMigratedVersion = async (db, version, config) => {
2202
- await db.silentArrays(
2203
- `DELETE FROM ${quoteWithSchema({
2077
+ const renameMigrationVersionsInDb = async (config, adapter, values) => {
2078
+ await adapter.arrays({
2079
+ text: `UPDATE ${quoteWithSchema({
2204
2080
  name: config.migrationsTable
2205
- })} WHERE version = '${version}'`
2081
+ })} AS t SET version = v.version FROM (VALUES ${values.map(
2082
+ ([oldVersion, , newVersion], i) => `('${oldVersion}', $${i + 1}, '${newVersion}')`
2083
+ ).join(
2084
+ ", "
2085
+ )}) v(oldVersion, name, version) WHERE t.version = v.oldVersion`,
2086
+ values: values.map(([, name]) => name)
2087
+ });
2088
+ };
2089
+
2090
+ var __defProp$6 = Object.defineProperty;
2091
+ var __defProps$3 = Object.defineProperties;
2092
+ var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
2093
+ var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
2094
+ var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
2095
+ var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
2096
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2097
+ var __spreadValues$6 = (a, b) => {
2098
+ for (var prop in b || (b = {}))
2099
+ if (__hasOwnProp$6.call(b, prop))
2100
+ __defNormalProp$6(a, prop, b[prop]);
2101
+ if (__getOwnPropSymbols$6)
2102
+ for (var prop of __getOwnPropSymbols$6(b)) {
2103
+ if (__propIsEnum$6.call(b, prop))
2104
+ __defNormalProp$6(a, prop, b[prop]);
2105
+ }
2106
+ return a;
2107
+ };
2108
+ var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
2109
+ const getMigrations = async (ctx, config, up, allowDuplicates) => {
2110
+ var _a;
2111
+ return ((_a = ctx.migrationsPromise) != null ? _a : ctx.migrationsPromise = config.migrations ? getMigrationsFromConfig(__spreadProps$3(__spreadValues$6({}, config), { migrations: config.migrations })) : getMigrationsFromFiles(config, allowDuplicates)).then(
2112
+ (data) => up ? data : { renameTo: data.renameTo, migrations: [...data.migrations].reverse() }
2113
+ );
2114
+ };
2115
+ function getMigrationsFromConfig(config, allowDuplicates) {
2116
+ const result = [];
2117
+ const versions = {};
2118
+ const { migrations, basePath } = config;
2119
+ for (const key in migrations) {
2120
+ const version = getMigrationVersionOrThrow(config, path.basename(key));
2121
+ if (versions[version] && !allowDuplicates) {
2122
+ throw new Error(
2123
+ `Migration ${key} has the same version as ${versions[version]}`
2124
+ );
2125
+ }
2126
+ versions[version] = key;
2127
+ result.push({
2128
+ path: path.resolve(basePath, key),
2129
+ version,
2130
+ load: migrations[key]
2131
+ });
2132
+ }
2133
+ return Promise.resolve({
2134
+ migrations: result
2135
+ });
2136
+ }
2137
+ const sortMigrationsAsc = (a, b) => +a.version - +b.version;
2138
+ async function getMigrationsFromFiles(config, allowDuplicates, getVersion = getMigrationVersionOrThrow) {
2139
+ const { migrationsPath, import: imp } = config;
2140
+ const entries = await fs.readdir(migrationsPath, { withFileTypes: true }).catch(
2141
+ () => []
2142
+ );
2143
+ const versions = {};
2144
+ const result = entries.reduce(
2145
+ (data, file) => {
2146
+ if (!file.isFile())
2147
+ return data;
2148
+ if (fileNamesToChangeMigrationIdMap[file.name]) {
2149
+ if (data.renameTo) {
2150
+ throw new Error(
2151
+ `Both files for renaming to serial and timestamp found, only one must remain`
2152
+ );
2153
+ }
2154
+ data.renameTo = file.name === ".rename-to-serial.json" ? "serial" : "timestamp";
2155
+ return data;
2156
+ } else {
2157
+ checkExt(file.name);
2158
+ }
2159
+ const version = getVersion(config, file.name);
2160
+ const filePath = path.resolve(migrationsPath, file.name);
2161
+ if (versions[version] && !allowDuplicates) {
2162
+ throw new Error(
2163
+ `Migration ${node_url.pathToFileURL(
2164
+ filePath
2165
+ )} has the same version as ${node_url.pathToFileURL(
2166
+ versions[version]
2167
+ )}
2168
+ Run \`**db command** rebase\` to reorganize files with duplicated versions.`
2169
+ );
2170
+ }
2171
+ versions[version] = filePath;
2172
+ data.migrations.push({
2173
+ path: filePath,
2174
+ version,
2175
+ async load() {
2176
+ try {
2177
+ await imp(this.path);
2178
+ } catch (err) {
2179
+ if (err.code !== "ERR_UNSUPPORTED_ESM_URL_SCHEME")
2180
+ throw err;
2181
+ await imp(node_url.pathToFileURL(this.path).pathname);
2182
+ }
2183
+ }
2184
+ });
2185
+ return data;
2186
+ },
2187
+ { migrations: [] }
2206
2188
  );
2189
+ result.migrations.sort(sortMigrationsAsc);
2190
+ return result;
2191
+ }
2192
+ function checkExt(filePath) {
2193
+ const ext = path.extname(filePath);
2194
+ if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
2195
+ throw new Error(
2196
+ `Only .ts, .js, and .mjs files are supported for migration, received: ${filePath}`
2197
+ );
2198
+ }
2199
+ }
2200
+ function getMigrationVersionOrThrow(config, filePath) {
2201
+ const name = path.basename(filePath);
2202
+ const value = getMigrationVersion(config, name);
2203
+ if (value)
2204
+ return value;
2205
+ if (config.migrationId === "timestamp") {
2206
+ throw new Error(
2207
+ `Migration file name should start with 14 digit timestamp, received ${name}`
2208
+ );
2209
+ } else {
2210
+ throw new Error(
2211
+ `Migration file name should start with 4 digit serial number, received ${name}.
2212
+ You can automatically change migration ids to serial by running \`*db-command* change-ids serial\`.
2213
+ To keep using timestamp ids, set \`migrationId\` option of rake-db to 'timestamp'.`
2214
+ );
2215
+ }
2216
+ }
2217
+ function getMigrationVersion(config, name) {
2218
+ var _a;
2219
+ return (_a = config.migrationId === "timestamp" ? name.match(/^(\d{14})(_|\b)/) : name.match(/^(\d{4})(_|\b)/)) == null ? void 0 : _a[1];
2220
+ }
2221
+ function getDigitsPrefix(name) {
2222
+ var _a;
2223
+ const value = (_a = name.match(/^(\d+)\D/)) == null ? void 0 : _a[1];
2224
+ if (!value) {
2225
+ throw new Error(
2226
+ `Migration file should be prefixed with a serial number, received ${name}`
2227
+ );
2228
+ }
2229
+ return value;
2230
+ }
2231
+
2232
+ const saveMigratedVersion = async (db, version, name, config) => {
2233
+ await db.silentArrays({
2234
+ text: `INSERT INTO ${quoteWithSchema({
2235
+ name: config.migrationsTable
2236
+ })}(version, name) VALUES ($1, $2)`,
2237
+ values: [version, name]
2238
+ });
2239
+ };
2240
+ const removeMigratedVersion = async (db, version, name, config) => {
2241
+ const res = await db.silentArrays({
2242
+ text: `DELETE FROM ${quoteWithSchema({
2243
+ name: config.migrationsTable
2244
+ })} WHERE version = $1 AND name = $2`,
2245
+ values: [version, name]
2246
+ });
2247
+ if (res.rowCount === 0) {
2248
+ throw new Error(`Migration ${version}_${name} was not found in db`);
2249
+ }
2207
2250
  };
2208
2251
  class NoMigrationsTableError extends Error {
2209
2252
  }
2210
- const getMigratedVersionsMap = async (db, config) => {
2253
+ const getMigratedVersionsMap = async (ctx, adapter, config) => {
2211
2254
  try {
2212
- const result = await db.arrays(
2213
- `SELECT * FROM ${quoteWithSchema({ name: config.migrationsTable })}`
2214
- );
2215
- return Object.fromEntries(result.rows.map((row) => [row[0], true]));
2255
+ const table = quoteWithSchema({
2256
+ name: config.migrationsTable
2257
+ });
2258
+ const result = await adapter.arrays(`SELECT * FROM ${table}`);
2259
+ if (!result.fields[1]) {
2260
+ const { migrations } = await getMigrations(ctx, config, true);
2261
+ const map = {};
2262
+ for (const item of migrations) {
2263
+ const name = path.basename(item.path);
2264
+ map[item.version] = name.slice(getDigitsPrefix(name).length + 1);
2265
+ }
2266
+ const data = result.rows.map(
2267
+ ([version]) => {
2268
+ const name = map[version];
2269
+ if (!name) {
2270
+ throw new Error(
2271
+ `Migration for version ${version} is stored in db but is not found among available migrations`
2272
+ );
2273
+ }
2274
+ return { version, name };
2275
+ }
2276
+ );
2277
+ await adapter.arrays(`ALTER TABLE ${table} ADD COLUMN name TEXT`);
2278
+ await Promise.all(
2279
+ data.map(
2280
+ ({ version, name }) => adapter.arrays({
2281
+ text: `UPDATE ${table} SET name = $2 WHERE version = $1`,
2282
+ values: [version, name]
2283
+ })
2284
+ )
2285
+ );
2286
+ await adapter.arrays(
2287
+ `ALTER TABLE ${table} ALTER COLUMN name SET NOT NULL`
2288
+ );
2289
+ }
2290
+ return Object.fromEntries(result.rows);
2216
2291
  } catch (err) {
2217
2292
  if (err.code === "42P01") {
2218
2293
  throw new NoMigrationsTableError();
@@ -2222,26 +2297,55 @@ const getMigratedVersionsMap = async (db, config) => {
2222
2297
  }
2223
2298
  };
2224
2299
 
2225
- var __defProp$2 = Object.defineProperty;
2226
- var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
2227
- var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
2228
- var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
2229
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2230
- var __spreadValues$2 = (a, b) => {
2300
+ const createMigrationsTable = async (db, config) => {
2301
+ var _a, _b, _c;
2302
+ const { schema } = db;
2303
+ if (schema && schema !== "public") {
2304
+ try {
2305
+ await db.query(`CREATE SCHEMA "${schema}"`);
2306
+ (_a = config.logger) == null ? void 0 : _a.log(`Created schema ${schema}`);
2307
+ } catch (err) {
2308
+ if (err.code !== "42P06") {
2309
+ throw err;
2310
+ }
2311
+ }
2312
+ }
2313
+ try {
2314
+ await db.query(
2315
+ `CREATE TABLE ${quoteWithSchema({
2316
+ name: config.migrationsTable
2317
+ })} ( version TEXT NOT NULL, name TEXT NOT NULL )`
2318
+ );
2319
+ (_b = config.logger) == null ? void 0 : _b.log("Created versions table");
2320
+ } catch (err) {
2321
+ if (err.code === "42P07") {
2322
+ (_c = config.logger) == null ? void 0 : _c.log("Versions table exists");
2323
+ } else {
2324
+ throw err;
2325
+ }
2326
+ }
2327
+ };
2328
+
2329
+ var __defProp$5 = Object.defineProperty;
2330
+ var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
2331
+ var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
2332
+ var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
2333
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2334
+ var __spreadValues$5 = (a, b) => {
2231
2335
  for (var prop in b || (b = {}))
2232
- if (__hasOwnProp$2.call(b, prop))
2233
- __defNormalProp$2(a, prop, b[prop]);
2234
- if (__getOwnPropSymbols$2)
2235
- for (var prop of __getOwnPropSymbols$2(b)) {
2236
- if (__propIsEnum$2.call(b, prop))
2237
- __defNormalProp$2(a, prop, b[prop]);
2336
+ if (__hasOwnProp$5.call(b, prop))
2337
+ __defNormalProp$5(a, prop, b[prop]);
2338
+ if (__getOwnPropSymbols$5)
2339
+ for (var prop of __getOwnPropSymbols$5(b)) {
2340
+ if (__propIsEnum$5.call(b, prop))
2341
+ __defNormalProp$5(a, prop, b[prop]);
2238
2342
  }
2239
2343
  return a;
2240
2344
  };
2241
2345
  const RAKE_DB_LOCK_KEY = "8582141715823621641";
2242
2346
  function makeMigrateFn(defaultCount, up, fn) {
2243
- return async (options, config, args = []) => {
2244
- const files = await getMigrations(config, up);
2347
+ return async (ctx, options, config, args = []) => {
2348
+ const set = await getMigrations(ctx, config, up);
2245
2349
  const count = getCount(args);
2246
2350
  const conf = prepareConfig(config, args, count);
2247
2351
  const asts = [];
@@ -2252,21 +2356,22 @@ function makeMigrateFn(defaultCount, up, fn) {
2252
2356
  for (const opts of arrOptions) {
2253
2357
  const adapter = new pqb.Adapter(opts);
2254
2358
  try {
2255
- await adapter.transaction(begin, async (trx) => {
2359
+ await transaction(adapter, async (trx) => {
2256
2360
  await fn(
2361
+ ctx,
2257
2362
  trx,
2258
2363
  conf,
2259
- files,
2364
+ set,
2260
2365
  count != null ? count : defaultCount,
2261
2366
  localAsts
2262
2367
  );
2263
2368
  });
2264
2369
  } catch (err) {
2265
2370
  if (err instanceof NoMigrationsTableError) {
2266
- await adapter.transaction(begin, async (trx) => {
2371
+ await transaction(adapter, async (trx) => {
2267
2372
  const config2 = conf;
2268
- await createSchemaMigrations(trx, config2);
2269
- await fn(trx, config2, files, count != null ? count : defaultCount, localAsts);
2373
+ await createMigrationsTable(trx, config2);
2374
+ await fn(ctx, trx, config2, set, count != null ? count : defaultCount, localAsts);
2270
2375
  });
2271
2376
  } else {
2272
2377
  throw err;
@@ -2288,21 +2393,21 @@ function makeMigrateFn(defaultCount, up, fn) {
2288
2393
  const migrate = makeMigrateFn(
2289
2394
  Infinity,
2290
2395
  true,
2291
- (trx, config, files, count, asts) => migrateOrRollback(trx, config, files, count, asts, true)
2396
+ (ctx, trx, config, migrations, count, asts) => migrateOrRollback(ctx, trx, config, migrations, count, asts, true)
2292
2397
  );
2293
2398
  const rollback = makeMigrateFn(
2294
2399
  1,
2295
2400
  false,
2296
- (trx, config, files, count, asts) => migrateOrRollback(trx, config, files, count, asts, false)
2401
+ (ctx, trx, config, migrations, count, asts) => migrateOrRollback(ctx, trx, config, migrations, count, asts, false)
2297
2402
  );
2298
2403
  const redo = makeMigrateFn(
2299
2404
  1,
2300
- false,
2301
- async (trx, config, files, count, asts) => {
2302
- await migrateOrRollback(trx, config, files, count, asts, false);
2303
- files.reverse();
2304
- await migrateOrRollback(trx, config, files, count, asts, true, true);
2305
- files.reverse();
2405
+ true,
2406
+ async (ctx, trx, config, set, count, asts) => {
2407
+ set.migrations.reverse();
2408
+ await migrateOrRollback(ctx, trx, config, set, count, asts, false);
2409
+ set.migrations.reverse();
2410
+ await migrateOrRollback(ctx, trx, config, set, count, asts, true, true);
2306
2411
  }
2307
2412
  );
2308
2413
  const getDb = (adapter) => pqb.createDb({ adapter });
@@ -2311,7 +2416,7 @@ const getCount = (args) => {
2311
2416
  return isNaN(num) ? void 0 : num;
2312
2417
  };
2313
2418
  function prepareConfig(config, args, count) {
2314
- config = __spreadValues$2({}, config);
2419
+ config = __spreadValues$5({}, config);
2315
2420
  const i = count === void 0 ? 0 : 1;
2316
2421
  const arg = args[i];
2317
2422
  if (arg === "--code") {
@@ -2321,15 +2426,22 @@ function prepareConfig(config, args, count) {
2321
2426
  delete config.appCodeUpdater;
2322
2427
  return config;
2323
2428
  }
2324
- const migrateOrRollback = async (trx, config, files, count, asts, up, skipLock) => {
2429
+ const migrateOrRollback = async (ctx, trx, config, set, count, asts, up, skipLock) => {
2325
2430
  var _a, _b, _c;
2326
- if (!skipLock) {
2327
- await trx.query(`SELECT pg_advisory_xact_lock('${RAKE_DB_LOCK_KEY}')`);
2328
- }
2431
+ if (!skipLock)
2432
+ await queryLock(trx);
2329
2433
  let db;
2330
2434
  await ((_a = config[up ? "beforeMigrate" : "beforeRollback"]) == null ? void 0 : _a.call(config, db != null ? db : db = getDb(trx)));
2331
- const migratedVersions = await getMigratedVersionsMap(trx, config);
2332
- for (const file of files) {
2435
+ let migratedVersions = await getMigratedVersionsMap(ctx, trx, config);
2436
+ if (set.renameTo) {
2437
+ migratedVersions = await renameMigrations(
2438
+ config,
2439
+ trx,
2440
+ migratedVersions,
2441
+ set.renameTo
2442
+ );
2443
+ }
2444
+ for (const file of set.migrations) {
2333
2445
  if (up && migratedVersions[file.version] || !up && !migratedVersions[file.version]) {
2334
2446
  continue;
2335
2447
  }
@@ -2342,62 +2454,275 @@ const migrateOrRollback = async (trx, config, files, count, asts, up, skipLock)
2342
2454
  }
2343
2455
  await ((_c = config[up ? "afterMigrate" : "afterRollback"]) == null ? void 0 : _c.call(config, db != null ? db : db = getDb(trx)));
2344
2456
  };
2345
- async function runCodeUpdaterAfterAll(options, config, appCodeUpdater, asts, cache) {
2346
- for (const ast of asts) {
2347
- await (appCodeUpdater == null ? void 0 : appCodeUpdater.process({
2348
- ast,
2349
- options,
2350
- basePath: config.basePath,
2351
- cache,
2352
- logger: config.logger,
2353
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2354
- baseTable: config.baseTable,
2355
- import: config.import
2356
- }));
2457
+ async function renameMigrations(config, trx, migratedVersions, renameTo) {
2458
+ let first;
2459
+ for (const version in migratedVersions) {
2460
+ first = version;
2461
+ break;
2462
+ }
2463
+ if (!first || getMigrationVersion(config, first))
2464
+ return migratedVersions;
2465
+ const fileName = fileNamesToChangeMigrationId[renameTo];
2466
+ const filePath = path.join(config.migrationsPath, fileName);
2467
+ const json = await fs.readFile(filePath, "utf-8");
2468
+ let data;
2469
+ try {
2470
+ data = JSON.parse(json);
2471
+ if (typeof data !== "object")
2472
+ throw new Error("Config for renaming is not an object");
2473
+ } catch (err) {
2474
+ throw new Error(`Failed to read ${node_url.pathToFileURL(filePath)}`, {
2475
+ cause: err
2476
+ });
2477
+ }
2478
+ const values = [];
2479
+ const updatedVersions = {};
2480
+ for (const version in migratedVersions) {
2481
+ const name = migratedVersions[version];
2482
+ const key = `${version}_${name}`;
2483
+ let newVersion = data[key];
2484
+ if (!newVersion) {
2485
+ throw new Error(
2486
+ `Failed to find an entry for the migrated ${key} in the ${fileName} config`
2487
+ );
2488
+ }
2489
+ if (renameTo === "serial") {
2490
+ newVersion = String(newVersion).padStart(4, "0");
2491
+ }
2492
+ updatedVersions[newVersion] = name;
2493
+ values.push([version, name, newVersion]);
2494
+ }
2495
+ await renameMigrationVersionsInDb(config, trx, values);
2496
+ return updatedVersions;
2497
+ }
2498
+ async function runCodeUpdaterAfterAll(options, config, appCodeUpdater, asts, cache) {
2499
+ for (const ast of asts) {
2500
+ await (appCodeUpdater == null ? void 0 : appCodeUpdater.process({
2501
+ ast,
2502
+ options,
2503
+ basePath: config.basePath,
2504
+ cache,
2505
+ logger: config.logger,
2506
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2507
+ baseTable: config.baseTable,
2508
+ import: config.import
2509
+ }));
2510
+ }
2511
+ await (appCodeUpdater == null ? void 0 : appCodeUpdater.afterAll({
2512
+ options,
2513
+ basePath: config.basePath,
2514
+ cache,
2515
+ logger: config.logger,
2516
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2517
+ baseTable: config.baseTable,
2518
+ import: config.import
2519
+ }));
2520
+ }
2521
+ const changeCache = {};
2522
+ const runMigration = async (trx, up, file, config, asts) => {
2523
+ clearChanges();
2524
+ let changes = changeCache[file.path];
2525
+ if (!changes) {
2526
+ const module = await file.load();
2527
+ const exported = (module == null ? void 0 : module.default) && orchidCore.toArray(module.default);
2528
+ if (config.forceDefaultExports && !exported) {
2529
+ throw new RakeDbError(
2530
+ `Missing a default export in ${file.path} migration`
2531
+ );
2532
+ }
2533
+ changes = exported || getCurrentChanges();
2534
+ changeCache[file.path] = changes;
2535
+ }
2536
+ const db = createMigrationInterface(trx, up, config, asts);
2537
+ if (changes.length) {
2538
+ const from = up ? 0 : changes.length - 1;
2539
+ const to = up ? changes.length : -1;
2540
+ const step = up ? 1 : -1;
2541
+ for (let i = from; i !== to; i += step) {
2542
+ await changes[i](db, up);
2543
+ }
2544
+ }
2545
+ await (up ? saveMigratedVersion : removeMigratedVersion)(
2546
+ db.adapter,
2547
+ file.version,
2548
+ path.basename(file.path).slice(file.version.length + 1),
2549
+ config
2550
+ );
2551
+ };
2552
+
2553
+ var __defProp$4 = Object.defineProperty;
2554
+ var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
2555
+ var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
2556
+ var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
2557
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2558
+ var __spreadValues$4 = (a, b) => {
2559
+ for (var prop in b || (b = {}))
2560
+ if (__hasOwnProp$4.call(b, prop))
2561
+ __defNormalProp$4(a, prop, b[prop]);
2562
+ if (__getOwnPropSymbols$4)
2563
+ for (var prop of __getOwnPropSymbols$4(b)) {
2564
+ if (__propIsEnum$4.call(b, prop))
2565
+ __defNormalProp$4(a, prop, b[prop]);
2566
+ }
2567
+ return a;
2568
+ };
2569
+ const migrationConfigDefaults = {
2570
+ schemaConfig: pqb.defaultSchemaConfig,
2571
+ migrationsPath: path.join("src", "db", "migrations"),
2572
+ migrationId: "serial",
2573
+ migrationsTable: "schemaMigrations",
2574
+ snakeCase: false,
2575
+ commands: {},
2576
+ import: (path2) => {
2577
+ return import(path2).catch((err) => {
2578
+ if (err.code === "ERR_UNKNOWN_FILE_EXTENSION") {
2579
+ require(path2);
2580
+ } else {
2581
+ throw err;
2582
+ }
2583
+ });
2584
+ },
2585
+ log: true,
2586
+ logger: console,
2587
+ useCodeUpdater: true
2588
+ };
2589
+ const processRakeDbConfig = (config) => {
2590
+ var _a, _b;
2591
+ const result = __spreadValues$4(__spreadValues$4({}, migrationConfigDefaults), config);
2592
+ if (!result.recurrentPath) {
2593
+ result.recurrentPath = path.join(result.migrationsPath, "recurrent");
2594
+ }
2595
+ if (config.appCodeUpdater && (!("baseTable" in config) || !config.baseTable)) {
2596
+ throw new Error(
2597
+ "`baseTable` option is required in `rakeDb` for `appCodeUpdater`"
2598
+ );
2599
+ }
2600
+ if (!result.log) {
2601
+ delete result.logger;
2602
+ }
2603
+ if (!result.basePath || !result.dbScript) {
2604
+ let filePath = (_a = orchidCore.getStackTrace()) == null ? void 0 : _a[3].getFileName();
2605
+ if (!filePath) {
2606
+ throw new Error(
2607
+ "Failed to determine path to db script. Please set basePath option of rakeDb"
2608
+ );
2609
+ }
2610
+ if (filePath.startsWith("file://")) {
2611
+ filePath = node_url.fileURLToPath(filePath);
2612
+ }
2613
+ const ext = path.extname(filePath);
2614
+ if (ext !== ".ts" && ext !== ".js" && ext !== ".mjs") {
2615
+ throw new Error(
2616
+ `Add a .ts suffix to the "${path.basename(filePath)}" when calling it`
2617
+ );
2618
+ }
2619
+ result.basePath = path.dirname(filePath);
2620
+ result.dbScript = path.basename(filePath);
2621
+ }
2622
+ if ("migrationsPath" in result && !path.isAbsolute(result.migrationsPath)) {
2623
+ result.migrationsPath = path.resolve(
2624
+ result.basePath,
2625
+ result.migrationsPath
2626
+ );
2627
+ }
2628
+ if ("recurrentPath" in result && !path.isAbsolute(result.recurrentPath)) {
2629
+ result.recurrentPath = path.resolve(result.basePath, result.recurrentPath);
2630
+ }
2631
+ if ("baseTable" in config) {
2632
+ const proto = (_b = config.baseTable) == null ? void 0 : _b.prototype;
2633
+ result.columnTypes = proto.types || pqb.makeColumnTypes(pqb.defaultSchemaConfig);
2634
+ if (proto.snakeCase)
2635
+ result.snakeCase = true;
2636
+ if (proto.language)
2637
+ result.language = proto.language;
2638
+ } else {
2639
+ const ct = "columnTypes" in config && config.columnTypes;
2640
+ result.columnTypes = (typeof ct === "function" ? ct(
2641
+ pqb.makeColumnTypes(pqb.defaultSchemaConfig)
2642
+ ) : ct) || pqb.makeColumnTypes;
2643
+ }
2644
+ return result;
2645
+ };
2646
+ const getDatabaseAndUserFromOptions = (options) => {
2647
+ if (options.databaseURL) {
2648
+ const url = new URL(options.databaseURL);
2649
+ return {
2650
+ database: url.pathname.slice(1),
2651
+ user: url.username
2652
+ };
2653
+ } else {
2654
+ return {
2655
+ database: options.database,
2656
+ user: options.user
2657
+ };
2658
+ }
2659
+ };
2660
+
2661
+ var __defProp$3 = Object.defineProperty;
2662
+ var __defProps$2 = Object.defineProperties;
2663
+ var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
2664
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
2665
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
2666
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
2667
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2668
+ var __spreadValues$3 = (a, b) => {
2669
+ for (var prop in b || (b = {}))
2670
+ if (__hasOwnProp$3.call(b, prop))
2671
+ __defNormalProp$3(a, prop, b[prop]);
2672
+ if (__getOwnPropSymbols$3)
2673
+ for (var prop of __getOwnPropSymbols$3(b)) {
2674
+ if (__propIsEnum$3.call(b, prop))
2675
+ __defNormalProp$3(a, prop, b[prop]);
2676
+ }
2677
+ return a;
2678
+ };
2679
+ var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
2680
+ const setAdapterOptions = (options, set) => {
2681
+ if (options.databaseURL) {
2682
+ const url = new URL(options.databaseURL);
2683
+ if ("database" in set) {
2684
+ url.pathname = `/${set.database}`;
2685
+ }
2686
+ if (set.user !== void 0) {
2687
+ url.username = set.user;
2688
+ }
2689
+ if (set.password !== void 0) {
2690
+ url.password = set.password;
2691
+ }
2692
+ return __spreadProps$2(__spreadValues$3({}, options), { databaseURL: url.toString() });
2693
+ } else {
2694
+ return __spreadValues$3(__spreadValues$3({}, options), set);
2357
2695
  }
2358
- await (appCodeUpdater == null ? void 0 : appCodeUpdater.afterAll({
2359
- options,
2360
- basePath: config.basePath,
2361
- cache,
2362
- logger: config.logger,
2363
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2364
- baseTable: config.baseTable,
2365
- import: config.import
2366
- }));
2367
- }
2368
- const changeCache = {};
2369
- const begin = {
2370
- text: "BEGIN",
2371
- values: orchidCore.emptyArray
2372
2696
  };
2373
- const runMigration = async (trx, up, file, config, asts) => {
2374
- clearChanges();
2375
- let changes = changeCache[file.path];
2376
- if (!changes) {
2377
- const module = await file.load();
2378
- const exported = (module == null ? void 0 : module.default) && orchidCore.toArray(module.default);
2379
- if (config.forceDefaultExports && !exported) {
2380
- throw new RakeDbError(
2381
- `Missing a default export in ${file.path} migration`
2382
- );
2697
+ const setAdminCredentialsToOptions = async (options, create) => {
2698
+ const confirm = await prompts([
2699
+ {
2700
+ message: `Would you like to share admin credentials to ${create ? "create" : "drop"} a database`,
2701
+ type: "confirm",
2702
+ name: "confirm",
2703
+ initial: true
2383
2704
  }
2384
- changes = exported || getCurrentChanges();
2385
- changeCache[file.path] = changes;
2705
+ ]);
2706
+ if (!confirm.confirm) {
2707
+ return;
2386
2708
  }
2387
- const db = createMigrationInterface(trx, up, config, asts);
2388
- if (changes.length) {
2389
- const from = up ? 0 : changes.length - 1;
2390
- const to = up ? changes.length : -1;
2391
- const step = up ? 1 : -1;
2392
- for (let i = from; i !== to; i += step) {
2393
- await changes[i](db, up);
2709
+ const values = await prompts([
2710
+ {
2711
+ message: "Enter admin user:",
2712
+ type: "text",
2713
+ name: "user",
2714
+ initial: "postgres",
2715
+ min: 1
2716
+ },
2717
+ {
2718
+ message: "Enter admin password:",
2719
+ type: "password",
2720
+ name: "password"
2394
2721
  }
2395
- }
2396
- await (up ? saveMigratedVersion : removeMigratedVersion)(
2397
- db.adapter,
2398
- file.version,
2399
- config
2400
- );
2722
+ ]);
2723
+ return setAdapterOptions(options, __spreadProps$2(__spreadValues$3({}, values), {
2724
+ password: values.password || void 0
2725
+ }));
2401
2726
  };
2402
2727
 
2403
2728
  const execute = async (options, sql) => {
@@ -2460,7 +2785,7 @@ Don't use this command for database service providers, only for a local db.`;
2460
2785
  if (!args.create)
2461
2786
  return;
2462
2787
  const db = new pqb.Adapter(options);
2463
- await createSchemaMigrations(db, config);
2788
+ await createMigrationsTable(db, config);
2464
2789
  await db.close();
2465
2790
  };
2466
2791
  const createDb = async (arg, config) => {
@@ -2497,62 +2822,7 @@ const dropDb = async (arg, config) => {
2497
2822
  const resetDb = async (arg, config) => {
2498
2823
  await dropDb(arg, config);
2499
2824
  await createDb(arg, config);
2500
- await migrate(arg, config);
2501
- };
2502
-
2503
- const writeMigrationFile = async (config, version, name, content) => {
2504
- var _a;
2505
- await promises.mkdir(config.migrationsPath, { recursive: true });
2506
- const filePath = path.resolve(config.migrationsPath, `${version}_${name}.ts`);
2507
- const importPath = orchidCore.getImportPath(
2508
- filePath,
2509
- path.join(config.basePath, config.dbScript)
2510
- );
2511
- await promises.writeFile(filePath, content(importPath, name));
2512
- (_a = config.logger) == null ? void 0 : _a.log(`Created ${orchidCore.pathToLog(filePath)}`);
2513
- };
2514
- const generate = async (config, [name]) => {
2515
- if (!name)
2516
- throw new Error("Migration name is missing");
2517
- const version = makeFileTimeStamp();
2518
- await writeMigrationFile(config, version, name, makeContent);
2519
- };
2520
- const makeFileTimeStamp = () => {
2521
- const now = /* @__PURE__ */ new Date();
2522
- return [
2523
- now.getUTCFullYear(),
2524
- now.getUTCMonth() + 1,
2525
- now.getUTCDate(),
2526
- now.getUTCHours(),
2527
- now.getUTCMinutes(),
2528
- now.getUTCSeconds()
2529
- ].map((value) => value < 10 ? `0${value}` : value).join("");
2530
- };
2531
- const makeContent = (importPath, name) => {
2532
- let content = `import { change } from '${importPath}';
2533
-
2534
- change(async (db) => {`;
2535
- const [first, rest] = getFirstWordAndRest(name);
2536
- if (rest) {
2537
- if (first === "create" || first === "drop") {
2538
- content += `
2539
- await db.${first === "create" ? "createTable" : "dropTable"}('${rest}', (t) => ({
2540
-
2541
- }));`;
2542
- } else if (first === "change") {
2543
- content += `
2544
- await db.changeTable('${rest}', (t) => ({
2545
-
2546
- }));`;
2547
- } else if (first === "add" || first === "remove") {
2548
- const table = first === "add" ? getTextAfterTo(rest) : getTextAfterFrom(rest);
2549
- content += `
2550
- await db.changeTable(${table ? `'${table}'` : "tableName"}, (t) => ({
2551
-
2552
- }));`;
2553
- }
2554
- }
2555
- return content + "\n});\n";
2825
+ await migrate({}, arg, config);
2556
2826
  };
2557
2827
 
2558
2828
  const filterSchema = (table) => `${table} !~ '^pg_' AND ${table} != 'information_schema'`;
@@ -2924,33 +3194,33 @@ async function introspectDbSchema(db) {
2924
3194
  return data.rows[0];
2925
3195
  }
2926
3196
 
2927
- var __defProp$1 = Object.defineProperty;
2928
- var __defProps = Object.defineProperties;
2929
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
2930
- var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
2931
- var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
2932
- var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
2933
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2934
- var __spreadValues$1 = (a, b) => {
3197
+ var __defProp$2 = Object.defineProperty;
3198
+ var __defProps$1 = Object.defineProperties;
3199
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
3200
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
3201
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
3202
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
3203
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3204
+ var __spreadValues$2 = (a, b) => {
2935
3205
  for (var prop in b || (b = {}))
2936
- if (__hasOwnProp$1.call(b, prop))
2937
- __defNormalProp$1(a, prop, b[prop]);
2938
- if (__getOwnPropSymbols$1)
2939
- for (var prop of __getOwnPropSymbols$1(b)) {
2940
- if (__propIsEnum$1.call(b, prop))
2941
- __defNormalProp$1(a, prop, b[prop]);
3206
+ if (__hasOwnProp$2.call(b, prop))
3207
+ __defNormalProp$2(a, prop, b[prop]);
3208
+ if (__getOwnPropSymbols$2)
3209
+ for (var prop of __getOwnPropSymbols$2(b)) {
3210
+ if (__propIsEnum$2.call(b, prop))
3211
+ __defNormalProp$2(a, prop, b[prop]);
2942
3212
  }
2943
3213
  return a;
2944
3214
  };
2945
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
3215
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
2946
3216
  var __objRest = (source, exclude) => {
2947
3217
  var target = {};
2948
3218
  for (var prop in source)
2949
- if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0)
3219
+ if (__hasOwnProp$2.call(source, prop) && exclude.indexOf(prop) < 0)
2950
3220
  target[prop] = source[prop];
2951
- if (source != null && __getOwnPropSymbols$1)
2952
- for (var prop of __getOwnPropSymbols$1(source)) {
2953
- if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop))
3221
+ if (source != null && __getOwnPropSymbols$2)
3222
+ for (var prop of __getOwnPropSymbols$2(source)) {
3223
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$2.call(source, prop))
2954
3224
  target[prop] = source[prop];
2955
3225
  }
2956
3226
  return target;
@@ -2981,7 +3251,7 @@ const structureToAst = async (ctx, adapter) => {
2981
3251
  });
2982
3252
  }
2983
3253
  for (const it of data.collations) {
2984
- ast.push(__spreadProps(__spreadValues$1({
3254
+ ast.push(__spreadProps$1(__spreadValues$2({
2985
3255
  type: "collation",
2986
3256
  action: "create"
2987
3257
  }, it), {
@@ -3076,7 +3346,7 @@ const structureToAst = async (ctx, adapter) => {
3076
3346
  );
3077
3347
  }
3078
3348
  for (const [fkey, table] of outerConstraints) {
3079
- ast.push(__spreadProps(__spreadValues$1({}, constraintToAst(ctx, fkey)), {
3349
+ ast.push(__spreadProps$1(__spreadValues$2({}, constraintToAst(ctx, fkey)), {
3080
3350
  type: "constraint",
3081
3351
  action: "create",
3082
3352
  tableSchema: table.schemaName === ctx.currentSchema ? void 0 : table.schemaName,
@@ -3233,7 +3503,7 @@ const pushTableAst = (ctx, ast, data, domains, table, pendingTables, innerConstr
3233
3503
  indexes: tableIndexes.filter(
3234
3504
  (index) => index.columns.length > 1 || index.columns.some((it) => "expression" in it)
3235
3505
  ).map((index) => ({
3236
- columns: index.columns.map((it) => __spreadProps(__spreadValues$1({}, "column" in it ? { column: it.column } : { expression: it.expression }), {
3506
+ columns: index.columns.map((it) => __spreadProps$1(__spreadValues$2({}, "column" in it ? { column: it.column } : { expression: it.expression }), {
3237
3507
  collate: it.collate,
3238
3508
  opclass: it.opclass,
3239
3509
  order: it.order
@@ -3333,9 +3603,9 @@ const makeColumnsShape = (ctx, data, domains, tableName, columns, primaryKey, in
3333
3603
  for (let item of columns) {
3334
3604
  const isSerial = getIsSerial(item);
3335
3605
  if (isSerial) {
3336
- item = __spreadProps(__spreadValues$1({}, item), { default: void 0 });
3606
+ item = __spreadProps$1(__spreadValues$2({}, item), { default: void 0 });
3337
3607
  }
3338
- let column = getColumn(ctx, data, domains, __spreadProps(__spreadValues$1({}, item), {
3608
+ let column = getColumn(ctx, data, domains, __spreadProps$1(__spreadValues$2({}, item), {
3339
3609
  type: item.type,
3340
3610
  isArray: item.isArray,
3341
3611
  isSerial
@@ -3659,13 +3929,13 @@ const pullDbStructure = async (options, config) => {
3659
3929
  const result = astToMigration(config, ast);
3660
3930
  if (!result)
3661
3931
  return;
3662
- const version = makeFileTimeStamp();
3932
+ const version = await makeFileVersion({}, config);
3663
3933
  await writeMigrationFile(config, version, "pull", result);
3664
3934
  const silentQueries = Object.assign(adapter, {
3665
3935
  silentQuery: adapter.query,
3666
3936
  silentArrays: adapter.arrays
3667
3937
  });
3668
- await saveMigratedVersion(silentQueries, version, config);
3938
+ await saveMigratedVersion(silentQueries, version, "pull", config);
3669
3939
  const cache = {};
3670
3940
  for (const item of ast) {
3671
3941
  await ((_a = config == null ? void 0 : config.appCodeUpdater) == null ? void 0 : _a.process({
@@ -3714,7 +3984,7 @@ const runRecurrentMigrations = async (options, config) => {
3714
3984
  dbs != null ? dbs : dbs = orchidCore.toArray(options).map(
3715
3985
  (opts) => pqb.createDb({ adapter: new pqb.Adapter(opts) })
3716
3986
  );
3717
- const sql = await promises.readFile(path, "utf-8");
3987
+ const sql = await fs.readFile(path, "utf-8");
3718
3988
  await Promise.all(
3719
3989
  dbs.map(async (db) => {
3720
3990
  await db.adapter.arrays(sql);
@@ -3731,7 +4001,7 @@ const runRecurrentMigrations = async (options, config) => {
3731
4001
  }
3732
4002
  };
3733
4003
  const readdirRecursive = async (dirPath, cb) => {
3734
- const list = await promises.readdir(dirPath).catch((err) => {
4004
+ const list = await fs.readdir(dirPath).catch((err) => {
3735
4005
  if (err.code !== "ENOENT")
3736
4006
  throw err;
3737
4007
  return;
@@ -3741,7 +4011,7 @@ const readdirRecursive = async (dirPath, cb) => {
3741
4011
  await Promise.all(
3742
4012
  list.map(async (item) => {
3743
4013
  const path$1 = path.join(dirPath, item);
3744
- const info = await promises.stat(path$1);
4014
+ const info = await fs.stat(path$1);
3745
4015
  if (info.isDirectory()) {
3746
4016
  await readdirRecursive(path$1, cb);
3747
4017
  } else if (info.isFile() && path$1.endsWith(".sql")) {
@@ -3751,6 +4021,290 @@ const readdirRecursive = async (dirPath, cb) => {
3751
4021
  );
3752
4022
  };
3753
4023
 
4024
+ const listMigrationsStatuses = async (options, config, args) => {
4025
+ var _a, _b;
4026
+ const adapters = options.map((opts) => new pqb.Adapter(opts));
4027
+ const ctx = {};
4028
+ const [{ migrations }, ...migrated] = await Promise.all([
4029
+ getMigrations(ctx, config, true),
4030
+ ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
4031
+ ]);
4032
+ const map = {};
4033
+ let maxVersionLength = 12;
4034
+ let maxNameLength = 4;
4035
+ for (let i = 0; i < options.length; i++) {
4036
+ const list = migrated[i];
4037
+ const key = Object.entries(list).map(([version, up]) => `${version}${up ? "t" : "f"}`).join("");
4038
+ const database = options[i].database || new URL(options[i].databaseURL).pathname.slice(1);
4039
+ if (map[key]) {
4040
+ map[key].databases.push(database);
4041
+ continue;
4042
+ }
4043
+ map[key] = {
4044
+ databases: [database],
4045
+ migrations: migrations.map((item) => {
4046
+ if (item.version.length > maxVersionLength) {
4047
+ maxVersionLength = item.version.length;
4048
+ }
4049
+ const name = path.parse(item.path).name.slice(item.version.length + 1).replace(
4050
+ /([a-z])([A-Z])/g,
4051
+ (_, a, b) => `${a} ${b.toLocaleLowerCase()}`
4052
+ ).replace(/[-_](.)/g, (_, char) => ` ${char.toLocaleLowerCase()}`).replace(/^\w/, (match) => match.toLocaleUpperCase());
4053
+ if (name.length > maxNameLength) {
4054
+ maxNameLength = name.length;
4055
+ }
4056
+ return {
4057
+ up: !!list[item.version],
4058
+ version: item.version,
4059
+ name,
4060
+ url: node_url.pathToFileURL(item.path)
4061
+ };
4062
+ })
4063
+ };
4064
+ }
4065
+ const showUrl = args.includes("p") || args.includes("path");
4066
+ const colors = typeof config.log === "object" ? (_a = config.log.colors) != null ? _a : true : true;
4067
+ const yellow = colors ? (s) => `\x1B[33m${s}\x1B[0m` : (s) => s;
4068
+ const green = colors ? (s) => `\x1B[32m${s}\x1B[0m` : (s) => s;
4069
+ const red = colors ? (s) => `\x1B[31m${s}\x1B[0m` : (s) => s;
4070
+ const blue = colors ? (s) => `\x1B[34m${s}\x1B[0m` : (s) => s;
4071
+ const log = Object.values(map).map(({ databases, migrations: migrations2 }) => {
4072
+ let log2 = ` ${yellow("Database:")} ${databases.join(", ")}`;
4073
+ if (migrations2.length === 0) {
4074
+ return log2 + `
4075
+
4076
+ No migrations available`;
4077
+ }
4078
+ const lineSeparator = yellow(
4079
+ makeChars(14 + maxVersionLength + maxNameLength, "-")
4080
+ );
4081
+ const columnSeparator = yellow("|");
4082
+ log2 += "\n\n " + yellow(
4083
+ `Status | Migration ID${makeChars(
4084
+ maxVersionLength - 12,
4085
+ " "
4086
+ )} | Name
4087
+ ${lineSeparator}`
4088
+ );
4089
+ for (const migration of migrations2) {
4090
+ log2 += `
4091
+ ${migration.up ? ` ${green("Up")} ` : red("Down")} ${columnSeparator} ${blue(migration.version)}${makeChars(
4092
+ maxVersionLength - migration.version.length,
4093
+ " "
4094
+ )} ${columnSeparator} ${migration.name}`;
4095
+ if (showUrl) {
4096
+ log2 += `
4097
+ ${migration.url}
4098
+ `;
4099
+ }
4100
+ }
4101
+ return log2 += showUrl ? lineSeparator : `
4102
+ ${lineSeparator}`;
4103
+ }).join("\n\n");
4104
+ ((_b = config.logger) != null ? _b : console).log(log);
4105
+ await Promise.all(adapters.map((adapter) => adapter.close()));
4106
+ };
4107
+ const makeChars = (count, char) => {
4108
+ let chars = "";
4109
+ for (let i = 0; i < count; i++) {
4110
+ chars += char;
4111
+ }
4112
+ return chars;
4113
+ };
4114
+
4115
+ var __defProp$1 = Object.defineProperty;
4116
+ var __defProps = Object.defineProperties;
4117
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4118
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
4119
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
4120
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
4121
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4122
+ var __spreadValues$1 = (a, b) => {
4123
+ for (var prop in b || (b = {}))
4124
+ if (__hasOwnProp$1.call(b, prop))
4125
+ __defNormalProp$1(a, prop, b[prop]);
4126
+ if (__getOwnPropSymbols$1)
4127
+ for (var prop of __getOwnPropSymbols$1(b)) {
4128
+ if (__propIsEnum$1.call(b, prop))
4129
+ __defNormalProp$1(a, prop, b[prop]);
4130
+ }
4131
+ return a;
4132
+ };
4133
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
4134
+ const rebase = async (options, config) => {
4135
+ var _a, _b;
4136
+ if (config.migrations) {
4137
+ throw new Error("Cannot rebase migrations defined in the config");
4138
+ }
4139
+ if (config.migrationId !== "serial") {
4140
+ throw new Error(
4141
+ `Cannot rebase when the 'migrationId' is set to '${config.migrationId}' in the config`
4142
+ );
4143
+ }
4144
+ const adapters = options.map((opts) => new pqb.Adapter(opts));
4145
+ const ctx = {};
4146
+ const [set, ...versionMaps] = await Promise.all([
4147
+ await getMigrations(ctx, config, true, true),
4148
+ ...adapters.map((adapter) => getMigratedVersionsMap(ctx, adapter, config))
4149
+ ]);
4150
+ await Promise.all(adapters.map((adapter) => adapter.close()));
4151
+ const files = set.migrations.map((file) => __spreadProps(__spreadValues$1({}, file), {
4152
+ name: path.basename(file.path),
4153
+ serial: +file.version
4154
+ }));
4155
+ if (!files.length)
4156
+ return;
4157
+ const start = files.findIndex(
4158
+ (file, i) => i !== 0 && file.serial === files[i - 1].serial
4159
+ );
4160
+ if (start === -1)
4161
+ return;
4162
+ const combinedVersionsMap = {};
4163
+ for (const map of versionMaps) {
4164
+ Object.assign(combinedVersionsMap, map);
4165
+ }
4166
+ const renames = [];
4167
+ const renamesMap = {};
4168
+ let minVersionToMigrate = (_b = (_a = files.find((file) => !combinedVersionsMap[file.version])) == null ? void 0 : _a.serial) != null ? _b : Infinity;
4169
+ const migratedFiles = [];
4170
+ let maxNewVersion = 0;
4171
+ let move = 0;
4172
+ for (let i = start; i < files.length; i++) {
4173
+ const prev = files[i - 1];
4174
+ const file = files[i];
4175
+ let moveFile;
4176
+ const migratedName = combinedVersionsMap[file.version];
4177
+ if (prev.serial === file.serial) {
4178
+ if (migratedName) {
4179
+ if (prev.name === migratedName) {
4180
+ moveFile = prev;
4181
+ } else if (file.name === migratedName) {
4182
+ moveFile = file;
4183
+ }
4184
+ }
4185
+ if (moveFile) {
4186
+ if (moveFile.serial < minVersionToMigrate) {
4187
+ minVersionToMigrate = moveFile.serial;
4188
+ }
4189
+ migratedFiles.push(moveFile);
4190
+ } else if (!moveFile) {
4191
+ move++;
4192
+ const result = await prompts([
4193
+ {
4194
+ type: "select",
4195
+ name: "file",
4196
+ message: "Which should go first?",
4197
+ choices: [
4198
+ {
4199
+ title: prev.name,
4200
+ value: "prev"
4201
+ },
4202
+ {
4203
+ title: file.name,
4204
+ value: "current"
4205
+ }
4206
+ ]
4207
+ }
4208
+ ]);
4209
+ moveFile = result.file === "prev" ? prev : file;
4210
+ }
4211
+ }
4212
+ let newVersion = file.serial;
4213
+ if (move) {
4214
+ newVersion += move;
4215
+ if (moveFile === prev && !renamesMap[prev.path])
4216
+ newVersion--;
4217
+ if (file.serial !== newVersion) {
4218
+ if (newVersion < minVersionToMigrate)
4219
+ minVersionToMigrate = newVersion;
4220
+ const values = [file.path, newVersion];
4221
+ renames.push(values);
4222
+ renamesMap[file.path] = values;
4223
+ }
4224
+ if (moveFile === prev) {
4225
+ if (prev.serial < minVersionToMigrate)
4226
+ minVersionToMigrate = prev.serial;
4227
+ newVersion = prev.serial + move;
4228
+ let item = [prev.path, newVersion];
4229
+ if (renamesMap[prev.path]) {
4230
+ renamesMap[prev.path] = item;
4231
+ for (let i2 = renames.length - 1; i2 >= 0; i2--) {
4232
+ const rename = renames[i2];
4233
+ rename[1]--;
4234
+ renames[i2] = item;
4235
+ if (rename[0] === prev.path)
4236
+ break;
4237
+ renamesMap[item[0]] = item;
4238
+ item = rename;
4239
+ }
4240
+ } else {
4241
+ renames.push(item);
4242
+ renamesMap[prev.path] = item;
4243
+ }
4244
+ }
4245
+ }
4246
+ if (file.name !== migratedName && newVersion > maxNewVersion) {
4247
+ maxNewVersion = newVersion;
4248
+ }
4249
+ }
4250
+ if (!renames.length && !migratedFiles.length)
4251
+ return;
4252
+ maxNewVersion++;
4253
+ renames.push(
4254
+ ...migratedFiles.map((file, i) => {
4255
+ const rename = [file.path, maxNewVersion + i];
4256
+ renamesMap[file.path] = rename;
4257
+ return rename;
4258
+ })
4259
+ );
4260
+ if (!renames.length)
4261
+ return;
4262
+ const migrationsDown = files.filter(
4263
+ (file) => combinedVersionsMap[file.version] === file.name && file.serial >= minVersionToMigrate
4264
+ );
4265
+ const migrationsUp = files.reduce((files2, file) => {
4266
+ const rename = renamesMap[file.path];
4267
+ if (rename) {
4268
+ const version = String(rename[1]).padStart(4, "0");
4269
+ files2.push(__spreadProps(__spreadValues$1({}, file), {
4270
+ path: path.join(
4271
+ path.dirname(rename[0]),
4272
+ version + path.basename(rename[0]).slice(version.length)
4273
+ ),
4274
+ version
4275
+ }));
4276
+ } else if (!combinedVersionsMap[file.version] || file.serial >= minVersionToMigrate) {
4277
+ files2.push(file);
4278
+ }
4279
+ return files2;
4280
+ }, []).sort((a, b) => +b.version - +a.version);
4281
+ set.migrations = migrationsDown;
4282
+ await rakeDb$1.redo(
4283
+ ctx,
4284
+ options,
4285
+ __spreadProps(__spreadValues$1({}, config), {
4286
+ async afterRollback() {
4287
+ set.migrations = migrationsUp;
4288
+ },
4289
+ async afterMigrate() {
4290
+ set.migrations = migrationsDown;
4291
+ }
4292
+ }),
4293
+ ["all"]
4294
+ );
4295
+ for (let i = renames.length - 1; i >= 0; i--) {
4296
+ const [from, version] = renames[i];
4297
+ const prefix = String(version).padStart(4, "0");
4298
+ await fs.rename(
4299
+ from,
4300
+ path.join(
4301
+ path.dirname(from),
4302
+ prefix + path.basename(from).slice(prefix.length)
4303
+ )
4304
+ );
4305
+ }
4306
+ };
4307
+
3754
4308
  var __defProp = Object.defineProperty;
3755
4309
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3756
4310
  var __hasOwnProp = Object.prototype.hasOwnProperty;
@@ -3808,15 +4362,21 @@ const runCommand = async (options, config, args = process.argv.slice(2)) => {
3808
4362
  } else if (arg === "reset") {
3809
4363
  await resetDb(options, config);
3810
4364
  } else if (arg === "up" || arg === "migrate") {
3811
- await migrate(options, config, args.slice(1));
4365
+ await migrate({}, options, config, args.slice(1));
3812
4366
  } else if (arg === "down" || arg === "rollback") {
3813
- await rollback(options, config, args.slice(1));
4367
+ await rollback({}, options, config, args.slice(1));
3814
4368
  } else if (arg === "redo") {
3815
- await redo(options, config, args.slice(1));
4369
+ await redo({}, options, config, args.slice(1));
3816
4370
  } else if (arg === "new") {
3817
4371
  await generate(config, args.slice(1));
3818
4372
  } else if (arg === "pull") {
3819
4373
  await pullDbStructure(orchidCore.toArray(options)[0], config);
4374
+ } else if (arg === "status" || arg === "s") {
4375
+ await listMigrationsStatuses(orchidCore.toArray(options), config, args.slice(1));
4376
+ } else if (arg === "rebase") {
4377
+ await rebase(orchidCore.toArray(options), config);
4378
+ } else if (arg === "change-ids") {
4379
+ await changeIds(orchidCore.toArray(options), config, args.slice(1));
3820
4380
  } else if (config.commands[arg]) {
3821
4381
  await config.commands[arg](orchidCore.toArray(options), config, args.slice(1));
3822
4382
  } else if (arg !== "rec" && arg !== "recurrent") {
@@ -3841,7 +4401,12 @@ Commands:
3841
4401
  up migrate pending migrations, don't run recurrent
3842
4402
  rollback or down rollback the last migrated
3843
4403
  redo rollback and migrate, run recurrent
4404
+ status or s list migrations statuses
4405
+ status path or s p list migrations statuses and paths to files
3844
4406
  rec or recurrent run recurrent migrations
4407
+ change-ids serial change migrations ids to 4 digit serial
4408
+ change-ids serial 42 change migrations ids to custom digits serial
4409
+ change-ids timestamp change migrations ids to timestamps
3845
4410
  no or unknown command prints this message
3846
4411
 
3847
4412
  Migrate arguments:
@@ -3866,10 +4431,14 @@ exports.createDb = createDb;
3866
4431
  exports.createMigrationInterface = createMigrationInterface;
3867
4432
  exports.dropDb = dropDb;
3868
4433
  exports.generate = generate;
4434
+ exports.generateTimeStamp = generateTimeStamp;
4435
+ exports.getDatabaseAndUserFromOptions = getDatabaseAndUserFromOptions;
3869
4436
  exports.getMigratedVersionsMap = getMigratedVersionsMap;
3870
- exports.makeFileTimeStamp = makeFileTimeStamp;
4437
+ exports.makeFileVersion = makeFileVersion;
3871
4438
  exports.migrate = migrate;
3872
4439
  exports.migrateOrRollback = migrateOrRollback;
4440
+ exports.migrationConfigDefaults = migrationConfigDefaults;
4441
+ exports.processRakeDbConfig = processRakeDbConfig;
3873
4442
  exports.rakeDb = rakeDb;
3874
4443
  exports.redo = redo;
3875
4444
  exports.removeMigratedVersion = removeMigratedVersion;