@prisma-next/family-sql 0.14.0-dev.5 → 0.14.0-dev.50

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 (79) hide show
  1. package/dist/{authoring-type-constructors-CjFfO6LM.mjs → authoring-type-constructors-CXd-8ydc.mjs} +7 -30
  2. package/dist/authoring-type-constructors-CXd-8ydc.mjs.map +1 -0
  3. package/dist/{control-adapter-Cmw9LvEP.d.mts → control-adapter-BVOj4gXI.d.mts} +42 -8
  4. package/dist/control-adapter-BVOj4gXI.d.mts.map +1 -0
  5. package/dist/control-adapter.d.mts +1 -1
  6. package/dist/control.d.mts +238 -6
  7. package/dist/control.d.mts.map +1 -1
  8. package/dist/control.mjs +336 -942
  9. package/dist/control.mjs.map +1 -1
  10. package/dist/diff.d.mts +150 -0
  11. package/dist/diff.d.mts.map +1 -0
  12. package/dist/diff.mjs +188 -0
  13. package/dist/diff.mjs.map +1 -0
  14. package/dist/ir.d.mts +26 -9
  15. package/dist/ir.d.mts.map +1 -1
  16. package/dist/ir.mjs +2 -2
  17. package/dist/ir.mjs.map +1 -1
  18. package/dist/migration.d.mts +11 -2
  19. package/dist/migration.d.mts.map +1 -1
  20. package/dist/migration.mjs +7 -0
  21. package/dist/migration.mjs.map +1 -1
  22. package/dist/pack.mjs +1 -1
  23. package/dist/psl-infer.d.mts +101 -0
  24. package/dist/psl-infer.d.mts.map +1 -0
  25. package/dist/psl-infer.mjs +342 -0
  26. package/dist/psl-infer.mjs.map +1 -0
  27. package/dist/schema-differ-DnoopSXm.d.mts +45 -0
  28. package/dist/schema-differ-DnoopSXm.d.mts.map +1 -0
  29. package/dist/schema-verify-W3r631Jh.mjs +226 -0
  30. package/dist/schema-verify-W3r631Jh.mjs.map +1 -0
  31. package/dist/{sql-contract-serializer-BR2vC7Z-.mjs → sql-contract-serializer-C75cfMSS.mjs} +46 -20
  32. package/dist/sql-contract-serializer-C75cfMSS.mjs.map +1 -0
  33. package/dist/{types-kgstZ_Zd.d.mts → types-BW7pzb2j.d.mts} +34 -139
  34. package/dist/types-BW7pzb2j.d.mts.map +1 -0
  35. package/package.json +23 -23
  36. package/src/core/authoring-entity-types.ts +12 -37
  37. package/src/core/control-adapter.ts +10 -5
  38. package/src/core/control-instance.ts +210 -42
  39. package/src/core/control-target-descriptor.ts +98 -0
  40. package/src/core/diff/diff-tree-normalization.ts +211 -0
  41. package/src/core/diff/schema-verify.ts +324 -0
  42. package/src/core/diff/sql-schema-diff.ts +77 -0
  43. package/src/core/diff/verifier-disposition.ts +30 -0
  44. package/src/core/ir/sql-contract-serializer-base.ts +70 -56
  45. package/src/core/ir/sql-contract-serializer.ts +5 -7
  46. package/src/core/ir/sql-schema-verifier-base.ts +5 -5
  47. package/src/core/migrations/contract-to-schema-ir.ts +110 -30
  48. package/src/core/migrations/field-event-planner.ts +2 -2
  49. package/src/core/migrations/native-type-expander.ts +28 -0
  50. package/src/core/migrations/schema-differ.ts +41 -0
  51. package/src/core/migrations/types.ts +31 -34
  52. package/src/core/psl-contract-infer/printer-config.ts +12 -6
  53. package/src/core/psl-contract-infer/relation-inference.ts +9 -1
  54. package/src/core/sql-migration.ts +12 -1
  55. package/src/exports/control.ts +11 -1
  56. package/src/exports/diff.ts +38 -0
  57. package/src/exports/psl-infer.ts +39 -0
  58. package/dist/authoring-type-constructors-CjFfO6LM.mjs.map +0 -1
  59. package/dist/control-adapter-Cmw9LvEP.d.mts.map +0 -1
  60. package/dist/schema-verify.d.mts +0 -39
  61. package/dist/schema-verify.d.mts.map +0 -1
  62. package/dist/schema-verify.mjs +0 -2
  63. package/dist/sql-contract-serializer-BR2vC7Z-.mjs.map +0 -1
  64. package/dist/test-utils.d.mts +0 -2
  65. package/dist/test-utils.mjs +0 -2
  66. package/dist/types-kgstZ_Zd.d.mts.map +0 -1
  67. package/dist/verify-sql-schema-thU-jKpf.d.mts +0 -66
  68. package/dist/verify-sql-schema-thU-jKpf.d.mts.map +0 -1
  69. package/dist/verify-sql-schema-xT4udQLQ.mjs +0 -1501
  70. package/dist/verify-sql-schema-xT4udQLQ.mjs.map +0 -1
  71. package/src/core/psl-contract-infer/postgres-default-mapping.ts +0 -16
  72. package/src/core/psl-contract-infer/postgres-type-map.ts +0 -157
  73. package/src/core/psl-contract-infer/sql-schema-ir-to-psl-ast.ts +0 -795
  74. package/src/core/schema-verify/control-verify-emit.ts +0 -46
  75. package/src/core/schema-verify/verifier-disposition.ts +0 -58
  76. package/src/core/schema-verify/verify-helpers.ts +0 -820
  77. package/src/core/schema-verify/verify-sql-schema.ts +0 -1311
  78. package/src/exports/schema-verify.ts +0 -18
  79. package/src/exports/test-utils.ts +0 -9
