@prisma-next/family-sql 0.8.0 → 0.9.0-dev.2

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 (43) hide show
  1. package/README.md +5 -5
  2. package/dist/control-adapter.d.mts +11 -1
  3. package/dist/control-adapter.d.mts.map +1 -1
  4. package/dist/control.d.mts +3 -3
  5. package/dist/control.d.mts.map +1 -1
  6. package/dist/control.mjs +37 -30
  7. package/dist/control.mjs.map +1 -1
  8. package/dist/ir.d.mts +135 -0
  9. package/dist/ir.d.mts.map +1 -0
  10. package/dist/ir.mjs +37 -0
  11. package/dist/ir.mjs.map +1 -0
  12. package/dist/migration.d.mts +1 -1
  13. package/dist/runtime.mjs +1 -1
  14. package/dist/schema-verify.d.mts +2 -1
  15. package/dist/schema-verify.d.mts.map +1 -1
  16. package/dist/schema-verify.mjs +1 -1
  17. package/dist/sql-contract-serializer-qUQCnP-k.mjs +125 -0
  18. package/dist/sql-contract-serializer-qUQCnP-k.mjs.map +1 -0
  19. package/dist/{timestamp-now-generator-BWp8S2sa.mjs → timestamp-now-generator-r7BP5n3l.mjs} +1 -1
  20. package/dist/{timestamp-now-generator-BWp8S2sa.mjs.map → timestamp-now-generator-r7BP5n3l.mjs.map} +1 -1
  21. package/dist/{types-Da-eOg20.d.mts → types-DMINfGUO.d.mts} +37 -25
  22. package/dist/types-DMINfGUO.d.mts.map +1 -0
  23. package/dist/{verify-pRYxnpiG.mjs → verify-Crewz6hG.mjs} +1 -1
  24. package/dist/{verify-pRYxnpiG.mjs.map → verify-Crewz6hG.mjs.map} +1 -1
  25. package/dist/{verify-sql-schema-DV-UsTG9.mjs → verify-sql-schema-BXw7yx6L.mjs} +53 -7
  26. package/dist/verify-sql-schema-BXw7yx6L.mjs.map +1 -0
  27. package/dist/{verify-sql-schema-CPHiuYHR.d.mts → verify-sql-schema-Bfvz07Ik.d.mts} +14 -2
  28. package/dist/verify-sql-schema-Bfvz07Ik.d.mts.map +1 -0
  29. package/dist/verify.mjs +1 -1
  30. package/package.json +22 -21
  31. package/src/core/control-adapter.ts +14 -0
  32. package/src/core/control-instance.ts +33 -52
  33. package/src/core/ir/sql-contract-serializer-base.ts +136 -0
  34. package/src/core/ir/sql-contract-serializer.ts +18 -0
  35. package/src/core/ir/sql-schema-verifier-base.ts +56 -0
  36. package/src/core/migrations/contract-to-schema-ir.ts +71 -22
  37. package/src/core/migrations/types.ts +25 -5
  38. package/src/core/schema-verify/verify-sql-schema.ts +117 -21
  39. package/src/exports/control.ts +1 -1
  40. package/src/exports/ir.ts +6 -0
  41. package/dist/types-Da-eOg20.d.mts.map +0 -1
  42. package/dist/verify-sql-schema-CPHiuYHR.d.mts.map +0 -1
  43. package/dist/verify-sql-schema-DV-UsTG9.mjs.map +0 -1
