@prisma-next/target-postgres 0.9.0 → 0.10.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/{codec-ids-RvYfmUmi.d.mts → codec-ids-D9fJ4HP5.d.mts} +1 -1
  2. package/dist/{codec-ids-RvYfmUmi.d.mts.map → codec-ids-D9fJ4HP5.d.mts.map} +1 -1
  3. package/dist/codec-ids.d.mts +1 -1
  4. package/dist/{codec-types-667FxIW8.d.mts → codec-types-CRlHq7Cz.d.mts} +2 -2
  5. package/dist/{codec-types-667FxIW8.d.mts.map → codec-types-CRlHq7Cz.d.mts.map} +1 -1
  6. package/dist/codec-types.d.mts +1 -1
  7. package/dist/{codecs-DXeDABSO.d.mts → codecs-Dud5KDNk.d.mts} +2 -2
  8. package/dist/{codecs-DXeDABSO.d.mts.map → codecs-Dud5KDNk.d.mts.map} +1 -1
  9. package/dist/codecs.d.mts +1 -1
  10. package/dist/control.d.mts +1 -1
  11. package/dist/control.mjs +5 -5
  12. package/dist/{data-transform-COkGR6Ns.mjs → data-transform-CdtGUWp2.mjs} +1 -1
  13. package/dist/{data-transform-COkGR6Ns.mjs.map → data-transform-CdtGUWp2.mjs.map} +1 -1
  14. package/dist/{data-transform-B6p02mFJ.d.mts → data-transform-bmOKkygi.d.mts} +2 -2
  15. package/dist/{data-transform-B6p02mFJ.d.mts.map → data-transform-bmOKkygi.d.mts.map} +1 -1
  16. package/dist/data-transform.d.mts +1 -1
  17. package/dist/data-transform.mjs +1 -1
  18. package/dist/descriptor-meta-zrZzWmJF.mjs +91 -0
  19. package/dist/{descriptor-meta-DFUCClk_.mjs.map → descriptor-meta-zrZzWmJF.mjs.map} +1 -1
  20. package/dist/enum-planning.d.mts +1 -1
  21. package/dist/{errors-BiOloWUh.mjs → errors--zafB5_n.mjs} +1 -1
  22. package/dist/{errors-BiOloWUh.mjs.map → errors--zafB5_n.mjs.map} +1 -1
  23. package/dist/errors.mjs +1 -1
  24. package/dist/{issue-planner-BhWVYyE1.mjs → issue-planner-qalHRCI2.mjs} +179 -77
  25. package/dist/issue-planner-qalHRCI2.mjs.map +1 -0
  26. package/dist/issue-planner.d.mts +2 -2
  27. package/dist/issue-planner.d.mts.map +1 -1
  28. package/dist/issue-planner.mjs +1 -1
  29. package/dist/migration.d.mts +3 -3
  30. package/dist/migration.mjs +3 -3
  31. package/dist/{op-factory-call-c1zELk3U.d.mts → op-factory-call-Drccm_JD.d.mts} +3 -3
  32. package/dist/{op-factory-call-c1zELk3U.d.mts.map → op-factory-call-Drccm_JD.d.mts.map} +1 -1
  33. package/dist/{op-factory-call-DerP9BoT.mjs → op-factory-call-Zsrdty3k.mjs} +2 -2
  34. package/dist/{op-factory-call-DerP9BoT.mjs.map → op-factory-call-Zsrdty3k.mjs.map} +1 -1
  35. package/dist/op-factory-call.d.mts +1 -1
  36. package/dist/op-factory-call.mjs +1 -1
  37. package/dist/pack.d.mts +2 -2
  38. package/dist/pack.mjs +1 -1
  39. package/dist/{planner-DnzPpv1j.mjs → planner-C8yhbXOq.mjs} +84 -5
  40. package/dist/planner-C8yhbXOq.mjs.map +1 -0
  41. package/dist/{planner-ddl-builders-5QIyhBUF.mjs → planner-ddl-builders-DINYrbJ3.mjs} +4 -4
  42. package/dist/{planner-ddl-builders-5QIyhBUF.mjs.map → planner-ddl-builders-DINYrbJ3.mjs.map} +1 -1
  43. package/dist/planner-ddl-builders.d.mts +1 -1
  44. package/dist/planner-ddl-builders.mjs +1 -1
  45. package/dist/{planner-identity-values-BUYNOCwb.mjs → planner-identity-values-ojX-6cPV.mjs} +1 -1
  46. package/dist/{planner-identity-values-BUYNOCwb.mjs.map → planner-identity-values-ojX-6cPV.mjs.map} +1 -1
  47. package/dist/planner-identity-values.mjs +1 -1
  48. package/dist/{planner-produced-postgres-migration-FYsKh26I.mjs → planner-produced-postgres-migration-BqGLw7VT.mjs} +4 -4
  49. package/dist/{planner-produced-postgres-migration-FYsKh26I.mjs.map → planner-produced-postgres-migration-BqGLw7VT.mjs.map} +1 -1
  50. package/dist/{planner-produced-postgres-migration-D34ftfEK.d.mts → planner-produced-postgres-migration-c9lpjPv1.d.mts} +3 -3
  51. package/dist/{planner-produced-postgres-migration-D34ftfEK.d.mts.map → planner-produced-postgres-migration-c9lpjPv1.d.mts.map} +1 -1
  52. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  53. package/dist/planner-produced-postgres-migration.mjs +1 -1
  54. package/dist/planner-schema-lookup-BGyukuzG.mjs +57 -0
  55. package/dist/planner-schema-lookup-BGyukuzG.mjs.map +1 -0
  56. package/dist/planner-schema-lookup.d.mts.map +1 -1
  57. package/dist/planner-schema-lookup.mjs +1 -1
  58. package/dist/{planner-sql-checks-Cd016Ycs.mjs → planner-sql-checks-BM4sD6Xc.mjs} +28 -11
  59. package/dist/planner-sql-checks-BM4sD6Xc.mjs.map +1 -0
  60. package/dist/planner-sql-checks.d.mts +11 -0
  61. package/dist/planner-sql-checks.d.mts.map +1 -1
  62. package/dist/planner-sql-checks.mjs +1 -1
  63. package/dist/{planner-target-details-iYJwzFHP.d.mts → planner-target-details-CIj61DUj.d.mts} +1 -1
  64. package/dist/{planner-target-details-iYJwzFHP.d.mts.map → planner-target-details-CIj61DUj.d.mts.map} +1 -1
  65. package/dist/planner-target-details.d.mts +1 -1
  66. package/dist/planner.d.mts +1 -1
  67. package/dist/planner.d.mts.map +1 -1
  68. package/dist/planner.mjs +1 -1
  69. package/dist/postgres-contract-serializer-CcZO9ukP.mjs +83 -0
  70. package/dist/postgres-contract-serializer-CcZO9ukP.mjs.map +1 -0
  71. package/dist/{postgres-enum-type-CrKq8au9.d.mts → postgres-enum-type-CNhPTDhy.d.mts} +1 -1
  72. package/dist/{postgres-enum-type-CrKq8au9.d.mts.map → postgres-enum-type-CNhPTDhy.d.mts.map} +1 -1
  73. package/dist/{postgres-migration-q4oWyNJE.mjs → postgres-migration-C5os-tkl.mjs} +3 -3
  74. package/dist/{postgres-migration-q4oWyNJE.mjs.map → postgres-migration-C5os-tkl.mjs.map} +1 -1
  75. package/dist/{postgres-migration-CiQzhcMe.d.mts → postgres-migration-jvsKgUDM.d.mts} +3 -3
  76. package/dist/{postgres-migration-CiQzhcMe.d.mts.map → postgres-migration-jvsKgUDM.d.mts.map} +1 -1
  77. package/dist/postgres-schema-BosNxhWq.mjs +163 -0
  78. package/dist/postgres-schema-BosNxhWq.mjs.map +1 -0
  79. package/dist/{render-ops-CkiuHSNj.mjs → render-ops-BC2PtCkj.mjs} +1 -1
  80. package/dist/{render-ops-CkiuHSNj.mjs.map → render-ops-BC2PtCkj.mjs.map} +1 -1
  81. package/dist/render-ops.d.mts +1 -1
  82. package/dist/render-ops.mjs +1 -1
  83. package/dist/{render-typescript-C9XWI8Ld.mjs → render-typescript-nRHbqLbI.mjs} +1 -1
  84. package/dist/{render-typescript-C9XWI8Ld.mjs.map → render-typescript-nRHbqLbI.mjs.map} +1 -1
  85. package/dist/render-typescript.mjs +1 -1
  86. package/dist/runtime.d.mts +7 -17
  87. package/dist/runtime.d.mts.map +1 -1
  88. package/dist/runtime.mjs +2 -2
  89. package/dist/{shared-DLYdmYo-.d.mts → shared-ByhSooBS.d.mts} +6 -4
  90. package/dist/shared-ByhSooBS.d.mts.map +1 -0
  91. package/dist/{statement-builders-BSIQMClE.mjs → statement-builders-vImtdfmM.mjs} +1 -1
  92. package/dist/{statement-builders-BSIQMClE.mjs.map → statement-builders-vImtdfmM.mjs.map} +1 -1
  93. package/dist/statement-builders.mjs +1 -1
  94. package/dist/{tables-Ce_Q0I8B.mjs → tables-DZ-5Yxi0.mjs} +3 -3
  95. package/dist/tables-DZ-5Yxi0.mjs.map +1 -0
  96. package/dist/{types-Dq74Z3eu.d.mts → types-D-XIpzHA.d.mts} +1 -1
  97. package/dist/types-D-XIpzHA.d.mts.map +1 -0
  98. package/dist/types.d.mts +125 -3
  99. package/dist/types.d.mts.map +1 -0
  100. package/dist/types.mjs +2 -1
  101. package/package.json +17 -17
  102. package/src/core/migrations/issue-planner.ts +131 -41
  103. package/src/core/migrations/operations/constraints.ts +1 -1
  104. package/src/core/migrations/operations/shared.ts +4 -2
  105. package/src/core/migrations/planner-ddl-builders.ts +2 -2
  106. package/src/core/migrations/planner-schema-lookup.ts +30 -6
  107. package/src/core/migrations/planner-sql-checks.ts +29 -11
  108. package/src/core/migrations/planner-strategies.ts +138 -43
  109. package/src/core/migrations/planner.ts +14 -1
  110. package/src/core/migrations/verify-postgres-namespaces.ts +87 -0
  111. package/src/core/postgres-contract-serializer.ts +139 -60
  112. package/src/core/postgres-schema.ts +208 -0
  113. package/src/exports/types.ts +5 -0
  114. package/dist/descriptor-meta-DFUCClk_.mjs +0 -124
  115. package/dist/issue-planner-BhWVYyE1.mjs.map +0 -1
  116. package/dist/planner-DnzPpv1j.mjs.map +0 -1
  117. package/dist/planner-schema-lookup--u9whY_Y.mjs +0 -29
  118. package/dist/planner-schema-lookup--u9whY_Y.mjs.map +0 -1
  119. package/dist/planner-sql-checks-Cd016Ycs.mjs.map +0 -1
  120. package/dist/postgres-contract-serializer-D5VJk6lo.mjs +0 -61
  121. package/dist/postgres-contract-serializer-D5VJk6lo.mjs.map +0 -1
  122. package/dist/shared-DLYdmYo-.d.mts.map +0 -1
  123. package/dist/tables-Ce_Q0I8B.mjs.map +0 -1
  124. package/dist/types-Dq74Z3eu.d.mts.map +0 -1