@@ -0,0 +1,150 @@
1
+ import { a as NativeTypeNormalizer, c as isUniqueConstraintSatisfied, o as arraysEqual, s as isIndexSatisfied } from "./control-adapter-BVOj4gXI.mjs";
2
+ import { n as CodecControlHooks } from "./types-BW7pzb2j.mjs";
3
+ import { t as SqlSchemaDiffFn } from "./schema-differ-DnoopSXm.mjs";
4
+ import { DiffSubjectGranularity, SchemaDiffIssue, VerifierIssueCategory, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
5
+ import { Contract, ControlPolicy } from "@prisma-next/contract/types";
6
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
7
+ import { SqlIndexIR, SqlSchemaIR, SqlSchemaIRNode, SqlUniqueIR } from "@prisma-next/sql-schema-ir/types";
8
+ import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
9
+
10
+ //#region src/core/diff/diff-tree-normalization.d.ts
11
+ interface SemanticSatisfactionInput {
12
+ readonly expectedUniques: readonly SqlUniqueIR[];
13
+ readonly expectedIndexes: readonly SqlIndexIR[];
14
+ readonly actualUniques: readonly SqlUniqueIR[];
15
+ readonly actualIndexes: readonly SqlIndexIR[];
16
+ }
17
+ interface SemanticSatisfactionResult {
18
+ readonly actualUniques: readonly SqlUniqueIR[];
19
+ readonly actualIndexes: readonly SqlIndexIR[];
20
+ }
21
+ /**
22
+ * Adjusts a table pair's ACTUAL unique/index child lists so the legacy
23
+ * walk's cross-kind semantic satisfaction materializes as same-kind node
24
+ * pairs for the differ (the differ pairs strictly by id, so a `unique:`
25
+ * node can never pair with an `index:` node). Three legacy rules, ported
26
+ * from `isUniqueConstraintSatisfied` / `isIndexSatisfied` and the
27
+ * strict-extras loops of the retired relational walk:
28
+ *
29
+ * 1. A contract unique satisfied by a live unique INDEX: the actual index
30
+ * node is reclassified as a unique node (it pairs with the expected
31
+ * unique and stops being a candidate extra).
32
+ * 2. A contract index (with no type/options demands) satisfied by a live
33
+ * unique CONSTRAINT: a same-kind actual index node is synthesized so
34
+ * the expected index pairs — the unique constraint itself stays (the
35
+ * legacy strict-extras loop still reports it as an undeclared unique).
36
+ * 3. Live unique indexes are never extras in the legacy walk (its
37
+ * strict-extras loop skips `unique: true` rows), so any remaining
38
+ * actual unique-index node with no expected index counterpart is
39
+ * dropped rather than surfacing as `not-expected`.
40
+ */
41
+ declare function resolveSemanticSatisfaction(input: SemanticSatisfactionInput): SemanticSatisfactionResult;
42
+ /**
43
+ * Applies {@link resolveSemanticSatisfaction} across a flat table pair set:
44
+ * every actual table with an expected counterpart gets its unique/index
45
+ * child lists adjusted; unpaired tables pass through untouched.
46
+ */
47
+ declare function normalizeFlatActualForDiff(expected: SqlSchemaIR, actual: SqlSchemaIR): SqlSchemaIR;
48
+ /**
49
+ * Neutralizes the FK schema segment on a flat expected tree so its FK diff
50
+ * nodes pair with introspected FKs on single-schema targets: the family
51
+ * converter stamps `referencedSchema` with the contract namespace id
52
+ * verbatim (the unbound sentinel on non-namespaced targets), while a
53
+ * single-schema introspection stamps none — resolving both sides to the
54
+ * empty segment makes the ids meet.
55
+ */
56
+ declare function neutralizeFlatExpectedFkSchemas(expected: SqlSchemaIR): SqlSchemaIR;
57
+ //#endregion
58
+ //#region src/core/diff/schema-verify.d.ts
59
+ /**
60
+ * Resolves an issue's framework-neutral {@link DiffSubjectGranularity} on
61
+ * demand, from the issue's node's `nodeKind` via the target-provided
62
+ * `granularityOf` map. The node carries only its `nodeKind` identity, never a
63
+ * classification, and nothing is stamped onto the issue — every consumer
64
+ * (the family verdict below, the framework aggregate's unclaimed-elements
65
+ * sweep via {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable})
66
+ * calls this the same way, resolved by the family/target that owns the node
67
+ * vocabulary. `undefined` for an issue with no node.
68
+ */
69
+ declare function classifyDiffSubjectGranularity(issue: SchemaDiffIssue, granularityOf: (nodeKind: string) => DiffSubjectGranularity): DiffSubjectGranularity | undefined;
70
+ /**
71
+ * Re-keys the legacy `classifySqlVerifierIssueKind` category mapping on the
72
+ * issue's {@link DiffSubjectGranularity} (resolved via `granularityOf`) + the
73
+ * issue reason. The vocabulary maps one-to-one: an undeclared live entity or
74
+ * namespace is `extraTopLevelObject`, an undeclared live field
75
+ * `extraNestedElement`, undeclared auxiliaries (constraints, indexes,
76
+ * defaults) and structural leaves (policies) `extraAuxiliary`; a value-set
77
+ * drift on a check node is `valueDrift`; every other paired divergence is
78
+ * `declaredIncompatible`; anything the database lacks is `declaredMissing`.
79
+ * `granularityOf` is the target's classifier, so target and extension node
80
+ * kinds classify without the family importing them.
81
+ */
82
+ declare function classifySqlDiffIssue(issue: SchemaDiffIssue, granularityOf: (nodeKind: string) => DiffSubjectGranularity): VerifierIssueCategory;
83
+ interface SqlDiffVerdictInput {
84
+ /** The full, ownership-scoped diff issue list from the target's differ. */
85
+ readonly issues: readonly SchemaDiffIssue[];
86
+ /** Resolves a diff issue's subject table's declared control policy directly from the contract. */
87
+ readonly resolveControlPolicy: (issue: SchemaDiffIssue) => ControlPolicy | undefined;
88
+ readonly strict: boolean;
89
+ readonly defaultControlPolicy: ControlPolicy | undefined;
90
+ /** The target's classifier: a diff issue node's `nodeKind` → its subject granularity. */
91
+ readonly granularityOf: (nodeKind: string) => DiffSubjectGranularity;
92
+ }
93
+ interface SqlDiffVerdict {
94
+ readonly failures: readonly SchemaDiffIssue[];
95
+ readonly warnings: readonly SchemaDiffIssue[];
96
+ }
97
+ /**
98
+ * Applies the two consumer filters to a diff issue list: strict gating
99
+ * (relational `not-expected` findings drop in lenient mode) and
100
+ * control-policy disposition (each surviving issue grades against its
101
+ * subject table's effective policy; suppressed issues drop, `observed`
102
+ * subjects warn). The verify verdict is `failures.length === 0`.
103
+ */
104
+ declare function computeSqlDiffVerdict(input: SqlDiffVerdictInput): SqlDiffVerdict;
105
+ interface StorageTypeVerdictInput {
106
+ readonly contract: Contract<SqlStorage>;
107
+ /**
108
+ * Expected/actual namespace-node pairs the target's differ input produced:
109
+ * for a namespaced tree, one entry per expected namespace with a
110
+ * non-empty table set, paired by DDL schema name (absent actual side for
111
+ * a schema the database lacks); a flat tree is the sole pair.
112
+ */
113
+ readonly namespacePairs: ReadonlyArray<{
114
+ readonly actual: SqlSchemaIRNode | undefined;
115
+ }>;
116
+ readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;
117
+ }
118
+ /**
119
+ * Runs the codec `verifyType` hooks the way the legacy walk did: once per
120
+ * contract namespace with tables, against that namespace's paired actual
121
+ * node (the hook reads namespace-scoped state such as
122
+ * `nativeEnumTypeNames` off it). Issue dispositions grade against the
123
+ * contract default policy, matching the legacy `pushTypeNode` semantics.
124
+ */
125
+ interface StorageTypeVerdict {
126
+ readonly failures: readonly SchemaDiffIssue[];
127
+ readonly warnings: readonly SchemaDiffIssue[];
128
+ }
129
+ declare function computeStorageTypeVerdict(input: StorageTypeVerdictInput): StorageTypeVerdict;
130
+ interface VerifySqlSchemaByDiffInput {
131
+ readonly contract: Contract<SqlStorage>;
132
+ readonly schema: SqlSchemaIRNode;
133
+ readonly strict: boolean;
134
+ readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
135
+ /** The target's full-tree node diff (`diffSchema` descriptor hook). */
136
+ readonly diffSchema: SqlSchemaDiffFn;
137
+ /** The target's classifier: a diff issue node's `nodeKind` → its subject granularity. */
138
+ readonly granularityOf: (nodeKind: string) => DiffSubjectGranularity;
139
+ }
140
+ /**
141
+ * THE SQL schema verify: runs the target's full-tree node diff, grades it
142
+ * through the family's post-diff filters (strict gating + control-policy
143
+ * disposition) plus the codec `verifyType` hook findings, and wraps the
144
+ * verdict in the issue-based result envelope. `ok` holds exactly when both
145
+ * issue lists are empty — the lists carry the verdict's failures.
146
+ */
147
+ declare function verifySqlSchemaByDiff(input: VerifySqlSchemaByDiffInput): VerifyDatabaseSchemaResult;
148
+ //#endregion
149
+ export { type NativeTypeNormalizer, type SemanticSatisfactionInput, type SemanticSatisfactionResult, type SqlDiffVerdict, type SqlDiffVerdictInput, type StorageTypeVerdict, type StorageTypeVerdictInput, type VerifySqlSchemaByDiffInput, arraysEqual, classifyDiffSubjectGranularity, classifySqlDiffIssue, computeSqlDiffVerdict, computeStorageTypeVerdict, isIndexSatisfied, isUniqueConstraintSatisfied, neutralizeFlatExpectedFkSchemas, normalizeFlatActualForDiff, resolveSemanticSatisfaction, verifySqlSchemaByDiff };
150
+ //# sourceMappingURL=diff.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.mts","names":[],"sources":["../src/core/diff/diff-tree-normalization.ts","../src/core/diff/schema-verify.ts"],"mappings":";;;;;;;;;;UAqCiB,yBAAA;EAAA,SACN,eAAA,WAA0B,WAAA;EAAA,SAC1B,eAAA,WAA0B,UAAA;EAAA,SAC1B,aAAA,WAAwB,WAAA;EAAA,SACxB,aAAA,WAAwB,UAAA;AAAA;AAAA,UAGlB,0BAAA;EAAA,SACN,aAAA,WAAwB,WAAA;EAAA,SACxB,aAAA,WAAwB,UAAU;AAAA;;;;;AAAA;AA2B7C;;;;;;;;AAE6B;AAyD7B;;;;;;iBA3DgB,2BAAA,CACd,KAAA,EAAO,yBAAA,GACN,0BAA0B;;;;;;iBAyDb,0BAAA,CACd,QAAA,EAAU,WAAA,EACV,MAAA,EAAQ,WAAA,GACP,WAAA;;AAAW;AAuCd;;;;;;iBAAgB,+BAAA,CAAgC,QAAA,EAAU,WAAA,GAAc,WAAW;;;;;;;;;;AArItC;AAG7C;;iBCcgB,8BAAA,CACd,KAAA,EAAO,eAAA,EACP,aAAA,GAAgB,QAAA,aAAqB,sBAAA,GACpC,sBAAA;;;;;;ADc0B;AAyD7B;;;;;;iBCjCgB,oBAAA,CACd,KAAA,EAAO,eAAA,EACP,aAAA,GAAgB,QAAA,aAAqB,sBAAA,GACpC,qBAAA;AAAA,UA4Cc,mBAAA;EDbL;EAAA,SCeD,MAAA,WAAiB,eAAA;EDdlB;EAAA,SCgBC,oBAAA,GAAuB,KAAA,EAAO,eAAA,KAAoB,aAAA;EAAA,SAClD,MAAA;EAAA,SACA,oBAAA,EAAsB,aAAA;EDjBnB;EAAA,SCmBH,aAAA,GAAgB,QAAA,aAAqB,sBAAA;AAAA;AAAA,UAG/B,cAAA;EAAA,SACN,QAAA,WAAmB,eAAA;EAAA,SACnB,QAAA,WAAmB,eAAe;AAAA;;;ADesC;;;;ACpHnF;iBA+GgB,qBAAA,CAAsB,KAAA,EAAO,mBAAA,GAAsB,cAAc;AAAA,UA+BhE,uBAAA;EAAA,SACN,QAAA,EAAU,QAAA,CAAS,UAAA;EA7IS;;;;;;EAAA,SAoJ5B,cAAA,EAAgB,aAAA;IAAA,SACd,MAAA,EAAQ,eAAA;EAAA;EAAA,SAEV,UAAA,EAAY,WAAA,SAAoB,iBAAA;AAAA;AAtJlB;AAsCzB;;;;;;AAtCyB,UAgKR,kBAAA;EAAA,SACN,QAAA,WAAmB,eAAA;EAAA,SACnB,QAAA,WAAmB,eAAe;AAAA;AAAA,iBAG7B,yBAAA,CAA0B,KAAA,EAAO,uBAAA,GAA0B,kBAAkB;AAAA,UA6B5E,0BAAA;EAAA,SACN,QAAA,EAAU,QAAA,CAAS,UAAA;EAAA,SACnB,MAAA,EAAQ,eAAA;EAAA,SACR,MAAA;EAAA,SACA,mBAAA,EAAqB,aAAA,CAAc,8BAAA;EAjH7B;EAAA,SAmHN,UAAA,EAAY,eAAA;;WAEZ,aAAA,GAAgB,QAAA,aAAqB,sBAAA;AAAA;;;;;;;;iBAUhC,qBAAA,CACd,KAAA,EAAO,0BAAA,GACN,0BAA0B"}
package/dist/diff.mjs ADDED
@@ -0,0 +1,188 @@
1
+ import { a as computeStorageTypeVerdict, i as computeSqlDiffVerdict, n as classifyDiffSubjectGranularity, o as verifySqlSchemaByDiff, r as classifySqlDiffIssue } from "./schema-verify-W3r631Jh.mjs";
2
+ import { SqlForeignKeyIR, SqlIndexIR, SqlSchemaIR, SqlTableIR, SqlUniqueIR } from "@prisma-next/sql-schema-ir/types";
3
+ //#region src/core/diff/diff-tree-normalization.ts
4
+ /**
5
+ * ⚠️ ACCEPTED-UNDER-PROTEST DEBT — DELETE IN SLICE 2.6 (`unify-unique-and-index-nodes`).
6
+ *
7
+ * A unique constraint IS a unique index. This slice modeled uniques and indexes
8
+ * as two separate node kinds (`SqlUniqueIR` vs `SqlIndexIR` — even though
9
+ * `SqlIndexIR` already carries `unique: boolean`), so the strict-by-kind differ
10
+ * cannot pair a contract unique with a live unique index. This whole file
11
+ * exists only to reconcile those two representations after the fact — it
12
+ * should not exist.
13
+ *
14
+ * The fix — delete `SqlUniqueIR`, model unique enforcement as
15
+ * `SqlIndexIR { unique: true }` on both derivation and introspection, and
16
+ * delete `diff-tree-normalization.ts` — is specified in
17
+ * `projects/postgres-rls/slices/unify-unique-and-index-nodes/spec.md` and
18
+ * scheduled as the very next slice. Do NOT extend this.
19
+ */
20
+ /**
21
+ * Pre-diff tree normalization: adjustments to the actual/expected trees the
22
+ * generic differ (`diffSchemas`) runs over, so legacy semantic-equivalence
23
+ * rules (a unique constraint satisfied by a unique index, an FK schema
24
+ * segment that differs only in spelling) surface as same-kind node pairs
25
+ * instead of spurious drift.
26
+ */
27
+ function sameColumns(a, b) {
28
+ return a.length === b.length && a.every((c, i) => c === b[i]);
29
+ }
30
+ /**
31
+ * Adjusts a table pair's ACTUAL unique/index child lists so the legacy
32
+ * walk's cross-kind semantic satisfaction materializes as same-kind node
33
+ * pairs for the differ (the differ pairs strictly by id, so a `unique:`
34
+ * node can never pair with an `index:` node). Three legacy rules, ported
35
+ * from `isUniqueConstraintSatisfied` / `isIndexSatisfied` and the
36
+ * strict-extras loops of the retired relational walk:
37
+ *
38
+ * 1. A contract unique satisfied by a live unique INDEX: the actual index
39
+ * node is reclassified as a unique node (it pairs with the expected
40
+ * unique and stops being a candidate extra).
41
+ * 2. A contract index (with no type/options demands) satisfied by a live
42
+ * unique CONSTRAINT: a same-kind actual index node is synthesized so
43
+ * the expected index pairs — the unique constraint itself stays (the
44
+ * legacy strict-extras loop still reports it as an undeclared unique).
45
+ * 3. Live unique indexes are never extras in the legacy walk (its
46
+ * strict-extras loop skips `unique: true` rows), so any remaining
47
+ * actual unique-index node with no expected index counterpart is
48
+ * dropped rather than surfacing as `not-expected`.
49
+ */
50
+ function resolveSemanticSatisfaction(input) {
51
+ let actualIndexes = [...input.actualIndexes];
52
+ const actualUniques = [...input.actualUniques];
53
+ for (const expectedUnique of input.expectedUniques) {
54
+ if (actualUniques.some((u) => sameColumns(u.columns, expectedUnique.columns))) continue;
55
+ const satisfyingIndex = actualIndexes.find((idx) => idx.unique && sameColumns(idx.columns, expectedUnique.columns));
56
+ if (satisfyingIndex) {
57
+ actualIndexes = actualIndexes.filter((idx) => idx !== satisfyingIndex);
58
+ actualUniques.push(new SqlUniqueIR({
59
+ columns: satisfyingIndex.columns,
60
+ ...satisfyingIndex.name !== void 0 ? { name: satisfyingIndex.name } : {}
61
+ }));
62
+ }
63
+ }
64
+ for (const expectedIndex of input.expectedIndexes) {
65
+ if (expectedIndex.type !== void 0 || expectedIndex.options !== void 0) continue;
66
+ if (actualIndexes.some((idx) => sameColumns(idx.columns, expectedIndex.columns))) continue;
67
+ const satisfyingUnique = actualUniques.find((u) => sameColumns(u.columns, expectedIndex.columns));
68
+ if (satisfyingUnique) actualIndexes.push(new SqlIndexIR({
69
+ columns: satisfyingUnique.columns,
70
+ unique: false
71
+ }));
72
+ }
73
+ actualIndexes = actualIndexes.filter((idx) => !idx.unique || input.expectedIndexes.some((exp) => sameColumns(exp.columns, idx.columns)));
74
+ return {
75
+ actualUniques,
76
+ actualIndexes
77
+ };
78
+ }
79
+ /**
80
+ * Applies {@link resolveSemanticSatisfaction} across a flat table pair set:
81
+ * every actual table with an expected counterpart gets its unique/index
82
+ * child lists adjusted; unpaired tables pass through untouched.
83
+ */
84
+ function normalizeFlatActualForDiff(expected, actual) {
85
+ const tables = {};
86
+ for (const [name, actualTable] of Object.entries(actual.tables)) {
87
+ const expectedTable = expected.tables[name];
88
+ if (expectedTable === void 0) {
89
+ tables[name] = actualTable;
90
+ continue;
91
+ }
92
+ const adjusted = resolveSemanticSatisfaction({
93
+ expectedUniques: expectedTable.uniques,
94
+ expectedIndexes: expectedTable.indexes,
95
+ actualUniques: actualTable.uniques,
96
+ actualIndexes: actualTable.indexes
97
+ });
98
+ tables[name] = new SqlTableIR({
99
+ name: actualTable.name,
100
+ columns: actualTable.columns,
101
+ foreignKeys: actualTable.foreignKeys,
102
+ uniques: adjusted.actualUniques,
103
+ indexes: adjusted.actualIndexes,
104
+ ...actualTable.primaryKey !== void 0 ? { primaryKey: actualTable.primaryKey } : {},
105
+ ...actualTable.annotations !== void 0 ? { annotations: actualTable.annotations } : {},
106
+ ...actualTable.checks !== void 0 ? { checks: actualTable.checks } : {}
107
+ });
108
+ }
109
+ return new SqlSchemaIR({
110
+ tables,
111
+ ...actual.annotations !== void 0 ? { annotations: actual.annotations } : {}
112
+ });
113
+ }
114
+ /**
115
+ * Neutralizes the FK schema segment on a flat expected tree so its FK diff
116
+ * nodes pair with introspected FKs on single-schema targets: the family
117
+ * converter stamps `referencedSchema` with the contract namespace id
118
+ * verbatim (the unbound sentinel on non-namespaced targets), while a
119
+ * single-schema introspection stamps none — resolving both sides to the
120
+ * empty segment makes the ids meet.
121
+ */
122
+ function neutralizeFlatExpectedFkSchemas(expected) {
123
+ const tables = {};
124
+ for (const [name, table] of Object.entries(expected.tables)) {
125
+ if (table.foreignKeys.length === 0) {
126
+ tables[name] = table;
127
+ continue;
128
+ }
129
+ const foreignKeys = table.foreignKeys.map((fk) => new SqlForeignKeyIR({
130
+ columns: fk.columns,
131
+ referencedTable: fk.referencedTable,
132
+ referencedColumns: fk.referencedColumns,
133
+ ...fk.referencedSchema !== void 0 ? { referencedSchema: fk.referencedSchema } : {},
134
+ ...fk.name !== void 0 ? { name: fk.name } : {},
135
+ ...fk.onDelete !== void 0 ? { onDelete: fk.onDelete } : {},
136
+ ...fk.onUpdate !== void 0 ? { onUpdate: fk.onUpdate } : {},
137
+ ...fk.annotations !== void 0 ? { annotations: fk.annotations } : {},
138
+ resolvedReferencedNamespace: ""
139
+ }));
140
+ tables[name] = new SqlTableIR({
141
+ name: table.name,
142
+ columns: table.columns,
143
+ foreignKeys,
144
+ uniques: table.uniques,
145
+ indexes: table.indexes,
146
+ ...table.primaryKey !== void 0 ? { primaryKey: table.primaryKey } : {},
147
+ ...table.annotations !== void 0 ? { annotations: table.annotations } : {},
148
+ ...table.checks !== void 0 ? { checks: table.checks } : {}
149
+ });
150
+ }
151
+ return new SqlSchemaIR({
152
+ tables,
153
+ ...expected.annotations !== void 0 ? { annotations: expected.annotations } : {}
154
+ });
155
+ }
156
+ //#endregion
157
+ //#region src/core/diff/sql-schema-diff.ts
158
+ /**
159
+ * Compares two arrays of strings for equality (order-sensitive).
160
+ */
161
+ function arraysEqual(a, b) {
162
+ if (a.length !== b.length) return false;
163
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
164
+ return true;
165
+ }
166
+ /**
167
+ * Checks if a unique constraint requirement is satisfied by the given columns:
168
+ * a unique constraint with the same columns, or a unique index with the same
169
+ * columns (semantic satisfaction). Used by the planners to keep the
170
+ * "stronger satisfies weaker" behavior consistent across the control plane.
171
+ */
172
+ function isUniqueConstraintSatisfied(uniques, indexes, columns) {
173
+ if (uniques.some((unique) => arraysEqual(unique.columns, columns))) return true;
174
+ return indexes.some((index) => index.unique && arraysEqual(index.columns, columns));
175
+ }
176
+ /**
177
+ * Checks if an index requirement is satisfied by the given columns: any index
178
+ * (unique or non-unique) with the same columns, or a unique constraint with
179
+ * the same columns (stronger satisfies weaker).
180
+ */
181
+ function isIndexSatisfied(indexes, uniques, columns) {
182
+ if (indexes.some((index) => arraysEqual(index.columns, columns))) return true;
183
+ return uniques.some((unique) => arraysEqual(unique.columns, columns));
184
+ }
185
+ //#endregion
186
+ export { arraysEqual, classifyDiffSubjectGranularity, classifySqlDiffIssue, computeSqlDiffVerdict, computeStorageTypeVerdict, isIndexSatisfied, isUniqueConstraintSatisfied, neutralizeFlatExpectedFkSchemas, normalizeFlatActualForDiff, resolveSemanticSatisfaction, verifySqlSchemaByDiff };
187
+
188
+ //# sourceMappingURL=diff.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.mjs","names":[],"sources":["../src/core/diff/diff-tree-normalization.ts","../src/core/diff/sql-schema-diff.ts"],"sourcesContent":["/**\n * ⚠️ ACCEPTED-UNDER-PROTEST DEBT — DELETE IN SLICE 2.6 (`unify-unique-and-index-nodes`).\n *\n * A unique constraint IS a unique index. This slice modeled uniques and indexes\n * as two separate node kinds (`SqlUniqueIR` vs `SqlIndexIR` — even though\n * `SqlIndexIR` already carries `unique: boolean`), so the strict-by-kind differ\n * cannot pair a contract unique with a live unique index. This whole file\n * exists only to reconcile those two representations after the fact — it\n * should not exist.\n *\n * The fix — delete `SqlUniqueIR`, model unique enforcement as\n * `SqlIndexIR { unique: true }` on both derivation and introspection, and\n * delete `diff-tree-normalization.ts` — is specified in\n * `projects/postgres-rls/slices/unify-unique-and-index-nodes/spec.md` and\n * scheduled as the very next slice. Do NOT extend this.\n */\n\n/**\n * Pre-diff tree normalization: adjustments to the actual/expected trees the\n * generic differ (`diffSchemas`) runs over, so legacy semantic-equivalence\n * rules (a unique constraint satisfied by a unique index, an FK schema\n * segment that differs only in spelling) surface as same-kind node pairs\n * instead of spurious drift.\n */\n\nimport {\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\n\n// ============================================================================\n// Semantic satisfaction — derivation-side normalization of the actual tree\n// ============================================================================\n\nexport interface SemanticSatisfactionInput {\n readonly expectedUniques: readonly SqlUniqueIR[];\n readonly expectedIndexes: readonly SqlIndexIR[];\n readonly actualUniques: readonly SqlUniqueIR[];\n readonly actualIndexes: readonly SqlIndexIR[];\n}\n\nexport interface SemanticSatisfactionResult {\n readonly actualUniques: readonly SqlUniqueIR[];\n readonly actualIndexes: readonly SqlIndexIR[];\n}\n\nfunction sameColumns(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((c, i) => c === b[i]);\n}\n\n/**\n * Adjusts a table pair's ACTUAL unique/index child lists so the legacy\n * walk's cross-kind semantic satisfaction materializes as same-kind node\n * pairs for the differ (the differ pairs strictly by id, so a `unique:`\n * node can never pair with an `index:` node). Three legacy rules, ported\n * from `isUniqueConstraintSatisfied` / `isIndexSatisfied` and the\n * strict-extras loops of the retired relational walk:\n *\n * 1. A contract unique satisfied by a live unique INDEX: the actual index\n * node is reclassified as a unique node (it pairs with the expected\n * unique and stops being a candidate extra).\n * 2. A contract index (with no type/options demands) satisfied by a live\n * unique CONSTRAINT: a same-kind actual index node is synthesized so\n * the expected index pairs — the unique constraint itself stays (the\n * legacy strict-extras loop still reports it as an undeclared unique).\n * 3. Live unique indexes are never extras in the legacy walk (its\n * strict-extras loop skips `unique: true` rows), so any remaining\n * actual unique-index node with no expected index counterpart is\n * dropped rather than surfacing as `not-expected`.\n */\nexport function resolveSemanticSatisfaction(\n input: SemanticSatisfactionInput,\n): SemanticSatisfactionResult {\n let actualIndexes = [...input.actualIndexes];\n const actualUniques = [...input.actualUniques];\n\n // Rule 1: reclassify a satisfying unique index as the unique constraint\n // the contract declared.\n for (const expectedUnique of input.expectedUniques) {\n const alreadyPaired = actualUniques.some((u) => sameColumns(u.columns, expectedUnique.columns));\n if (alreadyPaired) continue;\n const satisfyingIndex = actualIndexes.find(\n (idx) => idx.unique && sameColumns(idx.columns, expectedUnique.columns),\n );\n if (satisfyingIndex) {\n actualIndexes = actualIndexes.filter((idx) => idx !== satisfyingIndex);\n actualUniques.push(\n new SqlUniqueIR({\n columns: satisfyingIndex.columns,\n ...(satisfyingIndex.name !== undefined ? { name: satisfyingIndex.name } : {}),\n }),\n );\n }\n }\n\n // Rule 2: synthesize an index node from a satisfying unique constraint.\n for (const expectedIndex of input.expectedIndexes) {\n if (expectedIndex.type !== undefined || expectedIndex.options !== undefined) continue;\n const alreadyPaired = actualIndexes.some((idx) =>\n sameColumns(idx.columns, expectedIndex.columns),\n );\n if (alreadyPaired) continue;\n const satisfyingUnique = actualUniques.find((u) =>\n sameColumns(u.columns, expectedIndex.columns),\n );\n if (satisfyingUnique) {\n actualIndexes.push(new SqlIndexIR({ columns: satisfyingUnique.columns, unique: false }));\n }\n }\n\n // Rule 3: remaining unique indexes with no expected counterpart are\n // invisible to the legacy extras loop — drop them.\n actualIndexes = actualIndexes.filter(\n (idx) =>\n !idx.unique || input.expectedIndexes.some((exp) => sameColumns(exp.columns, idx.columns)),\n );\n\n return { actualUniques, actualIndexes };\n}\n\n// ============================================================================\n// Flat-tree helpers (single-schema targets)\n// ============================================================================\n\n/**\n * Applies {@link resolveSemanticSatisfaction} across a flat table pair set:\n * every actual table with an expected counterpart gets its unique/index\n * child lists adjusted; unpaired tables pass through untouched.\n */\nexport function normalizeFlatActualForDiff(\n expected: SqlSchemaIR,\n actual: SqlSchemaIR,\n): SqlSchemaIR {\n const tables: Record<string, SqlTableIR> = {};\n for (const [name, actualTable] of Object.entries(actual.tables)) {\n const expectedTable = expected.tables[name];\n if (expectedTable === undefined) {\n tables[name] = actualTable;\n continue;\n }\n const adjusted = resolveSemanticSatisfaction({\n expectedUniques: expectedTable.uniques,\n expectedIndexes: expectedTable.indexes,\n actualUniques: actualTable.uniques,\n actualIndexes: actualTable.indexes,\n });\n tables[name] = new SqlTableIR({\n name: actualTable.name,\n columns: actualTable.columns,\n foreignKeys: actualTable.foreignKeys,\n uniques: adjusted.actualUniques,\n indexes: adjusted.actualIndexes,\n ...(actualTable.primaryKey !== undefined ? { primaryKey: actualTable.primaryKey } : {}),\n ...(actualTable.annotations !== undefined ? { annotations: actualTable.annotations } : {}),\n ...(actualTable.checks !== undefined ? { checks: actualTable.checks } : {}),\n });\n }\n return new SqlSchemaIR({\n tables,\n ...(actual.annotations !== undefined ? { annotations: actual.annotations } : {}),\n });\n}\n\n/**\n * Neutralizes the FK schema segment on a flat expected tree so its FK diff\n * nodes pair with introspected FKs on single-schema targets: the family\n * converter stamps `referencedSchema` with the contract namespace id\n * verbatim (the unbound sentinel on non-namespaced targets), while a\n * single-schema introspection stamps none — resolving both sides to the\n * empty segment makes the ids meet.\n */\nexport function neutralizeFlatExpectedFkSchemas(expected: SqlSchemaIR): SqlSchemaIR {\n const tables: Record<string, SqlTableIR> = {};\n for (const [name, table] of Object.entries(expected.tables)) {\n if (table.foreignKeys.length === 0) {\n tables[name] = table;\n continue;\n }\n const foreignKeys = table.foreignKeys.map(\n (fk) =>\n new SqlForeignKeyIR({\n columns: fk.columns,\n referencedTable: fk.referencedTable,\n referencedColumns: fk.referencedColumns,\n ...(fk.referencedSchema !== undefined ? { referencedSchema: fk.referencedSchema } : {}),\n ...(fk.name !== undefined ? { name: fk.name } : {}),\n ...(fk.onDelete !== undefined ? { onDelete: fk.onDelete } : {}),\n ...(fk.onUpdate !== undefined ? { onUpdate: fk.onUpdate } : {}),\n ...(fk.annotations !== undefined ? { annotations: fk.annotations } : {}),\n resolvedReferencedNamespace: '',\n }),\n );\n tables[name] = new SqlTableIR({\n name: table.name,\n columns: table.columns,\n foreignKeys,\n uniques: table.uniques,\n indexes: table.indexes,\n ...(table.primaryKey !== undefined ? { primaryKey: table.primaryKey } : {}),\n ...(table.annotations !== undefined ? { annotations: table.annotations } : {}),\n ...(table.checks !== undefined ? { checks: table.checks } : {}),\n });\n }\n return new SqlSchemaIR({\n tables,\n ...(expected.annotations !== undefined ? { annotations: expected.annotations } : {}),\n });\n}\n","/**\n * Shared relational-diff types and semantic-satisfaction predicates. The\n * coordinate-based issue diff this module used to house (`collectSqlSchemaIssues`\n * / `collectSqlSchemaIssuesPerNamespace`) retired once the migration planner\n * took `plan(start, end)` over the one differ (`buildPostgresPlanDiff` /\n * `buildSqlitePlanDiff`); what remains here is consumed by the surviving\n * verify verdict (`schema-verify.ts`) and the control adapters.\n */\n\nimport type { ColumnDefault } from '@prisma-next/contract/types';\nimport type { SqlIndexIR, SqlUniqueIR } from '@prisma-next/sql-schema-ir/types';\n\n/**\n * Function type for normalizing raw database default expressions into ColumnDefault.\n * Target-specific implementations handle database dialect differences.\n */\nexport type DefaultNormalizer = (\n rawDefault: string,\n nativeType: string,\n) => ColumnDefault | undefined;\n\n/**\n * Function type for normalizing schema native types to canonical form for comparison.\n * Target-specific implementations handle dialect-specific type name variations\n * (e.g., Postgres 'varchar' → 'character varying', 'timestamptz' normalization).\n */\nexport type NativeTypeNormalizer = (nativeType: string) => string;\n\n/**\n * Compares two arrays of strings for equality (order-sensitive).\n */\nexport function arraysEqual(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Checks if a unique constraint requirement is satisfied by the given columns:\n * a unique constraint with the same columns, or a unique index with the same\n * columns (semantic satisfaction). Used by the planners to keep the\n * \"stronger satisfies weaker\" behavior consistent across the control plane.\n */\nexport function isUniqueConstraintSatisfied(\n uniques: readonly SqlUniqueIR[],\n indexes: readonly SqlIndexIR[],\n columns: readonly string[],\n): boolean {\n const hasConstraint = uniques.some((unique) => arraysEqual(unique.columns, columns));\n if (hasConstraint) {\n return true;\n }\n return indexes.some((index) => index.unique && arraysEqual(index.columns, columns));\n}\n\n/**\n * Checks if an index requirement is satisfied by the given columns: any index\n * (unique or non-unique) with the same columns, or a unique constraint with\n * the same columns (stronger satisfies weaker).\n */\nexport function isIndexSatisfied(\n indexes: readonly SqlIndexIR[],\n uniques: readonly SqlUniqueIR[],\n columns: readonly string[],\n): boolean {\n const hasMatchingIndex = indexes.some((index) => arraysEqual(index.columns, columns));\n if (hasMatchingIndex) {\n return true;\n }\n return uniques.some((unique) => arraysEqual(unique.columns, columns));\n}\n"],"mappings":"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"}
package/dist/ir.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { ContractSerializer, SchemaIssue, SchemaVerifier, SchemaVerifyOptions, SchemaVerifyResult } from "@prisma-next/framework-components/control";
1
+ import { ContractSerializer, SchemaDiffIssue, SchemaVerifier, SchemaVerifyOptions, SchemaVerifyResult } from "@prisma-next/framework-components/control";
2
2
  import { AnyEntityKindDescriptor, Namespace } from "@prisma-next/framework-components/ir";
3
- import { SqlNamespaceTablesInput, SqlStorage, SqlStorageTypeEntry } from "@prisma-next/sql-contract/types";
4
3
  import { Contract } from "@prisma-next/contract/types";
4
+ import { SqlNamespaceInput, SqlStorage, SqlStorageTypeEntry } from "@prisma-next/sql-contract/types";
5
5
  import { JsonObject } from "@prisma-next/utils/json";
6
6
 
7
7
  //#region src/core/ir/sql-contract-serializer-base.d.ts
@@ -41,11 +41,24 @@ declare abstract class SqlContractSerializerBase<TContract extends Contract<SqlS
41
41
  sortStorage: import("@prisma-next/contract/hashing").StorageSort;
42
42
  protected parseSqlContractStructure(json: unknown): Contract<SqlStorage>;
43
43
  protected hydrateSqlStorage(validated: Contract<SqlStorage>): Contract<SqlStorage>;
44
- protected abstract get defaultNamespaceId(): string;
45
- protected hydrateSqlNamespaceMap(namespaces: Readonly<Record<string, Namespace | Record<string, unknown>>>): Readonly<Record<string, Namespace>>;
46
- protected hydrateSqlNamespaceEntry(nsId: string, raw: Namespace | Record<string, unknown>): Namespace | SqlNamespaceTablesInput;
44
+ protected hydrateSqlNamespaceMap(namespaces: Readonly<Record<string, Record<string, unknown>>>): Readonly<Record<string, Namespace>>;
45
+ protected hydrateSqlNamespaceEntry(nsId: string, raw: Record<string, unknown>): Namespace | SqlNamespaceInput;
47
46
  protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry;
48
47
  protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract;
48
+ /**
49
+ * Serializes a namespace's `entries` dict by walking every enumerable
50
+ * kind — no kind is named here, mirroring the generic hydrate walk in
51
+ * `hydrateSqlNamespaceEntry` above. `table` is the SQL family's one
52
+ * universal base kind (every namespace carries it), so it is always
53
+ * emitted, even when empty; every other kind — target- or
54
+ * pack-contributed — is emitted only when it holds at least one entry.
55
+ * A kind carried non-enumerable on `entries` is excluded here for free,
56
+ * since `Object.entries` honors enumerability.
57
+ */
58
+ protected serializeNamespaceEntries(entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>): Record<string, Record<string, JsonObject>>;
59
+ private serializeEntries;
60
+ protected serializeJsonObject(value: unknown): JsonObject;
61
+ private serializeJsonValue;
49
62
  }