package/dist/ir.d.mts ADDED
@@ -0,0 +1,135 @@
1
+ import { ContractSerializer, SchemaIssue, SchemaVerifier, SchemaVerifyOptions, SchemaVerifyResult } from "@prisma-next/framework-components/control";
2
+ import { SqlStorage, SqlStorageTypeEntry } from "@prisma-next/sql-contract/types";
3
+ import { Contract } from "@prisma-next/contract/types";
4
+ import { JsonObject } from "@prisma-next/utils/json";
5
+
6
+ //#region src/core/ir/sql-contract-serializer-base.d.ts
7
+ type SqlEntityHydrationFactory = (entry: unknown) => SqlStorageTypeEntry;
8
+ /**
9
+ * SQL family `ContractSerializer` abstract base. Carries the SQL-shared
10
+ * deserialization pipeline:
11
+ *
12
+ * 1. `parseSqlContractStructure` validates the on-disk JSON envelope
13
+ * against the SQL contract arktype schema (`validateSqlContractFully`)
14
+ * and returns the validated flat-data shape.
15
+ * 2. `hydrateSqlStorage` walks the validated `storage` subtree and
16
+ * constructs the family-shared SQL Contract IR class hierarchy
17
+ * (`SqlStorage` -> `StorageTable` -> `StorageColumn` / `PrimaryKey`
18
+ * / …). The rest of the contract envelope is JSON-clean primitive
19
+ * data and passes through unchanged.
20
+ * 3. `constructTargetContract` is the target-specific extension hook;
21
+ * defaults to identity. Targets that need to attach target-only
22
+ * fields (e.g. target-specific derived storage fields) override it.
23
+ *
24
+ * Default `serializeContract` is identity over the contract — concrete
25
+ * SQL targets ship JSON-clean class instances, so the contract value
26
+ * can be stringified directly. The non-enumerable family-level `kind`
27
+ * discriminator on `SqlNode` instances stays out of the persisted
28
+ * envelope automatically. Targets that need to canonicalize on the way
29
+ * out (key ordering, dropping computed-only fields) override
30
+ * `serializeContract` directly.
31
+ */
32
+ declare abstract class SqlContractSerializerBase<TContract extends Contract<SqlStorage>> implements ContractSerializer<TContract> {
33
+ private readonly entityTypeRegistry;
34
+ constructor(entityTypeRegistry: ReadonlyMap<string, SqlEntityHydrationFactory>);
35
+ deserializeContract(json: unknown): TContract;
36
+ serializeContract(contract: TContract): JsonObject;
37
+ /**
38
+ * Family-shared validation pipeline (delegates to
39
+ * `validateSqlContractFully` in `@prisma-next/sql-contract/validators`):
40
+ * structural arktype + framework-shared domain + SQL storage
41
+ * logical-consistency + SQL storage semantic + model ↔ storage
42
+ * reference checks. Subclasses override to add target-specific
43
+ * structural checks before hydration; the family default suffices
44
+ * for targets whose contract shape is the SQL-shared shape
45
+ * (Postgres, SQLite today).
46
+ */
47
+ protected parseSqlContractStructure(json: unknown): Contract<SqlStorage>;
48
+ /**
49
+ * Family-shared hydration walker. Lifts the validated flat-data
50
+ * `storage` subtree into the SQL Contract IR class hierarchy by
51
+ * constructing a single `SqlStorage` instance — its constructor
52
+ * cascades nested instantiation of `StorageTable`, `StorageColumn`,
53
+ * `PrimaryKey`, `UniqueConstraint`, `Index`, `ForeignKey`,
54
+ * `ForeignKeyReferences`, and `StorageTypeInstance`. The rest of the
55
+ * contract envelope (target identity, hashes, capabilities, models,
56
+ * meta, …) is JSON-clean primitive data and passes through unchanged.
57
+ *
58
+ * Polymorphic `storage.types` entries are normalised before the
59
+ * `SqlStorage` constructor runs: when an entry carries an enumerable
60
+ * string `kind`, the serializer looks up a pack-registered hydration
61
+ * factory for that discriminator and delegates reconstruction. Entries
62
+ * with no registered factory pass through unchanged (codec-typed JSON
63
+ * stays codec-typed until `SqlStorage` normalises it).
64
+ */
65
+ protected hydrateSqlStorage(validated: Contract<SqlStorage>): Contract<SqlStorage>;
66
+ /**
67
+ * Per-entry hydration dispatcher for `storage.types`. When `kind` is a
68
+ * string and the constructor registry supplies a factory for that key,
69
+ * the factory returns the hydrated `SqlStorageTypeEntry`. Otherwise the
70
+ * entry passes through unchanged for `SqlStorage` to normalise.
71
+ */
72
+ protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry;
73
+ /**
74
+ * Target-specific construction hook. Defaults to identity; targets
75
+ * that need to wrap the hydrated contract (e.g. attach target-only
76
+ * derived fields, narrow the contract type to a target-specific
77
+ * subtype) override.
78
+ */
79
+ protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract;
80
+ }
81
+ //#endregion
82
+ //#region src/core/ir/sql-contract-serializer.d.ts
83
+ /**
84
+ * Default SQL family `ContractSerializer` concretion. Inherits the
85
+ * full SQL-shared deserialization pipeline (structural validation +
86
+ * IR-class hydration) without pack-registered `storage.types`
87
+ * hydration factories — targets that emit polymorphic JSON outside the
88
+ * codec-typed envelope wire a target-specific subclass with a populated
89
+ * registry (see Postgres). Family-level call sites instantiate this
90
+ * default directly when no target serializer is supplied.
91
+ */
92
+ declare class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {
93
+ constructor();
94
+ }
95
+ //#endregion
96
+ //#region src/core/ir/sql-schema-verifier-base.d.ts
97
+ /**
98
+ * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared
99
+ * walk (table-by-table + column-by-column matching keyed by
100
+ * `(namespace.id, name)`, FK / unique / index comparisons via the
101
+ * existing helpers in `verify-helpers.ts`) and exposes a protected hook
102
+ * for target extensions (Postgres functions, RLS policies, future
103
+ * target-only kinds).
104
+ *
105
+ * The base accumulates issues in a single buffer and returns the
106
+ * combined result; the per-SPI family abstract handles the result
107
+ * envelope shape so concrete subclasses focus on target-specific
108
+ * verification logic.
109
+ *
110
+ * The protected hooks (`verifyCommonSqlSchema`,
111
+ * `verifyTargetExtensions`) carry the stable base API that target
112
+ * subclasses (`PostgresSchemaVerifier`, `SqliteSchemaVerifier`)
113
+ * compile against; the SQL-shared walk implementation will be lifted
114
+ * into this base when the verifier behaviour migrates off the
115
+ * legacy adapter shells.
116
+ */
117
+ declare abstract class SqlSchemaVerifierBase<TContract, TSchema> implements SchemaVerifier<TContract, TSchema> {
118
+ verifySchema(options: SchemaVerifyOptions<TContract, TSchema>): SchemaVerifyResult;
119
+ /**
120
+ * SQL-shared verification — table/column/FK/unique/index walks keyed
121
+ * by `(namespace.id, name)`. Concrete subclasses provide the
122
+ * family-shared implementation today; a future iteration will lift
123
+ * the shared walk into this base.
124
+ */
125
+ protected abstract verifyCommonSqlSchema(options: SchemaVerifyOptions<TContract, TSchema>): readonly SchemaIssue[];
126
+ /**
127
+ * Target-specific extensions — e.g. Postgres functions, future RLS
128
+ * policies, namespace-mismatch issues. Returns the empty list when the
129
+ * target ships no extensions over the SQL family alphabet.
130
+ */
131
+ protected abstract verifyTargetExtensions(options: SchemaVerifyOptions<TContract, TSchema>): readonly SchemaIssue[];
132
+ }
133
+ //#endregion
134
+ export { SqlContractSerializer, SqlContractSerializerBase, type SqlEntityHydrationFactory, SqlSchemaVerifierBase };
135
+ //# sourceMappingURL=ir.d.mts.map
@@ -0,0 +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":";;;;;;KAMY,yBAAA,IAA6B,KAAA,cAAmB,mBAAA;;AAA5D;;;;;AA0BA;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,iBAGX,kBAAA;cAAA,kBAAA,EAAoB,WAAA,SAAoB,yBAAA;EAG3D,mBAAA,CAAoB,IAAA,YAAgB,SAAA;EAMpC,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAZX;;;;;;;;;;EAAA,UA8BnB,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EA3B1C;;;;;;;;;;;;;;;;;EAAA,UAgDT,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EA2B7D;;;;;;EAAA,UAAA,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAqB7B;;;;;;EAAA,UAAxB,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;AAAA;;;;;;AA9HrE;;;;;AA0BA;cCnBa,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;ADP9E;;;;;AA0BA;;;;;;;;;;uBELsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EFiCZ;;;;;;EAAA,mBEpBjC,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;EFuFyC;;;;;EAAA,mBEhFlC,sBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;AAAA"}
package/dist/ir.mjs ADDED
@@ -0,0 +1,37 @@
1
+ import { n as SqlContractSerializerBase, t as SqlContractSerializer } from "./sql-contract-serializer-qUQCnP-k.mjs";
2
+ //#region src/core/ir/sql-schema-verifier-base.ts
3
+ /**
4
+ * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared
5
+ * walk (table-by-table + column-by-column matching keyed by
6
+ * `(namespace.id, name)`, FK / unique / index comparisons via the
7
+ * existing helpers in `verify-helpers.ts`) and exposes a protected hook
8
+ * for target extensions (Postgres functions, RLS policies, future
9
+ * target-only kinds).
10
+ *
11
+ * The base accumulates issues in a single buffer and returns the
12
+ * combined result; the per-SPI family abstract handles the result
13
+ * envelope shape so concrete subclasses focus on target-specific
14
+ * verification logic.
15
+ *
16
+ * The protected hooks (`verifyCommonSqlSchema`,
17
+ * `verifyTargetExtensions`) carry the stable base API that target
18
+ * subclasses (`PostgresSchemaVerifier`, `SqliteSchemaVerifier`)
19
+ * compile against; the SQL-shared walk implementation will be lifted
20
+ * into this base when the verifier behaviour migrates off the
21
+ * legacy adapter shells.
22
+ */
23
+ var SqlSchemaVerifierBase = class {
24
+ verifySchema(options) {
25
+ const issues = [];
26
+ issues.push(...this.verifyCommonSqlSchema(options));
27
+ issues.push(...this.verifyTargetExtensions(options));
28
+ return {
29
+ ok: issues.length === 0,
30
+ issues
31
+ };
32
+ }
33
+ };
34
+ //#endregion
35
+ export { SqlContractSerializer, SqlContractSerializerBase, SqlSchemaVerifierBase };
36
+
37
+ //# sourceMappingURL=ir.mjs.map
@@ -0,0 +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,EAAE;EAChC,OAAO,KAAK,GAAG,KAAK,sBAAsB,QAAQ,CAAC;EACnD,OAAO,KAAK,GAAG,KAAK,uBAAuB,QAAQ,CAAC;EACpD,OAAO;GAAE,IAAI,OAAO,WAAW;GAAG;GAAQ"}
@@ -1,4 +1,4 @@
1
- import { O as SqlPlanTargetDetails, g as SqlMigrationPlanOperation } from "./types-Da-eOg20.mjs";
1
+ import { O as SqlPlanTargetDetails, g as SqlMigrationPlanOperation } from "./types-DMINfGUO.mjs";
2
2
  import { Migration } from "@prisma-next/migration-tools/migration";
3
3
 
4
4
  //#region src/core/sql-migration.d.ts
package/dist/runtime.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as TIMESTAMP_NOW_GENERATOR_ID } from "./timestamp-now-generator-BWp8S2sa.mjs";
1
+ import { t as TIMESTAMP_NOW_GENERATOR_ID } from "./timestamp-now-generator-r7BP5n3l.mjs";
2
2
  //#region src/core/runtime-instance.ts