@@ -1,12 +1,14 @@
1
1
  import { t as PostgresEnumType } from "./postgres-enum-type-DS-KLVRH.mjs";
2
2
  import { r as readExistingEnumValues, t as determineEnumDiff } from "./enum-planning-Bqp96iIw.mjs";
3
3
  import { i as quoteIdentifier } from "./sql-utils-BewXAnsG.mjs";
4
- import { a as columnNullabilityCheck, c as qualifyTableName, i as columnHasNoDefaultCheck, r as columnExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-Cd016Ycs.mjs";
5
- import { C as SetNotNullCall, S as SetDefaultCall, _ as DropIndexCall, a as AddUniqueCall, b as RawSqlCall, d as CreateTableCall, f as DataTransformCall, g as DropEnumTypeCall, h as DropDefaultCall, i as AddPrimaryKeyCall, l as CreateIndexCall, m as DropConstraintCall, n as AddEnumValuesCall, o as AlterColumnTypeCall, p as DropColumnCall, r as AddForeignKeyCall, s as CreateEnumTypeCall, t as AddColumnCall, v as DropNotNullCall, x as RenameTypeCall, y as DropTableCall } from "./op-factory-call-DerP9BoT.mjs";
6
- import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-5QIyhBUF.mjs";
7
- import { n as resolveIdentityValue } from "./planner-identity-values-BUYNOCwb.mjs";
8
- import { i as hasUniqueConstraint, n as hasForeignKey, t as buildSchemaLookupMap } from "./planner-schema-lookup--u9whY_Y.mjs";
4
+ import { r as isPostgresSchema } from "./postgres-schema-BosNxhWq.mjs";
5
+ import { a as columnNullabilityCheck, c as qualifyTableName, i as columnHasNoDefaultCheck, r as columnExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-BM4sD6Xc.mjs";
6
+ import { C as SetNotNullCall, S as SetDefaultCall, _ as DropIndexCall, a as AddUniqueCall, b as RawSqlCall, d as CreateTableCall, f as DataTransformCall, g as DropEnumTypeCall, h as DropDefaultCall, i as AddPrimaryKeyCall, l as CreateIndexCall, m as DropConstraintCall, n as AddEnumValuesCall, o as AlterColumnTypeCall, p as DropColumnCall, r as AddForeignKeyCall, s as CreateEnumTypeCall, t as AddColumnCall, u as CreateSchemaCall, v as DropNotNullCall, x as RenameTypeCall, y as DropTableCall } from "./op-factory-call-Zsrdty3k.mjs";
7
+ import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-DINYrbJ3.mjs";
8
+ import { n as resolveIdentityValue } from "./planner-identity-values-ojX-6cPV.mjs";
9
+ import { i as hasUniqueConstraint, n as hasForeignKey, t as buildSchemaLookupMap } from "./planner-schema-lookup-BGyukuzG.mjs";
9
10
  import { ifDefined } from "@prisma-next/utils/defined";
11
+ import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
10
12
  import { isPostgresEnumStorageEntry } from "@prisma-next/sql-contract/types";
11
13
  import { arraysEqual } from "@prisma-next/family-sql/schema-verify";
12
14
  import { notOk, ok } from "@prisma-next/utils/result";
@@ -86,8 +88,60 @@ function buildAddNotNullColumnWithTemporaryDefaultOperation(options) {
86
88
  //#endregion
87
89
  //#region src/core/migrations/planner-strategies.ts
88
90
  const REBUILD_SUFFIX = "__prisma_next_new";
89
- function buildColumnSpec(table, column, ctx, overrides) {
90
- const col = ctx.toContract.storage.tables[table]?.columns[column];
91
+ /**
92
+ * Look up a storage table by its explicit namespace coordinate. Returns
93
+ * `undefined` when the namespace has no table by that name (or no such
94
+ * namespace exists). Callers that get `undefined` MUST treat it as an
95
+ * explicit conflict — never silently fall back to a global default
96
+ * schema or a name-only walk, because that footgun would resolve a
97
+ * stale or duplicate table name to whichever namespace the iteration
98
+ * order surfaced first (a real data-loss hazard in multi-namespace
99
+ * contracts where two namespaces can carry the same table name).
100
+ */
101
+ function tableAt(storage, namespaceId, tableName) {
102
+ return storage.namespaces[namespaceId]?.tables[tableName];
103
+ }
104
+ /**
105
+ * Default namespace coordinate for an issue that does not carry one
106
+ * explicitly. Hand-crafted unit-test issues and `extra_table` issues
107
+ * fall back to `__unbound__`, the only namespace any single-namespace
108
+ * contract carries — verifier-emitted issues for legacy
109
+ * single-namespace contracts already stamp this id explicitly. Typed
110
+ * structurally so issue variants without a `namespaceId` slot
111
+ * (e.g. `EnumValuesChangedIssue`) flow through to the same fallback.
112
+ */
113
+ function resolveNamespaceIdForIssue(issue) {
114
+ return issue.namespaceId ?? UNBOUND_NAMESPACE_ID;
115
+ }
116
+ /**
117
+ * Resolve the DDL schema name for a namespace coordinate. Postgres-aware
118
+ * namespaces dispatch to their polymorphic `ddlSchemaName` override —
119
+ * named schemas return their own id and the unbound singleton projects
120
+ * to `'public'` (sibling-present) or the framework sentinel
121
+ * (sibling-absent). Legacy single-namespace contracts whose `__unbound__`
122
+ * slot is the framework-default `SqlUnboundNamespace` (rather than the
123
+ * Postgres-aware `PostgresUnboundSchema`) flow the coordinate through
124
+ * unchanged so downstream `qualifyTableName` resolves polymorphically.
125
+ */
126
+ function resolveDdlSchemaForNamespace(ctx, namespaceId) {
127
+ const namespace = ctx.toContract.storage.namespaces[namespaceId];
128
+ if (isPostgresSchema(namespace)) return namespace.ddlSchemaName(ctx.toContract.storage);
129
+ return namespaceId;
130
+ }
131
+ /**
132
+ * Finds a type entry by name across all namespace type registries.
133
+ * Namespace types (e.g. Postgres enums) live under
134
+ * `storage.namespaces[nsId].types`, not under `storage.types`.
135
+ */
136
+ function locateNamespaceType(storage, typeName) {
137
+ for (const ns of Object.values(storage.namespaces)) {
138
+ if (!("types" in ns) || ns.types == null) continue;
139
+ const entry = ns.types[typeName];
140
+ if (entry !== void 0) return entry;
141
+ }
142
+ }
143
+ function buildColumnSpec(namespaceId, table, column, ctx, overrides) {
144
+ const col = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
91
145
  if (!col) throw new Error(`Column "${table}"."${column}" not found in destination contract`);
92
146
  const mutableHooks = ctx.codecHooks;
93
147
  const mutableTypes = ctx.storageTypes;
@@ -98,8 +152,8 @@ function buildColumnSpec(table, column, ctx, overrides) {
98
152
  nullable: overrides?.nullable ?? col.nullable
99
153
  };
100
154
  }
101
- function buildAlterTypeOptions(table, column, ctx, using) {
102
- const col = ctx.toContract.storage.tables[table]?.columns[column];
155
+ function buildAlterTypeOptions(namespaceId, table, column, ctx, using) {
156
+ const col = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
103
157
  if (!col) throw new Error(`Column "${table}"."${column}" not found in destination contract`);
104
158
  const mutableHooks = ctx.codecHooks;
105
159
  const mutableTypes = ctx.storageTypes;
@@ -117,12 +171,14 @@ const notNullBackfillCallStrategy = (issues, ctx) => {
117
171
  const calls = [];
118
172
  for (const issue of issues) {
119
173
  if (issue.kind !== "missing_column" || !issue.table || !issue.column) continue;
120
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
174
+ const namespaceId = resolveNamespaceIdForIssue(issue);
175
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
121
176
  if (!column) continue;
122
177
  if (column.nullable === true || column.default !== void 0) continue;
123
178
  matched.push(issue);
124
- const spec = buildColumnSpec(issue.table, issue.column, ctx, { nullable: true });
125
- calls.push(new AddColumnCall(ctx.schemaName, issue.table, spec), new DataTransformCall(`backfill-${issue.table}-${issue.column}`, `backfill-${issue.table}-${issue.column}:check`, `backfill-${issue.table}-${issue.column}:run`), new SetNotNullCall(ctx.schemaName, issue.table, issue.column));
179
+ const spec = buildColumnSpec(namespaceId, issue.table, issue.column, ctx, { nullable: true });
180
+ const schemaForTable = resolveDdlSchemaForNamespace(ctx, namespaceId);
181
+ calls.push(new AddColumnCall(schemaForTable, issue.table, spec), new DataTransformCall(`backfill-${issue.table}-${issue.column}`, `backfill-${issue.table}-${issue.column}:check`, `backfill-${issue.table}-${issue.column}:run`), new SetNotNullCall(schemaForTable, issue.table, issue.column));
126
182
  }
127
183
  if (matched.length === 0) return { kind: "no_match" };
128
184
  return {
@@ -145,8 +201,9 @@ const typeChangeCallStrategy = (issues, ctx) => {
145
201
  for (const issue of issues) {
146
202
  if (issue.kind !== "type_mismatch") continue;
147
203
  if (!issue.table || !issue.column) continue;
148
- const fromColumn = ctx.fromContract?.storage.tables[issue.table]?.columns[issue.column];
149
- const toColumn = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
204
+ const namespaceId = resolveNamespaceIdForIssue(issue);
205
+ const fromColumn = ctx.fromContract ? tableAt(ctx.fromContract.storage, namespaceId, issue.table)?.columns[issue.column] : void 0;
206
+ const toColumn = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
150
207
  if (!fromColumn || !toColumn) continue;
151
208
  const fromType = fromColumn.nativeType;
152
209
  const toType = toColumn.nativeType;
@@ -154,9 +211,10 @@ const typeChangeCallStrategy = (issues, ctx) => {
154
211
  const isSafeWidening = SAFE_WIDENINGS.has(`${fromType}→${toType}`);
155
212
  if (!isSafeWidening && !dataAllowed) continue;
156
213
  matched.push(issue);
157
- const alterOpts = buildAlterTypeOptions(issue.table, issue.column, ctx);
158
- if (isSafeWidening) calls.push(new AlterColumnTypeCall(ctx.schemaName, issue.table, issue.column, alterOpts));
159
- else calls.push(new DataTransformCall(`typechange-${issue.table}-${issue.column}`, `typechange-${issue.table}-${issue.column}:check`, `typechange-${issue.table}-${issue.column}:run`), new AlterColumnTypeCall(ctx.schemaName, issue.table, issue.column, alterOpts));
214
+ const alterOpts = buildAlterTypeOptions(namespaceId, issue.table, issue.column, ctx);
215
+ const schemaForTable = resolveDdlSchemaForNamespace(ctx, namespaceId);
216
+ if (isSafeWidening) calls.push(new AlterColumnTypeCall(schemaForTable, issue.table, issue.column, alterOpts));
217
+ else calls.push(new DataTransformCall(`typechange-${issue.table}-${issue.column}`, `typechange-${issue.table}-${issue.column}:check`, `typechange-${issue.table}-${issue.column}:run`), new AlterColumnTypeCall(schemaForTable, issue.table, issue.column, alterOpts));
160
218
  }
161
219
  if (matched.length === 0) return { kind: "no_match" };
162
220
  return {
@@ -172,11 +230,13 @@ const nullableTighteningCallStrategy = (issues, ctx) => {
172
230
  const calls = [];
173
231
  for (const issue of issues) {
174
232
  if (issue.kind !== "nullability_mismatch" || !issue.table || !issue.column) continue;
175
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
233
+ const namespaceId = resolveNamespaceIdForIssue(issue);
234
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
176
235
  if (!column) continue;
177
236
  if (column.nullable === true) continue;
178
237
  matched.push(issue);
179
- calls.push(new DataTransformCall(`handle-nulls-${issue.table}-${issue.column}`, `handle-nulls-${issue.table}-${issue.column}:check`, `handle-nulls-${issue.table}-${issue.column}:run`), new SetNotNullCall(ctx.schemaName, issue.table, issue.column));
238
+ const schemaForTable = resolveDdlSchemaForNamespace(ctx, namespaceId);
239
+ calls.push(new DataTransformCall(`handle-nulls-${issue.table}-${issue.column}`, `handle-nulls-${issue.table}-${issue.column}:check`, `handle-nulls-${issue.table}-${issue.column}:run`), new SetNotNullCall(schemaForTable, issue.table, issue.column));
180
240
  }
181
241
  if (matched.length === 0) return { kind: "no_match" };
182
242
  return {
@@ -187,22 +247,26 @@ const nullableTighteningCallStrategy = (issues, ctx) => {
187
247
  };
188
248
  };
189
249
  function enumRebuildCallRecipe(typeName, ctx) {
190
- const toType = ctx.toContract.storage.types?.[typeName];
250
+ const toType = locateNamespaceType(ctx.toContract.storage, typeName);
191
251
  if (!toType) return [];
192
252
  const isEnum = isPostgresEnumStorageEntry(toType);
193
253
  const nativeType = toType.nativeType;
194
254
  const desiredValues = isEnum ? toType.values : toType.typeParams["values"] ?? [];
195
255
  const tempName = `${nativeType}${REBUILD_SUFFIX}`;
196
256
  const columnRefs = [];
197
- for (const [tableName, table] of Object.entries(ctx.toContract.storage.tables)) for (const [columnName, column] of Object.entries(table.columns)) if (column.typeRef === typeName) columnRefs.push({
198
- table: tableName,
199
- column: columnName
200
- });
257
+ for (const [nsId, ns] of Object.entries(ctx.toContract.storage.namespaces)) for (const [tableName, tableNode] of Object.entries(ns.tables)) {
258
+ const table = tableNode;
259
+ for (const [columnName, column] of Object.entries(table.columns)) if (column.typeRef === typeName) columnRefs.push({
260
+ namespaceId: nsId,
261
+ table: tableName,
262
+ column: columnName
263
+ });
264
+ }
201
265
  return [
202
266
  new CreateEnumTypeCall(ctx.schemaName, tempName, desiredValues),
203
267
  ...columnRefs.map((ref) => {
204
268
  const using = `${ref.column}::text::${tempName}`;
205
- return new AlterColumnTypeCall(ctx.schemaName, ref.table, ref.column, {
269
+ return new AlterColumnTypeCall(resolveDdlSchemaForNamespace(ctx, ref.namespaceId), ref.table, ref.column, {
206
270
  qualifiedTargetType: tempName,
207
271
  formatTypeExpected: tempName,
208
272
  rawTargetTypeForLabel: tempName,
@@ -246,7 +310,7 @@ function enumRebuildCallRecipe(typeName, ctx) {
246
310
  * `CreateTableCall` that references the new enum.
247
311
  */
248
312
  const nativeEnumPlanCallStrategy = (issues, ctx) => {
249
- const enumTypes = collectPostgresEnumTypes(ctx.toContract.storage.types);
313
+ const enumTypes = collectPostgresEnumTypes(ctx.toContract.storage);
250
314
  if (enumTypes.size === 0) return { kind: "no_match" };
251
315
  const dataAllowed = ctx.policy.allowedOperationClasses.includes("data");
252
316
  const calls = [];
@@ -289,9 +353,13 @@ const nativeEnumPlanCallStrategy = (issues, ctx) => {
289
353
  recipe: emittedRebuildRecipe
290
354
  };
291
355
  };
292
- function collectPostgresEnumTypes(storageTypes) {
356
+ function collectPostgresEnumTypes(storage) {
293
357
  const result = /* @__PURE__ */ new Map();
294
- for (const [name, instance] of Object.entries(storageTypes ?? {}).sort(([a], [b]) => a.localeCompare(b))) if (instance instanceof PostgresEnumType) result.set(name, instance);
358
+ for (const ns of Object.values(storage.namespaces)) {
359
+ if (!("types" in ns) || ns.types == null) continue;
360
+ const nsTypes = ns.types;
361
+ for (const [name, instance] of Object.entries(nsTypes).sort(([a], [b]) => a.localeCompare(b))) if (instance instanceof PostgresEnumType) result.set(name, instance);
362
+ }
295
363
  return result;
296
364
  }
297
365
  /**
@@ -362,7 +430,8 @@ const notNullAddColumnCallStrategy = (issues, ctx) => {
362
430
  const mutableStorageTypes = ctx.storageTypes;
363
431
  for (const issue of issues) {
364
432
  if (issue.kind !== "missing_column" || !issue.table || !issue.column) continue;
365
- const contractTable = ctx.toContract.storage.tables[issue.table];
433
+ const namespaceId = resolveNamespaceIdForIssue(issue);
434
+ const contractTable = tableAt(ctx.toContract.storage, namespaceId, issue.table);
366
435
  const column = contractTable?.columns[issue.column];
367
436
  if (!column) continue;
368
437
  const notNull = column.nullable !== true;
@@ -379,9 +448,10 @@ const notNullAddColumnCallStrategy = (issues, ctx) => {
379
448
  columnName: issue.column
380
449
  });
381
450
  matched.push(issue);
451
+ const schemaForTable = resolveDdlSchemaForNamespace(ctx, namespaceId);
382
452
  if (canUseSharedTempDefault && temporaryDefault !== null) {
383
453
  calls.push(new RawSqlCall(buildAddNotNullColumnWithTemporaryDefaultOperation({
384
- schema: ctx.schemaName,
454
+ schema: schemaForTable,
385
455
  tableName: issue.table,
386
456
  columnName: issue.column,
387
457
  column,
@@ -391,14 +461,14 @@ const notNullAddColumnCallStrategy = (issues, ctx) => {
391
461
  })));
392
462
  continue;
393
463
  }
394
- const qualified = qualifyTableName(ctx.schemaName, issue.table);
464
+ const qualified = qualifyTableName(schemaForTable, issue.table);
395
465
  calls.push(new RawSqlCall({
396
- ...buildAddColumnOperationIdentity(ctx.schemaName, issue.table, issue.column),
466
+ ...buildAddColumnOperationIdentity(schemaForTable, issue.table, issue.column),
397
467
  operationClass: "additive",
398
468
  precheck: [{
399
469
  description: `ensure column "${issue.column}" is missing`,
400
470
  sql: columnExistsCheck({
401
- schema: ctx.schemaName,
471
+ schema: schemaForTable,
402
472
  table: issue.table,
403
473
  column: issue.column,
404
474
  exists: false
@@ -414,14 +484,14 @@ const notNullAddColumnCallStrategy = (issues, ctx) => {
414
484
  postcheck: [{
415
485
  description: `verify column "${issue.column}" exists`,
416
486
  sql: columnExistsCheck({
417
- schema: ctx.schemaName,
487
+ schema: schemaForTable,
418
488
  table: issue.table,
419
489
  column: issue.column
420
490
  })
421
491
  }, {
422
492
  description: `verify column "${issue.column}" is NOT NULL`,
423
493
  sql: columnNullabilityCheck({
424
- schema: ctx.schemaName,
494
+ schema: schemaForTable,
425
495
  table: issue.table,
426
496
  column: issue.column,
427
497
  nullable: false
@@ -444,7 +514,7 @@ function canUseSharedTemporaryDefaultStrategy(options) {
444
514
  if (!schemaLookup || !hasUniqueConstraint(schemaLookup, unique.columns)) return false;
445
515
  }
446
516
  for (const foreignKey of table.foreignKeys) {
447
- if (foreignKey.constraint === false || !foreignKey.columns.includes(columnName)) continue;
517
+ if (foreignKey.constraint === false || !foreignKey.source.columns.includes(columnName)) continue;
448
518
  if (!schemaLookup || !hasForeignKey(schemaLookup, foreignKey)) return false;
449
519
  }
450
520
  return true;
@@ -489,7 +559,15 @@ const postgresPlannerStrategies = [
489
559
  ];
490
560
  //#endregion
491
561
  //#region src/core/migrations/issue-planner.ts
562
+ function locateNamespaceTypeInStorage(storage, typeName) {
563
+ for (const ns of Object.values(storage.namespaces)) {
564
+ if (!("types" in ns) || ns.types == null) continue;
565
+ const entry = ns.types[typeName];
566
+ if (entry !== void 0) return entry;
567
+ }
568
+ }
492
569
  const ISSUE_KIND_ORDER = {
570
+ missing_schema: 1,
493
571
  type_missing: 2,
494
572
  type_values_mismatch: 3,
495
573
  enum_values_changed: 3,
@@ -536,79 +614,94 @@ function toColumnSpec(name, column, codecHooks, storageTypes) {
536
614
  }
537
615
  function mapIssueToCall(issue, ctx) {
538
616
  const { schemaName, codecHooks, storageTypes } = ctx;
617
+ const tableSchema = (issue) => {
618
+ if (issue.kind === "extra_table") return schemaName;
619
+ if (!("table" in issue) || !issue.table) return schemaName;
620
+ return resolveDdlSchemaForNamespace(ctx, resolveNamespaceIdForIssue(issue));
621
+ };
539
622
  switch (issue.kind) {
623
+ case "missing_schema": {
624
+ const namespaceId = issue.namespaceId;
625
+ if (!namespaceId) return notOk(issueConflict("unsupportedOperation", "Missing schema issue has no namespaceId"));
626
+ return ok([new CreateSchemaCall(resolveDdlSchemaForNamespace(ctx, namespaceId))]);
627
+ }
540
628
  case "missing_table": {
541
629
  if (!issue.table) return notOk(issueConflict("unsupportedOperation", "Missing table issue has no table name"));
542
- const contractTable = ctx.toContract.storage.tables[issue.table];
543
- if (!contractTable) return notOk(issueConflict("unsupportedOperation", `Table "${issue.table}" reported missing but not found in destination contract`));
630
+ const namespaceId = resolveNamespaceIdForIssue(issue);
631
+ const contractTable = tableAt(ctx.toContract.storage, namespaceId, issue.table);
632
+ if (!contractTable) return notOk(issueConflict("unsupportedOperation", `Table "${issue.table}" in namespace "${namespaceId}" reported missing but not found in destination contract`));
633
+ const schemaForTable = tableSchema(issue);
544
634
  const columns = Object.entries(contractTable.columns).map(([name, column]) => toColumnSpec(name, column, codecHooks, storageTypes));
545
635
  const primaryKey = contractTable.primaryKey ? { columns: contractTable.primaryKey.columns } : void 0;
546
- const calls = [new CreateTableCall(schemaName, issue.table, columns, primaryKey)];
636
+ const calls = [new CreateTableCall(schemaForTable, issue.table, columns, primaryKey)];
547
637
  for (const index of contractTable.indexes) {
548
638
  const indexName = index.name ?? `${issue.table}_${index.columns.join("_")}_idx`;
549
639
  const extras = {};
550
640
  if (index.type !== void 0) extras.type = index.type;
551
641
  if (index.options !== void 0) extras.options = index.options;
552
- calls.push(new CreateIndexCall(schemaName, issue.table, indexName, [...index.columns], extras));
642
+ calls.push(new CreateIndexCall(schemaForTable, issue.table, indexName, [...index.columns], extras));
553
643
  }
554
644
  const explicitIndexColumnSets = new Set(contractTable.indexes.map((idx) => idx.columns.join(",")));
555
645
  for (const fk of contractTable.foreignKeys) {
556
646
  if (fk.constraint) {
557
647
  const fkSpec = {
558
- name: fk.name ?? `${issue.table}_${fk.columns.join("_")}_fkey`,
559
- columns: fk.columns,
648
+ name: fk.name ?? `${issue.table}_${fk.source.columns.join("_")}_fkey`,
649
+ columns: fk.source.columns,
560
650
  references: {
561
- table: fk.references.table,
562
- columns: fk.references.columns
651
+ schema: fk.target.namespaceId,
652
+ table: fk.target.tableName,
653
+ columns: fk.target.columns
563
654
  },
564
655
  ...fk.onDelete !== void 0 && { onDelete: fk.onDelete },
565
656
  ...fk.onUpdate !== void 0 && { onUpdate: fk.onUpdate }
566
657
  };
567
- calls.push(new AddForeignKeyCall(schemaName, issue.table, fkSpec));
658
+ calls.push(new AddForeignKeyCall(schemaForTable, issue.table, fkSpec));
568
659
  }
569
- if (fk.index && !explicitIndexColumnSets.has(fk.columns.join(","))) {
570
- const indexName = `${issue.table}_${fk.columns.join("_")}_idx`;
571
- calls.push(new CreateIndexCall(schemaName, issue.table, indexName, [...fk.columns]));
660
+ if (fk.index && !explicitIndexColumnSets.has(fk.source.columns.join(","))) {
661
+ const indexName = `${issue.table}_${fk.source.columns.join("_")}_idx`;
662
+ calls.push(new CreateIndexCall(schemaForTable, issue.table, indexName, [...fk.source.columns]));
572
663
  }
573
664
  }
574
665
  for (const unique of contractTable.uniques) {
575
666
  const constraintName = unique.name ?? `${issue.table}_${unique.columns.join("_")}_key`;
576
- calls.push(new AddUniqueCall(schemaName, issue.table, constraintName, [...unique.columns]));
667
+ calls.push(new AddUniqueCall(schemaForTable, issue.table, constraintName, [...unique.columns]));
577
668
  }
578
669
  return ok(calls);
579
670
  }
580
671
  case "missing_column":
581
672
  if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Missing column issue has no table/column name"));
582
673
  {
583
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
674
+ const namespaceId = resolveNamespaceIdForIssue(issue);
675
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
584
676
  if (!column) return notOk(issueConflict("unsupportedOperation", `Column "${issue.table}"."${issue.column}" not in destination contract`));
585
- return ok([new AddColumnCall(schemaName, issue.table, toColumnSpec(issue.column, column, codecHooks, storageTypes))]);
677
+ return ok([new AddColumnCall(tableSchema(issue), issue.table, toColumnSpec(issue.column, column, codecHooks, storageTypes))]);
586
678
  }
587
679
  case "default_missing":
588
680
  if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Default missing issue has no table/column name"));
589
681
  {
590
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
682
+ const namespaceId = resolveNamespaceIdForIssue(issue);
683
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
591
684
  if (!column?.default) return notOk(issueConflict("unsupportedOperation", `Column "${issue.table}"."${issue.column}" has no default in contract`));
592
685
  const defaultSql = buildColumnDefaultSql(column.default, column);
593
686
  if (!defaultSql) return ok([]);
594
- return ok([new SetDefaultCall(schemaName, issue.table, issue.column, defaultSql)]);
687
+ return ok([new SetDefaultCall(tableSchema(issue), issue.table, issue.column, defaultSql)]);
595
688
  }
596
689
  case "extra_table":
597
690
  if (!issue.table) return notOk(issueConflict("unsupportedOperation", "Extra table issue has no table name"));
598
- return ok([new DropTableCall(schemaName, issue.table)]);
691
+ return ok([new DropTableCall(tableSchema(issue), issue.table)]);
599
692
  case "extra_column":
600
693
  if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Extra column issue has no table/column name"));
601
- return ok([new DropColumnCall(schemaName, issue.table, issue.column)]);
694
+ return ok([new DropColumnCall(tableSchema(issue), issue.table, issue.column)]);
602
695
  case "extra_index":
603
696
  if (!issue.table || !issue.indexOrConstraint) return notOk(issueConflict("unsupportedOperation", "Extra index issue has no table/index name"));
604
- return ok([new DropIndexCall(schemaName, issue.table, issue.indexOrConstraint)]);
697
+ return ok([new DropIndexCall(tableSchema(issue), issue.table, issue.indexOrConstraint)]);
605
698
  case "extra_unique_constraint":
606
699
  case "extra_foreign_key":
607
700
  case "extra_primary_key": {
608
701
  if (!issue.table) return notOk(issueConflict("unsupportedOperation", "Extra constraint issue has no table/constraint name"));
609
702
  const constraintName = issue.indexOrConstraint ?? (issue.kind === "extra_primary_key" ? `${issue.table}_pkey` : void 0);
610
703
  if (!constraintName) return notOk(issueConflict("unsupportedOperation", "Extra constraint issue has no table/constraint name"));
611
- return ok([new DropConstraintCall(schemaName, issue.table, constraintName, {
704
+ return ok([new DropConstraintCall(tableSchema(issue), issue.table, constraintName, {
612
705
  extra_unique_constraint: "unique",
613
706
  extra_foreign_key: "foreignKey",
614
707
  extra_primary_key: "primaryKey"
@@ -616,23 +709,26 @@ function mapIssueToCall(issue, ctx) {
616
709
  }
617
710
  case "extra_default":
618
711
  if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Extra default issue has no table/column name"));
619
- return ok([new DropDefaultCall(schemaName, issue.table, issue.column)]);
712
+ return ok([new DropDefaultCall(tableSchema(issue), issue.table, issue.column)]);
620
713
  case "nullability_mismatch": {
621
714
  if (!issue.table || !issue.column) return notOk(issueConflict("nullabilityConflict", "Nullability mismatch has no table/column name"));
622
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
715
+ const namespaceId = resolveNamespaceIdForIssue(issue);
716
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
623
717
  if (!column) return notOk(issueConflict("nullabilityConflict", `Column "${issue.table}"."${issue.column}" not found in destination contract`));
624
- return ok(column.nullable ? [new DropNotNullCall(schemaName, issue.table, issue.column)] : [new SetNotNullCall(schemaName, issue.table, issue.column)]);
718
+ const schemaForTable = tableSchema(issue);
719
+ return ok(column.nullable ? [new DropNotNullCall(schemaForTable, issue.table, issue.column)] : [new SetNotNullCall(schemaForTable, issue.table, issue.column)]);
625
720
  }
626
721
  case "type_mismatch":
627
722
  if (!issue.table || !issue.column) return notOk(issueConflict("typeMismatch", "Type mismatch has no table/column name"));
628
723
  {
629
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
724
+ const namespaceId = resolveNamespaceIdForIssue(issue);
725
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
630
726
  if (!column) return notOk(issueConflict("typeMismatch", `Column "${issue.table}"."${issue.column}" not in destination contract`));
631
727
  const hooksMap = codecHooks;
632
728
  const typesMap = storageTypes;
633
729
  const qualifiedTargetType = buildColumnTypeSql(column, hooksMap, typesMap, false);
634
730
  const formatTypeExpected = buildExpectedFormatType(column, hooksMap, typesMap);
635
- return ok([new AlterColumnTypeCall(schemaName, issue.table, issue.column, {
731
+ return ok([new AlterColumnTypeCall(tableSchema(issue), issue.table, issue.column, {
636
732
  qualifiedTargetType,
637
733
  formatTypeExpected,
638
734
  rawTargetTypeForLabel: qualifiedTargetType
@@ -641,19 +737,21 @@ function mapIssueToCall(issue, ctx) {
641
737
  case "default_mismatch":
642
738
  if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Default mismatch has no table/column name"));
643
739
  {
644
- const column = ctx.toContract.storage.tables[issue.table]?.columns[issue.column];
740
+ const namespaceId = resolveNamespaceIdForIssue(issue);
741
+ const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
645
742
  if (!column?.default) return ok([]);
646
743
  const defaultSql = buildColumnDefaultSql(column.default, column);
647
744
  if (!defaultSql) return ok([]);
648
- return ok([new SetDefaultCall(schemaName, issue.table, issue.column, defaultSql, "widening")]);
745
+ return ok([new SetDefaultCall(tableSchema(issue), issue.table, issue.column, defaultSql, "widening")]);
649
746
  }
650
747
  case "primary_key_mismatch":
651
748
  if (!issue.table) return notOk(issueConflict("indexIncompatible", "Primary key issue has no table name"));
652
749
  if (isMissing(issue)) {
653
- const pk = ctx.toContract.storage.tables[issue.table]?.primaryKey;
750
+ const namespaceId = resolveNamespaceIdForIssue(issue);
751
+ const pk = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.primaryKey;
654
752
  if (!pk) return notOk(issueConflict("indexIncompatible", `No primary key in contract for "${issue.table}"`));
655
753
  const constraintName = pk.name ?? `${issue.table}_pkey`;
656
- return ok([new AddPrimaryKeyCall(schemaName, issue.table, constraintName, pk.columns)]);
754
+ return ok([new AddPrimaryKeyCall(tableSchema(issue), issue.table, constraintName, pk.columns)]);
657
755
  }
658
756
  return notOk(issueConflict("indexIncompatible", `Primary key on "${issue.table}" has different columns (expected: ${issue.expected}, actual: ${issue.actual})`, { table: issue.table }));
659
757
  case "unique_constraint_mismatch":
@@ -661,19 +759,20 @@ function mapIssueToCall(issue, ctx) {
661
759
  if (isMissing(issue) && issue.expected) {
662
760
  const columns = issue.expected.split(", ");
663
761
  const constraintName = `${issue.table}_${columns.join("_")}_key`;
664
- return ok([new AddUniqueCall(schemaName, issue.table, constraintName, columns)]);
762
+ return ok([new AddUniqueCall(tableSchema(issue), issue.table, constraintName, columns)]);
665
763
  }
666
764
  return notOk(issueConflict("indexIncompatible", `Unique constraint on "${issue.table}" differs (expected: ${issue.expected}, actual: ${issue.actual})`, { table: issue.table }));
667
765
  case "index_mismatch":
668
766
  if (!issue.table) return notOk(issueConflict("indexIncompatible", "Index issue has no table name"));
669
767
  if (isMissing(issue) && issue.expected) {
768
+ const namespaceId = resolveNamespaceIdForIssue(issue);
670
769
  const columns = issue.expected.split(", ");
671
- const contractIndex = ctx.toContract.storage.tables[issue.table]?.indexes.find((idx) => arraysEqual(idx.columns, columns));
770
+ const contractIndex = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.indexes.find((idx) => arraysEqual(idx.columns, columns));
672
771
  const indexName = contractIndex?.name ?? `${issue.table}_${columns.join("_")}_idx`;
673
772
  const extras = {};
674
773
  if (contractIndex?.type !== void 0) extras.type = contractIndex.type;
675
774
  if (contractIndex?.options !== void 0) extras.options = contractIndex.options;
676
- return ok([new CreateIndexCall(schemaName, issue.table, indexName, columns, extras)]);
775
+ return ok([new CreateIndexCall(tableSchema(issue), issue.table, indexName, columns, extras)]);
677
776
  }
678
777
  return notOk(issueConflict("indexIncompatible", `Index on "${issue.table}" differs (expected: ${issue.expected}, actual: ${issue.actual})`, { table: issue.table }));
679
778
  case "foreign_key_mismatch":
@@ -681,21 +780,23 @@ function mapIssueToCall(issue, ctx) {
681
780
  if (isMissing(issue) && issue.expected) {
682
781
  const arrowIdx = issue.expected.indexOf(" -> ");
683
782
  if (arrowIdx >= 0) {
783
+ const namespaceId = resolveNamespaceIdForIssue(issue);
684
784
  const columns = issue.expected.slice(0, arrowIdx).split(", ");
685
785
  const fkName = `${issue.table}_${columns.join("_")}_fkey`;
686
- const fk = ctx.toContract.storage.tables[issue.table]?.foreignKeys.find((k) => k.columns.join(", ") === columns.join(", "));
786
+ const fk = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.foreignKeys.find((k) => k.source.columns.join(", ") === columns.join(", "));
687
787
  if (fk) {
688
788
  const fkSpec = {
689
789
  name: fkName,
690
- columns: fk.columns,
790
+ columns: fk.source.columns,
691
791
  references: {
692
- table: fk.references.table,
693
- columns: fk.references.columns
792
+ schema: fk.target.namespaceId,
793
+ table: fk.target.tableName,
794
+ columns: fk.target.columns
694
795
  },
695
796
  ...fk.onDelete !== void 0 && { onDelete: fk.onDelete },
696
797
  ...fk.onUpdate !== void 0 && { onUpdate: fk.onUpdate }
697
798
  };
698
- return ok([new AddForeignKeyCall(schemaName, issue.table, fkSpec)]);
799
+ return ok([new AddForeignKeyCall(tableSchema(issue), issue.table, fkSpec)]);
699
800
  }
700
801
  return notOk(issueConflict("foreignKeyConflict", `Foreign key on "${issue.table}" (${columns.join(", ")}) not found in destination contract`, { table: issue.table }));
701
802
  }
@@ -703,10 +804,11 @@ function mapIssueToCall(issue, ctx) {
703
804
  return notOk(issueConflict("foreignKeyConflict", `Foreign key on "${issue.table}" differs (expected: ${issue.expected}, actual: ${issue.actual})`, { table: issue.table }));
704
805
  case "type_missing": {
705
806
  if (!issue.typeName) return notOk(issueConflict("unsupportedOperation", "Type missing issue has no typeName"));
706
- const typeInstance = ctx.toContract.storage.types?.[issue.typeName];
807
+ const typeInstance = ctx.toContract.storage.types?.[issue.typeName] ?? locateNamespaceTypeInStorage(ctx.toContract.storage, issue.typeName);
707
808
  if (!typeInstance) return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" reported missing but not found in destination contract`));
708
809
  if (typeInstance instanceof PostgresEnumType) return ok([new CreateEnumTypeCall(schemaName, issue.typeName, typeInstance.values, typeInstance.nativeType)]);
709
- return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${typeInstance.codecId}" — only enum types are supported`));
810
+ const codecInstance = typeInstance;
811
+ return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${codecInstance.codecId}" — only enum types are supported`));
710
812
  }
711
813
  case "type_values_mismatch": return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName ?? "unknown"}" values differ — type alteration not yet supported`));
712
814
  default: return notOk(issueConflict("unsupportedOperation", `Unhandled issue kind: ${issue.kind}`));
@@ -874,4 +976,4 @@ function planIssues(options) {
874
976
  //#endregion
875
977
  export { postgresPlannerStrategies as n, planIssues as t };
876
978
 
877
- //# sourceMappingURL=issue-planner-BhWVYyE1.mjs.map
979
+ //# sourceMappingURL=issue-planner-qalHRCI2.mjs.map