@warlock.js/cascade 5.24.0 → 5.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +30 -5
  2. package/README.md +101 -101
  3. package/bin/cascade.js +0 -0
  4. package/cjs/index.cjs +307 -88
  5. package/cjs/index.cjs.map +1 -1
  6. package/esm/contracts/database-driver.contract.d.mts +22 -1
  7. package/esm/contracts/database-driver.contract.d.mts.map +1 -1
  8. package/esm/contracts/index.d.mts +1 -1
  9. package/esm/contracts/query-builder.contract.d.mts +7 -0
  10. package/esm/contracts/query-builder.contract.d.mts.map +1 -1
  11. package/esm/data-source/data-source-registry.d.mts +8 -6
  12. package/esm/data-source/data-source-registry.d.mts.map +1 -1
  13. package/esm/data-source/data-source-registry.mjs +7 -1
  14. package/esm/data-source/data-source-registry.mjs.map +1 -1
  15. package/esm/drivers/mongodb/mongodb-driver.d.mts +13 -0
  16. package/esm/drivers/mongodb/mongodb-driver.d.mts.map +1 -1
  17. package/esm/drivers/mongodb/mongodb-driver.mjs +71 -2
  18. package/esm/drivers/mongodb/mongodb-driver.mjs.map +1 -1
  19. package/esm/drivers/mongodb/mongodb-query-builder.d.mts +5 -0
  20. package/esm/drivers/mongodb/mongodb-query-builder.d.mts.map +1 -1
  21. package/esm/drivers/mongodb/mongodb-query-builder.mjs +11 -1
  22. package/esm/drivers/mongodb/mongodb-query-builder.mjs.map +1 -1
  23. package/esm/drivers/postgres/postgres-driver.d.mts +9 -0
  24. package/esm/drivers/postgres/postgres-driver.d.mts.map +1 -1
  25. package/esm/drivers/postgres/postgres-driver.mjs +55 -7
  26. package/esm/drivers/postgres/postgres-driver.mjs.map +1 -1
  27. package/esm/drivers/postgres/postgres-query-builder.d.mts +5 -0
  28. package/esm/drivers/postgres/postgres-query-builder.d.mts.map +1 -1
  29. package/esm/drivers/postgres/postgres-query-builder.mjs +15 -0
  30. package/esm/drivers/postgres/postgres-query-builder.mjs.map +1 -1
  31. package/esm/drivers/postgres/postgres-query-parser.d.mts +1 -4
  32. package/esm/drivers/postgres/postgres-query-parser.d.mts.map +1 -1
  33. package/esm/drivers/postgres/postgres-query-parser.mjs +4 -5
  34. package/esm/drivers/postgres/postgres-query-parser.mjs.map +1 -1
  35. package/esm/errors/unsafe-filter.error.mjs.map +1 -1
  36. package/esm/errors/unsafe-raw-expression.error.mjs.map +1 -1
  37. package/esm/errors/unsupported-lock-for-update.error.d.mts +11 -0
  38. package/esm/errors/unsupported-lock-for-update.error.d.mts.map +1 -0
  39. package/esm/errors/unsupported-lock-for-update.error.mjs +16 -0
  40. package/esm/errors/unsupported-lock-for-update.error.mjs.map +1 -0
  41. package/esm/events/model-events.mjs.map +1 -1
  42. package/esm/index.d.mts +4 -3
  43. package/esm/index.mjs +2 -1
  44. package/esm/migration/index.d.mts +1 -1
  45. package/esm/migration/migration-order.mjs +6 -3
  46. package/esm/migration/migration-order.mjs.map +1 -1
  47. package/esm/migration/migration-runner.d.mts +5 -3
  48. package/esm/migration/migration-runner.d.mts.map +1 -1
  49. package/esm/migration/migration-runner.mjs +3 -2
  50. package/esm/migration/migration-runner.mjs.map +1 -1
  51. package/esm/migration/migration.d.mts +11 -1
  52. package/esm/migration/migration.d.mts.map +1 -1
  53. package/esm/migration/migration.mjs +45 -2
  54. package/esm/migration/migration.mjs.map +1 -1
  55. package/esm/migration/sql-grammar.mjs.map +1 -1
  56. package/esm/model/generate-model-id.mjs +23 -0
  57. package/esm/model/generate-model-id.mjs.map +1 -0
  58. package/esm/model/methods/delete-methods.mjs.map +1 -1
  59. package/esm/model/methods/meta-methods.mjs.map +1 -1
  60. package/esm/model/methods/query-methods.mjs +38 -11
  61. package/esm/model/methods/query-methods.mjs.map +1 -1
  62. package/esm/model/methods/write-methods.mjs.map +1 -1
  63. package/esm/model/model.d.mts +2 -2
  64. package/esm/model/model.d.mts.map +1 -1
  65. package/esm/model/model.mjs +1 -1
  66. package/esm/model/model.mjs.map +1 -1
  67. package/esm/query-builder/query-builder.d.mts +5 -0
  68. package/esm/query-builder/query-builder.d.mts.map +1 -1
  69. package/esm/query-builder/query-builder.mjs +16 -1
  70. package/esm/query-builder/query-builder.mjs.map +1 -1
  71. package/esm/utils/sanitize-filter.mjs.map +1 -1
  72. package/esm/validation/plugins/database-rules-plugin.mjs.map +1 -1
  73. package/esm/writer/database-writer.d.mts +0 -33
  74. package/esm/writer/database-writer.d.mts.map +1 -1
  75. package/esm/writer/database-writer.mjs +3 -52
  76. package/esm/writer/database-writer.mjs.map +1 -1
  77. package/llms-full.txt +2911 -2864
  78. package/package.json +5 -5
  79. package/skills/aggregate-data/SKILL.md +165 -165
  80. package/skills/alter-migration/SKILL.md +531 -531
  81. package/skills/configure-delete-strategy/SKILL.md +130 -130
  82. package/skills/define-model/SKILL.md +205 -205
  83. package/skills/define-relations/SKILL.md +171 -171
  84. package/skills/manage-data-sources/SKILL.md +177 -140
  85. package/skills/manage-transactions/SKILL.md +215 -205
  86. package/skills/paginate-results/SKILL.md +122 -122
  87. package/skills/perform-atomic-ops/SKILL.md +156 -156
  88. package/skills/query-data/SKILL.md +213 -213
  89. package/skills/run-cascade-cli/SKILL.md +125 -125
  90. package/skills/search-by-vector/SKILL.md +127 -127
  91. package/skills/subscribe-to-model-events/SKILL.md +148 -148
  92. package/skills/track-changes/SKILL.md +127 -127
  93. package/skills/write-migration/SKILL.md +206 -206
@@ -5,11 +5,14 @@ import { compareCreatedAt } from "./parse-created-at.mjs";
5
5
  * Comparator for applying migrations — oldest first.
6
6
  *
7
7
  * Priority:
8
- * 1. `order` override (lower = earlier, default 0)
9
- * 2. `createdAt` timestamp (older = earlier)
10
- * 3. Alphabetical by migration name (last resort)
8
+ * 1. package origin before app origin
9
+ * 2. `order` override (lower = earlier, default 0)
10
+ * 3. `createdAt` timestamp (older = earlier)
11
+ * 4. Alphabetical by migration name (last resort)
11
12
  */
12
13
  function sortMigrations(a, b) {
14
+ const byOrigin = Number(a.origin === "app") - Number(b.origin === "app");
15
+ if (byOrigin !== 0) return byOrigin;
13
16
  const byOrder = (a.order ?? 0) - (b.order ?? 0);
14
17
  if (byOrder !== 0) return byOrder;
15
18
  const byCreatedAt = compareCreatedAt(a.createdAt, b.createdAt);
@@ -1 +1 @@
1
- {"version":3,"file":"migration-order.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/migration-order.ts"],"sourcesContent":["import { compareCreatedAt } from \"./parse-created-at\";\n\n/** The minimum shape ordering needs — the runner passes full migration classes. */\ntype Orderable = {\n createdAt?: string;\n migrationName: string;\n order?: number;\n};\n\n/**\n * Comparator for applying migrations — oldest first.\n *\n * Priority:\n * 1. `order` override (lower = earlier, default 0)\n * 2. `createdAt` timestamp (older = earlier)\n * 3. Alphabetical by migration name (last resort)\n */\nexport function sortMigrations(a: Orderable, b: Orderable): number {\n const byOrder = (a.order ?? 0) - (b.order ?? 0);\n\n if (byOrder !== 0) {\n return byOrder;\n }\n\n const byCreatedAt = compareCreatedAt(a.createdAt, b.createdAt);\n\n if (byCreatedAt !== undefined) {\n return byCreatedAt;\n }\n\n // Last resort: alphabetical\n return a.migrationName.localeCompare(b.migrationName);\n}\n\n/**\n * Comparator for rolling migrations back — newest first, the exact inverse of\n * {@link sortMigrations}.\n *\n * A rollback has to undo migrations in the reverse of the order they were\n * applied, or a `down()` will hit schema its predecessor already removed —\n * dropping a table before dropping the column that was added to it.\n *\n * This must be an explicit descending sort rather than a `.reverse()` of the\n * executed list: that list is read back ordered by `batch, name`, so it is\n * alphabetical rather than chronological, and reversing it merely produces\n * reverse-alphabetical order.\n */\nexport function sortMigrationsForRollback(a: Orderable, b: Orderable): number {\n return sortMigrations(b, a);\n}\n"],"mappings":";;;;;;;;;;;AAiBA,SAAgB,eAAe,GAAc,GAAsB;CACjE,MAAM,WAAW,EAAE,SAAS,MAAM,EAAE,SAAS;CAE7C,IAAI,YAAY,GACd,OAAO;CAGT,MAAM,cAAc,iBAAiB,EAAE,WAAW,EAAE,SAAS;CAE7D,IAAI,gBAAgB,QAClB,OAAO;CAIT,OAAO,EAAE,cAAc,cAAc,EAAE,aAAa;AACtD;;;;;;;;;;;;;;AAeA,SAAgB,0BAA0B,GAAc,GAAsB;CAC5E,OAAO,eAAe,GAAG,CAAC;AAC5B"}
1
+ {"version":3,"file":"migration-order.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/migration-order.ts"],"sourcesContent":["import { compareCreatedAt } from \"./parse-created-at\";\nimport type { MigrationOrigin } from \"./migration\";\n\n/** The minimum shape ordering needs — the runner passes full migration classes. */\ntype Orderable = {\n createdAt?: string;\n migrationName: string;\n order?: number;\n origin?: MigrationOrigin;\n};\n\n/**\n * Comparator for applying migrations — oldest first.\n *\n * Priority:\n * 1. package origin before app origin\n * 2. `order` override (lower = earlier, default 0)\n * 3. `createdAt` timestamp (older = earlier)\n * 4. Alphabetical by migration name (last resort)\n */\nexport function sortMigrations(a: Orderable, b: Orderable): number {\n const byOrigin = Number(a.origin === \"app\") - Number(b.origin === \"app\");\n\n if (byOrigin !== 0) {\n return byOrigin;\n }\n\n const byOrder = (a.order ?? 0) - (b.order ?? 0);\n\n if (byOrder !== 0) {\n return byOrder;\n }\n\n const byCreatedAt = compareCreatedAt(a.createdAt, b.createdAt);\n\n if (byCreatedAt !== undefined) {\n return byCreatedAt;\n }\n\n // Last resort: alphabetical\n return a.migrationName.localeCompare(b.migrationName);\n}\n\n/**\n * Comparator for rolling migrations back — newest first, the exact inverse of\n * {@link sortMigrations}.\n *\n * A rollback has to undo migrations in the reverse of the order they were\n * applied, or a `down()` will hit schema its predecessor already removed —\n * dropping a table before dropping the column that was added to it.\n *\n * This must be an explicit descending sort rather than a `.reverse()` of the\n * executed list: that list is read back ordered by `batch, name`, so it is\n * alphabetical rather than chronological, and reversing it merely produces\n * reverse-alphabetical order.\n */\nexport function sortMigrationsForRollback(a: Orderable, b: Orderable): number {\n return sortMigrations(b, a);\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,SAAgB,eAAe,GAAc,GAAsB;CACjE,MAAM,WAAW,OAAO,EAAE,WAAW,KAAK,IAAI,OAAO,EAAE,WAAW,KAAK;CAEvE,IAAI,aAAa,GACf,OAAO;CAGT,MAAM,WAAW,EAAE,SAAS,MAAM,EAAE,SAAS;CAE7C,IAAI,YAAY,GACd,OAAO;CAGT,MAAM,cAAc,iBAAiB,EAAE,WAAW,EAAE,SAAS;CAE7D,IAAI,gBAAgB,QAClB,OAAO;CAIT,OAAO,EAAE,cAAc,cAAc,EAAE,aAAa;AACtD;;;;;;;;;;;;;;AAeA,SAAgB,0BAA0B,GAAc,GAAsB;CAC5E,OAAO,eAAe,GAAG,CAAC;AAC5B"}
@@ -1,4 +1,4 @@
1
- import { Migration, MigrationContract } from "./migration.mjs";
1
+ import { Migration, MigrationContract, MigrationOrigin } from "./migration.mjs";
2
2
  import { DataSource } from "../data-source/data-source.mjs";
3
3
  import { MigrationRecord, MigrationResult } from "./types.mjs";
4
4
 
@@ -9,6 +9,7 @@ import { MigrationRecord, MigrationResult } from "./types.mjs";
9
9
  type MigrationClass = (new () => Migration) & {
10
10
  migrationName: string;
11
11
  createdAt?: string;
12
+ origin?: MigrationOrigin;
12
13
  };
13
14
  /**
14
15
  * What a caller may hand to {@link MigrationRunner.register}.
@@ -29,6 +30,7 @@ type MigrationClass = (new () => Migration) & {
29
30
  type RegisterableMigration = (new () => MigrationContract) & {
30
31
  migrationName?: string;
31
32
  createdAt?: string;
33
+ origin?: MigrationOrigin;
32
34
  };
33
35
  /**
34
36
  * Options for migration execution.
@@ -149,7 +151,7 @@ declare class MigrationRunner {
149
151
  * The migration name is read from `MigrationClass.migrationName`.
150
152
  *
151
153
  * @param MigrationClass - Migration class (must have static `name` set)
152
- * @param createdAt - Optional timestamp for ordering
154
+ * @param origin - Registration source; defaults to `"app"` for direct registrations.
153
155
  * @returns This runner for chaining
154
156
  *
155
157
  * @example
@@ -158,7 +160,7 @@ declare class MigrationRunner {
158
160
  * runner.register(CreateUsersTable);
159
161
  * ```
160
162
  */