3
3
  /**
4
4
  * Creates a SQL execution-plane family instance.
@@ -1,6 +1,7 @@
1
- import { i as verifySqlSchema, n as NativeTypeNormalizer, r as VerifySqlSchemaOptions } from "./verify-sql-schema-CPHiuYHR.mjs";
1
+ import { i as verifySqlSchema, n as NativeTypeNormalizer, r as VerifySqlSchemaOptions } from "./verify-sql-schema-Bfvz07Ik.mjs";
2
2
  import { SchemaIssue } from "@prisma-next/framework-components/control";
3
3
  import { SqlIndexIR, SqlUniqueIR } from "@prisma-next/sql-schema-ir/types";
4
+
4
5
  //#region src/core/schema-verify/verify-helpers.d.ts
5
6
  /**
6
7
  * Compares two arrays of strings for equality (order-sensitive).
@@ -1 +1 @@
1
- {"version":3,"file":"schema-verify.d.mts","names":[],"sources":["../src/core/schema-verify/verify-helpers.ts"],"mappings":";;;;;;;iBAqDgB,WAAA,CAAY,CAAA,qBAAsB,CAAA;AA+BlD;;;;;;;;;;;AA0BA;AA1BA,iBAAgB,2BAAA,CACd,OAAA,WAAkB,WAAA,IAClB,OAAA,WAAkB,UAAA,IAClB,OAAA;;;;;;;;;;;;;iBAuBc,gBAAA,CACd,OAAA,WAAkB,UAAA,IAClB,OAAA,WAAkB,WAAA,IAClB,OAAA"}
1
+ {"version":3,"file":"schema-verify.d.mts","names":[],"sources":["../src/core/schema-verify/verify-helpers.ts"],"mappings":";;;;;;;;iBAqDgB,WAAA,CAAY,CAAA,qBAAsB,CAAA;AA+BlD;;;;;;;;;;;AA0BA;AA1BA,iBAAgB,2BAAA,CACd,OAAA,WAAkB,WAAA,IAClB,OAAA,WAAkB,UAAA,IAClB,OAAA;;;;;;;;;;;;;iBAuBc,gBAAA,CACd,OAAA,WAAkB,UAAA,IAClB,OAAA,WAAkB,WAAA,IAClB,OAAA"}
@@ -1,2 +1,2 @@
1
- import { i as isUniqueConstraintSatisfied, n as arraysEqual, r as isIndexSatisfied, t as verifySqlSchema } from "./verify-sql-schema-DV-UsTG9.mjs";
1
+ import { i as isUniqueConstraintSatisfied, n as arraysEqual, r as isIndexSatisfied, t as verifySqlSchema } from "./verify-sql-schema-BXw7yx6L.mjs";
2
2
  export { arraysEqual, isIndexSatisfied, isUniqueConstraintSatisfied, verifySqlSchema };
@@ -0,0 +1,125 @@
1
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
2
+ import { validateSqlContractFully } from "@prisma-next/sql-contract/validators";
3
+ //#region src/core/ir/sql-contract-serializer-base.ts
4
+ /**
5
+ * SQL family `ContractSerializer` abstract base. Carries the SQL-shared
6
+ * deserialization pipeline:
7
+ *
8
+ * 1. `parseSqlContractStructure` validates the on-disk JSON envelope
9
+ * against the SQL contract arktype schema (`validateSqlContractFully`)
10
+ * and returns the validated flat-data shape.
11
+ * 2. `hydrateSqlStorage` walks the validated `storage` subtree and
12
+ * constructs the family-shared SQL Contract IR class hierarchy
13
+ * (`SqlStorage` -> `StorageTable` -> `StorageColumn` / `PrimaryKey`
14
+ * / …). The rest of the contract envelope is JSON-clean primitive
15
+ * data and passes through unchanged.
16
+ * 3. `constructTargetContract` is the target-specific extension hook;
17
+ * defaults to identity. Targets that need to attach target-only
18
+ * fields (e.g. target-specific derived storage fields) override it.
19
+ *
20
+ * Default `serializeContract` is identity over the contract — concrete
21
+ * SQL targets ship JSON-clean class instances, so the contract value
22
+ * can be stringified directly. The non-enumerable family-level `kind`
23
+ * discriminator on `SqlNode` instances stays out of the persisted
24
+ * envelope automatically. Targets that need to canonicalize on the way
25
+ * out (key ordering, dropping computed-only fields) override
26
+ * `serializeContract` directly.
27
+ */
28
+ var SqlContractSerializerBase = class {
29
+ entityTypeRegistry;
30
+ constructor(entityTypeRegistry) {
31
+ this.entityTypeRegistry = entityTypeRegistry;
32
+ }
33
+ deserializeContract(json) {
34
+ const validated = this.parseSqlContractStructure(json);
35
+ const hydrated = this.hydrateSqlStorage(validated);
36
+ return this.constructTargetContract(hydrated);
37
+ }
38
+ serializeContract(contract) {
39
+ return contract;
40
+ }
41
+ /**
42
+ * Family-shared validation pipeline (delegates to
43
+ * `validateSqlContractFully` in `@prisma-next/sql-contract/validators`):
44
+ * structural arktype + framework-shared domain + SQL storage
45
+ * logical-consistency + SQL storage semantic + model ↔ storage
46
+ * reference checks. Subclasses override to add target-specific
47
+ * structural checks before hydration; the family default suffices
48
+ * for targets whose contract shape is the SQL-shared shape
49
+ * (Postgres, SQLite today).
50
+ */
51
+ parseSqlContractStructure(json) {
52
+ return validateSqlContractFully(json);
53
+ }
54
+ /**
55
+ * Family-shared hydration walker. Lifts the validated flat-data
56
+ * `storage` subtree into the SQL Contract IR class hierarchy by
57
+ * constructing a single `SqlStorage` instance — its constructor
58
+ * cascades nested instantiation of `StorageTable`, `StorageColumn`,
59
+ * `PrimaryKey`, `UniqueConstraint`, `Index`, `ForeignKey`,
60
+ * `ForeignKeyReferences`, and `StorageTypeInstance`. The rest of the
61
+ * contract envelope (target identity, hashes, capabilities, models,
62
+ * meta, …) is JSON-clean primitive data and passes through unchanged.
63
+ *
64
+ * Polymorphic `storage.types` entries are normalised before the
65
+ * `SqlStorage` constructor runs: when an entry carries an enumerable
66
+ * string `kind`, the serializer looks up a pack-registered hydration
67
+ * factory for that discriminator and delegates reconstruction. Entries
68
+ * with no registered factory pass through unchanged (codec-typed JSON
69
+ * stays codec-typed until `SqlStorage` normalises it).
70
+ */
71
+ hydrateSqlStorage(validated) {
72
+ const types = validated.storage.types;
73
+ const hydratedTypes = types !== void 0 ? Object.fromEntries(Object.entries(types).map(([name, entry]) => [name, this.hydrateStorageTypeEntry(entry)])) : void 0;
74
+ return {
75
+ ...validated,
76
+ storage: new SqlStorage({
77
+ ...validated.storage,
78
+ ...hydratedTypes !== void 0 ? { types: hydratedTypes } : {}
79
+ })
80
+ };
81
+ }
82
+ /**
83
+ * Per-entry hydration dispatcher for `storage.types`. When `kind` is a
84
+ * string and the constructor registry supplies a factory for that key,
85
+ * the factory returns the hydrated `SqlStorageTypeEntry`. Otherwise the
86
+ * entry passes through unchanged for `SqlStorage` to normalise.
87
+ */
88
+ hydrateStorageTypeEntry(entry) {
89
+ if (typeof entry !== "object" || entry === null) return entry;
90
+ const kind = entry.kind;
91
+ if (typeof kind !== "string") return entry;
92
+ const factory = this.entityTypeRegistry.get(kind);
93
+ if (factory === void 0) return entry;
94
+ return factory(entry);
95
+ }
96
+ /**
97
+ * Target-specific construction hook. Defaults to identity; targets
98
+ * that need to wrap the hydrated contract (e.g. attach target-only
99
+ * derived fields, narrow the contract type to a target-specific
100
+ * subtype) override.
101
+ */
102
+ constructTargetContract(hydrated) {
103
+ return hydrated;
104
+ }
105
+ };
106
+ //#endregion
107
+ //#region src/core/ir/sql-contract-serializer.ts
108
+ /**
109
+ * Default SQL family `ContractSerializer` concretion. Inherits the
110
+ * full SQL-shared deserialization pipeline (structural validation +
111
+ * IR-class hydration) without pack-registered `storage.types`
112
+ * hydration factories — targets that emit polymorphic JSON outside the
113
+ * codec-typed envelope wire a target-specific subclass with a populated
114
+ * registry (see Postgres). Family-level call sites instantiate this
115
+ * default directly when no target serializer is supplied.
116
+ */
117
+ var SqlContractSerializer = class extends SqlContractSerializerBase {
118
+ constructor() {
119
+ super(/* @__PURE__ */ new Map());
120
+ }
121
+ };
122
+ //#endregion
123
+ export { SqlContractSerializerBase as n, SqlContractSerializer as t };
124
+
125
+ //# sourceMappingURL=sql-contract-serializer-qUQCnP-k.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-contract-serializer-qUQCnP-k.mjs","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSerializer } from '@prisma-next/framework-components/control';\nimport { SqlStorage, type SqlStorageTypeEntry } from '@prisma-next/sql-contract/types';\nimport { validateSqlContractFully } from '@prisma-next/sql-contract/validators';\nimport type { JsonObject } from '@prisma-next/utils/json';\n\nexport type SqlEntityHydrationFactory = (entry: unknown) => SqlStorageTypeEntry;\n\n/**\n * SQL family `ContractSerializer` abstract base. Carries the SQL-shared\n * deserialization pipeline:\n *\n * 1. `parseSqlContractStructure` validates the on-disk JSON envelope\n * against the SQL contract arktype schema (`validateSqlContractFully`)\n * and returns the validated flat-data shape.\n * 2. `hydrateSqlStorage` walks the validated `storage` subtree and\n * constructs the family-shared SQL Contract IR class hierarchy\n * (`SqlStorage` -> `StorageTable` -> `StorageColumn` / `PrimaryKey`\n * / …). The rest of the contract envelope is JSON-clean primitive\n * data and passes through unchanged.\n * 3. `constructTargetContract` is the target-specific extension hook;\n * defaults to identity. Targets that need to attach target-only\n * fields (e.g. target-specific derived storage fields) override it.\n *\n * Default `serializeContract` is identity over the contract — concrete\n * SQL targets ship JSON-clean class instances, so the contract value\n * can be stringified directly. The non-enumerable family-level `kind`\n * discriminator on `SqlNode` instances stays out of the persisted\n * envelope automatically. Targets that need to canonicalize on the way\n * out (key ordering, dropping computed-only fields) override\n * `serializeContract` directly.\n */\nexport abstract class SqlContractSerializerBase<TContract extends Contract<SqlStorage>>\n implements ContractSerializer<TContract>\n{\n constructor(\n private readonly entityTypeRegistry: ReadonlyMap<string, SqlEntityHydrationFactory>,\n ) {}\n\n deserializeContract(json: unknown): TContract {\n const validated = this.parseSqlContractStructure(json);\n const hydrated = this.hydrateSqlStorage(validated);\n return this.constructTargetContract(hydrated);\n }\n\n serializeContract(contract: TContract): JsonObject {\n // Targets that ship enumerable runtime-only fields must override\n // this method (mirroring `MongoTargetContractSerializer.serializeContract`)\n // to construct the persisted envelope explicitly; the default identity\n // works only when every enumerable own property belongs in the JSON.\n return contract as unknown as JsonObject;\n }\n\n /**\n * Family-shared validation pipeline (delegates to\n * `validateSqlContractFully` in `@prisma-next/sql-contract/validators`):\n * structural arktype + framework-shared domain + SQL storage\n * logical-consistency + SQL storage semantic + model ↔ storage\n * reference checks. Subclasses override to add target-specific\n * structural checks before hydration; the family default suffices\n * for targets whose contract shape is the SQL-shared shape\n * (Postgres, SQLite today).\n */\n protected parseSqlContractStructure(json: unknown): Contract<SqlStorage> {\n return validateSqlContractFully<Contract<SqlStorage>>(json);\n }\n\n /**\n * Family-shared hydration walker. Lifts the validated flat-data\n * `storage` subtree into the SQL Contract IR class hierarchy by\n * constructing a single `SqlStorage` instance — its constructor\n * cascades nested instantiation of `StorageTable`, `StorageColumn`,\n * `PrimaryKey`, `UniqueConstraint`, `Index`, `ForeignKey`,\n * `ForeignKeyReferences`, and `StorageTypeInstance`. The rest of the\n * contract envelope (target identity, hashes, capabilities, models,\n * meta, …) is JSON-clean primitive data and passes through unchanged.\n *\n * Polymorphic `storage.types` entries are normalised before the\n * `SqlStorage` constructor runs: when an entry carries an enumerable\n * string `kind`, the serializer looks up a pack-registered hydration\n * factory for that discriminator and delegates reconstruction. Entries\n * with no registered factory pass through unchanged (codec-typed JSON\n * stays codec-typed until `SqlStorage` normalises it).\n */\n protected hydrateSqlStorage(validated: Contract<SqlStorage>): Contract<SqlStorage> {\n const types = validated.storage.types;\n const hydratedTypes =\n types !== undefined\n ? Object.fromEntries(\n Object.entries(types).map(([name, entry]) => [\n name,\n this.hydrateStorageTypeEntry(entry),\n ]),\n )\n : undefined;\n\n return {\n ...validated,\n storage: new SqlStorage({\n ...validated.storage,\n ...(hydratedTypes !== undefined ? { types: hydratedTypes } : {}),\n }),\n };\n }\n\n /**\n * Per-entry hydration dispatcher for `storage.types`. When `kind` is a\n * string and the constructor registry supplies a factory for that key,\n * the factory returns the hydrated `SqlStorageTypeEntry`. Otherwise the\n * entry passes through unchanged for `SqlStorage` to normalise.\n */\n protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry {\n if (typeof entry !== 'object' || entry === null) {\n return entry;\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind !== 'string') {\n return entry;\n }\n const factory = this.entityTypeRegistry.get(kind);\n if (factory === undefined) {\n return entry;\n }\n return factory(entry);\n }\n\n /**\n * Target-specific construction hook. Defaults to identity; targets\n * that need to wrap the hydrated contract (e.g. attach target-only\n * derived fields, narrow the contract type to a target-specific\n * subtype) override.\n */\n protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract {\n return hydrated as TContract;\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { SqlContractSerializerBase } from './sql-contract-serializer-base';\n\n/**\n * Default SQL family `ContractSerializer` concretion. Inherits the\n * full SQL-shared deserialization pipeline (structural validation +\n * IR-class hydration) without pack-registered `storage.types`\n * hydration factories — targets that emit polymorphic JSON outside the\n * codec-typed envelope wire a target-specific subclass with a populated\n * registry (see Postgres). Family-level call sites instantiate this\n * default directly when no target serializer is supplied.\n */\nexport class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n super(new Map());\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAsB,4BAAtB,MAEA;CAEqB;CADnB,YACE,oBACA;EADiB,KAAA,qBAAA;;CAGnB,oBAAoB,MAA0B;EAC5C,MAAM,YAAY,KAAK,0BAA0B,KAAK;EACtD,MAAM,WAAW,KAAK,kBAAkB,UAAU;EAClD,OAAO,KAAK,wBAAwB,SAAS;;CAG/C,kBAAkB,UAAiC;EAKjD,OAAO;;;;;;;;;;;;CAaT,0BAAoC,MAAqC;EACvE,OAAO,yBAA+C,KAAK;;;;;;;;;;;;;;;;;;;CAoB7D,kBAA4B,WAAuD;EACjF,MAAM,QAAQ,UAAU,QAAQ;EAChC,MAAM,gBACJ,UAAU,KAAA,IACN,OAAO,YACL,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,CAC3C,MACA,KAAK,wBAAwB,MAAM,CACpC,CAAC,CACH,GACD,KAAA;EAEN,OAAO;GACL,GAAG;GACH,SAAS,IAAI,WAAW;IACtB,GAAG,UAAU;IACb,GAAI,kBAAkB,KAAA,IAAY,EAAE,OAAO,eAAe,GAAG,EAAE;IAChE,CAAC;GACH;;;;;;;;CASH,wBAAkC,OAAiD;EACjF,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;EAET,MAAM,OAAQ,MAA6B;EAC3C,IAAI,OAAO,SAAS,UAClB,OAAO;EAET,MAAM,UAAU,KAAK,mBAAmB,IAAI,KAAK;EACjD,IAAI,YAAY,KAAA,GACd,OAAO;EAET,OAAO,QAAQ,MAAM;;;;;;;;CASvB,wBAAkC,UAA2C;EAC3E,OAAO;;;;;;;;;;;;;;ACxHX,IAAa,wBAAb,cAA2C,0BAAgD;CACzF,cAAc;EACZ,sBAAM,IAAI,KAAK,CAAC"}
@@ -83,4 +83,4 @@ function temporalAuthoringPresets(input) {
83
83
  //#endregion
84
84
  export { temporalAuthoringPresets as n, timestampNowControlDescriptor as r, TIMESTAMP_NOW_GENERATOR_ID as t };
85
85
 
86
- //# sourceMappingURL=timestamp-now-generator-BWp8S2sa.mjs.map
86
+ //# sourceMappingURL=timestamp-now-generator-r7BP5n3l.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"timestamp-now-generator-BWp8S2sa.mjs","names":[],"sources":["../src/core/timestamp-now-generator.ts"],"sourcesContent":["import type { AuthoringFieldPresetDescriptor } from '@prisma-next/framework-components/authoring';\nimport type { MutationDefaultGeneratorDescriptor } from '@prisma-next/framework-components/control';\n\n/**\n * Canonical id for the wall-clock-now mutation default generator.\n *\n * Owned by `family-sql` because that's where the generator lives. The\n * id flows out from here to (1) the control-plane descriptor and the\n * temporal field-preset pair below, (2) the runtime-plane sibling\n * `timestamp-now-runtime-generator.ts`, and (3) authoring surfaces\n * (PSL `temporal.updatedAt()`, TS `field.temporal.updatedAt()`) via\n * the descriptor flow. Co-locating the constant with its only owner\n * keeps the framework layer free of concrete generator ids.\n */\nexport const TIMESTAMP_NOW_GENERATOR_ID = 'timestampNow' as const;\n\n/**\n * Builds the canonical control-plane descriptor for the wall-clock-now\n * mutation default generator. The descriptor's `id` and `buildPhases`\n * are target-agnostic so PSL `temporal.updatedAt()` and TS\n * `field.temporal.updatedAt()` lower to byte-identical contracts.\n *\n * `applicableCodecIds` is omitted: `timestampNow` is preset-only (not\n * reachable via `@default(timestampNow())` lowering), and the codec is\n * co-registered by the preset descriptor itself, so the\n * `@default(...)` compatibility check has no role to play here.\n */\nexport function timestampNowControlDescriptor(): MutationDefaultGeneratorDescriptor {\n return {\n id: TIMESTAMP_NOW_GENERATOR_ID,\n buildPhases: () => ({\n onCreate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n onUpdate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n }),\n };\n}\n\n/**\n * Builds the canonical `temporal.{createdAt,updatedAt}` field-preset pair\n * for a SQL target. `createdAt` lowers to a `now()` storage default;\n * `updatedAt` lowers to the `timestampNow` execution generator on both\n * `onCreate` and `onUpdate` (RD: \"last modified time\", non-null). Targets\n * supply the codec/native-type pair that matches their timestamp column;\n * everything else is shared so PSL `temporal.updatedAt()` and TS\n * `field.temporal.updatedAt()` lower to byte-identical contracts across\n * targets by construction.\n */\nexport function temporalAuthoringPresets<\n const CodecId extends string,\n const NativeType extends string,\n>(input: { readonly codecId: CodecId; readonly nativeType: NativeType }) {\n const { codecId, nativeType } = input;\n return {\n createdAt: {\n kind: 'fieldPreset',\n output: {\n codecId,\n nativeType,\n default: { kind: 'function', expression: 'now()' },\n },\n },\n updatedAt: {\n kind: 'fieldPreset',\n output: {\n codecId,\n nativeType,\n executionDefaults: {\n onCreate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n onUpdate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n },\n },\n },\n } as const satisfies Record<string, AuthoringFieldPresetDescriptor>;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,MAAa,6BAA6B;;;;;;;;;;;;AAa1C,SAAgB,gCAAoE;CAClF,OAAO;EACL,IAAI;EACJ,oBAAoB;GAClB,UAAU;IAAE,MAAM;IAAa,IAAI;IAA4B;GAC/D,UAAU;IAAE,MAAM;IAAa,IAAI;IAA4B;GAChE;EACF;;;;;;;;;;;;AAaH,SAAgB,yBAGd,OAAuE;CACvE,MAAM,EAAE,SAAS,eAAe;CAChC,OAAO;EACL,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,SAAS;KAAE,MAAM;KAAY,YAAY;KAAS;IACnD;GACF;EACD,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,mBAAmB;KACjB,UAAU;MAAE,MAAM;MAAa,IAAI;MAA4B;KAC/D,UAAU;MAAE,MAAM;MAAa,IAAI;MAA4B;KAChE;IACF;GACF;EACF"}
1
+ {"version":3,"file":"timestamp-now-generator-r7BP5n3l.mjs","names":[],"sources":["../src/core/timestamp-now-generator.ts"],"sourcesContent":["import type { AuthoringFieldPresetDescriptor } from '@prisma-next/framework-components/authoring';\nimport type { MutationDefaultGeneratorDescriptor } from '@prisma-next/framework-components/control';\n\n/**\n * Canonical id for the wall-clock-now mutation default generator.\n *\n * Owned by `family-sql` because that's where the generator lives. The\n * id flows out from here to (1) the control-plane descriptor and the\n * temporal field-preset pair below, (2) the runtime-plane sibling\n * `timestamp-now-runtime-generator.ts`, and (3) authoring surfaces\n * (PSL `temporal.updatedAt()`, TS `field.temporal.updatedAt()`) via\n * the descriptor flow. Co-locating the constant with its only owner\n * keeps the framework layer free of concrete generator ids.\n */\nexport const TIMESTAMP_NOW_GENERATOR_ID = 'timestampNow' as const;\n\n/**\n * Builds the canonical control-plane descriptor for the wall-clock-now\n * mutation default generator. The descriptor's `id` and `buildPhases`\n * are target-agnostic so PSL `temporal.updatedAt()` and TS\n * `field.temporal.updatedAt()` lower to byte-identical contracts.\n *\n * `applicableCodecIds` is omitted: `timestampNow` is preset-only (not\n * reachable via `@default(timestampNow())` lowering), and the codec is\n * co-registered by the preset descriptor itself, so the\n * `@default(...)` compatibility check has no role to play here.\n */\nexport function timestampNowControlDescriptor(): MutationDefaultGeneratorDescriptor {\n return {\n id: TIMESTAMP_NOW_GENERATOR_ID,\n buildPhases: () => ({\n onCreate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n onUpdate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n }),\n };\n}\n\n/**\n * Builds the canonical `temporal.{createdAt,updatedAt}` field-preset pair\n * for a SQL target. `createdAt` lowers to a `now()` storage default;\n * `updatedAt` lowers to the `timestampNow` execution generator on both\n * `onCreate` and `onUpdate` (RD: \"last modified time\", non-null). Targets\n * supply the codec/native-type pair that matches their timestamp column;\n * everything else is shared so PSL `temporal.updatedAt()` and TS\n * `field.temporal.updatedAt()` lower to byte-identical contracts across\n * targets by construction.\n */\nexport function temporalAuthoringPresets<\n const CodecId extends string,\n const NativeType extends string,\n>(input: { readonly codecId: CodecId; readonly nativeType: NativeType }) {\n const { codecId, nativeType } = input;\n return {\n createdAt: {\n kind: 'fieldPreset',\n output: {\n codecId,\n nativeType,\n default: { kind: 'function', expression: 'now()' },\n },\n },\n updatedAt: {\n kind: 'fieldPreset',\n output: {\n codecId,\n nativeType,\n executionDefaults: {\n onCreate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n onUpdate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n },\n },\n },\n } as const satisfies Record<string, AuthoringFieldPresetDescriptor>;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,MAAa,6BAA6B;;;;;;;;;;;;AAa1C,SAAgB,gCAAoE;CAClF,OAAO;EACL,IAAI;EACJ,oBAAoB;GAClB,UAAU;IAAE,MAAM;IAAa,IAAI;IAA4B;GAC/D,UAAU;IAAE,MAAM;IAAa,IAAI;IAA4B;GAChE;EACF;;;;;;;;;;;;AAaH,SAAgB,yBAGd,OAAuE;CACvE,MAAM,EAAE,SAAS,eAAe;CAChC,OAAO;EACL,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,SAAS;KAAE,MAAM;KAAY,YAAY;KAAS;IACnD;GACF;EACD,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,mBAAmB;KACjB,UAAU;MAAE,MAAM;MAAa,IAAI;MAA4B;KAC/D,UAAU;MAAE,MAAM;MAAa,IAAI;MAA4B;KAChE;IACF;GACF;EACF"}
@@ -1,10 +1,10 @@
1
- import { ContractSpace, ControlAdapterDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyInstance, ControlStack, MigratableTargetDescriptor, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, MigrationPlannerFailureResult, MigrationPlannerSuccessResult, MigrationRunnerExecutionChecks, MigrationRunnerFailure, MigrationRunnerSuccessValue, OpFactoryCall, OperationContext, OperationPreview, OperationPreviewCapable, PslContractInferCapable, SchemaIssue, SchemaViewCapable, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
1
+ import { ContractSerializer, ContractSpace, ControlAdapterDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyInstance, ControlStack, MigratableTargetDescriptor, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, MigrationPlannerFailureResult, MigrationPlannerSuccessResult, MigrationRunnerExecutionChecks, MigrationRunnerFailure, MigrationRunnerSuccessValue, OpFactoryCall, OperationContext, OperationPreview, OperationPreviewCapable, PslContractInferCapable, SchemaIssue, SchemaVerifier, SchemaViewCapable, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
2
+ import { SqlStorage, StorageColumn, StorageTable, StorageTypeInstance } from "@prisma-next/sql-contract/types";
2
3
  import { Result } from "@prisma-next/utils/result";
3
4
  import { Contract } from "@prisma-next/contract/types";
4
5
  import { AnyQueryAst, LoweredStatement, LowererContext } from "@prisma-next/sql-relational-core/ast";
5
6
  import { SqlSchemaIR } from "@prisma-next/sql-schema-ir/types";
6
7
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
7
- import { SqlStorage, StorageColumn, StorageTable, StorageTypeInstance } from "@prisma-next/sql-contract/types";
8
8
  import { TypesImportSpec } from "@prisma-next/framework-components/emission";
9
9
  import { PslDocumentAst } from "@prisma-next/framework-components/psl-ast";
10
10
  import { SqlOperationDescriptors } from "@prisma-next/sql-operations";
@@ -22,19 +22,16 @@ interface SqlFamilyInstanceState {
22
22
  readonly extensionIds: ReadonlyArray<string>;
23
23
  readonly typeMetadataRegistry: SqlTypeMetadataRegistry;
24
24
  }
25
- interface SchemaVerifyOptions {
26
- readonly driver: ControlDriverInstance<'sql', string>;
27
- readonly contract: unknown;
28
- readonly strict: boolean;
29
- readonly context?: OperationContext;
25
+ interface SqlControlFamilyInstance extends ControlFamilyInstance<'sql', SqlSchemaIR>, SchemaViewCapable<SqlSchemaIR>, PslContractInferCapable<SqlSchemaIR>, OperationPreviewCapable, SqlFamilyInstanceState {
30
26
  /**
31
- * Active framework components participating in this composition.
32
- * All components must have matching familyId ('sql') and targetId.
27
+ * The family seam-of-record for on-disk contract reads. Structurally
28
+ * validates the JSON envelope, then hydrates IR-class instances via
29
+ * the per-target ContractSerializer. The single named entry point
30
+ * every CLI on-disk read crosses (TML-2536) — `as Contract` casts
31
+ * in production package sources are a serializer-bypass smell guarded
32
+ * by `pnpm lint:no-contract-cast`.
33
33
  */
34
- readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
35
- }
36
- interface SqlControlFamilyInstance extends ControlFamilyInstance<'sql', SqlSchemaIR>, SchemaViewCapable<SqlSchemaIR>, PslContractInferCapable<SqlSchemaIR>, OperationPreviewCapable, SqlFamilyInstanceState {
37
- validateContract(contractJson: unknown): Contract;
34
+ deserializeContract(contractJson: unknown): Contract;
38
35
  verify(options: {
39
36
  readonly driver: ControlDriverInstance<'sql', string>;
40
37
  readonly contract: unknown;
@@ -42,17 +39,17 @@ interface SqlControlFamilyInstance extends ControlFamilyInstance<'sql', SqlSchem
42
39
  readonly contractPath: string;
43
40
  readonly configPath?: string;
44
41
  }): Promise<VerifyDatabaseResult>;
45
- schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult>;
46
42
  /**
47
43
  * Verify a contract against an already-introspected schema slice.
48
44
  *
49
- * Used by the aggregate verifier to invoke per-member verification
50
- * with the live schema pre-projected to the member's claimed slice
51
- * via `projectSchemaToSpace`. Closes F23 without per-member
52
- * pre-projection, single-contract verifiers see other-space tables
45
+ * Callers that need to verify against the live database compose
46
+ * `introspect({ driver })` + `verifySchema({ contract, schema, ... })`.
47
+ * The aggregate verifier projects each member's claimed slice via
48
+ * `projectSchemaToSpace` and hands the projected slice in — this
49
+ * keeps per-member verification from surfacing sibling-space tables
53
50
  * as `extras`.
54
51
  */
55
- schemaVerifyAgainstSchema(options: {
52
+ verifySchema(options: {
56
53
  readonly contract: unknown;
57
54
  readonly schema: SqlSchemaIR;
58
55
  readonly strict: boolean;
@@ -325,9 +322,10 @@ interface SqlMigrationPlannerPlanOptions {
325
322
  * or `null` for reconciliation flows that have no prior contract.
326
323
  *
327
324
  * Required at every call site so the structural fact "I have a prior
328
- * contract / I don't" is visible in the type. `migration plan` supplies
329
- * the previous bundle's `metadata.toContract`; `db update` / `db init`
330
- * reconcile against the live schema and pass `null`. Strategies that
325
+ * contract / I don't" is visible in the type. `migration plan` reads
326
+ * the predecessor bundle's `end-contract.json` from disk and passes
327
+ * the parsed value; `db update` / `db init` reconcile against the
328
+ * live schema and pass `null`. Strategies that
331
329
  * need from/to column-shape comparisons (unsafe type change, nullability
332
330
  * tightening) use this to decide whether to emit `dataTransform`
333
331
  * placeholders; they short-circuit when it is `null`.
@@ -445,8 +443,22 @@ interface MultiSpaceRunnerFailure extends SqlMigrationRunnerFailure {
445
443
  readonly failingSpace: string;
446
444
  }
447
445
  type MultiSpaceRunnerResult = Result<MultiSpaceRunnerSuccessValue, MultiSpaceRunnerFailure>;
448
- interface SqlControlTargetDescriptor<TTargetId extends string, TTargetDetails> extends MigratableTargetDescriptor<'sql', TTargetId, SqlControlFamilyInstance> {
446
+ interface SqlControlTargetDescriptor<TTargetId extends string, TTargetDetails, TContract extends Contract<SqlStorage> = Contract<SqlStorage>> extends MigratableTargetDescriptor<'sql', TTargetId, SqlControlFamilyInstance> {
449
447
  readonly queryOperations?: () => SqlOperationDescriptors;
448
+ /**
449
+ * JSON ⇄ class boundary for the SQL target's contract. The descriptor
450
+ * composes a concrete `SqlContractSerializerBase` subclass; the rest
451
+ * of the control stack reaches `descriptor.contractSerializer` rather
452
+ * than importing a per-target deserialization function.
453
+ */
454
+ readonly contractSerializer: ContractSerializer<TContract>;
455
+ /**
456
+ * Per-target schema verifier walking the contract against
457
+ * `SqlSchemaIR`. The descriptor composes a concrete
458
+ * `SqlSchemaVerifierBase` subclass; the family-shared walk lives on
459
+ * the base, the target-specific dispatch on the subclass.
460
+ */
461
+ readonly schemaVerifier: SchemaVerifier<TContract, SqlSchemaIR>;
450
462
  createPlanner(family: SqlControlFamilyInstance): SqlMigrationPlanner<TTargetDetails>;
451
463
  createRunner(family: SqlControlFamilyInstance): SqlMigrationRunner<TTargetDetails>;
452
464
  }
@@ -468,5 +480,5 @@ interface CreateSqlMigrationPlanOptions<TTargetDetails> {
468
480
  readonly meta?: AnyRecord;
469
481
  }
470
482
  //#endregion
471
- export { SqlPlannerConflictKind as A, SqlMigrationRunnerExecuteCallbacks as C, SqlMigrationRunnerSuccessValue as D, SqlMigrationRunnerResult as E, StorageTypePlanResult as F, SchemaVerifyOptions as I, SqlControlFamilyInstance as L, SqlPlannerFailureResult as M, SqlPlannerResult as N, SqlPlanTargetDetails as O, SqlPlannerSuccessResult as P, SqlMigrationRunnerErrorCode as S, SqlMigrationRunnerFailure as T, SqlMigrationPlanOperationStep as _, FieldEvent as a, SqlMigrationPlannerPlanOptions as b, MultiSpaceRunnerResult as c, SqlControlAdapterDescriptor as d, SqlControlExtensionDescriptor as f, SqlMigrationPlanOperation as g, SqlMigrationPlanContractInfo as h, ExpandNativeTypeInput as i, SqlPlannerConflictLocation as j, SqlPlannerConflict as k, MultiSpaceRunnerSuccessValue as l, SqlMigrationPlan as m, CodecControlHooks as n, FieldEventContext as o, SqlControlTargetDescriptor as p, CreateSqlMigrationPlanOptions as r, MultiSpaceRunnerFailure as s, AnyRecord as t, ResolveIdentityValueInput as u, SqlMigrationPlanOperationTarget as v, SqlMigrationRunnerExecuteOptions as w, SqlMigrationRunner as x, SqlMigrationPlanner as y };
472
- //# sourceMappingURL=types-Da-eOg20.d.mts.map
483
+ export { SqlPlannerConflictKind as A, SqlMigrationRunnerExecuteCallbacks as C, SqlMigrationRunnerSuccessValue as D, SqlMigrationRunnerResult as E, StorageTypePlanResult as F, SqlControlFamilyInstance as I, SqlPlannerFailureResult as M, SqlPlannerResult as N, SqlPlanTargetDetails as O, SqlPlannerSuccessResult as P, SqlMigrationRunnerErrorCode as S, SqlMigrationRunnerFailure as T, SqlMigrationPlanOperationStep as _, FieldEvent as a, SqlMigrationPlannerPlanOptions as b, MultiSpaceRunnerResult as c, SqlControlAdapterDescriptor as d, SqlControlExtensionDescriptor as f, SqlMigrationPlanOperation as g, SqlMigrationPlanContractInfo as h, ExpandNativeTypeInput as i, SqlPlannerConflictLocation as j, SqlPlannerConflict as k, MultiSpaceRunnerSuccessValue as l, SqlMigrationPlan as m, CodecControlHooks as n, FieldEventContext as o, SqlControlTargetDescriptor as p, CreateSqlMigrationPlanOptions as r, MultiSpaceRunnerFailure as s, AnyRecord as t, ResolveIdentityValueInput as u, SqlMigrationPlanOperationTarget as v, SqlMigrationRunnerExecuteOptions as w, SqlMigrationRunner as x, SqlMigrationPlanner as y };
484
+ //# sourceMappingURL=types-DMINfGUO.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DMINfGUO.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/migrations/types.ts"],"mappings":"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"}
@@ -78,4 +78,4 @@ function collectSupportedCodecTypeIds(descriptors) {
78
78
  //#endregion
79
79
  export { parseContractMarkerRow as n, collectSupportedCodecTypeIds as t };
80
80
 
81
- //# sourceMappingURL=verify-pRYxnpiG.mjs.map
81
+ //# sourceMappingURL=verify-Crewz6hG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-pRYxnpiG.mjs","names":[],"sources":["../src/core/verify.ts"],"sourcesContent":["import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { type } from 'arktype';\n\nconst MetaSchema = type({ '[string]': 'unknown' });\n\nfunction parseMeta(meta: unknown): Record<string, unknown> {\n if (meta === null || meta === undefined) {\n return {};\n }\n\n let parsed: unknown;\n if (typeof meta === 'string') {\n try {\n parsed = JSON.parse(meta);\n } catch {\n return {};\n }\n } else {\n parsed = meta;\n }\n\n const result = MetaSchema(parsed);\n if (result instanceof type.errors) {\n return {};\n }\n\n return result as Record<string, unknown>;\n}\n\n/**\n * SQLite stores `contract_json` as TEXT, so the wire shape is a JSON string;\n * Postgres uses `jsonb` and returns an already-parsed value. Normalize both\n * here so `ContractMarkerRecord.contractJson` is always the structured form.\n */\nfunction parseContractJson(value: unknown): unknown {\n if (value === null || value === undefined) return null;\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\n/**\n * Wire shape of a `prisma_contract.marker` row as it comes out of a SQL\n * driver. Snake-cased to match the on-disk column names. Shared by every\n * SQL target's `readMarker` so each runner doesn't redeclare it inline.\n */\nexport type ContractMarkerRow = {\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n // SQLite stores arrays as JSON-TEXT, so this is `string` on the wire from\n // a SQLite driver and `string[]` from a Postgres driver. Targets normalize\n // before passing to `parseContractMarkerRow`.\n invariants: unknown;\n};\n\nconst ContractMarkerRowSchema = type({\n core_hash: 'string',\n profile_hash: 'string',\n 'contract_json?': 'unknown | null',\n 'canonical_version?': 'number | null',\n 'updated_at?': 'Date | string',\n 'app_tag?': 'string | null',\n 'meta?': 'unknown | null',\n invariants: type('string').array(),\n});\n\n/**\n * Parses a contract marker row from database query result.\n * This is SQL-specific parsing logic (handles SQL row structure with snake_case columns).\n */\nexport function parseContractMarkerRow(row: unknown): ContractMarkerRecord {\n const result = ContractMarkerRowSchema(row);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Invalid contract marker row: ${messages}`);\n }\n\n const updatedAt = result.updated_at\n ? result.updated_at instanceof Date\n ? result.updated_at\n : new Date(result.updated_at)\n : new Date();\n\n return {\n storageHash: result.core_hash,\n profileHash: result.profile_hash,\n contractJson: parseContractJson(result.contract_json),\n canonicalVersion: result.canonical_version ?? null,\n updatedAt,\n appTag: result.app_tag ?? null,\n meta: parseMeta(result.meta),\n invariants: result.invariants,\n };\n}\n\n/**\n * Collects supported codec type IDs from adapter and extension manifests.\n * Returns a sorted, unique array of type IDs that are declared in the manifests.\n * This enables coverage checks by comparing contract column types against supported types.\n *\n * Note: This extracts type IDs from manifest type imports, not from runtime codec registries.\n * The manifests declare which codec types are available, but the actual type IDs\n * are defined in the codec-types TypeScript modules that are imported.\n *\n * For MVP, we return an empty array since extracting type IDs from TypeScript modules\n * would require runtime evaluation or static analysis. This can be enhanced later.\n */\nexport function collectSupportedCodecTypeIds(\n descriptors: ReadonlyArray<{ readonly id: string }>,\n): readonly string[] {\n // For MVP, return empty array\n // Future enhancement: Extract type IDs from codec-types modules via static analysis\n // or require manifests to explicitly list supported type IDs\n void descriptors;\n return [];\n}\n"],"mappings":";;AAGA,MAAM,aAAa,KAAK,EAAE,YAAY,WAAW,CAAC;AAElD,SAAS,UAAU,MAAwC;CACzD,IAAI,SAAS,QAAQ,SAAS,KAAA,GAC5B,OAAO,EAAE;CAGX,IAAI;CACJ,IAAI,OAAO,SAAS,UAClB,IAAI;EACF,SAAS,KAAK,MAAM,KAAK;SACnB;EACN,OAAO,EAAE;;MAGX,SAAS;CAGX,MAAM,SAAS,WAAW,OAAO;CACjC,IAAI,kBAAkB,KAAK,QACzB,OAAO,EAAE;CAGX,OAAO;;;;;;;AAQT,SAAS,kBAAkB,OAAyB;CAClD,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,OAAO,KAAK,MAAM,MAAM;SAClB;EACN,OAAO;;;AAuBX,MAAM,0BAA0B,KAAK;CACnC,WAAW;CACX,cAAc;CACd,kBAAkB;CAClB,sBAAsB;CACtB,eAAe;CACf,YAAY;CACZ,SAAS;CACT,YAAY,KAAK,SAAS,CAAC,OAAO;CACnC,CAAC;;;;;AAMF,SAAgB,uBAAuB,KAAoC;CACzE,MAAM,SAAS,wBAAwB,IAAI;CAC3C,IAAI,kBAAkB,KAAK,QAAQ;EACjC,MAAM,WAAW,OAAO,KAAK,MAA2B,EAAE,QAAQ,CAAC,KAAK,KAAK;EAC7E,MAAM,IAAI,MAAM,gCAAgC,WAAW;;CAG7D,MAAM,YAAY,OAAO,aACrB,OAAO,sBAAsB,OAC3B,OAAO,aACP,IAAI,KAAK,OAAO,WAAW,mBAC7B,IAAI,MAAM;CAEd,OAAO;EACL,aAAa,OAAO;EACpB,aAAa,OAAO;EACpB,cAAc,kBAAkB,OAAO,cAAc;EACrD,kBAAkB,OAAO,qBAAqB;EAC9C;EACA,QAAQ,OAAO,WAAW;EAC1B,MAAM,UAAU,OAAO,KAAK;EAC5B,YAAY,OAAO;EACpB;;;;;;;;;;;;;;AAeH,SAAgB,6BACd,aACmB;CAKnB,OAAO,EAAE"}
1
+ {"version":3,"file":"verify-Crewz6hG.mjs","names":[],"sources":["../src/core/verify.ts"],"sourcesContent":["import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { type } from 'arktype';\n\nconst MetaSchema = type({ '[string]': 'unknown' });\n\nfunction parseMeta(meta: unknown): Record<string, unknown> {\n if (meta === null || meta === undefined) {\n return {};\n }\n\n let parsed: unknown;\n if (typeof meta === 'string') {\n try {\n parsed = JSON.parse(meta);\n } catch {\n return {};\n }\n } else {\n parsed = meta;\n }\n\n const result = MetaSchema(parsed);\n if (result instanceof type.errors) {\n return {};\n }\n\n return result as Record<string, unknown>;\n}\n\n/**\n * SQLite stores `contract_json` as TEXT, so the wire shape is a JSON string;\n * Postgres uses `jsonb` and returns an already-parsed value. Normalize both\n * here so `ContractMarkerRecord.contractJson` is always the structured form.\n */\nfunction parseContractJson(value: unknown): unknown {\n if (value === null || value === undefined) return null;\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\n/**\n * Wire shape of a `prisma_contract.marker` row as it comes out of a SQL\n * driver. Snake-cased to match the on-disk column names. Shared by every\n * SQL target's `readMarker` so each runner doesn't redeclare it inline.\n */\nexport type ContractMarkerRow = {\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n // SQLite stores arrays as JSON-TEXT, so this is `string` on the wire from\n // a SQLite driver and `string[]` from a Postgres driver. Targets normalize\n // before passing to `parseContractMarkerRow`.\n invariants: unknown;\n};\n\nconst ContractMarkerRowSchema = type({\n core_hash: 'string',\n profile_hash: 'string',\n 'contract_json?': 'unknown | null',\n 'canonical_version?': 'number | null',\n 'updated_at?': 'Date | string',\n 'app_tag?': 'string | null',\n 'meta?': 'unknown | null',\n invariants: type('string').array(),\n});\n\n/**\n * Parses a contract marker row from database query result.\n * This is SQL-specific parsing logic (handles SQL row structure with snake_case columns).\n */\nexport function parseContractMarkerRow(row: unknown): ContractMarkerRecord {\n const result = ContractMarkerRowSchema(row);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Invalid contract marker row: ${messages}`);\n }\n\n const updatedAt = result.updated_at\n ? result.updated_at instanceof Date\n ? result.updated_at\n : new Date(result.updated_at)\n : new Date();\n\n return {\n storageHash: result.core_hash,\n profileHash: result.profile_hash,\n contractJson: parseContractJson(result.contract_json),\n canonicalVersion: result.canonical_version ?? null,\n updatedAt,\n appTag: result.app_tag ?? null,\n meta: parseMeta(result.meta),\n invariants: result.invariants,\n };\n}\n\n/**\n * Collects supported codec type IDs from adapter and extension manifests.\n * Returns a sorted, unique array of type IDs that are declared in the manifests.\n * This enables coverage checks by comparing contract column types against supported types.\n *\n * Note: This extracts type IDs from manifest type imports, not from runtime codec registries.\n * The manifests declare which codec types are available, but the actual type IDs\n * are defined in the codec-types TypeScript modules that are imported.\n *\n * For MVP, we return an empty array since extracting type IDs from TypeScript modules\n * would require runtime evaluation or static analysis. This can be enhanced later.\n */\nexport function collectSupportedCodecTypeIds(\n descriptors: ReadonlyArray<{ readonly id: string }>,\n): readonly string[] {\n // For MVP, return empty array\n // Future enhancement: Extract type IDs from codec-types modules via static analysis\n // or require manifests to explicitly list supported type IDs\n void descriptors;\n return [];\n}\n"],"mappings":";;AAGA,MAAM,aAAa,KAAK,EAAE,YAAY,WAAW,CAAC;AAElD,SAAS,UAAU,MAAwC;CACzD,IAAI,SAAS,QAAQ,SAAS,KAAA,GAC5B,OAAO,EAAE;CAGX,IAAI;CACJ,IAAI,OAAO,SAAS,UAClB,IAAI;EACF,SAAS,KAAK,MAAM,KAAK;SACnB;EACN,OAAO,EAAE;;MAGX,SAAS;CAGX,MAAM,SAAS,WAAW,OAAO;CACjC,IAAI,kBAAkB,KAAK,QACzB,OAAO,EAAE;CAGX,OAAO;;;;;;;AAQT,SAAS,kBAAkB,OAAyB;CAClD,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,OAAO,KAAK,MAAM,MAAM;SAClB;EACN,OAAO;;;AAuBX,MAAM,0BAA0B,KAAK;CACnC,WAAW;CACX,cAAc;CACd,kBAAkB;CAClB,sBAAsB;CACtB,eAAe;CACf,YAAY;CACZ,SAAS;CACT,YAAY,KAAK,SAAS,CAAC,OAAO;CACnC,CAAC;;;;;AAMF,SAAgB,uBAAuB,KAAoC;CACzE,MAAM,SAAS,wBAAwB,IAAI;CAC3C,IAAI,kBAAkB,KAAK,QAAQ;EACjC,MAAM,WAAW,OAAO,KAAK,MAA2B,EAAE,QAAQ,CAAC,KAAK,KAAK;EAC7E,MAAM,IAAI,MAAM,gCAAgC,WAAW;;CAG7D,MAAM,YAAY,OAAO,aACrB,OAAO,sBAAsB,OAC3B,OAAO,aACP,IAAI,KAAK,OAAO,WAAW,mBAC7B,IAAI,MAAM;CAEd,OAAO;EACL,aAAa,OAAO;EACpB,aAAa,OAAO;EACpB,cAAc,kBAAkB,OAAO,cAAc;EACrD,kBAAkB,OAAO,qBAAqB;EAC9C;EACA,QAAQ,OAAO,WAAW;EAC1B,MAAM,UAAU,OAAO,KAAK;EAC5B,YAAY,OAAO;EACpB;;;;;;;;;;;;;;AAeH,SAAgB,6BACd,aACmB;CAKnB,OAAO,EAAE"}