50
63
  //#endregion
51
64
  //#region src/core/ir/sql-contract-serializer.d.ts
@@ -57,10 +70,14 @@ declare abstract class SqlContractSerializerBase<TContract extends Contract<SqlS
57
70
  * codec-typed envelope wire a target-specific subclass with a populated
58
71
  * registry (see Postgres). Family-level call sites instantiate this
59
72
  * default directly when no target serializer is supplied.
73
+ *
74
+ * Because this serializer has no target concretion, deserialization of
75
+ * contracts that include namespace entries from JSON will throw unless
76
+ * the caller provides pre-hydrated `NamespaceBase` instances. Production
77
+ * paths always supply a target-specific serializer.
60
78
  */
61
79
  declare class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {
62
80
  constructor();
63
- protected get defaultNamespaceId(): string;
64
81
  }
65
82
  //#endregion
66
83
  //#region src/core/ir/sql-schema-verifier-base.d.ts
@@ -68,7 +85,7 @@ declare class SqlContractSerializer extends SqlContractSerializerBase<Contract<S
68
85
  * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared
69
86
  * walk (table-by-table + column-by-column matching keyed by
70
87
  * `(namespace.id, name)`, FK / unique / index comparisons via the
71
- * existing helpers in `verify-helpers.ts`) and exposes a protected hook
88
+ * shared satisfaction helpers in `sql-schema-diff.ts`) and exposes a protected hook
72
89
  * for target extensions (Postgres functions, RLS policies, future
73
90
  * target-only kinds).