161
- register(MigrationClass: RegisterableMigration): this;
163
+ register(MigrationClass: RegisterableMigration, origin?: MigrationOrigin): this;
162
164
  /**
163
165
  * Register multiple migrations.
164
166
  *
@@ -1 +1 @@
1
- {"version":3,"file":"migration-runner.d.mts","names":[],"sources":["../../../../../../../cascade/src/migration/migration-runner.ts"],"mappings":";;;;;;;AAW2E;KAKtE,cAAA,cAA4B,SAAS;EACxC,aAAA;EACA,SAAA;AAAA;;;;AAAS;AAAA;;;;;;;;AAqBA;AAAA;;;KAFN,qBAAA,cAAmC,iBAAiB;EACvD,aAAA;EACA,SAAA;AAAA;;AAmCqB;AAqCvB;KA9CK,cAAA;yDAEM,MAAA,YA4CoC;EAAA,SA1CpC,MAAA;EAkFiB;;;;EAAA,SA7EjB,YAAA;AAAA;;;;;;iBAqCK,kBAAA,CAAmB,IAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAwClC,eAAA;EAuBP;EAAA,SArBY,UAAA,EAAY,cAAA;EAsBxB;EAAA,QAnBI,UAAA;EAiBN;EAAA,iBAde,gBAAA;EAgCgB;EAAA,iBA7BhB,eAAA;EAsCT;EAAA,iBAnCS,OAAA;EA4DT;;;;;cApDN,OAAA;IACE,UAAA,GAAa,UAAA;IACb,eAAA;IACA,OAAA;EAAA;EA0PY;;;EA3OT,aAAA,CAAc,UAAA,EAAY,UAAA;EAyR1B;;;EAAA,QAhRC,aAAA;EA8SN;;;EAAA,QApSM,kBAAA;EAsSG;;;;EAAA,QAvRH,iBAAA;EA4SN;EAAA,QArSM,QAAA;EAsSG;EAAA,QAjSH,UAAA;EA2TqB;;;;;;;EAAA,QA5SrB,oBAAA;EA2iBe;EAAA,QAnhBf,WAAA;EAsnBK;EAAA,QAnnBC,YAAA;EAmnBY;;;;EAAA,QAzmBZ,QAAA;EAsnBH;EAAA,QAxlBG,WAAA;EAylBX;;;;;;;;;;;;;;;EA9eI,QAAA,CAAS,cAAA,EAAgB,qBAAA;EAgkB5B;;;;;;EA5hBG,YAAA,CAAa,UAAA,EAAY,qBAAA;EAuyBxB;;;EA7xBD,KAAA;EA60BJ;;;EAr0BI,kBAAA;EAi6BO;;;;;;;;;;AA2DkB;AAUlC;;EAj9Be,GAAA,CACX,cAAA,EAAgB,cAAA,EAChB,OAAA,GAAS,cAAA,GACR,OAAA,CAAQ,eAAA;EA88BuC;AAAA;;;;;;;;;;;EA37BrC,QAAA,CACX,cAAA,EAAgB,cAAA,EAChB,OAAA,GAAS,cAAA,GACR,OAAA,CAAQ,eAAA;;;;;;;;;;;;;;;;EA0BE,MAAA,CAAO,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;EAAA,QAS7C,cAAA;;;;;EAsPD,SAAA,CAAU,OAAA;IAAW,WAAA;IAAuB,OAAA;EAAA,IAA2B,OAAA;;;;;;;EAmGvE,YAAA,CAAa,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;;;;;;;;EAWpD,eAAA,CACX,OAAA,UACA,OAAA,GAAS,cAAA,GACR,OAAA,CAAQ,eAAA;EAAA,QAMG,uBAAA;;;;;;;EAkDD,WAAA,CAAY,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;;;;;;;EAWnD,KAAA,CAAM,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;;;;EAa7C,MAAA,IAAU,OAAA,CACrB,KAAA;IACE,IAAA;IACA,KAAA;IACA,QAAA;IACA,KAAA;EAAA;;;;;;;;;;;;UAsCU,wBAAA;;;;UA2CA,YAAA;;;;;;;;;UA6JN,uBAAA;;;;;;;;;;;;;;;;;;;UA0BA,kBAAA;;;;;;;;;;;;;EA8CK,oBAAA,CACX,OAAA;IAAW,QAAA;EAAA,IACV,OAAA,CAAQ,cAAA;;;;;;;;;;;;;;;UA6BG,uBAAA;;;;EA8DD,qBAAA,CACX,UAAA,GAAY,UAAA,EACZ,OAAA;IAAW,QAAA;EAAA,IACV,OAAA,CAAQ,eAAA;;;;UAuBG,eAAA;;;;UAuBA,qBAAA;;;;UAWA,kBAAA;AAAA;AAAA,cAUH,eAAA,EAAe,eAAwB"}
1
+ {"version":3,"file":"migration-runner.d.mts","names":[],"sources":["../../../../../../../cascade/src/migration/migration-runner.ts"],"mappings":";;;;;;;AAgB2E;KAKtE,cAAA,cAA4B,SAAA;EAC/B,aAAA;EACA,SAAA;EACA,MAAA,GAAS,eAAe;AAAA;;;;;AAAA;AAAA;;;;;;;;;;AAsBA;KAHrB,qBAAA,cAAmC,iBAAA;EACtC,aAAA;EACA,SAAA;EACA,MAAA,GAAS,eAAe;AAAA;;;;KA0BrB,cAAA;EA8CW,uDA5CL,MAAA;WAEA,MAAA;EA0CoC;AAwC/C;;;EAxC+C,SArCpC,YAAA;AAAA;;;;;;iBAqCK,kBAAA,CAAmB,IAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAwClC,eAAA;EAWM;EAAA,SATD,UAAA,EAAY,cAAA;;UAGpB,UAAA;EAkBS;EAAA,iBAfA,gBAAA;EAiBb;EAAA,iBAda,eAAA;EA6BV;EAAA,iBA1BU,OAAA;EA0BI;;;;;cAlBnB,OAAA;IACE,UAAA,GAAa,UAAA;IACb,eAAA;IACA,OAAA;EAAA;EA+IU;;;EAhIP,aAAA,CAAc,UAAA,EAAY,UAAA;EA2O8B;;;EAAA,QAlOvD,aAAA;EAuQY;;;EAAA,QA7PZ,kBAAA;EAqSU;;;;EAAA,QAtRV,iBAAA;EAwRG;EAAA,QAjRH,QAAA;EAqSU;EAAA,QAhSV,UAAA;EAiSG;;;;;;;EAAA,QAlRH,oBAAA;EA6SmD;EAAA,QArRnD,WAAA;EAohBK;EAAA,QAjhBC,YAAA;EAkhBsB;;;;EAAA,QAxgBtB,QAAA;EA4mBY;EAAA,QA9kBZ,WAAA;EA8kBmD;;;;;;;;;;;;;;;EAne1D,QAAA,CAAS,cAAA,EAAgB,qBAAA,EAAuB,MAAA,GAAQ,eAAA;EAojBb;;;;;;EA/gB3C,YAAA,CAAa,UAAA,EAAY,qBAAA;EAgiB5B;;;EAthBG,KAAA;EAqwBC;;;EA7vBD,kBAAA;EAs0BL;;;;;;;;;;;;;EAjzBW,GAAA,CACX,cAAA,EAAgB,cAAA,EAChB,OAAA,GAAS,cAAA,GACR,OAAA,CAAQ,eAAA;EAq8BqB;AAAA;AAUlC;;;;AAAoD;;;;;;EA57BrC,QAAA,CACX,cAAA,EAAgB,cAAA,EAChB,OAAA,GAAS,cAAA,GACR,OAAA,CAAQ,eAAA;;;;;;;;;;;;;;;;EA0BE,MAAA,CAAO,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;EAAA,QAS7C,cAAA;;;;;EAsPD,SAAA,CACX,OAAA;IAAW,WAAA;IAAuB,OAAA;EAAA,IACjC,OAAA;;;;;;;EAmGU,YAAA,CAAa,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;;;;;;;;EAWpD,eAAA,CACX,OAAA,UACA,OAAA,GAAS,cAAA,GACR,OAAA,CAAQ,eAAA;EAAA,QAMG,uBAAA;;;;;;;EAkDD,WAAA,CAAY,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;;;;;;;EAWnD,KAAA,CAAM,OAAA,GAAS,cAAA,GAAsB,OAAA,CAAQ,eAAA;;;;EAa7C,MAAA,IAAU,OAAA,CACrB,KAAA;IACE,IAAA;IACA,KAAA;IACA,QAAA;IACA,KAAA;EAAA;;;;;;;;;;;;UAsCU,wBAAA;;;;UA2CA,YAAA;;;;;;;;;UA6JN,uBAAA;;;;;;;;;;;;;;;;;;;UA0BA,kBAAA;;;;;;;;;;;;;EA8CK,oBAAA,CACX,OAAA;IAAW,QAAA;EAAA,IACV,OAAA,CAAQ,cAAA;;;;;;;;;;;;;;;UA6BG,uBAAA;;;;EA6DD,qBAAA,CACX,UAAA,GAAY,UAAA,EACZ,OAAA;IAAW,QAAA;EAAA,IACV,OAAA,CAAQ,eAAA;;;;UAuBG,eAAA;;;;UAuBA,qBAAA;;;;UAWA,kBAAA;AAAA;AAAA,cAUH,eAAA,EAAe,eAAwB"}
@@ -237,7 +237,7 @@ var MigrationRunner = class {
237
237
  * The migration name is read from `MigrationClass.migrationName`.
238
238
  *
239
239
  * @param MigrationClass - Migration class (must have static `name` set)
240
- * @param createdAt - Optional timestamp for ordering
240
+ * @param origin - Registration source; defaults to `"app"` for direct registrations.
241
241
  * @returns This runner for chaining
242
242
  *
243
243
  * @example
@@ -246,7 +246,7 @@ var MigrationRunner = class {
246
246
  * runner.register(CreateUsersTable);
247
247
  * ```
248
248
  */