74
91
  *
@@ -92,13 +109,13 @@ declare abstract class SqlSchemaVerifierBase<TContract, TSchema> implements Sche
92
109
  * family-shared implementation today; a future iteration will lift
93
110
  * the shared walk into this base.
94
111
  */
95
- protected abstract verifyCommonSqlSchema(options: SchemaVerifyOptions<TContract, TSchema>): readonly SchemaIssue[];
112
+ protected abstract verifyCommonSqlSchema(options: SchemaVerifyOptions<TContract, TSchema>): readonly SchemaDiffIssue[];
96
113
  /**
97
114
  * Target-specific extensions — e.g. Postgres functions, future RLS
98
115
  * policies, namespace-mismatch issues. Returns the empty list when the
99
116
  * target ships no extensions over the SQL family alphabet.
100
117
  */
101
- protected abstract verifyTargetExtensions(options: SchemaVerifyOptions<TContract, TSchema>): readonly SchemaIssue[];
118
+ protected abstract verifyTargetExtensions(options: SchemaVerifyOptions<TContract, TSchema>): readonly SchemaDiffIssue[];
102
119
  }
103
120
  //#endregion
104
121
  export { SqlContractSerializer, SqlContractSerializerBase, type SqlEntityHydrationFactory, SqlSchemaVerifierBase };
package/dist/ir.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts","../src/core/ir/sql-schema-verifier-base.ts"],"mappings":";;;;;;;KAsCY,yBAAA,IAA6B,KAAc;;AAAvD;;;;AAAuD;AA0BvD;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,mBAMT,uBAAA,EAAyB,WAAA,SAE1C,yBAAA;EAAA,iBANa,cAAA;EAAA,iBACA,UAAA;cAGI,uBAAA,GAAyB,WAAA,SAE1C,yBAAA,GAEF,eAAA,YAA0B,uBAAA;EAO5B,mBAAA,WAA8B,SAAA,GAAY,SAAA,EAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAIxC,mBAAA,0CAAmB,sBAAA;EAEnB,WAAA,0CAAW,WAAA;EAAA,UAED,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,uBAyDhD,kBAAA;EAAA,UAEb,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA,GAAY,MAAA,sBAC/C,QAAA,CAAS,MAAA,SAAe,SAAA;EAAA,UAmBjB,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,SAAA,GAAY,MAAA,oBAChB,SAAA,GAAY,uBAAA;EAAA,UAmCL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAkBrD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;AAAA;;;;;;;AAzMrE;;;;AAAuD;cCxB1C,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;gBAOrD,kBAAA;AAAA;;;;;;;;;ADiBzB;;;;AAAuD;AA0BvD;;;;;;;;;uBErCsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EFoDlC;;;;;;EAAA,mBEvCX,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;EF0DoC;;;;;EAAA,mBEnD7B,sBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;AAAA"}
1
+ {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts","../src/core/ir/sql-schema-verifier-base.ts"],"mappings":";;;;;;;KAmCY,yBAAA,IAA6B,KAAc;;AAAvD;;;;AAAuD;AA0BvD;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,mBAMT,uBAAA,EAAyB,WAAA,SAE1C,yBAAA;EAAA,iBANa,cAAA;EAAA,iBACA,UAAA;cAGI,uBAAA,GAAyB,WAAA,SAE1C,yBAAA,GAEF,eAAA,YAA0B,uBAAA;EAO5B,mBAAA,WAA8B,SAAA,GAAY,SAAA,EAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAIxC,mBAAA,0CAAmB,sBAAA;EAEnB,WAAA,0CAAW,WAAA;EAAA,UAED,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,UAuC7D,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,MAAA,sBACnC,QAAA,CAAS,MAAA,SAAe,SAAA;EAAA,UAcjB,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,MAAA,oBACJ,SAAA,GAAY,iBAAA;EAAA,UA+BL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAkBrD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;EAAd;;;;;;;;;;EAAA,UAc3C,yBAAA,CACR,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA,uBACzC,MAAA,SAAe,MAAA,SAAe,UAAA;EAAA,QAazB,gBAAA;EAAA,UAQE,mBAAA,CAAoB,KAAA,YAAiB,UAAA;EAAA,QAOvC,kBAAA;AAAA;;;;;;;AAxNV;;;;AAAuD;AA0BvD;;;;;cC3Ca,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;;ADiB9E;;;;AAAuD;AA0BvD;;;;;;;;;uBElCsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EFiDlC;;;;;;EAAA,mBEpCX,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,eAAA;EFuDoC;;;;;EAAA,mBEhD7B,sBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,eAAA;AAAA"}
package/dist/ir.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { n as SqlContractSerializerBase, t as SqlContractSerializer } from "./sql-contract-serializer-BR2vC7Z-.mjs";
1
+ import { n as SqlContractSerializerBase, t as SqlContractSerializer } from "./sql-contract-serializer-C75cfMSS.mjs";
2
2
  //#region src/core/ir/sql-schema-verifier-base.ts
3
3
  /**
4
4
  * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared
5
5
  * walk (table-by-table + column-by-column matching keyed by
6
6
  * `(namespace.id, name)`, FK / unique / index comparisons via the
7
- * existing helpers in `verify-helpers.ts`) and exposes a protected hook
7
+ * shared satisfaction helpers in `sql-schema-diff.ts`) and exposes a protected hook
8
8
  * for target extensions (Postgres functions, RLS policies, future
9
9
  * target-only kinds).
10
10
  *
package/dist/ir.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.mjs","names":[],"sources":["../src/core/ir/sql-schema-verifier-base.ts"],"sourcesContent":["import type {\n SchemaIssue,\n SchemaVerifier,\n SchemaVerifyOptions,\n SchemaVerifyResult,\n} from '@prisma-next/framework-components/control';\n\n/**\n * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared\n * walk (table-by-table + column-by-column matching keyed by\n * `(namespace.id, name)`, FK / unique / index comparisons via the\n * existing helpers in `verify-helpers.ts`) and exposes a protected hook\n * for target extensions (Postgres functions, RLS policies, future\n * target-only kinds).\n *\n * The base accumulates issues in a single buffer and returns the\n * combined result; the per-SPI family abstract handles the result\n * envelope shape so concrete subclasses focus on target-specific\n * verification logic.\n *\n * The protected hooks (`verifyCommonSqlSchema`,\n * `verifyTargetExtensions`) carry the stable base API that target\n * subclasses (`PostgresSchemaVerifier`, `SqliteSchemaVerifier`)\n * compile against; the SQL-shared walk implementation will be lifted\n * into this base when the verifier behaviour migrates off the\n * legacy adapter shells.\n */\nexport abstract class SqlSchemaVerifierBase<TContract, TSchema>\n implements SchemaVerifier<TContract, TSchema>\n{\n verifySchema(options: SchemaVerifyOptions<TContract, TSchema>): SchemaVerifyResult {\n const issues: SchemaIssue[] = [];\n issues.push(...this.verifyCommonSqlSchema(options));\n issues.push(...this.verifyTargetExtensions(options));\n return { ok: issues.length === 0, issues };\n }\n\n /**\n * SQL-shared verification — table/column/FK/unique/index walks keyed\n * by `(namespace.id, name)`. Concrete subclasses provide the\n * family-shared implementation today; a future iteration will lift\n * the shared walk into this base.\n */\n protected abstract verifyCommonSqlSchema(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaIssue[];\n\n /**\n * Target-specific extensions — e.g. Postgres functions, future RLS\n * policies, namespace-mismatch issues. Returns the empty list when the\n * target ships no extensions over the SQL family alphabet.\n */\n protected abstract verifyTargetExtensions(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaIssue[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAsB,wBAAtB,MAEA;CACE,aAAa,SAAsE;EACjF,MAAM,SAAwB,CAAC;EAC/B,OAAO,KAAK,GAAG,KAAK,sBAAsB,OAAO,CAAC;EAClD,OAAO,KAAK,GAAG,KAAK,uBAAuB,OAAO,CAAC;EACnD,OAAO;GAAE,IAAI,OAAO,WAAW;GAAG;EAAO;CAC3C;AAoBF"}
1
+ {"version":3,"file":"ir.mjs","names":[],"sources":["../src/core/ir/sql-schema-verifier-base.ts"],"sourcesContent":["import type {\n SchemaDiffIssue,\n SchemaVerifier,\n SchemaVerifyOptions,\n SchemaVerifyResult,\n} from '@prisma-next/framework-components/control';\n\n/**\n * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared\n * walk (table-by-table + column-by-column matching keyed by\n * `(namespace.id, name)`, FK / unique / index comparisons via the\n * shared satisfaction helpers in `sql-schema-diff.ts`) and exposes a protected hook\n * for target extensions (Postgres functions, RLS policies, future\n * target-only kinds).\n *\n * The base accumulates issues in a single buffer and returns the\n * combined result; the per-SPI family abstract handles the result\n * envelope shape so concrete subclasses focus on target-specific\n * verification logic.\n *\n * The protected hooks (`verifyCommonSqlSchema`,\n * `verifyTargetExtensions`) carry the stable base API that target\n * subclasses (`PostgresSchemaVerifier`, `SqliteSchemaVerifier`)\n * compile against; the SQL-shared walk implementation will be lifted\n * into this base when the verifier behaviour migrates off the\n * legacy adapter shells.\n */\nexport abstract class SqlSchemaVerifierBase<TContract, TSchema>\n implements SchemaVerifier<TContract, TSchema>\n{\n verifySchema(options: SchemaVerifyOptions<TContract, TSchema>): SchemaVerifyResult {\n const issues: SchemaDiffIssue[] = [];\n issues.push(...this.verifyCommonSqlSchema(options));\n issues.push(...this.verifyTargetExtensions(options));\n return { ok: issues.length === 0, issues };\n }\n\n /**\n * SQL-shared verification — table/column/FK/unique/index walks keyed\n * by `(namespace.id, name)`. Concrete subclasses provide the\n * family-shared implementation today; a future iteration will lift\n * the shared walk into this base.\n */\n protected abstract verifyCommonSqlSchema(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaDiffIssue[];\n\n /**\n * Target-specific extensions — e.g. Postgres functions, future RLS\n * policies, namespace-mismatch issues. Returns the empty list when the\n * target ships no extensions over the SQL family alphabet.\n */\n protected abstract verifyTargetExtensions(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaDiffIssue[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAsB,wBAAtB,MAEA;CACE,aAAa,SAAsE;EACjF,MAAM,SAA4B,CAAC;EACnC,OAAO,KAAK,GAAG,KAAK,sBAAsB,OAAO,CAAC;EAClD,OAAO,KAAK,GAAG,KAAK,uBAAuB,OAAO,CAAC;EACnD,OAAO;GAAE,IAAI,OAAO,WAAW;GAAG;EAAO;CAC3C;AAoBF"}
@@ -1,4 +1,6 @@
1
- import { T as SqlPlanTargetDetails, p as SqlMigrationPlanOperation } from "./types-kgstZ_Zd.mjs";
1
+ import { f as SqlMigrationPlanOperation, w as SqlPlanTargetDetails } from "./types-BW7pzb2j.mjs";
2
+ import { Contract } from "@prisma-next/contract/types";
3
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
2
4
  import { Migration } from "@prisma-next/migration-tools/migration";
3
5
 
4
6
  //#region src/core/sql-migration.d.ts
@@ -13,10 +15,17 @@ import { Migration } from "@prisma-next/migration-tools/migration";
13
15
  * fully concrete operation shape. Target-free code in SQL family / tooling
14
16
  * parameterises over `TDetails` (and usually `TTargetId = string`).
15
17
  *
18
+ * The `Start` / `End` contract generics are forwarded to the framework
19
+ * `Migration` base so the derived `describe()` and the per-target view getters
20
+ * (`PostgresMigration` / `SqliteMigration`) carry each migration's precise
21
+ * contract types. The view getters themselves live on the per-target bases
22
+ * because the SQL ContractView shapes differ per target (SQLite unwraps its
23
+ * sole namespace to the root; Postgres is schema-qualified).
24
+ *
16
25
  * Keeps target-free contract/runtime features in the family layer while
17
26
  * letting adapters own target shape.
18
27
  */
19
- declare abstract class SqlMigration<TDetails extends SqlPlanTargetDetails, TTargetId extends string = string> extends Migration<SqlMigrationPlanOperation<TDetails>, 'sql', TTargetId> {
28
+ declare abstract class SqlMigration<TDetails extends SqlPlanTargetDetails, TTargetId extends string = string, Start extends Contract<SqlStorage> = Contract<SqlStorage>, End extends Contract<SqlStorage> = Contract<SqlStorage>> extends Migration<SqlMigrationPlanOperation<TDetails>, 'sql', TTargetId, Start, End> {
20
29
  /**
21
30
  * Sorted, deduplicated invariant ids declared by this migration's
22
31
  * data-transform ops. Derived from `this.operations` so the field remains
@@ -1 +1 @@
1
- {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/sql-migration.ts"],"mappings":";;;;;;AAmBA;;;;;;;;;;;;uBAAsB,YAAA,kBACH,oBAAA,6CAET,SAAA,CAAU,yBAAA,CAA0B,QAAA,UAAkB,SAAA;EAAtD;;;;;;AAWc;;;;EAXd,IAWJ,kBAAA;AAAA"}
1
+ {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/sql-migration.ts"],"mappings":";;;;;;;;AA4BA;;;;;;;;;;;;;;;;;;;uBAAsB,YAAA,kBACH,oBAAA,mDAEH,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA,eAClC,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA,WACpC,SAAA,CAAU,yBAAA,CAA0B,QAAA,UAAkB,SAAA,EAAW,KAAA,EAAO,GAAA;EAJhF;;;;;;;;;;EAAA,IAeI,kBAAA;AAAA"}
@@ -13,6 +13,13 @@ import { isThenable } from "@prisma-next/utils/promise";
13
13
  * fully concrete operation shape. Target-free code in SQL family / tooling
14
14
  * parameterises over `TDetails` (and usually `TTargetId = string`).
15
15
  *
16
+ * The `Start` / `End` contract generics are forwarded to the framework
17
+ * `Migration` base so the derived `describe()` and the per-target view getters
18
+ * (`PostgresMigration` / `SqliteMigration`) carry each migration's precise
19
+ * contract types. The view getters themselves live on the per-target bases
20
+ * because the SQL ContractView shapes differ per target (SQLite unwraps its
21
+ * sole namespace to the root; Postgres is schema-qualified).
22
+ *
16
23
  * Keeps target-free contract/runtime features in the family layer while
17
24
  * letting adapters own target shape.
18
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/sql-migration.ts"],"sourcesContent":["import { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport { Migration } from '@prisma-next/migration-tools/migration';\nimport { isThenable } from '@prisma-next/utils/promise';\nimport type { SqlMigrationPlanOperation, SqlPlanTargetDetails } from './migrations/types';\n\n/**\n * Family-owned base class for SQL migrations.\n *\n * Generic in `TDetails` (family plan target details, e.g. Postgres vs SQLite)\n * and in `TTargetId` (the literal target identifier, e.g. `'postgres'`).\n *\n * Adapters (Postgres, SQLite, …) extend this with a concrete `TDetails` and\n * a fixed `TTargetId` literal, so the public `Migration<TOp>` base sees the\n * fully concrete operation shape. Target-free code in SQL family / tooling\n * parameterises over `TDetails` (and usually `TTargetId = string`).\n *\n * Keeps target-free contract/runtime features in the family layer while\n * letting adapters own target shape.\n */\nexport abstract class SqlMigration<\n TDetails extends SqlPlanTargetDetails,\n TTargetId extends string = string,\n> extends Migration<SqlMigrationPlanOperation<TDetails>, 'sql', TTargetId> {\n /**\n * Sorted, deduplicated invariant ids declared by this migration's\n * data-transform ops. Derived from `this.operations` so the field remains\n * consistent with the operation list — planner-built plans (`db init`,\n * `db update`) yield `[]` because they emit no data-transform ops.\n *\n * Required by `SqlMigrationPlan.providedInvariants` (tightened from\n * optional at the SQL-family layer); the framework-level\n * `MigrationPlan.providedInvariants?` stays optional.\n */\n get providedInvariants(): readonly string[] {\n const ops = this.operations.filter(\n (op): op is SqlMigrationPlanOperation<TDetails> => !isThenable(op),\n );\n return deriveProvidedInvariants(ops);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,IAAsB,eAAtB,cAGU,UAAiE;;;;;;;;;;;CAWzE,IAAI,qBAAwC;EAI1C,OAAO,yBAHK,KAAK,WAAW,QACzB,OAAkD,CAAC,WAAW,EAAE,CAEjC,CAAC;CACrC;AACF"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/sql-migration.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport { Migration } from '@prisma-next/migration-tools/migration';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { isThenable } from '@prisma-next/utils/promise';\nimport type { SqlMigrationPlanOperation, SqlPlanTargetDetails } from './migrations/types';\n\n/**\n * Family-owned base class for SQL migrations.\n *\n * Generic in `TDetails` (family plan target details, e.g. Postgres vs SQLite)\n * and in `TTargetId` (the literal target identifier, e.g. `'postgres'`).\n *\n * Adapters (Postgres, SQLite, …) extend this with a concrete `TDetails` and\n * a fixed `TTargetId` literal, so the public `Migration<TOp>` base sees the\n * fully concrete operation shape. Target-free code in SQL family / tooling\n * parameterises over `TDetails` (and usually `TTargetId = string`).\n *\n * The `Start` / `End` contract generics are forwarded to the framework\n * `Migration` base so the derived `describe()` and the per-target view getters\n * (`PostgresMigration` / `SqliteMigration`) carry each migration's precise\n * contract types. The view getters themselves live on the per-target bases\n * because the SQL ContractView shapes differ per target (SQLite unwraps its\n * sole namespace to the root; Postgres is schema-qualified).\n *\n * Keeps target-free contract/runtime features in the family layer while\n * letting adapters own target shape.\n */\nexport abstract class SqlMigration<\n TDetails extends SqlPlanTargetDetails,\n TTargetId extends string = string,\n Start extends Contract<SqlStorage> = Contract<SqlStorage>,\n End extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends Migration<SqlMigrationPlanOperation<TDetails>, 'sql', TTargetId, Start, End> {\n /**\n * Sorted, deduplicated invariant ids declared by this migration's\n * data-transform ops. Derived from `this.operations` so the field remains\n * consistent with the operation list — planner-built plans (`db init`,\n * `db update`) yield `[]` because they emit no data-transform ops.\n *\n * Required by `SqlMigrationPlan.providedInvariants` (tightened from\n * optional at the SQL-family layer); the framework-level\n * `MigrationPlan.providedInvariants?` stays optional.\n */\n get providedInvariants(): readonly string[] {\n const ops = this.operations.filter(\n (op): op is SqlMigrationPlanOperation<TDetails> => !isThenable(op),\n );\n return deriveProvidedInvariants(ops);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,IAAsB,eAAtB,cAKU,UAA6E;;;;;;;;;;;CAWrF,IAAI,qBAAwC;EAI1C,OAAO,yBAHK,KAAK,WAAW,QACzB,OAAkD,CAAC,WAAW,EAAE,CAEjC,CAAC;CACrC;AACF"}
package/dist/pack.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as sqlFamilyPslBlockDescriptors, n as sqlFamilyAuthoringFieldPresets, r as sqlFamilyEntityTypes, t as sqlFamilyAuthoringTypes } from "./authoring-type-constructors-CjFfO6LM.mjs";
1
+ import { i as sqlFamilyPslBlockDescriptors, n as sqlFamilyAuthoringFieldPresets, r as sqlFamilyEntityTypes, t as sqlFamilyAuthoringTypes } from "./authoring-type-constructors-CXd-8ydc.mjs";
2
2
  //#region src/exports/pack.ts
3
3
  const sqlFamilyPack = {
4
4
  kind: "family",