249
- register(MigrationClass) {
249
+ register(MigrationClass, origin = "app") {
250
250
  const name = MigrationClass.migrationName;
251
251
  if (!name) throw new Error("Migration class must have a static 'migrationName' property set. Set it in CLI after importing: MigrationClass.migrationName = \"filename\";");
252
252
  const existing = this.migrations.find((m) => m.migrationName === name);
@@ -254,6 +254,7 @@ var MigrationRunner = class {
254
254
  if (existing !== MigrationClass) throw new Error(`Duplicate migration name "${name}": two different migration classes resolve to the same name. Rename one of the files (or set a unique static 'migrationName').`);
255
255
  return this;
256
256
  }
257
+ MigrationClass.origin = origin;
257
258
  this.migrations.push(MigrationClass);
258
259
  return this;
259
260
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migration-runner.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/migration-runner.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport type { MigrationDriverContract } from \"../contracts/migration-driver.contract\";\r\nimport type { DataSource } from \"../data-source/data-source\";\r\nimport { dataSourceRegistry } from \"../data-source/data-source-registry\";\r\nimport { type Migration, type MigrationContract, type MigrationStep } from \"./migration\";\r\nimport { sortMigrations, sortMigrationsForRollback } from \"./migration-order\";\r\nimport { parseCreatedAt } from \"./parse-created-at\";\r\nimport { SQLGrammar } from \"./sql-grammar\";\r\nimport type { MigrationRecord, MigrationResult, TaggedSQL } from \"./types\";\r\n\r\n/**\r\n * Migration class type with static name property.\r\n */\r\ntype MigrationClass = (new () => Migration) & {\r\n migrationName: string;\r\n createdAt?: string;\r\n};\r\n\r\n/**\r\n * What a caller may hand to {@link MigrationRunner.register}.\r\n *\r\n * Looser than {@link MigrationClass} in exactly one way: `migrationName` may be\r\n * absent. That is the documented workflow — the CLI imports a migration file and\r\n * sets the name from the filename afterwards — and `register()` enforces it at\r\n * runtime, throwing a message that says so. Once past that check the name IS\r\n * present, which is why everything stored and read downstream uses the stricter\r\n * type. Requiring it on the INPUT made the runner reject the very classes the\r\n * public `MigrationConstructor` describes.\r\n *\r\n * It constructs a MigrationContract rather than the abstract Migration class for the\r\n * same reason: `typeof Migration` is abstract and cannot satisfy `new () => Migration`,\r\n * and the public MigrationConstructor is declared against the contract. The runner only\r\n * ever uses contract members on what it registers.\r\n */\r\ntype RegisterableMigration = (new () => MigrationContract) & {\r\n migrationName?: string;\r\n createdAt?: string;\r\n};\r\n\r\n/**\r\n * Resolved instance data for a single pending migration.\r\n * @internal\r\n */\r\ntype MigrationData = {\r\n MigrationClass: MigrationClass;\r\n migration: Migration;\r\n name: string;\r\n /** Data source this migration runs against (its own, else the runner's). */\r\n dataSource: DataSource;\r\n /** Serialized `up()` statements (empty for direct-execution drivers). */\r\n statements: string[];\r\n /** Same as `statements`, with queued data steps kept in authored order. */\r\n steps: MigrationStep[];\r\n /** Whether the migration runs inside a transaction. */\r\n transactional: boolean;\r\n /** Driver has no SQL dialect (MongoDB): executed through `runMigration`. */\r\n direct: boolean;\r\n};\r\n\r\n/**\r\n * Options for migration execution.\r\n */\r\ntype ExecuteOptions = {\r\n /** Run in dry-run mode (no actual changes) */\r\n readonly dryRun?: boolean;\r\n /** Record to migrations table (default: true for batch, false for single) */\r\n readonly record?: boolean;\r\n /**\r\n * Rollback only: delete the `_migrations` rows whose migration file is no\r\n * longer registered, instead of failing on them.\r\n */\r\n readonly pruneMissing?: boolean;\r\n};\r\n\r\n/** Name of the lock document Mongo migrations claim inside the migrations collection. */\r\nconst MIGRATION_LOCK_NAME = \"__warlock_migration_lock__\";\r\nconst MIGRATION_LOCK_KEY = \"warlock:migrations\";\r\nconst MIGRATION_LOCK_TTL_MS = 10 * 60 * 1000;\r\nconst MIGRATION_LOCK_WAIT_MS = 60 * 1000;\r\nconst MIGRATION_LOCK_RETRY_MS = 1000;\r\n\r\n/** Held lock for one data source. `refresh` extends the TTL; `release` frees it. */\r\ntype MigrationLock = {\r\n refresh: () => Promise<void>;\r\n release: () => Promise<void>;\r\n};\r\n\r\ntype PgLockClient = {\r\n query: (sql: string, params?: unknown[]) => Promise<unknown>;\r\n release: () => void;\r\n};\r\n\r\n/** Minimal Mongo surface the lock needs (kept structural: no driver import). */\r\ntype MongoLockDatabase = {\r\n collection: (name: string) => {\r\n findOneAndUpdate: (filter: object, update: object, options: object) => Promise<unknown>;\r\n findOne: (filter: object) => Promise<{ owner?: string; expiresAt?: unknown } | null>;\r\n deleteOne: (filter: object) => Promise<unknown>;\r\n };\r\n};\r\n\r\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\r\n\r\n/**\r\n * Derive a migration name from a file path: drop everything after the first dot\r\n * and strip a trailing `-migration` / `_migration` suffix. Shared by every CLI\r\n * so the same file is recorded under the same name.\r\n */\r\nexport function inferMigrationName(file: string): string {\r\n const basename = path.basename(file).split(\".\")[0] ?? \"\";\r\n\r\n return basename.replace(/-migration$/, \"\").replace(/_migration$/, \"\");\r\n}\r\n\r\n/**\r\n * Migration runner that executes migrations.\r\n *\r\n * This is a pure executor - it doesn't discover migrations.\r\n * Discovery is handled by the framework (e.g., @warlock.js/core CLI).\r\n *\r\n * The migration name is read from the static `name` property on the class,\r\n * which should be set by the CLI after importing:\r\n *\r\n * @example\r\n * ```typescript\r\n * // In CLI after importing:\r\n * const { default: MigrationClass } = await import(\"./create-users.migration.ts\");\r\n * MigrationClass.migrationName ??= \"create-users\";\r\n *\r\n * // Then register or execute:\r\n * runner.register(MigrationClass);\r\n * // or\r\n * await runner.execute(MigrationClass);\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple direct execution\r\n * await runner.execute(CreateUsersTable);\r\n * await runner.rollback(CreateUsersTable);\r\n *\r\n * // Registry pattern for batch operations\r\n * runner.register(CreateUsersTable);\r\n * runner.register(AddEmailIndex);\r\n * await runner.runAll();\r\n * await runner.rollbackAll();\r\n * ```\r\n */\r\nexport class MigrationRunner {\r\n /** Registered migrations */\r\n public readonly migrations: MigrationClass[] = [];\r\n\r\n /** Data source to use */\r\n private dataSource?: DataSource;\r\n\r\n /** Cached migration drivers, one per data source */\r\n private readonly migrationDrivers = new Map<DataSource, MigrationDriverContract>();\r\n\r\n /** Table name for tracking migrations */\r\n private readonly migrationsTable: string;\r\n\r\n /** Whether to log operations */\r\n private readonly verbose: boolean;\r\n\r\n /**\r\n * Create a new migration runner.\r\n *\r\n * @param options - Runner options\r\n */\r\n public constructor(\r\n options: {\r\n dataSource?: DataSource;\r\n migrationsTable?: string;\r\n verbose?: boolean;\r\n } = {},\r\n ) {\r\n this.dataSource = options.dataSource;\r\n this.migrationsTable = options.migrationsTable ?? \"_migrations\";\r\n this.verbose = options.verbose ?? true;\r\n }\r\n\r\n // ============================================================================\r\n // DATA SOURCE\r\n // ============================================================================\r\n\r\n /**\r\n * Set the data source.\r\n */\r\n public setDataSource(dataSource: DataSource): this {\r\n this.dataSource = dataSource;\r\n this.migrationDrivers.clear();\r\n return this;\r\n }\r\n\r\n /**\r\n * Get the data source.\r\n */\r\n private getDataSource(): DataSource {\r\n if (!this.dataSource) {\r\n this.dataSource = dataSourceRegistry.get();\r\n }\r\n return this.dataSource;\r\n }\r\n\r\n /**\r\n * Get the migration driver.\r\n */\r\n private getMigrationDriver(\r\n dataSource: DataSource = this.getDataSource(),\r\n ): MigrationDriverContract {\r\n let driver = this.migrationDrivers.get(dataSource);\r\n if (!driver) {\r\n driver = dataSource.driver.migrationDriver();\r\n this.migrationDrivers.set(dataSource, driver);\r\n }\r\n return driver;\r\n }\r\n\r\n /**\r\n * Resolve a migration's declared data source (name or instance).\r\n * Falls back to the runner's own data source when it declares none.\r\n */\r\n private resolveDataSource(declared?: string | DataSource): DataSource {\r\n if (!declared) return this.getDataSource();\r\n if (typeof declared === \"string\") return dataSourceRegistry.get(declared);\r\n return declared;\r\n }\r\n\r\n /** Data source a registered migration class runs against. */\r\n private sourceOf(MigrationClass: MigrationClass): DataSource {\r\n return this.resolveDataSource(new MigrationClass().dataSource);\r\n }\r\n\r\n /** Distinct data sources across the registered migrations (runner's own included). */\r\n private getSources(): DataSource[] {\r\n const sources = new Set<DataSource>([this.getDataSource()]);\r\n for (const MigrationClass of this.migrations) {\r\n sources.add(this.sourceOf(MigrationClass));\r\n }\r\n return [...sources];\r\n }\r\n\r\n /**\r\n * Resolve whether a migration runs in a transaction:\r\n * 1. migration-level flag (instance, else the static from `Migration.create/alter`)\r\n * 2. `CONCURRENTLY` statements cannot run in a transaction block\r\n * 3. data-source config\r\n * 4. driver default\r\n */\r\n private resolveTransactional(\r\n MigrationClass: MigrationClass,\r\n migration: Migration,\r\n dataSource: DataSource,\r\n statements: string[] = [],\r\n ): boolean {\r\n const explicit =\r\n migration.transactional ?? (MigrationClass as { transactional?: boolean }).transactional;\r\n\r\n if (explicit !== undefined) return explicit;\r\n\r\n if (statements.some((sql) => /\\bCONCURRENTLY\\b/i.test(sql))) return false;\r\n\r\n return (\r\n dataSource.migrations?.transactional ??\r\n this.getMigrationDriver(dataSource).getDefaultTransactional()\r\n );\r\n }\r\n\r\n // ============================================================================\r\n // LOCKING\r\n // ============================================================================\r\n\r\n /** Locks held by the run in progress (Mongo TTL heartbeat). */\r\n private activeLocks: MigrationLock[] = [];\r\n\r\n /** Extend every held lock's TTL; called between migrations. */\r\n private async refreshLocks(): Promise<void> {\r\n for (const lock of this.activeLocks) {\r\n await lock.refresh();\r\n }\r\n }\r\n\r\n /**\r\n * Run `callback` while holding a migration lock on every given data source, so\r\n * concurrent `migrate` invocations (replicas, init containers) serialize.\r\n */\r\n private async withLock<T>(sources: DataSource[], callback: () => Promise<T>): Promise<T> {\r\n const held: MigrationLock[] = [];\r\n\r\n try {\r\n for (const dataSource of sources) {\r\n const lock = await this.acquireLock(dataSource);\r\n if (lock) held.push(lock);\r\n }\r\n\r\n this.activeLocks = held;\r\n\r\n return await callback();\r\n } finally {\r\n this.activeLocks = [];\r\n\r\n for (const lock of held.reverse()) {\r\n try {\r\n await lock.release();\r\n } catch (error) {\r\n log.warn(\r\n \"database\",\r\n \"migration\",\r\n `Failed to release migration lock: ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n /** Acquire the lock for one data source; `undefined` when its driver has no lock support. */\r\n private async acquireLock(dataSource: DataSource): Promise<MigrationLock | undefined> {\r\n const driver = dataSource.driver as unknown as {\r\n name: string;\r\n getClient?: () => { connect?: () => Promise<PgLockClient> };\r\n getDatabase?: () => MongoLockDatabase;\r\n };\r\n\r\n if (driver.name === \"postgres\" && driver.getClient) {\r\n // A dedicated client: advisory locks are per-session, not per-pool.\r\n const client = await driver.getClient().connect?.();\r\n if (!client) return undefined;\r\n\r\n try {\r\n await client.query(\"SELECT pg_advisory_lock(hashtext($1))\", [MIGRATION_LOCK_KEY]);\r\n } catch (error) {\r\n client.release();\r\n throw error;\r\n }\r\n\r\n return {\r\n refresh: async () => {},\r\n release: async () => {\r\n try {\r\n await client.query(\"SELECT pg_advisory_unlock(hashtext($1))\", [MIGRATION_LOCK_KEY]);\r\n } finally {\r\n client.release();\r\n }\r\n },\r\n };\r\n }\r\n\r\n if (driver.getDatabase) {\r\n // The unique index on `name` (created here) makes the claim below atomic.\r\n await this.getMigrationDriver(dataSource).ensureMigrationsTable(this.migrationsTable);\r\n\r\n const collection = driver.getDatabase().collection(this.migrationsTable);\r\n const owner = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;\r\n const deadline = Date.now() + MIGRATION_LOCK_WAIT_MS;\r\n\r\n const claim = async (): Promise<boolean> => {\r\n const now = new Date();\r\n\r\n try {\r\n await collection.findOneAndUpdate(\r\n {\r\n name: MIGRATION_LOCK_NAME,\r\n $or: [{ expiresAt: { $lt: now } }, { owner }],\r\n },\r\n {\r\n $set: { owner, expiresAt: new Date(now.getTime() + MIGRATION_LOCK_TTL_MS) },\r\n $setOnInsert: { batch: 0 },\r\n },\r\n { upsert: true },\r\n );\r\n\r\n return true;\r\n } catch (error) {\r\n // Held by someone else: the upsert collides with the unique `name` index.\r\n if ((error as { code?: number }).code === 11000) return false;\r\n throw error;\r\n }\r\n };\r\n\r\n while (!(await claim())) {\r\n if (Date.now() >= deadline) {\r\n const holder = await collection.findOne({ name: MIGRATION_LOCK_NAME });\r\n throw new Error(\r\n `Could not acquire the migration lock within ${MIGRATION_LOCK_WAIT_MS / 1000}s; ` +\r\n `held by \"${holder?.owner ?? \"unknown\"}\" until ${holder?.expiresAt ?? \"unknown\"}.`,\r\n );\r\n }\r\n\r\n await sleep(MIGRATION_LOCK_RETRY_MS);\r\n }\r\n\r\n return {\r\n refresh: async () => {\r\n await claim();\r\n },\r\n release: async () => {\r\n await collection.deleteOne({ name: MIGRATION_LOCK_NAME, owner });\r\n },\r\n };\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n // ============================================================================\r\n // REGISTRATION\r\n // ============================================================================\r\n\r\n /**\r\n * Register a migration.\r\n *\r\n * The migration name is read from `MigrationClass.migrationName`.\r\n *\r\n * @param MigrationClass - Migration class (must have static `name` set)\r\n * @param createdAt - Optional timestamp for ordering\r\n * @returns This runner for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * CreateUsersTable.migrationName = \"2024-01-15_create-users\";\r\n * runner.register(CreateUsersTable);\r\n * ```\r\n */\r\n public register(MigrationClass: RegisterableMigration): this {\r\n const name = MigrationClass.migrationName;\r\n if (!name) {\r\n throw new Error(\r\n `Migration class must have a static 'migrationName' property set. ` +\r\n `Set it in CLI after importing: MigrationClass.migrationName = \"filename\";`,\r\n );\r\n }\r\n const existing = this.migrations.find((m) => m.migrationName === name);\r\n\r\n if (existing) {\r\n // Re-registering the same class is idempotent; a DIFFERENT class under the\r\n // same name would silently never run, so fail loudly.\r\n if ((existing as unknown) !== MigrationClass) {\r\n throw new Error(\r\n `Duplicate migration name \"${name}\": two different migration classes resolve to the same name. ` +\r\n `Rename one of the files (or set a unique static 'migrationName').`,\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n // `name` is proven present by the throw above, so this satisfies the stricter\r\n // stored type that every reader downstream relies on.\r\n this.migrations.push(MigrationClass as MigrationClass);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Register multiple migrations.\r\n *\r\n * @param migrations - Array of migration classes\r\n * @returns This runner for chaining\r\n */\r\n public registerMany(migrations: RegisterableMigration[]): this {\r\n for (const MigrationClass of migrations) {\r\n this.register(MigrationClass);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Clear all registered migrations.\r\n */\r\n public clear(): this {\r\n this.migrations.length = 0;\r\n return this;\r\n }\r\n\r\n /**\r\n * Get all registered migration names.\r\n */\r\n public getRegisteredNames(): string[] {\r\n return this.migrations.map((m) => m.migrationName);\r\n }\r\n\r\n // ============================================================================\r\n // SINGLE EXECUTION\r\n // ============================================================================\r\n\r\n /**\r\n * Execute a single migration's up() method.\r\n *\r\n * @param MigrationClass - Migration class to execute\r\n * @param options - Execution options\r\n * @returns Migration result\r\n *\r\n * @example\r\n * ```typescript\r\n * await runner.execute(CreateUsersTable);\r\n * await runner.execute(AddEmailIndex, { dryRun: true });\r\n * ```\r\n */\r\n public async run(\r\n MigrationClass: MigrationClass,\r\n options: ExecuteOptions = {},\r\n ): Promise<MigrationResult> {\r\n return this.runMigration(MigrationClass, \"up\", {\r\n dryRun: options.dryRun,\r\n record: options.record ?? false,\r\n });\r\n }\r\n\r\n /**\r\n * Execute a single migration's down() method.\r\n *\r\n * @param MigrationClass - Migration class to rollback\r\n * @param options - Execution options\r\n * @returns Migration result\r\n *\r\n * @example\r\n * ```typescript\r\n * await runner.rollback(CreateUsersTable);\r\n * ```\r\n */\r\n public async rollback(\r\n MigrationClass: MigrationClass,\r\n options: ExecuteOptions = {},\r\n ): Promise<MigrationResult> {\r\n return this.runMigration(MigrationClass, \"down\", {\r\n dryRun: options.dryRun,\r\n record: options.record ?? false,\r\n });\r\n }\r\n\r\n // ============================================================================\r\n // BATCH EXECUTION (REGISTERED MIGRATIONS)\r\n // ============================================================================\r\n\r\n /**\r\n * Run all pending registered migrations.\r\n *\r\n * Only runs migrations not already in the migrations table.\r\n *\r\n * @param options - Execution options\r\n * @returns Results for each migration\r\n *\r\n * @example\r\n * ```typescript\r\n * runner.register(CreateUsersTable);\r\n * runner.register(AddEmailIndex);\r\n * const results = await runner.runAll();\r\n * ```\r\n */\r\n public async runAll(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\r\n // A dry run writes nothing, so it needs no lock.\r\n if (options.dryRun) return this.runAllUnlocked(options);\r\n\r\n // The pending set is computed INSIDE the lock, so a replica that waited sees\r\n // what the winner already applied.\r\n return this.withLock(this.getSources(), () => this.runAllUnlocked(options));\r\n }\r\n\r\n private async runAllUnlocked(options: ExecuteOptions): Promise<MigrationResult[]> {\r\n const { dryRun = false, record = true } = options;\r\n\r\n const results: MigrationResult[] = [];\r\n\r\n // Get pending migrations (a dry run must not create the migrations table)\r\n const pending = await this.getPendingMigrations({ readOnly: dryRun });\r\n\r\n if (pending.length === 0) {\r\n log.warn(\"database\", \"migration\", \"Nothing to migrate.\");\r\n return results;\r\n }\r\n\r\n // Next batch number per data source: each source has its own migrations table.\r\n const sources = new Set<DataSource>();\r\n const migrationsData: MigrationData[] = [];\r\n\r\n log.info(\"database\", \"migration\", `Found ${pending.length} pending migration(s).`);\r\n\r\n // 1. Resolve each migration's data source and transactional mode, and collect\r\n // its SQL. Drivers without SQL serialization (MongoDB) are executed\r\n // directly through the migration driver instead.\r\n // Extension checks fire concurrently as CREATE EXTENSION statements are met.\r\n const extensionChecks: Promise<void>[] = [];\r\n\r\n for (const MigrationClass of pending) {\r\n const migration = this.createMigrationInstance(MigrationClass);\r\n const name = MigrationClass.migrationName;\r\n const dataSource = this.resolveDataSource(migration.dataSource);\r\n sources.add(dataSource);\r\n\r\n if (dataSource.driver.supportsSqlSerialization === false) {\r\n migrationsData.push({\r\n MigrationClass,\r\n migration,\r\n name,\r\n dataSource,\r\n statements: [],\r\n steps: [],\r\n transactional: false,\r\n direct: true,\r\n });\r\n continue;\r\n }\r\n\r\n migration.setDriver(this.getMigrationDriver(dataSource));\r\n migration.setMigrationDefaults(dataSource.migrationDefaults);\r\n // Collection must not run `withConnection` side effects during a dry run.\r\n migration.setDryRun?.(dryRun);\r\n\r\n await migration.up();\r\n const steps: MigrationStep[] = migration.toSteps?.() ?? migration.toSQL();\r\n const statements = steps.map((step) =>\r\n typeof step === \"string\" ? step : \"-- data step (withConnection) skipped\",\r\n );\r\n migration.setDryRun?.(false);\r\n\r\n migrationsData.push({\r\n MigrationClass,\r\n migration,\r\n name,\r\n dataSource,\r\n statements,\r\n steps,\r\n transactional:\r\n !!dataSource.driver.transaction &&\r\n this.resolveTransactional(MigrationClass, migration, dataSource, statements),\r\n direct: false,\r\n });\r\n\r\n for (const sql of statements) {\r\n if (SQLGrammar.classify(sql) === \"CREATE_EXTENSION\") {\r\n const ext = SQLGrammar.extractExtensionName(sql);\r\n if (ext) extensionChecks.push(this.informIfExtensionMissing(ext, dataSource));\r\n }\r\n }\r\n }\r\n\r\n // 2. Resolve all extension checks before any SQL is executed.\r\n await Promise.all(extensionChecks);\r\n\r\n // 3. Dry run: print statements in migration order (authored order kept; no\r\n // global phase sort, which would reorder add-column → backfill → NOT NULL).\r\n if (dryRun) {\r\n log.info(\"database\", \"migration\", \"Dry run enabled. Would execute the following statements:\");\r\n for (const data of migrationsData) {\r\n for (const sql of data.statements) {\r\n console.log(\r\n `-- [${SQLGrammar.classify(sql)}] Phase ${SQLGrammar.phase(sql)} [${data.name}]`,\r\n );\r\n console.log(sql + \";\\n\");\r\n }\r\n }\r\n return [];\r\n }\r\n\r\n const batches = new Map<DataSource, number>();\r\n for (const dataSource of sources) {\r\n batches.set(dataSource, await this.getNextBatchNumber(dataSource));\r\n }\r\n\r\n // 4. Split into runs: consecutive transactional migrations on the same data\r\n // source share one transaction; every other migration (non-transactional\r\n // or direct) runs alone.\r\n const runs: MigrationData[][] = [];\r\n for (const data of migrationsData) {\r\n const last = runs[runs.length - 1];\r\n const lastFirst = last?.[0];\r\n if (\r\n data.transactional &&\r\n last &&\r\n lastFirst?.transactional &&\r\n lastFirst.dataSource === data.dataSource\r\n ) {\r\n last.push(data);\r\n } else {\r\n runs.push([data]);\r\n }\r\n }\r\n\r\n for (const run of runs) {\r\n const first = run[0];\r\n if (!first) continue;\r\n await this.refreshLocks();\r\n const dataSource = first.dataSource;\r\n const nextBatch = batches.get(dataSource)!;\r\n const startTime = Date.now();\r\n\r\n if (first.direct) {\r\n const result = await this.runMigration(first.MigrationClass, \"up\", {\r\n dryRun,\r\n record,\r\n batch: nextBatch,\r\n });\r\n results.push(result);\r\n if (!result.success) break;\r\n continue;\r\n }\r\n\r\n const driver = dataSource.driver;\r\n let failed = false;\r\n let errorMessage = \"\";\r\n /** The migration that owns the SQL statement that threw. */\r\n let failingMigrationName: string | undefined;\r\n\r\n const executeRun = async (): Promise<void> => {\r\n for (const data of run) {\r\n for (const step of data.steps) {\r\n try {\r\n if (typeof step === \"string\") await driver.query(step);\r\n else await step.data();\r\n } catch (err) {\r\n failingMigrationName = data.name;\r\n throw err;\r\n }\r\n }\r\n\r\n // A non-transactional migration is recorded right after it applied.\r\n // Transactional ones are recorded inside the shared transaction.\r\n if (record) {\r\n await this.recordMigration(\r\n data.name,\r\n nextBatch,\r\n data.MigrationClass.createdAt\r\n ? parseCreatedAt(data.MigrationClass.createdAt)\r\n : new Date(),\r\n dataSource,\r\n );\r\n }\r\n }\r\n };\r\n\r\n try {\r\n if (first.transactional && driver.transaction) {\r\n await driver.transaction(executeRun);\r\n } else {\r\n await executeRun();\r\n }\r\n } catch (err) {\r\n failed = true;\r\n errorMessage = err instanceof Error ? err.message : String(err);\r\n }\r\n\r\n const durationMs = Date.now() - startTime;\r\n\r\n // Only the migration that owns the failing statement is marked failed;\r\n // the rest of its run is reported as rolled back.\r\n for (const data of run) {\r\n const isCulprit = failed && data.name === failingMigrationName;\r\n const wasSkipped = failed && !isCulprit;\r\n\r\n results.push({\r\n name: data.name,\r\n table: data.migration.table,\r\n direction: \"up\",\r\n success: !failed,\r\n error: isCulprit ? errorMessage : undefined,\r\n durationMs: Math.round(durationMs / run.length),\r\n executedAt: new Date(),\r\n });\r\n\r\n if (isCulprit) {\r\n log.error(\r\n \"database\",\r\n \"migration\",\r\n `${colors.magenta(data.name)}: ✗ Failed: ${errorMessage}`,\r\n );\r\n } else if (wasSkipped) {\r\n log.warn(\r\n \"database\",\r\n \"migration\",\r\n `${colors.magenta(data.name)}: rolled back (batch transaction failed)`,\r\n );\r\n } else {\r\n log.success(\r\n \"database\",\r\n \"migration\",\r\n `Migrated: ${colors.magenta(data.name)} successfully`,\r\n );\r\n }\r\n }\r\n\r\n if (failed) {\r\n log.error(\r\n \"database\",\r\n \"migration\",\r\n `Batch execution failed. Rollback performed if transactional.`,\r\n );\r\n throw new Error(\"Migration batch failed: \" + errorMessage);\r\n }\r\n }\r\n\r\n const successCount = results.filter((r) => r.success).length;\r\n log.success(\r\n \"database\",\r\n \"migration\",\r\n `Migration execution complete: ${successCount}/${pending.length} migrations processed successfully.`,\r\n );\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Export migrations as phase-ordered SQL files in database/sql/ directory.\r\n * By default, it exports all registered migrations. Use `pendingOnly: true` to export only pending ones.\r\n */\r\n public async exportSQL(options: { pendingOnly?: boolean; compact?: boolean } = {}): Promise<void> {\r\n if (this.getDataSource().driver.supportsSqlSerialization === false) {\r\n throw new Error(\r\n \"SQL export is not supported on this data source — its driver has no SQL dialect. \" +\r\n \"Migrations on this driver execute native commands through the migration driver instead.\",\r\n );\r\n }\r\n\r\n const migrationsToExport = options.pendingOnly\r\n ? await this.getPendingMigrations({ readOnly: true })\r\n : this.migrations;\r\n\r\n if (migrationsToExport.length === 0) {\r\n log.warn(\"database\", \"migration\", \"No migrations to export.\");\r\n return;\r\n }\r\n\r\n log.info(\r\n \"database\",\r\n \"migration\",\r\n `Exporting ${migrationsToExport.length} ${options.pendingOnly ? \"pending \" : \"\"}migration(s) to SQL files...`,\r\n );\r\n\r\n const upStatements: TaggedSQL[] = [];\r\n // Down SQL is grouped per migration so only the migration order is reversed,\r\n // never the statements inside one migration's down().\r\n const downGroups: { createdAt?: string; index: number; statements: TaggedSQL[] }[] = [];\r\n\r\n for (const [index, MigrationClass] of migrationsToExport.entries()) {\r\n const migration = this.createMigrationInstance(MigrationClass);\r\n const name = MigrationClass.migrationName;\r\n\r\n // Export performs no writes: `withConnection` callbacks are skipped.\r\n migration.setDryRun?.(true);\r\n\r\n // Collect up SQL\r\n await migration.up();\r\n for (const sql of migration.toSQL()) {\r\n upStatements.push({\r\n sql,\r\n phase: SQLGrammar.phase(sql),\r\n statementType: SQLGrammar.classify(sql),\r\n createdAt: MigrationClass.createdAt,\r\n migrationName: name,\r\n });\r\n }\r\n\r\n // Collect down SQL (reuse same instance — toSQL() cleared pendingOps)\r\n await migration.down();\r\n const statements: TaggedSQL[] = [];\r\n for (const sql of migration.toSQL()) {\r\n statements.push({\r\n sql,\r\n phase: SQLGrammar.phase(sql),\r\n statementType: SQLGrammar.classify(sql),\r\n createdAt: MigrationClass.createdAt,\r\n migrationName: name,\r\n });\r\n }\r\n downGroups.push({ createdAt: MigrationClass.createdAt, index, statements });\r\n }\r\n\r\n const sortedUp = SQLGrammar.sort(upStatements);\r\n // Down SQL: newest migration first (chronological, registration order breaks\r\n // ties), each migration's own down() statements keep their order.\r\n const sortedDown = downGroups\r\n .sort((a, b) => {\r\n const byDate = (a.createdAt ?? \"\").localeCompare(b.createdAt ?? \"\");\r\n return byDate !== 0 ? byDate : a.index - b.index;\r\n })\r\n .reverse()\r\n .flatMap((group) => group.statements);\r\n\r\n const upSQLString = this.formatSQLForExport(sortedUp, options.compact);\r\n const downSQLString = this.formatSQLForExport(sortedDown, options.compact);\r\n\r\n const rootPath = process.cwd();\r\n const sqlDir = path.join(rootPath, \"database\", \"sql\");\r\n\r\n if (!fs.existsSync(sqlDir)) {\r\n fs.mkdirSync(sqlDir, { recursive: true });\r\n }\r\n\r\n const timestamp = new Date().toISOString().replace(/T/, \"_\").replace(/:/g, \"-\").split(\".\")[0];\r\n const upPath = path.join(sqlDir, `migration_${timestamp}.up.sql`);\r\n const downPath = path.join(sqlDir, `migration_${timestamp}.down.sql`);\r\n\r\n fs.writeFileSync(upPath, upSQLString);\r\n fs.writeFileSync(downPath, downSQLString);\r\n\r\n log.success(\"database\", \"migration\", `Exported to:\\n- ${upPath}\\n- ${downPath}`);\r\n }\r\n\r\n /**\r\n * Rollback the last batch of migrations.\r\n *\r\n * @param options - Execution options\r\n * @returns Results for each migration\r\n */\r\n public async rollbackLast(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\r\n return this.rollbackBatches(1, options);\r\n }\r\n\r\n /**\r\n * Rollback N batches of migrations.\r\n *\r\n * @param batches - Number of batches to rollback\r\n * @param options - Execution options\r\n * @returns Results for each migration\r\n */\r\n public async rollbackBatches(\r\n batches: number,\r\n options: ExecuteOptions = {},\r\n ): Promise<MigrationResult[]> {\r\n if (options.dryRun) return this.rollbackBatchesUnlocked(batches, options);\r\n\r\n return this.withLock(this.getSources(), () => this.rollbackBatchesUnlocked(batches, options));\r\n }\r\n\r\n private async rollbackBatchesUnlocked(\r\n batches: number,\r\n options: ExecuteOptions,\r\n ): Promise<MigrationResult[]> {\r\n const dryRun = options.dryRun ?? false;\r\n const record = options.record ?? true;\r\n const results: MigrationResult[] = [];\r\n\r\n const toRollback = await this.getMigrationsToRollback(batches, {\r\n pruneMissing: options.pruneMissing,\r\n readOnly: dryRun,\r\n });\r\n\r\n if (toRollback.length === 0) {\r\n log.warn(\"database\", \"migration\", \"Nothing to rollback.\");\r\n return results;\r\n }\r\n\r\n log.info(\"database\", \"migration\", `Rolling back ${toRollback.length} migration(s).`);\r\n\r\n for (const MigrationClass of toRollback) {\r\n await this.refreshLocks();\r\n\r\n const result = await this.runMigration(MigrationClass, \"down\", {\r\n dryRun,\r\n record,\r\n });\r\n results.push(result);\r\n\r\n if (!result.success) {\r\n break;\r\n }\r\n }\r\n\r\n const successCount = results.filter((r) => r.success).length;\r\n log.success(\r\n \"database\",\r\n \"migration\",\r\n `Rollback complete: ${successCount}/${toRollback.length} successful.`,\r\n );\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Rollback all executed migrations.\r\n *\r\n * @param options - Execution options\r\n * @returns Results for each migration\r\n */\r\n public async rollbackAll(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\r\n // Batch numbers are per data source; rolling back \"all\" is every batch of each.\r\n return this.rollbackBatches(Number.POSITIVE_INFINITY, options);\r\n }\r\n\r\n /**\r\n * Reset and re-run: rollback all then run all.\r\n *\r\n * @param options - Execution options\r\n * @returns Combined results\r\n */\r\n public async fresh(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\r\n const rollbackResults = await this.rollbackAll(options);\r\n const runResults = await this.runAll(options);\r\n return [...rollbackResults, ...runResults];\r\n }\r\n\r\n // ============================================================================\r\n // STATUS\r\n // ============================================================================\r\n\r\n /**\r\n * Get status of all registered migrations.\r\n */\r\n public async status(): Promise<\r\n Array<{\r\n name: string;\r\n table: string;\r\n executed: boolean;\r\n batch: number | null;\r\n }>\r\n > {\r\n const executedBySource = new Map<DataSource, Map<string, MigrationRecord>>();\r\n\r\n for (const dataSource of this.getSources()) {\r\n const executed = await this.getExecutedMigrations(dataSource, { readOnly: true });\r\n executedBySource.set(dataSource, new Map(executed.map((r) => [r.name, r])));\r\n }\r\n\r\n return this.migrations.map((MigrationClass) => {\r\n const instance = new MigrationClass();\r\n const name = MigrationClass.migrationName;\r\n const record = executedBySource.get(this.sourceOf(MigrationClass))?.get(name);\r\n return {\r\n name,\r\n table: instance.table,\r\n executed: !!record,\r\n batch: record?.batch ?? null,\r\n };\r\n });\r\n }\r\n\r\n // ============================================================================\r\n // EXTENSION PRE-FLIGHT\r\n // ============================================================================\r\n\r\n /**\r\n * Check whether a database extension is available and inform the developer\r\n * if it is not installed.\r\n *\r\n * Does NOT throw — execution proceeds normally. If the extension is truly\r\n * missing, the database will surface its own error with full context already\r\n * displayed to the developer.\r\n *\r\n * @example\r\n * await this.informIfExtensionMissing(\"vector\");\r\n */\r\n private async informIfExtensionMissing(\r\n extension: string,\r\n dataSource: DataSource = this.getDataSource(),\r\n ): Promise<void> {\r\n try {\r\n const migrationDriver = this.getMigrationDriver(dataSource);\r\n const isAvailable = await migrationDriver.isExtensionAvailable(extension);\r\n\r\n if (!isAvailable) {\r\n const hr = \"─\".repeat(60);\r\n console.log(`\\n${colors.yellow(hr)}`);\r\n console.log(colors.yellow(` ⚠ Missing Database Extension: ${colors.bold(extension)}`));\r\n console.log(colors.yellow(hr));\r\n console.log();\r\n console.log(` A pending migration requires the ${colors.cyan(extension)} extension,`);\r\n console.log(` which is not installed on your database server.`);\r\n console.log();\r\n console.log(\r\n ` ${colors.bold(\"This means the physical database server is missing the extension package.\")}`,\r\n );\r\n console.log(` You cannot simply run CREATE EXTENSION until the package is installed`);\r\n console.log(` on the host machine or Docker container.`);\r\n console.log();\r\n\r\n const docsUrl = migrationDriver.getExtensionDocsUrl(extension);\r\n if (docsUrl) {\r\n console.log(` ${colors.bold(\"Or follow the installation guide:\")}`);\r\n console.log(` ${colors.cyan(docsUrl)}`);\r\n }\r\n console.log(`\\n${colors.yellow(hr)}\\n`);\r\n }\r\n } catch {\r\n // If the check itself fails, silently skip — don't break the migration.\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // PRIVATE HELPERS\r\n // ============================================================================\r\n\r\n /**\r\n * Run a single migration.\r\n */\r\n private async runMigration(\r\n MigrationClass: MigrationClass,\r\n direction: \"up\" | \"down\",\r\n options: {\r\n dryRun?: boolean;\r\n record?: boolean;\r\n batch?: number;\r\n } = {},\r\n ): Promise<MigrationResult> {\r\n const { dryRun = false, record = true } = options;\r\n const startTime = Date.now();\r\n let success = true;\r\n let error: string | undefined;\r\n\r\n const migration = new MigrationClass();\r\n const name = MigrationClass.migrationName;\r\n\r\n log.info(\r\n \"database\",\r\n \"migration\",\r\n `${direction === \"up\" ? \"Migrating\" : \"Rolling back\"}: ${colors.magenta(name)}...`,\r\n );\r\n\r\n try {\r\n if (!dryRun) {\r\n // The migration runs against its declared data source (default: the runner's)\r\n // and is recorded in THAT source's migrations table.\r\n const dataSource = this.resolveDataSource(migration.dataSource);\r\n const driver = this.getMigrationDriver(dataSource);\r\n migration.setDriver(driver);\r\n migration.setMigrationDefaults(dataSource.migrationDefaults);\r\n\r\n // ============================================================================\r\n // TRANSACTION RESOLUTION (3-tier hierarchy)\r\n // ============================================================================\r\n // 1. Migration-level explicit override (instance or static)\r\n // 2. CONCURRENTLY statements (cannot run in a transaction block)\r\n // 3. Config-level global override\r\n // 4. Driver default (PostgreSQL: true, MongoDB: false)\r\n // Resolved below, once the statements are known.\r\n\r\n // ============================================================================\r\n // EXECUTE WITH OR WITHOUT TRANSACTION\r\n // ============================================================================\r\n\r\n // Collect the requested direction's operations\r\n if (direction === \"up\") {\r\n await migration.up();\r\n } else {\r\n await migration.down();\r\n }\r\n\r\n const databaseDriver = dataSource.driver;\r\n\r\n // SQL-capable drivers serialize the queued operations to SQL strings;\r\n // drivers without SQL serialization (MongoDB) keep them queued and\r\n // execute them directly through the migration driver.\r\n const directExecution = databaseDriver.supportsSqlSerialization === false;\r\n const steps: MigrationStep[] = directExecution\r\n ? []\r\n : (migration.toSteps?.() ?? migration.toSQL());\r\n const sqlStatements = steps.filter((step): step is string => typeof step === \"string\");\r\n const shouldUseTransaction = this.resolveTransactional(\r\n MigrationClass,\r\n migration,\r\n dataSource,\r\n sqlStatements,\r\n );\r\n\r\n const applyMigration = async (): Promise<void> => {\r\n if (directExecution) {\r\n await migration.execute();\r\n return;\r\n }\r\n\r\n // Execute generated SQL statements sequentially (no phase-sorting here since it's single execution)\r\n for (const step of steps) {\r\n if (typeof step === \"string\") await databaseDriver.query(step);\r\n else await step.data();\r\n }\r\n };\r\n\r\n if (shouldUseTransaction && databaseDriver.transaction) {\r\n // Transactional execution\r\n await databaseDriver.transaction(async () => {\r\n await applyMigration();\r\n\r\n // Record migration tracking\r\n if (record) {\r\n if (direction === \"up\") {\r\n const batch = options.batch ?? (await this.getNextBatchNumber(dataSource));\r\n await this.recordMigration(\r\n name,\r\n batch,\r\n MigrationClass.createdAt ? parseCreatedAt(MigrationClass.createdAt) : new Date(),\r\n dataSource,\r\n );\r\n } else {\r\n await this.removeMigrationRecord(name, dataSource);\r\n }\r\n }\r\n });\r\n } else {\r\n // Non-transactional execution\r\n await applyMigration();\r\n\r\n if (record) {\r\n if (direction === \"up\") {\r\n const batch = options.batch ?? (await this.getNextBatchNumber(dataSource));\r\n await this.recordMigration(\r\n name,\r\n batch,\r\n MigrationClass.createdAt ? parseCreatedAt(MigrationClass.createdAt) : new Date(),\r\n dataSource,\r\n );\r\n } else {\r\n await this.removeMigrationRecord(name, dataSource);\r\n }\r\n }\r\n }\r\n }\r\n } catch (err) {\r\n success = false;\r\n error = err instanceof Error ? err.message : String(err);\r\n log.error(\"database\", \"migration\", `${colors.magenta(name)}: ✗ Failed: ${error}`);\r\n throw err;\r\n }\r\n\r\n const durationMs = Date.now() - startTime;\r\n\r\n if (success) {\r\n log.success(\r\n \"database\",\r\n \"migration\",\r\n `${direction == \"up\" ? \"Migrated\" : \"Rolled back\"}: ${colors.magenta(name)} successfully (${durationMs}ms)`,\r\n );\r\n }\r\n\r\n return {\r\n name,\r\n table: migration.table,\r\n direction,\r\n success,\r\n error,\r\n durationMs,\r\n executedAt: new Date(),\r\n };\r\n }\r\n\r\n /**\r\n * Create, configure, and return a ready-to-use migration instance.\r\n *\r\n * Centralises the repeated \"new + setDriver + setMigrationDefaults\" boilerplate\r\n * that all batch/single execution paths need.\r\n *\r\n * @internal\r\n */\r\n private createMigrationInstance(MigrationClass: MigrationClass): Migration {\r\n const migration = new MigrationClass();\r\n const dataSource = this.resolveDataSource(migration.dataSource);\r\n migration.setDriver(this.getMigrationDriver(dataSource));\r\n migration.setMigrationDefaults(dataSource.migrationDefaults);\r\n return migration;\r\n }\r\n\r\n /**\r\n * Format an ordered array of TaggedSQL into a human-readable SQL file string.\r\n *\r\n * Consecutive statements that belong to the same (phase, migration) group share\r\n * a single block comment at the top, avoiding the noisy per-statement repetition.\r\n *\r\n * Example output:\r\n * ```sql\r\n * /* Phase 3 [create-users] *\\/\r\n * ALTER TABLE \"users\" ADD COLUMN \"name\" TEXT NOT NULL;\r\n * ALTER TABLE \"users\" ADD COLUMN \"email\" TEXT NOT NULL;\r\n *\r\n * /* Phase 4 [create-users] *\\/\r\n * CREATE UNIQUE INDEX ...;\r\n * ```\r\n *\r\n * @internal\r\n */\r\n private formatSQLForExport(statements: TaggedSQL[], compact: boolean = false): string {\r\n const lines: string[] = [];\r\n\r\n if (compact) {\r\n // Just output raw statements, no grouping, no blank lines\r\n for (const stmt of statements) {\r\n lines.push(`${stmt.sql};`);\r\n }\r\n return lines.join(\"\\n\");\r\n }\r\n\r\n // Group statements by their phase and migration name\r\n const grouped = new Map<string, string[]>();\r\n\r\n for (const stmt of statements) {\r\n const groupKey = `Phase ${stmt.phase} [${stmt.migrationName}]`;\r\n if (!grouped.has(groupKey)) {\r\n grouped.set(groupKey, []);\r\n }\r\n grouped.get(groupKey)!.push(stmt.sql);\r\n }\r\n\r\n // Format each group\r\n for (const [groupKey, sqls] of grouped.entries()) {\r\n if (lines.length > 0) lines.push(\"\"); // blank line between groups\r\n lines.push(`/* ${groupKey} */`);\r\n for (const sql of sqls) {\r\n lines.push(`${sql};`);\r\n }\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n }\r\n\r\n /**\r\n * Get pending (not executed) registered migrations, in the order they would\r\n * execute.\r\n *\r\n * ⚠️ \"Registered\" is load-bearing. This filters `this.migrations`, which is\r\n * populated only by `register()` / `registerMany()`. A caller that has not\r\n * registered anything gets `[]` — indistinguishable from a database with\r\n * nothing pending. Anything reporting this set to a human MUST register\r\n * migrations first, or it will print a confident all-clear over an unknown.\r\n *\r\n * @see listPendingMigrations\r\n */\r\n public async getPendingMigrations(\r\n options: { readOnly?: boolean } = {},\r\n ): Promise<MigrationClass[]> {\r\n // \"Executed\" is judged in each migration's own data source's migrations table.\r\n const executedNames = new Map<DataSource, Set<string>>();\r\n for (const dataSource of this.getSources()) {\r\n const executed = await this.getExecutedMigrations(dataSource, options);\r\n executedNames.set(dataSource, new Set(executed.map((r) => r.name)));\r\n }\r\n\r\n const migrations = this.migrations.filter(\r\n (m) => !executedNames.get(this.sourceOf(m))?.has(m.migrationName),\r\n );\r\n\r\n return migrations.sort(sortMigrations);\r\n }\r\n\r\n /**\r\n * Get migrations to rollback, newest-first.\r\n *\r\n * A rollback must undo migrations in the exact inverse of the order `up`\r\n * applied them, or a `down()` will hit schema its predecessor already\r\n * removed — dropping a table before dropping the column added to it, say.\r\n *\r\n * The sort has to be explicitly **descending**. Reversing the executed list\r\n * is not enough: `getExecutedMigrations` orders by `batch, name`, so the\r\n * input is alphabetical rather than chronological, and reversing it only\r\n * yields reverse-alphabetical order. (Sorting *ascending* here — which is\r\n * what this method used to do after a `.reverse()` — silently restored the\r\n * forward `up` order and made the reverse dead code.)\r\n */\r\n private async getMigrationsToRollback(\r\n batches: number,\r\n options: { pruneMissing?: boolean; readOnly?: boolean } = {},\r\n ): Promise<MigrationClass[]> {\r\n const migrations: MigrationClass[] = [];\r\n const batchOf = new Map<MigrationClass, number>();\r\n const orphans: Array<{ name: string; dataSource: DataSource }> = [];\r\n\r\n // Batches are numbered per data source (each has its own migrations table).\r\n for (const dataSource of this.getSources()) {\r\n const executed = await this.getExecutedMigrations(dataSource, {\r\n readOnly: options.readOnly,\r\n });\r\n if (executed.length === 0) continue;\r\n\r\n const batchNumbers = [...new Set(executed.map((r) => r.batch))]\r\n .sort((a, b) => b - a)\r\n .slice(0, batches);\r\n\r\n for (const record of executed) {\r\n if (!batchNumbers.includes(record.batch)) continue;\r\n\r\n const MigrationClass = this.migrations.find(\r\n (m) => m.migrationName === record.name && this.sourceOf(m) === dataSource,\r\n );\r\n if (MigrationClass) {\r\n migrations.push(MigrationClass);\r\n batchOf.set(MigrationClass, record.batch);\r\n } else {\r\n orphans.push({ name: record.name, dataSource });\r\n }\r\n }\r\n }\r\n\r\n if (orphans.length > 0) {\r\n if (!options.pruneMissing) {\r\n throw new Error(\r\n `Cannot roll back: ${orphans.length} executed migration(s) have no registered file: ` +\r\n `${orphans.map((o) => o.name).join(\", \")}. ` +\r\n `They were renamed, deleted, or not matched by the migration pattern. ` +\r\n `Restore the file(s), or pass pruneMissing (--prune-missing) to delete those records.`,\r\n );\r\n }\r\n\r\n if (!options.readOnly) {\r\n for (const orphan of orphans) {\r\n await this.removeMigrationRecord(orphan.name, orphan.dataSource);\r\n log.warn(\"database\", \"migration\", `Pruned orphaned migration record: ${orphan.name}`);\r\n }\r\n }\r\n }\r\n\r\n // Newest batch first, then newest migration first within a batch.\r\n return migrations.sort(\r\n (a, b) =>\r\n (batchOf.get(b) ?? 0) - (batchOf.get(a) ?? 0) || sortMigrationsForRollback(a, b),\r\n );\r\n }\r\n\r\n /**\r\n * Get executed migration records.\r\n */\r\n public async getExecutedMigrations(\r\n dataSource: DataSource = this.getDataSource(),\r\n options: { readOnly?: boolean } = {},\r\n ): Promise<MigrationRecord[]> {\r\n const driver = dataSource.driver;\r\n const migrationDriver = this.getMigrationDriver(dataSource);\r\n\r\n if (options.readOnly) {\r\n // Dry runs and listings must not create the migrations table.\r\n if (!(await migrationDriver.tableExists(this.migrationsTable))) return [];\r\n } else {\r\n // A missing table is created here; every other error (connection,\r\n // permission…) propagates instead of looking like \"nothing executed\".\r\n await migrationDriver.ensureMigrationsTable(this.migrationsTable);\r\n }\r\n\r\n const queryBuilder = driver.queryBuilder<MigrationRecord>(this.migrationsTable);\r\n const records = await queryBuilder.orderBy(\"batch\", \"asc\").orderBy(\"name\", \"asc\").get();\r\n\r\n // The Mongo lock document lives in this collection; it is not a migration.\r\n return records.filter((record) => record.name !== MIGRATION_LOCK_NAME);\r\n }\r\n\r\n /**\r\n * Record a migration.\r\n */\r\n private async recordMigration(\r\n name: string,\r\n batch: number,\r\n createdAt?: Date,\r\n dataSource: DataSource = this.getDataSource(),\r\n ): Promise<void> {\r\n const driver = dataSource.driver;\r\n const migrationDriver = this.getMigrationDriver(dataSource);\r\n\r\n // Ensure migrations table exists\r\n await migrationDriver.ensureMigrationsTable(this.migrationsTable);\r\n\r\n await driver.insert(this.migrationsTable, {\r\n name,\r\n batch,\r\n executedAt: new Date(),\r\n createdAt,\r\n });\r\n }\r\n\r\n /**\r\n * Remove a migration record.\r\n */\r\n private async removeMigrationRecord(\r\n name: string,\r\n dataSource: DataSource = this.getDataSource(),\r\n ): Promise<void> {\r\n const driver = dataSource.driver;\r\n await driver.delete(this.migrationsTable, { name });\r\n }\r\n\r\n /**\r\n * Get next batch number.\r\n */\r\n private async getNextBatchNumber(\r\n dataSource: DataSource = this.getDataSource(),\r\n readOnly = false,\r\n ): Promise<number> {\r\n const executed = await this.getExecutedMigrations(dataSource, { readOnly });\r\n if (executed.length === 0) return 1;\r\n return Math.max(...executed.map((r) => r.batch)) + 1;\r\n }\r\n}\r\n\r\nexport const migrationRunner = new MigrationRunner();\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-runner.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/migration-runner.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { log } from \"@warlock.js/logger\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport type { MigrationDriverContract } from \"../contracts/migration-driver.contract\";\nimport type { DataSource } from \"../data-source/data-source\";\nimport { dataSourceRegistry } from \"../data-source/data-source-registry\";\nimport {\n type Migration,\n type MigrationContract,\n type MigrationOrigin,\n type MigrationStep,\n} from \"./migration\";\nimport { sortMigrations, sortMigrationsForRollback } from \"./migration-order\";\nimport { parseCreatedAt } from \"./parse-created-at\";\nimport { SQLGrammar } from \"./sql-grammar\";\nimport type { MigrationRecord, MigrationResult, TaggedSQL } from \"./types\";\n\n/**\n * Migration class type with static name property.\n */\ntype MigrationClass = (new () => Migration) & {\n migrationName: string;\n createdAt?: string;\n origin?: MigrationOrigin;\n};\n\n/**\n * What a caller may hand to {@link MigrationRunner.register}.\n *\n * Looser than {@link MigrationClass} in exactly one way: `migrationName` may be\n * absent. That is the documented workflow — the CLI imports a migration file and\n * sets the name from the filename afterwards — and `register()` enforces it at\n * runtime, throwing a message that says so. Once past that check the name IS\n * present, which is why everything stored and read downstream uses the stricter\n * type. Requiring it on the INPUT made the runner reject the very classes the\n * public `MigrationConstructor` describes.\n *\n * It constructs a MigrationContract rather than the abstract Migration class for the\n * same reason: `typeof Migration` is abstract and cannot satisfy `new () => Migration`,\n * and the public MigrationConstructor is declared against the contract. The runner only\n * ever uses contract members on what it registers.\n */\ntype RegisterableMigration = (new () => MigrationContract) & {\n migrationName?: string;\n createdAt?: string;\n origin?: MigrationOrigin;\n};\n\n/**\n * Resolved instance data for a single pending migration.\n * @internal\n */\ntype MigrationData = {\n MigrationClass: MigrationClass;\n migration: Migration;\n name: string;\n /** Data source this migration runs against (its own, else the runner's). */\n dataSource: DataSource;\n /** Serialized `up()` statements (empty for direct-execution drivers). */\n statements: string[];\n /** Same as `statements`, with queued data steps kept in authored order. */\n steps: MigrationStep[];\n /** Whether the migration runs inside a transaction. */\n transactional: boolean;\n /** Driver has no SQL dialect (MongoDB): executed through `runMigration`. */\n direct: boolean;\n};\n\n/**\n * Options for migration execution.\n */\ntype ExecuteOptions = {\n /** Run in dry-run mode (no actual changes) */\n readonly dryRun?: boolean;\n /** Record to migrations table (default: true for batch, false for single) */\n readonly record?: boolean;\n /**\n * Rollback only: delete the `_migrations` rows whose migration file is no\n * longer registered, instead of failing on them.\n */\n readonly pruneMissing?: boolean;\n};\n\n/** Name of the lock document Mongo migrations claim inside the migrations collection. */\nconst MIGRATION_LOCK_NAME = \"__warlock_migration_lock__\";\nconst MIGRATION_LOCK_KEY = \"warlock:migrations\";\nconst MIGRATION_LOCK_TTL_MS = 10 * 60 * 1000;\nconst MIGRATION_LOCK_WAIT_MS = 60 * 1000;\nconst MIGRATION_LOCK_RETRY_MS = 1000;\n\n/** Held lock for one data source. `refresh` extends the TTL; `release` frees it. */\ntype MigrationLock = {\n refresh: () => Promise<void>;\n release: () => Promise<void>;\n};\n\ntype PgLockClient = {\n query: (sql: string, params?: unknown[]) => Promise<unknown>;\n release: () => void;\n};\n\n/** Minimal Mongo surface the lock needs (kept structural: no driver import). */\ntype MongoLockDatabase = {\n collection: (name: string) => {\n findOneAndUpdate: (filter: object, update: object, options: object) => Promise<unknown>;\n findOne: (filter: object) => Promise<{ owner?: string; expiresAt?: unknown } | null>;\n deleteOne: (filter: object) => Promise<unknown>;\n };\n};\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\n/**\n * Derive a migration name from a file path: drop everything after the first dot\n * and strip a trailing `-migration` / `_migration` suffix. Shared by every CLI\n * so the same file is recorded under the same name.\n */\nexport function inferMigrationName(file: string): string {\n const basename = path.basename(file).split(\".\")[0] ?? \"\";\n\n return basename.replace(/-migration$/, \"\").replace(/_migration$/, \"\");\n}\n\n/**\n * Migration runner that executes migrations.\n *\n * This is a pure executor - it doesn't discover migrations.\n * Discovery is handled by the framework (e.g., @warlock.js/core CLI).\n *\n * The migration name is read from the static `name` property on the class,\n * which should be set by the CLI after importing:\n *\n * @example\n * ```typescript\n * // In CLI after importing:\n * const { default: MigrationClass } = await import(\"./create-users.migration.ts\");\n * MigrationClass.migrationName ??= \"create-users\";\n *\n * // Then register or execute:\n * runner.register(MigrationClass);\n * // or\n * await runner.execute(MigrationClass);\n * ```\n *\n * @example\n * ```typescript\n * // Simple direct execution\n * await runner.execute(CreateUsersTable);\n * await runner.rollback(CreateUsersTable);\n *\n * // Registry pattern for batch operations\n * runner.register(CreateUsersTable);\n * runner.register(AddEmailIndex);\n * await runner.runAll();\n * await runner.rollbackAll();\n * ```\n */\nexport class MigrationRunner {\n /** Registered migrations */\n public readonly migrations: MigrationClass[] = [];\n\n /** Data source to use */\n private dataSource?: DataSource;\n\n /** Cached migration drivers, one per data source */\n private readonly migrationDrivers = new Map<DataSource, MigrationDriverContract>();\n\n /** Table name for tracking migrations */\n private readonly migrationsTable: string;\n\n /** Whether to log operations */\n private readonly verbose: boolean;\n\n /**\n * Create a new migration runner.\n *\n * @param options - Runner options\n */\n public constructor(\n options: {\n dataSource?: DataSource;\n migrationsTable?: string;\n verbose?: boolean;\n } = {},\n ) {\n this.dataSource = options.dataSource;\n this.migrationsTable = options.migrationsTable ?? \"_migrations\";\n this.verbose = options.verbose ?? true;\n }\n\n // ============================================================================\n // DATA SOURCE\n // ============================================================================\n\n /**\n * Set the data source.\n */\n public setDataSource(dataSource: DataSource): this {\n this.dataSource = dataSource;\n this.migrationDrivers.clear();\n return this;\n }\n\n /**\n * Get the data source.\n */\n private getDataSource(): DataSource {\n if (!this.dataSource) {\n this.dataSource = dataSourceRegistry.get();\n }\n return this.dataSource;\n }\n\n /**\n * Get the migration driver.\n */\n private getMigrationDriver(\n dataSource: DataSource = this.getDataSource(),\n ): MigrationDriverContract {\n let driver = this.migrationDrivers.get(dataSource);\n if (!driver) {\n driver = dataSource.driver.migrationDriver();\n this.migrationDrivers.set(dataSource, driver);\n }\n return driver;\n }\n\n /**\n * Resolve a migration's declared data source (name or instance).\n * Falls back to the runner's own data source when it declares none.\n */\n private resolveDataSource(declared?: string | DataSource): DataSource {\n if (!declared) return this.getDataSource();\n if (typeof declared === \"string\") return dataSourceRegistry.get(declared);\n return declared;\n }\n\n /** Data source a registered migration class runs against. */\n private sourceOf(MigrationClass: MigrationClass): DataSource {\n return this.resolveDataSource(new MigrationClass().dataSource);\n }\n\n /** Distinct data sources across the registered migrations (runner's own included). */\n private getSources(): DataSource[] {\n const sources = new Set<DataSource>([this.getDataSource()]);\n for (const MigrationClass of this.migrations) {\n sources.add(this.sourceOf(MigrationClass));\n }\n return [...sources];\n }\n\n /**\n * Resolve whether a migration runs in a transaction:\n * 1. migration-level flag (instance, else the static from `Migration.create/alter`)\n * 2. `CONCURRENTLY` statements cannot run in a transaction block\n * 3. data-source config\n * 4. driver default\n */\n private resolveTransactional(\n MigrationClass: MigrationClass,\n migration: Migration,\n dataSource: DataSource,\n statements: string[] = [],\n ): boolean {\n const explicit =\n migration.transactional ?? (MigrationClass as { transactional?: boolean }).transactional;\n\n if (explicit !== undefined) return explicit;\n\n if (statements.some((sql) => /\\bCONCURRENTLY\\b/i.test(sql))) return false;\n\n return (\n dataSource.migrations?.transactional ??\n this.getMigrationDriver(dataSource).getDefaultTransactional()\n );\n }\n\n // ============================================================================\n // LOCKING\n // ============================================================================\n\n /** Locks held by the run in progress (Mongo TTL heartbeat). */\n private activeLocks: MigrationLock[] = [];\n\n /** Extend every held lock's TTL; called between migrations. */\n private async refreshLocks(): Promise<void> {\n for (const lock of this.activeLocks) {\n await lock.refresh();\n }\n }\n\n /**\n * Run `callback` while holding a migration lock on every given data source, so\n * concurrent `migrate` invocations (replicas, init containers) serialize.\n */\n private async withLock<T>(sources: DataSource[], callback: () => Promise<T>): Promise<T> {\n const held: MigrationLock[] = [];\n\n try {\n for (const dataSource of sources) {\n const lock = await this.acquireLock(dataSource);\n if (lock) held.push(lock);\n }\n\n this.activeLocks = held;\n\n return await callback();\n } finally {\n this.activeLocks = [];\n\n for (const lock of held.reverse()) {\n try {\n await lock.release();\n } catch (error) {\n log.warn(\n \"database\",\n \"migration\",\n `Failed to release migration lock: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n }\n\n /** Acquire the lock for one data source; `undefined` when its driver has no lock support. */\n private async acquireLock(dataSource: DataSource): Promise<MigrationLock | undefined> {\n const driver = dataSource.driver as unknown as {\n name: string;\n getClient?: () => { connect?: () => Promise<PgLockClient> };\n getDatabase?: () => MongoLockDatabase;\n };\n\n if (driver.name === \"postgres\" && driver.getClient) {\n // A dedicated client: advisory locks are per-session, not per-pool.\n const client = await driver.getClient().connect?.();\n if (!client) return undefined;\n\n try {\n await client.query(\"SELECT pg_advisory_lock(hashtext($1))\", [MIGRATION_LOCK_KEY]);\n } catch (error) {\n client.release();\n throw error;\n }\n\n return {\n refresh: async () => {},\n release: async () => {\n try {\n await client.query(\"SELECT pg_advisory_unlock(hashtext($1))\", [MIGRATION_LOCK_KEY]);\n } finally {\n client.release();\n }\n },\n };\n }\n\n if (driver.getDatabase) {\n // The unique index on `name` (created here) makes the claim below atomic.\n await this.getMigrationDriver(dataSource).ensureMigrationsTable(this.migrationsTable);\n\n const collection = driver.getDatabase().collection(this.migrationsTable);\n const owner = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n const deadline = Date.now() + MIGRATION_LOCK_WAIT_MS;\n\n const claim = async (): Promise<boolean> => {\n const now = new Date();\n\n try {\n await collection.findOneAndUpdate(\n {\n name: MIGRATION_LOCK_NAME,\n $or: [{ expiresAt: { $lt: now } }, { owner }],\n },\n {\n $set: { owner, expiresAt: new Date(now.getTime() + MIGRATION_LOCK_TTL_MS) },\n $setOnInsert: { batch: 0 },\n },\n { upsert: true },\n );\n\n return true;\n } catch (error) {\n // Held by someone else: the upsert collides with the unique `name` index.\n if ((error as { code?: number }).code === 11000) return false;\n throw error;\n }\n };\n\n while (!(await claim())) {\n if (Date.now() >= deadline) {\n const holder = await collection.findOne({ name: MIGRATION_LOCK_NAME });\n throw new Error(\n `Could not acquire the migration lock within ${MIGRATION_LOCK_WAIT_MS / 1000}s; ` +\n `held by \"${holder?.owner ?? \"unknown\"}\" until ${holder?.expiresAt ?? \"unknown\"}.`,\n );\n }\n\n await sleep(MIGRATION_LOCK_RETRY_MS);\n }\n\n return {\n refresh: async () => {\n await claim();\n },\n release: async () => {\n await collection.deleteOne({ name: MIGRATION_LOCK_NAME, owner });\n },\n };\n }\n\n return undefined;\n }\n\n // ============================================================================\n // REGISTRATION\n // ============================================================================\n\n /**\n * Register a migration.\n *\n * The migration name is read from `MigrationClass.migrationName`.\n *\n * @param MigrationClass - Migration class (must have static `name` set)\n * @param origin - Registration source; defaults to `\"app\"` for direct registrations.\n * @returns This runner for chaining\n *\n * @example\n * ```typescript\n * CreateUsersTable.migrationName = \"2024-01-15_create-users\";\n * runner.register(CreateUsersTable);\n * ```\n */\n public register(MigrationClass: RegisterableMigration, origin: MigrationOrigin = \"app\"): this {\n const name = MigrationClass.migrationName;\n if (!name) {\n throw new Error(\n `Migration class must have a static 'migrationName' property set. ` +\n `Set it in CLI after importing: MigrationClass.migrationName = \"filename\";`,\n );\n }\n const existing = this.migrations.find((m) => m.migrationName === name);\n\n if (existing) {\n // Re-registering the same class is idempotent; a DIFFERENT class under the\n // same name would silently never run, so fail loudly.\n if ((existing as unknown) !== MigrationClass) {\n throw new Error(\n `Duplicate migration name \"${name}\": two different migration classes resolve to the same name. ` +\n `Rename one of the files (or set a unique static 'migrationName').`,\n );\n }\n\n return this;\n }\n\n // `name` is proven present by the throw above, so this satisfies the stricter\n // stored type that every reader downstream relies on.\n MigrationClass.origin = origin;\n this.migrations.push(MigrationClass as MigrationClass);\n\n return this;\n }\n\n /**\n * Register multiple migrations.\n *\n * @param migrations - Array of migration classes\n * @returns This runner for chaining\n */\n public registerMany(migrations: RegisterableMigration[]): this {\n for (const MigrationClass of migrations) {\n this.register(MigrationClass);\n }\n return this;\n }\n\n /**\n * Clear all registered migrations.\n */\n public clear(): this {\n this.migrations.length = 0;\n return this;\n }\n\n /**\n * Get all registered migration names.\n */\n public getRegisteredNames(): string[] {\n return this.migrations.map((m) => m.migrationName);\n }\n\n // ============================================================================\n // SINGLE EXECUTION\n // ============================================================================\n\n /**\n * Execute a single migration's up() method.\n *\n * @param MigrationClass - Migration class to execute\n * @param options - Execution options\n * @returns Migration result\n *\n * @example\n * ```typescript\n * await runner.execute(CreateUsersTable);\n * await runner.execute(AddEmailIndex, { dryRun: true });\n * ```\n */\n public async run(\n MigrationClass: MigrationClass,\n options: ExecuteOptions = {},\n ): Promise<MigrationResult> {\n return this.runMigration(MigrationClass, \"up\", {\n dryRun: options.dryRun,\n record: options.record ?? false,\n });\n }\n\n /**\n * Execute a single migration's down() method.\n *\n * @param MigrationClass - Migration class to rollback\n * @param options - Execution options\n * @returns Migration result\n *\n * @example\n * ```typescript\n * await runner.rollback(CreateUsersTable);\n * ```\n */\n public async rollback(\n MigrationClass: MigrationClass,\n options: ExecuteOptions = {},\n ): Promise<MigrationResult> {\n return this.runMigration(MigrationClass, \"down\", {\n dryRun: options.dryRun,\n record: options.record ?? false,\n });\n }\n\n // ============================================================================\n // BATCH EXECUTION (REGISTERED MIGRATIONS)\n // ============================================================================\n\n /**\n * Run all pending registered migrations.\n *\n * Only runs migrations not already in the migrations table.\n *\n * @param options - Execution options\n * @returns Results for each migration\n *\n * @example\n * ```typescript\n * runner.register(CreateUsersTable);\n * runner.register(AddEmailIndex);\n * const results = await runner.runAll();\n * ```\n */\n public async runAll(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\n // A dry run writes nothing, so it needs no lock.\n if (options.dryRun) return this.runAllUnlocked(options);\n\n // The pending set is computed INSIDE the lock, so a replica that waited sees\n // what the winner already applied.\n return this.withLock(this.getSources(), () => this.runAllUnlocked(options));\n }\n\n private async runAllUnlocked(options: ExecuteOptions): Promise<MigrationResult[]> {\n const { dryRun = false, record = true } = options;\n\n const results: MigrationResult[] = [];\n\n // Get pending migrations (a dry run must not create the migrations table)\n const pending = await this.getPendingMigrations({ readOnly: dryRun });\n\n if (pending.length === 0) {\n log.warn(\"database\", \"migration\", \"Nothing to migrate.\");\n return results;\n }\n\n // Next batch number per data source: each source has its own migrations table.\n const sources = new Set<DataSource>();\n const migrationsData: MigrationData[] = [];\n\n log.info(\"database\", \"migration\", `Found ${pending.length} pending migration(s).`);\n\n // 1. Resolve each migration's data source and transactional mode, and collect\n // its SQL. Drivers without SQL serialization (MongoDB) are executed\n // directly through the migration driver instead.\n // Extension checks fire concurrently as CREATE EXTENSION statements are met.\n const extensionChecks: Promise<void>[] = [];\n\n for (const MigrationClass of pending) {\n const migration = this.createMigrationInstance(MigrationClass);\n const name = MigrationClass.migrationName;\n const dataSource = this.resolveDataSource(migration.dataSource);\n sources.add(dataSource);\n\n if (dataSource.driver.supportsSqlSerialization === false) {\n migrationsData.push({\n MigrationClass,\n migration,\n name,\n dataSource,\n statements: [],\n steps: [],\n transactional: false,\n direct: true,\n });\n continue;\n }\n\n migration.setDriver(this.getMigrationDriver(dataSource));\n migration.setMigrationDefaults(dataSource.migrationDefaults);\n // Collection must not run `withConnection` side effects during a dry run.\n migration.setDryRun?.(dryRun);\n\n await migration.up();\n const steps: MigrationStep[] = migration.toSteps?.() ?? migration.toSQL();\n const statements = steps.map((step) =>\n typeof step === \"string\" ? step : \"-- data step (withConnection) skipped\",\n );\n migration.setDryRun?.(false);\n\n migrationsData.push({\n MigrationClass,\n migration,\n name,\n dataSource,\n statements,\n steps,\n transactional:\n !!dataSource.driver.transaction &&\n this.resolveTransactional(MigrationClass, migration, dataSource, statements),\n direct: false,\n });\n\n for (const sql of statements) {\n if (SQLGrammar.classify(sql) === \"CREATE_EXTENSION\") {\n const ext = SQLGrammar.extractExtensionName(sql);\n if (ext) extensionChecks.push(this.informIfExtensionMissing(ext, dataSource));\n }\n }\n }\n\n // 2. Resolve all extension checks before any SQL is executed.\n await Promise.all(extensionChecks);\n\n // 3. Dry run: print statements in migration order (authored order kept; no\n // global phase sort, which would reorder add-column → backfill → NOT NULL).\n if (dryRun) {\n log.info(\"database\", \"migration\", \"Dry run enabled. Would execute the following statements:\");\n for (const data of migrationsData) {\n for (const sql of data.statements) {\n console.log(\n `-- [${SQLGrammar.classify(sql)}] Phase ${SQLGrammar.phase(sql)} [${data.name}]`,\n );\n console.log(sql + \";\\n\");\n }\n }\n return [];\n }\n\n const batches = new Map<DataSource, number>();\n for (const dataSource of sources) {\n batches.set(dataSource, await this.getNextBatchNumber(dataSource));\n }\n\n // 4. Split into runs: consecutive transactional migrations on the same data\n // source share one transaction; every other migration (non-transactional\n // or direct) runs alone.\n const runs: MigrationData[][] = [];\n for (const data of migrationsData) {\n const last = runs[runs.length - 1];\n const lastFirst = last?.[0];\n if (\n data.transactional &&\n last &&\n lastFirst?.transactional &&\n lastFirst.dataSource === data.dataSource\n ) {\n last.push(data);\n } else {\n runs.push([data]);\n }\n }\n\n for (const run of runs) {\n const first = run[0];\n if (!first) continue;\n await this.refreshLocks();\n const dataSource = first.dataSource;\n const nextBatch = batches.get(dataSource)!;\n const startTime = Date.now();\n\n if (first.direct) {\n const result = await this.runMigration(first.MigrationClass, \"up\", {\n dryRun,\n record,\n batch: nextBatch,\n });\n results.push(result);\n if (!result.success) break;\n continue;\n }\n\n const driver = dataSource.driver;\n let failed = false;\n let errorMessage = \"\";\n /** The migration that owns the SQL statement that threw. */\n let failingMigrationName: string | undefined;\n\n const executeRun = async (): Promise<void> => {\n for (const data of run) {\n for (const step of data.steps) {\n try {\n if (typeof step === \"string\") await driver.query(step);\n else await step.data();\n } catch (err) {\n failingMigrationName = data.name;\n throw err;\n }\n }\n\n // A non-transactional migration is recorded right after it applied.\n // Transactional ones are recorded inside the shared transaction.\n if (record) {\n await this.recordMigration(\n data.name,\n nextBatch,\n data.MigrationClass.createdAt\n ? parseCreatedAt(data.MigrationClass.createdAt)\n : new Date(),\n dataSource,\n );\n }\n }\n };\n\n try {\n if (first.transactional && driver.transaction) {\n await driver.transaction(executeRun);\n } else {\n await executeRun();\n }\n } catch (err) {\n failed = true;\n errorMessage = err instanceof Error ? err.message : String(err);\n }\n\n const durationMs = Date.now() - startTime;\n\n // Only the migration that owns the failing statement is marked failed;\n // the rest of its run is reported as rolled back.\n for (const data of run) {\n const isCulprit = failed && data.name === failingMigrationName;\n const wasSkipped = failed && !isCulprit;\n\n results.push({\n name: data.name,\n table: data.migration.table,\n direction: \"up\",\n success: !failed,\n error: isCulprit ? errorMessage : undefined,\n durationMs: Math.round(durationMs / run.length),\n executedAt: new Date(),\n });\n\n if (isCulprit) {\n log.error(\n \"database\",\n \"migration\",\n `${colors.magenta(data.name)}: ✗ Failed: ${errorMessage}`,\n );\n } else if (wasSkipped) {\n log.warn(\n \"database\",\n \"migration\",\n `${colors.magenta(data.name)}: rolled back (batch transaction failed)`,\n );\n } else {\n log.success(\n \"database\",\n \"migration\",\n `Migrated: ${colors.magenta(data.name)} successfully`,\n );\n }\n }\n\n if (failed) {\n log.error(\n \"database\",\n \"migration\",\n `Batch execution failed. Rollback performed if transactional.`,\n );\n throw new Error(\"Migration batch failed: \" + errorMessage);\n }\n }\n\n const successCount = results.filter((r) => r.success).length;\n log.success(\n \"database\",\n \"migration\",\n `Migration execution complete: ${successCount}/${pending.length} migrations processed successfully.`,\n );\n\n return results;\n }\n\n /**\n * Export migrations as phase-ordered SQL files in database/sql/ directory.\n * By default, it exports all registered migrations. Use `pendingOnly: true` to export only pending ones.\n */\n public async exportSQL(\n options: { pendingOnly?: boolean; compact?: boolean } = {},\n ): Promise<void> {\n if (this.getDataSource().driver.supportsSqlSerialization === false) {\n throw new Error(\n \"SQL export is not supported on this data source — its driver has no SQL dialect. \" +\n \"Migrations on this driver execute native commands through the migration driver instead.\",\n );\n }\n\n const migrationsToExport = options.pendingOnly\n ? await this.getPendingMigrations({ readOnly: true })\n : this.migrations;\n\n if (migrationsToExport.length === 0) {\n log.warn(\"database\", \"migration\", \"No migrations to export.\");\n return;\n }\n\n log.info(\n \"database\",\n \"migration\",\n `Exporting ${migrationsToExport.length} ${options.pendingOnly ? \"pending \" : \"\"}migration(s) to SQL files...`,\n );\n\n const upStatements: TaggedSQL[] = [];\n // Down SQL is grouped per migration so only the migration order is reversed,\n // never the statements inside one migration's down().\n const downGroups: { createdAt?: string; index: number; statements: TaggedSQL[] }[] = [];\n\n for (const [index, MigrationClass] of migrationsToExport.entries()) {\n const migration = this.createMigrationInstance(MigrationClass);\n const name = MigrationClass.migrationName;\n\n // Export performs no writes: `withConnection` callbacks are skipped.\n migration.setDryRun?.(true);\n\n // Collect up SQL\n await migration.up();\n for (const sql of migration.toSQL()) {\n upStatements.push({\n sql,\n phase: SQLGrammar.phase(sql),\n statementType: SQLGrammar.classify(sql),\n createdAt: MigrationClass.createdAt,\n migrationName: name,\n });\n }\n\n // Collect down SQL (reuse same instance — toSQL() cleared pendingOps)\n await migration.down();\n const statements: TaggedSQL[] = [];\n for (const sql of migration.toSQL()) {\n statements.push({\n sql,\n phase: SQLGrammar.phase(sql),\n statementType: SQLGrammar.classify(sql),\n createdAt: MigrationClass.createdAt,\n migrationName: name,\n });\n }\n downGroups.push({ createdAt: MigrationClass.createdAt, index, statements });\n }\n\n const sortedUp = SQLGrammar.sort(upStatements);\n // Down SQL: newest migration first (chronological, registration order breaks\n // ties), each migration's own down() statements keep their order.\n const sortedDown = downGroups\n .sort((a, b) => {\n const byDate = (a.createdAt ?? \"\").localeCompare(b.createdAt ?? \"\");\n return byDate !== 0 ? byDate : a.index - b.index;\n })\n .reverse()\n .flatMap((group) => group.statements);\n\n const upSQLString = this.formatSQLForExport(sortedUp, options.compact);\n const downSQLString = this.formatSQLForExport(sortedDown, options.compact);\n\n const rootPath = process.cwd();\n const sqlDir = path.join(rootPath, \"database\", \"sql\");\n\n if (!fs.existsSync(sqlDir)) {\n fs.mkdirSync(sqlDir, { recursive: true });\n }\n\n const timestamp = new Date().toISOString().replace(/T/, \"_\").replace(/:/g, \"-\").split(\".\")[0];\n const upPath = path.join(sqlDir, `migration_${timestamp}.up.sql`);\n const downPath = path.join(sqlDir, `migration_${timestamp}.down.sql`);\n\n fs.writeFileSync(upPath, upSQLString);\n fs.writeFileSync(downPath, downSQLString);\n\n log.success(\"database\", \"migration\", `Exported to:\\n- ${upPath}\\n- ${downPath}`);\n }\n\n /**\n * Rollback the last batch of migrations.\n *\n * @param options - Execution options\n * @returns Results for each migration\n */\n public async rollbackLast(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\n return this.rollbackBatches(1, options);\n }\n\n /**\n * Rollback N batches of migrations.\n *\n * @param batches - Number of batches to rollback\n * @param options - Execution options\n * @returns Results for each migration\n */\n public async rollbackBatches(\n batches: number,\n options: ExecuteOptions = {},\n ): Promise<MigrationResult[]> {\n if (options.dryRun) return this.rollbackBatchesUnlocked(batches, options);\n\n return this.withLock(this.getSources(), () => this.rollbackBatchesUnlocked(batches, options));\n }\n\n private async rollbackBatchesUnlocked(\n batches: number,\n options: ExecuteOptions,\n ): Promise<MigrationResult[]> {\n const dryRun = options.dryRun ?? false;\n const record = options.record ?? true;\n const results: MigrationResult[] = [];\n\n const toRollback = await this.getMigrationsToRollback(batches, {\n pruneMissing: options.pruneMissing,\n readOnly: dryRun,\n });\n\n if (toRollback.length === 0) {\n log.warn(\"database\", \"migration\", \"Nothing to rollback.\");\n return results;\n }\n\n log.info(\"database\", \"migration\", `Rolling back ${toRollback.length} migration(s).`);\n\n for (const MigrationClass of toRollback) {\n await this.refreshLocks();\n\n const result = await this.runMigration(MigrationClass, \"down\", {\n dryRun,\n record,\n });\n results.push(result);\n\n if (!result.success) {\n break;\n }\n }\n\n const successCount = results.filter((r) => r.success).length;\n log.success(\n \"database\",\n \"migration\",\n `Rollback complete: ${successCount}/${toRollback.length} successful.`,\n );\n\n return results;\n }\n\n /**\n * Rollback all executed migrations.\n *\n * @param options - Execution options\n * @returns Results for each migration\n */\n public async rollbackAll(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\n // Batch numbers are per data source; rolling back \"all\" is every batch of each.\n return this.rollbackBatches(Number.POSITIVE_INFINITY, options);\n }\n\n /**\n * Reset and re-run: rollback all then run all.\n *\n * @param options - Execution options\n * @returns Combined results\n */\n public async fresh(options: ExecuteOptions = {}): Promise<MigrationResult[]> {\n const rollbackResults = await this.rollbackAll(options);\n const runResults = await this.runAll(options);\n return [...rollbackResults, ...runResults];\n }\n\n // ============================================================================\n // STATUS\n // ============================================================================\n\n /**\n * Get status of all registered migrations.\n */\n public async status(): Promise<\n Array<{\n name: string;\n table: string;\n executed: boolean;\n batch: number | null;\n }>\n > {\n const executedBySource = new Map<DataSource, Map<string, MigrationRecord>>();\n\n for (const dataSource of this.getSources()) {\n const executed = await this.getExecutedMigrations(dataSource, { readOnly: true });\n executedBySource.set(dataSource, new Map(executed.map((r) => [r.name, r])));\n }\n\n return this.migrations.map((MigrationClass) => {\n const instance = new MigrationClass();\n const name = MigrationClass.migrationName;\n const record = executedBySource.get(this.sourceOf(MigrationClass))?.get(name);\n return {\n name,\n table: instance.table,\n executed: !!record,\n batch: record?.batch ?? null,\n };\n });\n }\n\n // ============================================================================\n // EXTENSION PRE-FLIGHT\n // ============================================================================\n\n /**\n * Check whether a database extension is available and inform the developer\n * if it is not installed.\n *\n * Does NOT throw — execution proceeds normally. If the extension is truly\n * missing, the database will surface its own error with full context already\n * displayed to the developer.\n *\n * @example\n * await this.informIfExtensionMissing(\"vector\");\n */\n private async informIfExtensionMissing(\n extension: string,\n dataSource: DataSource = this.getDataSource(),\n ): Promise<void> {\n try {\n const migrationDriver = this.getMigrationDriver(dataSource);\n const isAvailable = await migrationDriver.isExtensionAvailable(extension);\n\n if (!isAvailable) {\n const hr = \"─\".repeat(60);\n console.log(`\\n${colors.yellow(hr)}`);\n console.log(colors.yellow(` ⚠ Missing Database Extension: ${colors.bold(extension)}`));\n console.log(colors.yellow(hr));\n console.log();\n console.log(` A pending migration requires the ${colors.cyan(extension)} extension,`);\n console.log(` which is not installed on your database server.`);\n console.log();\n console.log(\n ` ${colors.bold(\"This means the physical database server is missing the extension package.\")}`,\n );\n console.log(` You cannot simply run CREATE EXTENSION until the package is installed`);\n console.log(` on the host machine or Docker container.`);\n console.log();\n\n const docsUrl = migrationDriver.getExtensionDocsUrl(extension);\n if (docsUrl) {\n console.log(` ${colors.bold(\"Or follow the installation guide:\")}`);\n console.log(` ${colors.cyan(docsUrl)}`);\n }\n console.log(`\\n${colors.yellow(hr)}\\n`);\n }\n } catch {\n // If the check itself fails, silently skip — don't break the migration.\n }\n }\n\n // ============================================================================\n // PRIVATE HELPERS\n // ============================================================================\n\n /**\n * Run a single migration.\n */\n private async runMigration(\n MigrationClass: MigrationClass,\n direction: \"up\" | \"down\",\n options: {\n dryRun?: boolean;\n record?: boolean;\n batch?: number;\n } = {},\n ): Promise<MigrationResult> {\n const { dryRun = false, record = true } = options;\n const startTime = Date.now();\n let success = true;\n let error: string | undefined;\n\n const migration = new MigrationClass();\n const name = MigrationClass.migrationName;\n\n log.info(\n \"database\",\n \"migration\",\n `${direction === \"up\" ? \"Migrating\" : \"Rolling back\"}: ${colors.magenta(name)}...`,\n );\n\n try {\n if (!dryRun) {\n // The migration runs against its declared data source (default: the runner's)\n // and is recorded in THAT source's migrations table.\n const dataSource = this.resolveDataSource(migration.dataSource);\n const driver = this.getMigrationDriver(dataSource);\n migration.setDriver(driver);\n migration.setMigrationDefaults(dataSource.migrationDefaults);\n\n // ============================================================================\n // TRANSACTION RESOLUTION (3-tier hierarchy)\n // ============================================================================\n // 1. Migration-level explicit override (instance or static)\n // 2. CONCURRENTLY statements (cannot run in a transaction block)\n // 3. Config-level global override\n // 4. Driver default (PostgreSQL: true, MongoDB: false)\n // Resolved below, once the statements are known.\n\n // ============================================================================\n // EXECUTE WITH OR WITHOUT TRANSACTION\n // ============================================================================\n\n // Collect the requested direction's operations\n if (direction === \"up\") {\n await migration.up();\n } else {\n await migration.down();\n }\n\n const databaseDriver = dataSource.driver;\n\n // SQL-capable drivers serialize the queued operations to SQL strings;\n // drivers without SQL serialization (MongoDB) keep them queued and\n // execute them directly through the migration driver.\n const directExecution = databaseDriver.supportsSqlSerialization === false;\n const steps: MigrationStep[] = directExecution\n ? []\n : (migration.toSteps?.() ?? migration.toSQL());\n const sqlStatements = steps.filter((step): step is string => typeof step === \"string\");\n const shouldUseTransaction = this.resolveTransactional(\n MigrationClass,\n migration,\n dataSource,\n sqlStatements,\n );\n\n const applyMigration = async (): Promise<void> => {\n if (directExecution) {\n await migration.execute();\n return;\n }\n\n // Execute generated SQL statements sequentially (no phase-sorting here since it's single execution)\n for (const step of steps) {\n if (typeof step === \"string\") await databaseDriver.query(step);\n else await step.data();\n }\n };\n\n if (shouldUseTransaction && databaseDriver.transaction) {\n // Transactional execution\n await databaseDriver.transaction(async () => {\n await applyMigration();\n\n // Record migration tracking\n if (record) {\n if (direction === \"up\") {\n const batch = options.batch ?? (await this.getNextBatchNumber(dataSource));\n await this.recordMigration(\n name,\n batch,\n MigrationClass.createdAt ? parseCreatedAt(MigrationClass.createdAt) : new Date(),\n dataSource,\n );\n } else {\n await this.removeMigrationRecord(name, dataSource);\n }\n }\n });\n } else {\n // Non-transactional execution\n await applyMigration();\n\n if (record) {\n if (direction === \"up\") {\n const batch = options.batch ?? (await this.getNextBatchNumber(dataSource));\n await this.recordMigration(\n name,\n batch,\n MigrationClass.createdAt ? parseCreatedAt(MigrationClass.createdAt) : new Date(),\n dataSource,\n );\n } else {\n await this.removeMigrationRecord(name, dataSource);\n }\n }\n }\n }\n } catch (err) {\n success = false;\n error = err instanceof Error ? err.message : String(err);\n log.error(\"database\", \"migration\", `${colors.magenta(name)}: ✗ Failed: ${error}`);\n throw err;\n }\n\n const durationMs = Date.now() - startTime;\n\n if (success) {\n log.success(\n \"database\",\n \"migration\",\n `${direction == \"up\" ? \"Migrated\" : \"Rolled back\"}: ${colors.magenta(name)} successfully (${durationMs}ms)`,\n );\n }\n\n return {\n name,\n table: migration.table,\n direction,\n success,\n error,\n durationMs,\n executedAt: new Date(),\n };\n }\n\n /**\n * Create, configure, and return a ready-to-use migration instance.\n *\n * Centralises the repeated \"new + setDriver + setMigrationDefaults\" boilerplate\n * that all batch/single execution paths need.\n *\n * @internal\n */\n private createMigrationInstance(MigrationClass: MigrationClass): Migration {\n const migration = new MigrationClass();\n const dataSource = this.resolveDataSource(migration.dataSource);\n migration.setDriver(this.getMigrationDriver(dataSource));\n migration.setMigrationDefaults(dataSource.migrationDefaults);\n return migration;\n }\n\n /**\n * Format an ordered array of TaggedSQL into a human-readable SQL file string.\n *\n * Consecutive statements that belong to the same (phase, migration) group share\n * a single block comment at the top, avoiding the noisy per-statement repetition.\n *\n * Example output:\n * ```sql\n * /* Phase 3 [create-users] *\\/\n * ALTER TABLE \"users\" ADD COLUMN \"name\" TEXT NOT NULL;\n * ALTER TABLE \"users\" ADD COLUMN \"email\" TEXT NOT NULL;\n *\n * /* Phase 4 [create-users] *\\/\n * CREATE UNIQUE INDEX ...;\n * ```\n *\n * @internal\n */\n private formatSQLForExport(statements: TaggedSQL[], compact: boolean = false): string {\n const lines: string[] = [];\n\n if (compact) {\n // Just output raw statements, no grouping, no blank lines\n for (const stmt of statements) {\n lines.push(`${stmt.sql};`);\n }\n return lines.join(\"\\n\");\n }\n\n // Group statements by their phase and migration name\n const grouped = new Map<string, string[]>();\n\n for (const stmt of statements) {\n const groupKey = `Phase ${stmt.phase} [${stmt.migrationName}]`;\n if (!grouped.has(groupKey)) {\n grouped.set(groupKey, []);\n }\n grouped.get(groupKey)!.push(stmt.sql);\n }\n\n // Format each group\n for (const [groupKey, sqls] of grouped.entries()) {\n if (lines.length > 0) lines.push(\"\"); // blank line between groups\n lines.push(`/* ${groupKey} */`);\n for (const sql of sqls) {\n lines.push(`${sql};`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Get pending (not executed) registered migrations, in the order they would\n * execute.\n *\n * ⚠️ \"Registered\" is load-bearing. This filters `this.migrations`, which is\n * populated only by `register()` / `registerMany()`. A caller that has not\n * registered anything gets `[]` — indistinguishable from a database with\n * nothing pending. Anything reporting this set to a human MUST register\n * migrations first, or it will print a confident all-clear over an unknown.\n *\n * @see listPendingMigrations\n */\n public async getPendingMigrations(\n options: { readOnly?: boolean } = {},\n ): Promise<MigrationClass[]> {\n // \"Executed\" is judged in each migration's own data source's migrations table.\n const executedNames = new Map<DataSource, Set<string>>();\n for (const dataSource of this.getSources()) {\n const executed = await this.getExecutedMigrations(dataSource, options);\n executedNames.set(dataSource, new Set(executed.map((r) => r.name)));\n }\n\n const migrations = this.migrations.filter(\n (m) => !executedNames.get(this.sourceOf(m))?.has(m.migrationName),\n );\n\n return migrations.sort(sortMigrations);\n }\n\n /**\n * Get migrations to rollback, newest-first.\n *\n * A rollback must undo migrations in the exact inverse of the order `up`\n * applied them, or a `down()` will hit schema its predecessor already\n * removed — dropping a table before dropping the column added to it, say.\n *\n * The sort has to be explicitly **descending**. Reversing the executed list\n * is not enough: `getExecutedMigrations` orders by `batch, name`, so the\n * input is alphabetical rather than chronological, and reversing it only\n * yields reverse-alphabetical order. (Sorting *ascending* here — which is\n * what this method used to do after a `.reverse()` — silently restored the\n * forward `up` order and made the reverse dead code.)\n */\n private async getMigrationsToRollback(\n batches: number,\n options: { pruneMissing?: boolean; readOnly?: boolean } = {},\n ): Promise<MigrationClass[]> {\n const migrations: MigrationClass[] = [];\n const batchOf = new Map<MigrationClass, number>();\n const orphans: Array<{ name: string; dataSource: DataSource }> = [];\n\n // Batches are numbered per data source (each has its own migrations table).\n for (const dataSource of this.getSources()) {\n const executed = await this.getExecutedMigrations(dataSource, {\n readOnly: options.readOnly,\n });\n if (executed.length === 0) continue;\n\n const batchNumbers = [...new Set(executed.map((r) => r.batch))]\n .sort((a, b) => b - a)\n .slice(0, batches);\n\n for (const record of executed) {\n if (!batchNumbers.includes(record.batch)) continue;\n\n const MigrationClass = this.migrations.find(\n (m) => m.migrationName === record.name && this.sourceOf(m) === dataSource,\n );\n if (MigrationClass) {\n migrations.push(MigrationClass);\n batchOf.set(MigrationClass, record.batch);\n } else {\n orphans.push({ name: record.name, dataSource });\n }\n }\n }\n\n if (orphans.length > 0) {\n if (!options.pruneMissing) {\n throw new Error(\n `Cannot roll back: ${orphans.length} executed migration(s) have no registered file: ` +\n `${orphans.map((o) => o.name).join(\", \")}. ` +\n `They were renamed, deleted, or not matched by the migration pattern. ` +\n `Restore the file(s), or pass pruneMissing (--prune-missing) to delete those records.`,\n );\n }\n\n if (!options.readOnly) {\n for (const orphan of orphans) {\n await this.removeMigrationRecord(orphan.name, orphan.dataSource);\n log.warn(\"database\", \"migration\", `Pruned orphaned migration record: ${orphan.name}`);\n }\n }\n }\n\n // Newest batch first, then newest migration first within a batch.\n return migrations.sort(\n (a, b) => (batchOf.get(b) ?? 0) - (batchOf.get(a) ?? 0) || sortMigrationsForRollback(a, b),\n );\n }\n\n /**\n * Get executed migration records.\n */\n public async getExecutedMigrations(\n dataSource: DataSource = this.getDataSource(),\n options: { readOnly?: boolean } = {},\n ): Promise<MigrationRecord[]> {\n const driver = dataSource.driver;\n const migrationDriver = this.getMigrationDriver(dataSource);\n\n if (options.readOnly) {\n // Dry runs and listings must not create the migrations table.\n if (!(await migrationDriver.tableExists(this.migrationsTable))) return [];\n } else {\n // A missing table is created here; every other error (connection,\n // permission…) propagates instead of looking like \"nothing executed\".\n await migrationDriver.ensureMigrationsTable(this.migrationsTable);\n }\n\n const queryBuilder = driver.queryBuilder<MigrationRecord>(this.migrationsTable);\n const records = await queryBuilder.orderBy(\"batch\", \"asc\").orderBy(\"name\", \"asc\").get();\n\n // The Mongo lock document lives in this collection; it is not a migration.\n return records.filter((record) => record.name !== MIGRATION_LOCK_NAME);\n }\n\n /**\n * Record a migration.\n */\n private async recordMigration(\n name: string,\n batch: number,\n createdAt?: Date,\n dataSource: DataSource = this.getDataSource(),\n ): Promise<void> {\n const driver = dataSource.driver;\n const migrationDriver = this.getMigrationDriver(dataSource);\n\n // Ensure migrations table exists\n await migrationDriver.ensureMigrationsTable(this.migrationsTable);\n\n await driver.insert(this.migrationsTable, {\n name,\n batch,\n executedAt: new Date(),\n createdAt,\n });\n }\n\n /**\n * Remove a migration record.\n */\n private async removeMigrationRecord(\n name: string,\n dataSource: DataSource = this.getDataSource(),\n ): Promise<void> {\n const driver = dataSource.driver;\n await driver.delete(this.migrationsTable, { name });\n }\n\n /**\n * Get next batch number.\n */\n private async getNextBatchNumber(\n dataSource: DataSource = this.getDataSource(),\n readOnly = false,\n ): Promise<number> {\n const executed = await this.getExecutedMigrations(dataSource, { readOnly });\n if (executed.length === 0) return 1;\n return Math.max(...executed.map((r) => r.batch)) + 1;\n }\n}\n\nexport const migrationRunner = new MigrationRunner();\n"],"mappings":"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"}
@@ -488,6 +488,8 @@ interface MigrationContract {
488
488
  */
489
489
  vector(column: string, dimensions: number): ColumnBuilder;
490
490
  }
491
+ /** The source that registered a migration with a runner. */
492
+ type MigrationOrigin = "package" | "app";
491
493
  /**
492
494
  * Constructor for the migration class.
493
495
  */
@@ -497,6 +499,7 @@ interface MigrationConstructor {
497
499
  createdAt?: string;
498
500
  transactional?: boolean;
499
501
  order?: number;
502
+ origin?: MigrationOrigin;
500
503
  }
501
504
  /**
502
505
  * Base class for all database migrations.
@@ -775,6 +778,13 @@ declare abstract class Migration implements MigrationContract {
775
778
  * Execute a single pending operation.
776
779
  */
777
780
  private executeOperation;
781
+ /**
782
+ * Reject two unnamed indexes that a driver would give the same name before
783
+ * either DDL command is sent. MongoDB's default names include directions;
784
+ * PostgreSQL's include the table and columns.
785
+ */
786
+ private assertNoGeneratedIndexNameCollisions;
787
+ private describeIndex;
778
788
  /**
779
789
  * Check if a table exists.
780
790
  *
@@ -2114,5 +2124,5 @@ type AlterSchema = {
2114
2124
  raw?: string | string[];
2115
2125
  };
2116
2126
  //#endregion
2117
- export { AlterSchema, ColumnMap, IndexEntry, Migration, MigrationAlterOptions, MigrationConstructor, MigrationContract, MigrationCreateOptions, MigrationStep, OperationType, PendingOperation, UniqueEntry, migrate };
2127
+ export { AlterSchema, ColumnMap, IndexEntry, Migration, MigrationAlterOptions, MigrationConstructor, MigrationContract, MigrationCreateOptions, MigrationOrigin, MigrationStep, OperationType, PendingOperation, UniqueEntry, migrate };
2118
2128
  //# sourceMappingURL=migration.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration.d.mts","names":[],"sources":["../../../../../../../cascade/src/migration/migration.ts"],"mappings":"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"}
1
+ {"version":3,"file":"migration.d.mts","names":[],"sources":["../../../../../../../cascade/src/migration/migration.ts"],"mappings":"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"}