@prisma-next/sql-contract 0.11.0-dev.7 → 0.11.0-dev.70

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.
@@ -1,5 +1,5 @@
1
1
  import { IRNodeBase, Namespace, NamespaceBase, Storage, StorageType } from "@prisma-next/framework-components/ir";
2
- import { ColumnDefault, StorageHashBase } from "@prisma-next/contract/types";
2
+ import { ColumnDefault, NamespaceId, StorageHashBase } from "@prisma-next/contract/types";
3
3
  import { CodecTrait } from "@prisma-next/framework-components/codec";
4
4
 
5
5
  //#region src/ir/sql-node.d.ts
@@ -54,7 +54,7 @@ interface ForeignKeyReferenceInput {
54
54
  * as the sentinel `namespaceId` for single-namespace (unbound) references.
55
55
  */
56
56
  declare class ForeignKeyReference extends SqlNode {
57
- readonly namespaceId: string;
57
+ readonly namespaceId: NamespaceId;
58
58
  readonly tableName: string;
59
59
  readonly columns: readonly string[];
60
60
  constructor(input: ForeignKeyReferenceInput);
@@ -330,7 +330,9 @@ interface SqlNamespaceTablesInput {
330
330
  interface SqlStorageInput<THash extends string = string> {
331
331
  readonly storageHash: StorageHashBase<THash>;
332
332
  readonly types?: Record<string, SqlStorageTypeEntry>;
333
- readonly namespaces?: Readonly<Record<string, Namespace | SqlNamespaceTablesInput>>;
333
+ readonly namespaces: Readonly<Record<string, SqlNamespace>> & {
334
+ readonly __unbound__: SqlNamespace;
335
+ };
334
336
  }
335
337
  /**
336
338
  * SQL Contract IR root node for the `storage` field.
@@ -342,16 +344,11 @@ interface SqlStorageInput<THash extends string = string> {
342
344
  * target-specific storage extensions).
343
345
  *
344
346
  * Honours the framework `Storage` interface: every SQL IR carries a
345
- * `namespaces` map keyed by namespace id. The default singleton
346
- * (`{ [UNBOUND_NAMESPACE_ID]: SqlUnboundNamespace.instance }`)
347
- * binds every contract authored before per-target namespace concretions
348
- * land; per-target namespace classes (`PostgresSchema.unbound`,
349
- * `SqliteUnboundDatabase.instance`) earn their slots when each
350
- * target's namespace shape lands.
347
+ * `namespaces` map keyed by namespace id. Callers must supply fully
348
+ * constructed `Namespace` instances construction discipline lives
349
+ * in the authoring builders and deserializer hydration paths.
351
350
  *
352
- * The constructor normalises optional `types` into class instances and
353
- * materialises plain namespace envelope objects into `Namespace` class
354
- * instances so downstream walks see a uniform AST.
351
+ * The constructor normalises optional `types` into class instances.
355
352
  * `types` is polymorphic per Decision 18 Option B: codec-triple inputs
356
353
  * are stamped with `kind: 'codec-instance'`; class-instance kinds
357
354
  * (e.g. Postgres-enum entries satisfying `PostgresEnumStorageEntry`)
@@ -373,6 +370,10 @@ declare class SqlStorage<THash extends string = string> extends SqlNode implemen
373
370
  constructor(input: SqlStorageInput<THash>);
374
371
  }
375
372
  //#endregion
373
+ //#region src/ir/build-sql-namespace.d.ts
374
+ declare function buildSqlNamespace(input: SqlNamespaceTablesInput): SqlNamespace;
375
+ declare function buildSqlNamespaceMap(namespaces: Readonly<Record<string, Namespace | SqlNamespaceTablesInput>>): Readonly<Record<string, SqlNamespace>>;
376
+ //#endregion
376
377
  //#region src/ir/sql-unbound-namespace.d.ts
377
378
  /**
378
379
  * Family-layer placeholder for the SQL unbound-namespace singleton —
@@ -507,5 +508,5 @@ type ExtractFieldOutputTypes<T> = FieldOutputTypesOf<ExtractTypeMapsFromContract
507
508
  type ExtractFieldInputTypes<T> = FieldInputTypesOf<ExtractTypeMapsFromContract<T>>;
508
509
  type ResolveCodecTypes<TContract, TTypeMaps> = [TTypeMaps] extends [never] ? ExtractCodecTypes<TContract> : CodecTypesOf<TTypeMaps>;
509
510
  //#endregion
510
- export { SqlNode as $, CODEC_INSTANCE_KIND as A, StorageColumnInput as B, TypeMapsPhantomKey as C, SqlStorage as D, SqlNamespaceTablesInput as E, StorageTable as F, POSTGRES_ENUM_KIND as G, IndexInput as H, StorageTableInput as I, ForeignKey as J, PostgresEnumStorageEntry as K, UniqueConstraint as L, StorageTypeInstanceInput as M, isStorageTypeInstance as N, SqlStorageInput as O, toStorageTypeInstance as P, ForeignKeyReferenceInput as Q, UniqueConstraintInput as R, TypeMaps as S, SqlUnboundNamespace as T, PrimaryKey as U, Index as V, PrimaryKeyInput as W, ReferentialAction as X, ForeignKeyInput as Y, ForeignKeyReference as Z, QueryOperationTypesOf as _, ExtractCodecTypes as a, SqlModelStorage as b, ExtractQueryOperationTypes as c, FieldOutputTypesOf as d, ForeignKeyOptions as f, QueryOperationTypesBase as g, QueryOperationTypeEntry as h, DEFAULT_FK_INDEX as i, StorageTypeInstance as j, SqlStorageTypeEntry as k, ExtractTypeMapsFromContract as l, QueryOperationSelfSpec as m, ContractWithTypeMaps as n, ExtractFieldInputTypes as o, QueryOperationReturn as p, isPostgresEnumStorageEntry as q, DEFAULT_FK_CONSTRAINT as r, ExtractFieldOutputTypes as s, CodecTypesOf as t, FieldInputTypesOf as u, ResolveCodecTypes as v, applyFkDefaults as w, SqlQueryOperationTypes as x, SqlModelFieldStorage as y, StorageColumn as z };
511
- //# sourceMappingURL=types-m5NX52zE.d.mts.map
511
+ export { ForeignKeyReference as $, SqlStorageInput as A, UniqueConstraintInput as B, TypeMapsPhantomKey as C, buildSqlNamespaceMap as D, buildSqlNamespace as E, isStorageTypeInstance as F, PrimaryKey as G, StorageColumnInput as H, toStorageTypeInstance as I, PostgresEnumStorageEntry as J, PrimaryKeyInput as K, StorageTable as L, CODEC_INSTANCE_KIND as M, StorageTypeInstance as N, SqlNamespaceTablesInput as O, StorageTypeInstanceInput as P, ReferentialAction as Q, StorageTableInput as R, TypeMaps as S, SqlUnboundNamespace as T, Index as U, StorageColumn as V, IndexInput as W, ForeignKey as X, isPostgresEnumStorageEntry as Y, ForeignKeyInput as Z, QueryOperationTypesOf as _, ExtractCodecTypes as a, SqlModelStorage as b, ExtractQueryOperationTypes as c, FieldOutputTypesOf as d, ForeignKeyReferenceInput as et, ForeignKeyOptions as f, QueryOperationTypesBase as g, QueryOperationTypeEntry as h, DEFAULT_FK_INDEX as i, SqlStorageTypeEntry as j, SqlStorage as k, ExtractTypeMapsFromContract as l, QueryOperationSelfSpec as m, ContractWithTypeMaps as n, ExtractFieldInputTypes as o, QueryOperationReturn as p, POSTGRES_ENUM_KIND as q, DEFAULT_FK_CONSTRAINT as r, ExtractFieldOutputTypes as s, CodecTypesOf as t, SqlNode as tt, FieldInputTypesOf as u, ResolveCodecTypes as v, applyFkDefaults as w, SqlQueryOperationTypes as x, SqlModelFieldStorage as y, UniqueConstraint as z };
512
+ //# sourceMappingURL=types-DU3qUbxM.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DU3qUbxM.d.mts","names":[],"sources":["../src/ir/sql-node.ts","../src/ir/foreign-key-reference.ts","../src/ir/foreign-key.ts","../src/ir/postgres-enum-storage-entry.ts","../src/ir/primary-key.ts","../src/ir/sql-index.ts","../src/ir/storage-column.ts","../src/ir/unique-constraint.ts","../src/ir/storage-table.ts","../src/ir/storage-type-instance.ts","../src/ir/sql-storage.ts","../src/ir/build-sql-namespace.ts","../src/ir/sql-unbound-namespace.ts","../src/types.ts"],"mappings":"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"}
package/dist/types.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as SqlNode, A as CODEC_INSTANCE_KIND, B as StorageColumnInput, C as TypeMapsPhantomKey, D as SqlStorage, E as SqlNamespaceTablesInput, F as StorageTable, G as POSTGRES_ENUM_KIND, H as IndexInput, I as StorageTableInput, J as ForeignKey, K as PostgresEnumStorageEntry, L as UniqueConstraint, M as StorageTypeInstanceInput, N as isStorageTypeInstance, O as SqlStorageInput, P as toStorageTypeInstance, Q as ForeignKeyReferenceInput, R as UniqueConstraintInput, S as TypeMaps, T as SqlUnboundNamespace, U as PrimaryKey, V as Index, W as PrimaryKeyInput, X as ReferentialAction, Y as ForeignKeyInput, Z as ForeignKeyReference, _ as QueryOperationTypesOf, a as ExtractCodecTypes, b as SqlModelStorage, c as ExtractQueryOperationTypes, d as FieldOutputTypesOf, f as ForeignKeyOptions, g as QueryOperationTypesBase, h as QueryOperationTypeEntry, i as DEFAULT_FK_INDEX, j as StorageTypeInstance, k as SqlStorageTypeEntry, l as ExtractTypeMapsFromContract, m as QueryOperationSelfSpec, n as ContractWithTypeMaps, o as ExtractFieldInputTypes, p as QueryOperationReturn, q as isPostgresEnumStorageEntry, r as DEFAULT_FK_CONSTRAINT, s as ExtractFieldOutputTypes, t as CodecTypesOf, u as FieldInputTypesOf, v as ResolveCodecTypes, w as applyFkDefaults, x as SqlQueryOperationTypes, y as SqlModelFieldStorage, z as StorageColumn } from "./types-m5NX52zE.mjs";
2
- export { CODEC_INSTANCE_KIND, type CodecTypesOf, type ContractWithTypeMaps, DEFAULT_FK_CONSTRAINT, DEFAULT_FK_INDEX, type ExtractCodecTypes, type ExtractFieldInputTypes, type ExtractFieldOutputTypes, type ExtractQueryOperationTypes, type ExtractTypeMapsFromContract, type FieldInputTypesOf, type FieldOutputTypesOf, ForeignKey, type ForeignKeyInput, type ForeignKeyOptions, ForeignKeyReference, type ForeignKeyReferenceInput, Index, type IndexInput, POSTGRES_ENUM_KIND, type PostgresEnumStorageEntry, PrimaryKey, type PrimaryKeyInput, type QueryOperationReturn, type QueryOperationSelfSpec, type QueryOperationTypeEntry, type QueryOperationTypesBase, type QueryOperationTypesOf, type ReferentialAction, type ResolveCodecTypes, type SqlModelFieldStorage, type SqlModelStorage, type SqlNamespaceTablesInput, SqlNode, type SqlQueryOperationTypes, SqlStorage, type SqlStorageInput, type SqlStorageTypeEntry, SqlUnboundNamespace, StorageColumn, type StorageColumnInput, StorageTable, type StorageTableInput, type StorageTypeInstance, type StorageTypeInstanceInput, type TypeMaps, type TypeMapsPhantomKey, UniqueConstraint, type UniqueConstraintInput, applyFkDefaults, isPostgresEnumStorageEntry, isStorageTypeInstance, toStorageTypeInstance };
1
+ import { $ as ForeignKeyReference, A as SqlStorageInput, B as UniqueConstraintInput, C as TypeMapsPhantomKey, D as buildSqlNamespaceMap, E as buildSqlNamespace, F as isStorageTypeInstance, G as PrimaryKey, H as StorageColumnInput, I as toStorageTypeInstance, J as PostgresEnumStorageEntry, K as PrimaryKeyInput, L as StorageTable, M as CODEC_INSTANCE_KIND, N as StorageTypeInstance, O as SqlNamespaceTablesInput, P as StorageTypeInstanceInput, Q as ReferentialAction, R as StorageTableInput, S as TypeMaps, T as SqlUnboundNamespace, U as Index, V as StorageColumn, W as IndexInput, X as ForeignKey, Y as isPostgresEnumStorageEntry, Z as ForeignKeyInput, _ as QueryOperationTypesOf, a as ExtractCodecTypes, b as SqlModelStorage, c as ExtractQueryOperationTypes, d as FieldOutputTypesOf, et as ForeignKeyReferenceInput, f as ForeignKeyOptions, g as QueryOperationTypesBase, h as QueryOperationTypeEntry, i as DEFAULT_FK_INDEX, j as SqlStorageTypeEntry, k as SqlStorage, l as ExtractTypeMapsFromContract, m as QueryOperationSelfSpec, n as ContractWithTypeMaps, o as ExtractFieldInputTypes, p as QueryOperationReturn, q as POSTGRES_ENUM_KIND, r as DEFAULT_FK_CONSTRAINT, s as ExtractFieldOutputTypes, t as CodecTypesOf, tt as SqlNode, u as FieldInputTypesOf, v as ResolveCodecTypes, w as applyFkDefaults, x as SqlQueryOperationTypes, y as SqlModelFieldStorage, z as UniqueConstraint } from "./types-DU3qUbxM.mjs";
2
+ export { CODEC_INSTANCE_KIND, type CodecTypesOf, type ContractWithTypeMaps, DEFAULT_FK_CONSTRAINT, DEFAULT_FK_INDEX, type ExtractCodecTypes, type ExtractFieldInputTypes, type ExtractFieldOutputTypes, type ExtractQueryOperationTypes, type ExtractTypeMapsFromContract, type FieldInputTypesOf, type FieldOutputTypesOf, ForeignKey, type ForeignKeyInput, type ForeignKeyOptions, ForeignKeyReference, type ForeignKeyReferenceInput, Index, type IndexInput, POSTGRES_ENUM_KIND, type PostgresEnumStorageEntry, PrimaryKey, type PrimaryKeyInput, type QueryOperationReturn, type QueryOperationSelfSpec, type QueryOperationTypeEntry, type QueryOperationTypesBase, type QueryOperationTypesOf, type ReferentialAction, type ResolveCodecTypes, type SqlModelFieldStorage, type SqlModelStorage, type SqlNamespaceTablesInput, SqlNode, type SqlQueryOperationTypes, SqlStorage, type SqlStorageInput, type SqlStorageTypeEntry, SqlUnboundNamespace, StorageColumn, type StorageColumnInput, StorageTable, type StorageTableInput, type StorageTypeInstance, type StorageTypeInstanceInput, type TypeMaps, type TypeMapsPhantomKey, UniqueConstraint, type UniqueConstraintInput, applyFkDefaults, buildSqlNamespace, buildSqlNamespaceMap, isPostgresEnumStorageEntry, isStorageTypeInstance, toStorageTypeInstance };
package/dist/types.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as ForeignKeyReference, a as CODEC_INSTANCE_KIND, c as StorageTable, d as SqlUnboundNamespace, f as Index, g as ForeignKey, h as isPostgresEnumStorageEntry, i as SqlStorage, l as UniqueConstraint, m as POSTGRES_ENUM_KIND, n as DEFAULT_FK_INDEX, o as isStorageTypeInstance, p as PrimaryKey, r as applyFkDefaults, s as toStorageTypeInstance, t as DEFAULT_FK_CONSTRAINT, u as StorageColumn, v as SqlNode } from "./types-C7t-bmro.mjs";
2
- export { CODEC_INSTANCE_KIND, DEFAULT_FK_CONSTRAINT, DEFAULT_FK_INDEX, ForeignKey, ForeignKeyReference, Index, POSTGRES_ENUM_KIND, PrimaryKey, SqlNode, SqlStorage, SqlUnboundNamespace, StorageColumn, StorageTable, UniqueConstraint, applyFkDefaults, isPostgresEnumStorageEntry, isStorageTypeInstance, toStorageTypeInstance };
1
+ import { _ as ForeignKey, a as CODEC_INSTANCE_KIND, b as SqlUnboundNamespace, c as POSTGRES_ENUM_KIND, d as buildSqlNamespaceMap, f as StorageTable, g as PrimaryKey, h as Index, i as SqlStorage, l as isPostgresEnumStorageEntry, m as StorageColumn, n as DEFAULT_FK_INDEX, o as isStorageTypeInstance, p as UniqueConstraint, r as applyFkDefaults, s as toStorageTypeInstance, t as DEFAULT_FK_CONSTRAINT, u as buildSqlNamespace, v as ForeignKeyReference, y as SqlNode } from "./types-DPkj4y3_.mjs";
2
+ export { CODEC_INSTANCE_KIND, DEFAULT_FK_CONSTRAINT, DEFAULT_FK_INDEX, ForeignKey, ForeignKeyReference, Index, POSTGRES_ENUM_KIND, PrimaryKey, SqlNode, SqlStorage, SqlUnboundNamespace, StorageColumn, StorageTable, UniqueConstraint, applyFkDefaults, buildSqlNamespace, buildSqlNamespaceMap, isPostgresEnumStorageEntry, isStorageTypeInstance, toStorageTypeInstance };
@@ -1,6 +1,6 @@
1
- import { D as SqlStorage, Q as ForeignKeyReferenceInput, X as ReferentialAction, Y as ForeignKeyInput } from "./types-m5NX52zE.mjs";
2
- import { Type } from "arktype";
1
+ import { Q as ReferentialAction, Z as ForeignKeyInput, k as SqlStorage } from "./types-DU3qUbxM.mjs";
3
2
  import { Contract } from "@prisma-next/contract/types";
3
+ import { Type } from "arktype";
4
4
  import * as _$arktype_internal_variants_object_ts0 from "arktype/internal/variants/object.ts";
5
5
  import * as _$arktype_internal_variants_string_ts0 from "arktype/internal/variants/string.ts";
6
6
 
@@ -33,7 +33,11 @@ declare const IndexSchema: _$arktype_internal_variants_object_ts0.ObjectType<{
33
33
  type?: string;
34
34
  options?: Record<string, unknown>;
35
35
  }, {}>;
36
- declare const ForeignKeyReferenceSchema: _$arktype_internal_variants_object_ts0.ObjectType<ForeignKeyReferenceInput, {}>;
36
+ declare const ForeignKeyReferenceSchema: _$arktype_internal_variants_object_ts0.ObjectType<{
37
+ namespaceId: string;
38
+ tableName: string;
39
+ columns: readonly string[];
40
+ }, {}>;
37
41
  declare const ReferentialActionSchema: _$arktype_internal_variants_string_ts0.StringType<ReferentialAction, {}>;
38
42
  declare const ForeignKeySchema: _$arktype_internal_variants_object_ts0.ObjectType<ForeignKeyInput, {}>;
39
43
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"validators.d.mts","names":[],"sources":["../src/validators.ts"],"mappings":";;;;;;;KAkBK,oBAAA;EAAA,SACM,IAAA;EAAA,SACA,KAAA,8BAAmC,MAAA;AAAA;AAAA,KAEzC,qBAAA;EAAA,SAAmC,IAAA;EAAA,SAA2B,UAAA;AAAA;AAAA,cAQtD,0BAAA,EAA0B,sCAAA,CAAA,UAAA,CAAA,oBAAA;AAAA,cAK1B,2BAAA,EAA2B,sCAAA,CAAA,UAAA,CAAA,qBAAA;AAAA,cAK3B,mBAAA,EAAmB,sCAAA,CAAA,UAAA,CAAA,oBAAA,GAAA,qBAAA;;;AApBoB;;;cAoF9C,sBAAA,EAKJ,sCAAA,CAL0B,UAAA;;;;;;cAoBf,WAAA,EAKX,sCAAA,CALsB,UAAA;;;;YAKtB,MAAA;AAAA;AAAA,cAEW,yBAAA,EAAyB,sCAAA,CAAA,UAAA,CAAA,wBAAA;AAAA,cAMzB,uBAAA,EAAuB,sCAAA,CAAA,UAAA,CAAA,iBAAA;AAAA,cAIvB,gBAAA,EAAgB,sCAAA,CAAA,UAAA,CAAA,eAAA;;;;AArGiE;;;iBA8L9E,0BAAA,CACd,SAAA,GAAY,WAAA,SAAoB,IAAA,aAC/B,IAAA;;;;;;;iBAkBa,sBAAA,CACd,SAAA,GAAY,WAAA,SAAoB,IAAA,aAC/B,IAAA;AAhIH;;;;;AAAA,iBAwPgB,uBAAA,CACd,SAAA,GAAY,WAAA,SAAoB,IAAA,aAC/B,IAAA;;;;;;;AAnPH;iBAsRgB,eAAA,CAAgB,KAAA,YAAiB,UAAA;AAAA,iBAajC,aAAA,CAAc,KAAA;;;AA7R9B;;;;;AAIA;;;;;AAyFA;iBA8PgB,wBAAA,CAAyB,OAAA,EAAS,UAAA;;;;;;;iBAsJlC,8BAAA,CAA+B,QAAA,EAAU,QAAA,CAAS,UAAA;;;;;;AAhYlE;iBAibgB,6BAAA,CAA8B,QAAA,EAAU,QAAA,CAAS,UAAA;AAAA,UA6FhD,+BAAA;EA7gBiB;;;;;;;;EAAA,SAshBvB,cAAA,GAAiB,IAAA;AAAA;;AA7Z5B;;;;;;;iBAwagB,wBAAA,WAAmC,QAAA,CAAS,UAAA,EAAA,CAC1D,KAAA,WACA,OAAA,GAAU,+BAAA,GACT,CAAA"}
1
+ {"version":3,"file":"validators.d.mts","names":[],"sources":["../src/validators.ts"],"mappings":";;;;;;;KA2BK,oBAAA;EAAA,SACM,IAAA;EAAA,SACA,KAAA,8BAAmC,MAAM;AAAA;AAAA,KAE/C,qBAAA;EAAA,SAAmC,IAAA;EAAA,SAA2B,UAAU;AAAA;AAAA,cAQhE,0BAAA,EAA0B,sCAAA,CAAA,UAAA,CAAA,oBAAA;AAAA,cAK1B,2BAAA,EAA2B,sCAAA,CAAA,UAAA,CAAA,qBAAA;AAAA,cAK3B,mBAAA,EAAmB,sCAAA,CAAA,UAAA,CAAA,oBAAA,GAAA,qBAAA;;AApBoB;AAAA;;;cAoF9C,sBAAA,EAKJ,sCAAA,CAL0B,UAAA;;;;;;cAoBf,WAAA,EAKX,sCAAA,CALsB,UAAA;;;;YAKtB,MAAA;AAAA;AAAA,cAEW,yBAAA,EAK8B,sCAAA,CALL,UAAA;;;;;cAOzB,uBAAA,EAAuB,sCAAA,CAAA,UAAA,CAAA,iBAAA;AAAA,cAIvB,gBAAA,EAAgB,sCAAA,CAAA,UAAA,CAAA,eAAA;;;;;;;iBAyFb,0BAAA,CACd,SAAA,GAAY,WAAA,SAAoB,IAAA,aAC/B,IAAA;;;;AA7GH;;;iBA+HgB,sBAAA,CACd,SAAA,GAAY,WAAA,SAAoB,IAAA,aAC/B,IAAA;;;;;;iBAgJa,uBAAA,CACd,SAAA,GAAY,WAAA,SAAoB,IAAA,aAC/B,IAAA;;;AA5QH;;;;;iBAoTgB,eAAA,CAAgB,KAAA,YAAiB,UAAU;AAAA,iBA4B3C,aAAA,CAAc,KAAc;;;;AAzU5C;;;;AAAoC;AAIpC;;;;AAA6B;iBAmYb,wBAAA,CAAyB,OAAmB,EAAV,UAAU;;;;;;;iBAsJ5C,8BAAA,CAA+B,QAAA,EAAU,QAAQ,CAAC,UAAA;;;;;;AA9b3D;iBAkfS,6BAAA,CAA8B,QAAA,EAAU,QAAQ,CAAC,UAAA;AAAA,UA6FhD,+BAAA;;;;;;;;;WASN,cAAA,GAAiB,IAAI;AAAA;;AApkBzB;AAgJP;;;;;;iBA+bgB,wBAAA,WAAmC,QAAA,CAAS,UAAA,EAAA,CAC1D,KAAA,WACA,OAAA,GAAU,+BAAA,GACT,CAAA"}
@@ -1,6 +1,10 @@
1
- import { i as SqlStorage } from "./types-C7t-bmro.mjs";
1
+ import { b as SqlUnboundNamespace, d as buildSqlNamespaceMap, i as SqlStorage } from "./types-DPkj4y3_.mjs";
2
+ import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
3
+ import { blindCast } from "@prisma-next/utils/casts";
4
+ import { CrossReferenceSchema } from "@prisma-next/contract/types";
2
5
  import { ContractValidationError } from "@prisma-next/contract/contract-validation-error";
3
6
  import { validateContractDomain } from "@prisma-next/contract/validate-domain";
7
+ import { ifDefined } from "@prisma-next/utils/defined";
4
8
  import { type } from "arktype";
5
9
  //#region src/validators.ts
6
10
  const literalKindSchema = type("'literal'");
@@ -92,7 +96,8 @@ const IndexSchema = type({
92
96
  "type?": "string",
93
97
  "options?": "Record<string, unknown>"
94
98
  });
95
- const ForeignKeyReferenceSchema = type.declare().type({
99
+ const ForeignKeyReferenceSchema = type({
100
+ "+": "reject",
96
101
  namespaceId: "string",
97
102
  tableName: "string",
98
103
  columns: type.string.array().readonly()
@@ -234,20 +239,37 @@ const ModelFieldSchema = type({
234
239
  "many?": "true",
235
240
  "dict?": "true"
236
241
  });
242
+ const ModelStorageSchema = type({
243
+ table: "string",
244
+ fields: type({ "[string]": type({
245
+ column: "string",
246
+ "codecId?": "string",
247
+ "nullable?": "boolean"
248
+ }) })
249
+ });
250
+ const ContractReferenceRelationSchema = type({
251
+ "+": "reject",
252
+ to: CrossReferenceSchema,
253
+ cardinality: "'1:1' | '1:N' | 'N:1'",
254
+ on: type({
255
+ "+": "reject",
256
+ localFields: type.string.array().readonly(),
257
+ targetFields: type.string.array().readonly()
258
+ })
259
+ });
260
+ const ContractEmbedRelationSchema = type({
261
+ "+": "reject",
262
+ to: CrossReferenceSchema,
263
+ cardinality: "'1:1' | '1:N'"
264
+ });
265
+ const ContractRelationSchema = ContractReferenceRelationSchema.or(ContractEmbedRelationSchema);
237
266
  const ModelSchema = type({
238
- storage: type({
239
- table: "string",
240
- fields: type({ "[string]": type({
241
- column: "string",
242
- "codecId?": "string",
243
- "nullable?": "boolean"
244
- }) })
245
- }),
267
+ storage: ModelStorageSchema,
246
268
  "fields?": type({ "[string]": ModelFieldSchema }),
247
- "relations?": type({ "[string]": "unknown" }),
269
+ "relations?": type({ "[string]": ContractRelationSchema }),
248
270
  "discriminator?": "unknown",
249
271
  "variants?": "unknown",
250
- "base?": "string",
272
+ "base?": CrossReferenceSchema,
251
273
  "owner?": "string"
252
274
  });
253
275
  const ContractMetaSchema = type({ "[string]": "unknown" });
@@ -267,10 +289,11 @@ function createSqlContractSchema(fragments) {
267
289
  "capabilities?": "Record<string, Record<string, boolean>>",
268
290
  "extensionPacks?": "Record<string, unknown>",
269
291
  "meta?": ContractMetaSchema,
270
- "roots?": "Record<string, string>",
271
- models: type({ "[string]": ModelSchema }),
272
- "valueObjects?": "Record<string, unknown>",
273
- "domain?": "unknown",
292
+ "roots?": type({ "[string]": CrossReferenceSchema }),
293
+ domain: type({ namespaces: type({ "[string]": type({
294
+ models: type({ "[string]": ModelSchema }),
295
+ "valueObjects?": "Record<string, unknown>"
296
+ }) }) }),
274
297
  storage,
275
298
  "execution?": ExecutionSchema
276
299
  });
@@ -289,7 +312,17 @@ function validateStorage(value) {
289
312
  const messages = result.map((p) => p.message).join("; ");
290
313
  throw new Error(`Storage validation failed: ${messages}`);
291
314
  }
292
- return new SqlStorage(result);
315
+ const validated = blindCast(result);
316
+ const namespaces = buildSqlNamespaceMap(validated.namespaces ?? {});
317
+ const unbound = namespaces[UNBOUND_NAMESPACE_ID] ?? SqlUnboundNamespace.instance;
318
+ return new SqlStorage({
319
+ storageHash: validated.storageHash,
320
+ ...ifDefined("types", validated.types),
321
+ namespaces: {
322
+ ...namespaces,
323
+ [UNBOUND_NAMESPACE_ID]: unbound
324
+ }
325
+ });
293
326
  }
294
327
  function validateModel(value) {
295
328
  const result = ModelSchema(value);
@@ -406,22 +439,25 @@ function validateStorageSemantics(storage) {
406
439
  * columns. Throws `ContractValidationError` on the first mismatch.
407
440
  */
408
441
  function validateModelStorageReferences(contract) {
409
- const models = contract.models;
410
- for (const [modelName, model] of Object.entries(models)) {
411
- const storageTable = model.storage.table;
412
- const rawTable = findStorageTableByTableName(contract.storage, storageTable);
413
- if (rawTable === void 0) throw new ContractValidationError(`Model "${modelName}" references non-existent table "${storageTable}"`, "storage");
414
- const table = rawTable;
415
- const columnNames = new Set(Object.keys(table.columns));
416
- for (const [fieldName, field] of Object.entries(model.storage.fields)) if (!columnNames.has(field.column)) throw new ContractValidationError(`Model "${modelName}" field "${fieldName}" references non-existent column "${field.column}" in table "${storageTable}"`, "storage");
417
- const JSON_NATIVE_TYPES = new Set(["json", "jsonb"]);
418
- for (const [fieldName, domainField] of Object.entries(model.fields ?? {})) {
419
- if (domainField.type?.kind !== "valueObject") continue;
420
- const storageField = model.storage.fields[fieldName];
421
- if (!storageField) continue;
422
- const column = table.columns[storageField.column];
423
- if (!column) continue;
424
- if (!JSON_NATIVE_TYPES.has(column.nativeType)) throw new ContractValidationError(`Model "${modelName}" field "${fieldName}" is a value object but storage column "${storageField.column}" has nativeType "${column.nativeType}" (expected json or jsonb)`, "storage");
442
+ for (const [namespaceId, namespace] of Object.entries(contract.domain.namespaces)) {
443
+ const models = namespace.models;
444
+ for (const [modelName, model] of Object.entries(models)) {
445
+ const qualifiedName = `${namespaceId}:${modelName}`;
446
+ const storageTable = model.storage.table;
447
+ const rawTable = findStorageTableByTableName(contract.storage, storageTable);
448
+ if (rawTable === void 0) throw new ContractValidationError(`Model "${qualifiedName}" references non-existent table "${storageTable}"`, "storage");
449
+ const table = rawTable;
450
+ const columnNames = new Set(Object.keys(table.columns));
451
+ for (const [fieldName, field] of Object.entries(model.storage.fields)) if (!columnNames.has(field.column)) throw new ContractValidationError(`Model "${qualifiedName}" field "${fieldName}" references non-existent column "${field.column}" in table "${storageTable}"`, "storage");
452
+ const JSON_NATIVE_TYPES = new Set(["json", "jsonb"]);
453
+ for (const [fieldName, domainField] of Object.entries(model.fields ?? {})) {
454
+ if (domainField.type?.kind !== "valueObject") continue;
455
+ const storageField = model.storage.fields[fieldName];
456
+ if (!storageField) continue;
457
+ const column = table.columns[storageField.column];
458
+ if (!column) continue;
459
+ if (!JSON_NATIVE_TYPES.has(column.nativeType)) throw new ContractValidationError(`Model "${qualifiedName}" field "${fieldName}" is a value object but storage column "${storageField.column}" has nativeType "${column.nativeType}" (expected json or jsonb)`, "storage");
460
+ }
425
461
  }
426
462
  }
427
463
  }
@@ -467,8 +503,7 @@ function validateSqlContractFully(value, options) {
467
503
  })() : value, options?.contractSchema ?? SqlContractSchema);
468
504
  validateContractDomain({
469
505
  roots: validated.roots,
470
- models: validated.models,
471
- ...validated.valueObjects ? { valueObjects: validated.valueObjects } : {}
506
+ domain: validated.domain
472
507
  });
473
508
  validateSqlStorageConsistency(validated);
474
509
  const semanticErrors = validateStorageSemantics(validated.storage);
@@ -1 +1 @@
1
- {"version":3,"file":"validators.mjs","names":["f","referencedTable"],"sources":["../src/validators.ts"],"sourcesContent":["import { ContractValidationError } from '@prisma-next/contract/contract-validation-error';\nimport type { Contract, ContractField, ContractModel } from '@prisma-next/contract/types';\nimport { validateContractDomain } from '@prisma-next/contract/validate-domain';\nimport type { Namespace } from '@prisma-next/framework-components/ir';\nimport { type Type, type } from 'arktype';\nimport {\n type ForeignKeyInput,\n type ForeignKeyReferenceInput,\n type PrimaryKeyInput,\n type ReferentialAction,\n type SqlModelStorage,\n SqlStorage,\n type SqlStorageInput,\n type StorageTable,\n type StorageTypeInstanceInput,\n type UniqueConstraintInput,\n} from './types';\n\ntype ColumnDefaultLiteral = {\n readonly kind: 'literal';\n readonly value: string | number | boolean | Record<string, unknown> | unknown[] | null;\n};\ntype ColumnDefaultFunction = { readonly kind: 'function'; readonly expression: string };\nconst literalKindSchema = type(\"'literal'\");\nconst functionKindSchema = type(\"'function'\");\nconst generatorKindSchema = type(\"'generator'\");\nconst generatorIdSchema = type('string').narrow((value, ctx) => {\n return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(value) ? true : ctx.mustBe('a flat generator id');\n});\n\nexport const ColumnDefaultLiteralSchema = type.declare<ColumnDefaultLiteral>().type({\n kind: literalKindSchema,\n value: 'string | number | boolean | null | unknown[] | Record<string, unknown>',\n});\n\nexport const ColumnDefaultFunctionSchema = type.declare<ColumnDefaultFunction>().type({\n kind: functionKindSchema,\n expression: 'string',\n});\n\nexport const ColumnDefaultSchema = ColumnDefaultLiteralSchema.or(ColumnDefaultFunctionSchema);\n\nconst ExecutionMutationDefaultValueSchema = type({\n '+': 'reject',\n kind: generatorKindSchema,\n id: generatorIdSchema,\n 'params?': 'Record<string, unknown>',\n});\n\nconst ExecutionMutationDefaultSchema = type({\n '+': 'reject',\n ref: {\n '+': 'reject',\n table: 'string',\n column: 'string',\n },\n 'onCreate?': ExecutionMutationDefaultValueSchema,\n 'onUpdate?': ExecutionMutationDefaultValueSchema,\n});\n\nconst ExecutionSchema = type({\n '+': 'reject',\n executionHash: 'string',\n mutations: {\n '+': 'reject',\n defaults: ExecutionMutationDefaultSchema.array().readonly(),\n },\n});\n\nconst StorageColumnSchema = type({\n '+': 'reject',\n nativeType: 'string',\n codecId: 'string',\n nullable: 'boolean',\n 'typeParams?': 'Record<string, unknown>',\n 'typeRef?': 'string',\n 'default?': ColumnDefaultSchema,\n}).narrow((col, ctx) => {\n if (col.typeParams !== undefined && col.typeRef !== undefined) {\n return ctx.mustBe('a column with either typeParams or typeRef, not both');\n }\n return true;\n});\n\n/**\n * Codec-triple entry persisted under `storage.types[name]`. Carries an\n * enumerable literal `kind: 'codec-instance'` discriminator so the\n * polymorphic slot dispatch can distinguish codec triples from\n * class-instance kinds (e.g. `'postgres-enum'`) sharing the slot.\n */\nconst StorageTypeInstanceSchema = type\n .declare<StorageTypeInstanceInput & { kind: 'codec-instance' }>()\n .type({\n kind: \"'codec-instance'\",\n codecId: 'string',\n nativeType: 'string',\n typeParams: 'Record<string, unknown>',\n });\n\n/**\n * Postgres native enum entry under `storage.namespaces[namespaceId].enum[name]`.\n * Document-scoped `storage.types` carries codec aliases only\n * (`DocumentScopedStorageTypeSchema`).\n */\nconst PostgresEnumTypeSchema = type({\n kind: \"'postgres-enum'\",\n 'name?': 'string',\n 'nativeType?': 'string',\n values: type.string.array().readonly(),\n});\n\n/** Document-scoped `storage.types`: codec triples only. */\nconst DocumentScopedStorageTypeSchema = StorageTypeInstanceSchema;\n\nconst PrimaryKeySchema = type.declare<PrimaryKeyInput>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nconst UniqueConstraintSchema = type.declare<UniqueConstraintInput>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nexport const IndexSchema = type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n 'type?': 'string',\n 'options?': 'Record<string, unknown>',\n});\n\nexport const ForeignKeyReferenceSchema = type.declare<ForeignKeyReferenceInput>().type({\n namespaceId: 'string',\n tableName: 'string',\n columns: type.string.array().readonly(),\n});\n\nexport const ReferentialActionSchema = type\n .declare<ReferentialAction>()\n .type(\"'noAction' | 'restrict' | 'cascade' | 'setNull' | 'setDefault'\");\n\nexport const ForeignKeySchema = type.declare<ForeignKeyInput>().type({\n source: ForeignKeyReferenceSchema,\n target: ForeignKeyReferenceSchema,\n 'name?': 'string',\n 'onDelete?': ReferentialActionSchema,\n 'onUpdate?': ReferentialActionSchema,\n constraint: 'boolean',\n index: 'boolean',\n});\n\nconst StorageTableSchema = type({\n '+': 'reject',\n columns: type({ '[string]': StorageColumnSchema }),\n 'primaryKey?': PrimaryKeySchema,\n uniques: UniqueConstraintSchema.array().readonly(),\n indexes: IndexSchema.array().readonly(),\n foreignKeys: ForeignKeySchema.array().readonly(),\n});\n\n/**\n * Re-exported so target packs can register their `validatorSchema`\n * fragment without re-declaring the schema for the kinds the family\n * core already validates. Full extraction of enum-specific schemas\n * into the Postgres pack is a follow-up; today the symbol lives here.\n */\nexport { PostgresEnumTypeSchema };\n\n/**\n * Composes a hardcoded family `fallback` schema with optional\n * pack-contributed `fragments` keyed by the entry's `kind`\n * discriminator. The composition is **additive**, not substitutive:\n *\n * - No fragments registered → entries are validated by `fallback`\n * alone (the unchanged baseline).\n * - An entry's `kind` matches `fallbackKind` AND a fragment for that\n * kind is registered → the entry must pass **both** `fallback` and\n * the fragment. This preserves family-owned invariants (e.g. the\n * built-in `PostgresEnumType` shape) even when a pack contributes\n * its own schema for the same kind.\n * - An entry's `kind` matches a registered fragment for some\n * non-fallback kind → the fragment alone validates the entry.\n * `fallback` is family-specific (validates a single hardcoded kind)\n * and would reject any other kind, so it does not apply here.\n * - An entry's `kind` matches no fragment → fall through to\n * `fallback`.\n */\nfunction namespaceSlotEntrySchema(\n fallback: Type<unknown>,\n fallbackKind: string,\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n if (fragments === undefined || fragments.size === 0) {\n return fallback;\n }\n return type('unknown').narrow((entry, ctx) => {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n return ctx.mustBe('an object');\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string') {\n const fragment = fragments.get(kind);\n if (fragment !== undefined) {\n if (kind === fallbackKind) {\n const baseParsed = fallback(entry);\n if (baseParsed instanceof type.errors) {\n return ctx.reject({ expected: baseParsed.summary });\n }\n }\n const parsed = fragment(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n }\n }\n const parsed = fallback(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n });\n}\n\n/**\n * Builds the per-namespace entry schema for `storage.namespaces[id]`.\n * Pack-contributed `validatorSchema` fragments — keyed by the\n * descriptor's `discriminator` — validate each entry by matching the\n * entry's `kind` field on the `'enum?'` slot.\n */\nexport function createNamespaceEntrySchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n return type({\n '+': 'reject',\n id: 'string',\n 'kind?': 'string',\n 'tables?': type({ '[string]': StorageTableSchema }),\n 'enum?': type({\n '[string]': namespaceSlotEntrySchema(PostgresEnumTypeSchema, 'postgres-enum', fragments),\n }),\n }) as Type<unknown>;\n}\n\n/**\n * Builds the storage schema. Pack contributions reach the per-namespace\n * entry shape through {@link createNamespaceEntrySchema}; the\n * document-scoped `storage.types` slot (codec triples only) and the\n * storage hash stay family-shared.\n */\nexport function createSqlStorageSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n const namespaceEntry = createNamespaceEntrySchema(fragments);\n return type({\n '+': 'reject',\n storageHash: 'string',\n 'types?': type({ '[string]': DocumentScopedStorageTypeSchema }),\n 'namespaces?': type({ '[string]': namespaceEntry }),\n }) as Type<unknown>;\n}\n\nconst StorageSchema = createSqlStorageSchema();\n\n// SQL-specific namespace walk shape (`tables` is the SQL family's idiom —\n// the framework `Namespace` interface no longer carries it). The wider\n// `object` table value keeps this helper structurally compatible with\n// `SqlNamespace` (whose tables narrow to `StorageTable`) and the JSON\n// envelope variants that lose class identity.\ntype NamespacedStorageWalk = {\n readonly namespaces: Readonly<\n Record<string, Namespace & { readonly tables?: Readonly<Record<string, object>> }>\n >;\n};\n\nfunction eachStorageTable(storage: NamespacedStorageWalk) {\n return Object.entries(storage.namespaces).flatMap(([namespaceId, ns]) =>\n Object.entries(ns.tables ?? {}).map(([tableName, table]) => ({\n namespaceId,\n tableName,\n table,\n })),\n );\n}\n\nfunction findStorageTableByTableName(storage: NamespacedStorageWalk, tableName: string): unknown {\n for (const ns of Object.values(storage.namespaces)) {\n const t = ns.tables?.[tableName];\n if (t !== undefined) {\n return t;\n }\n }\n return undefined;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction findDuplicateValue(values: readonly string[]): string | undefined {\n const seen = new Set<string>();\n for (const value of values) {\n if (seen.has(value)) {\n return value;\n }\n seen.add(value);\n }\n return undefined;\n}\n\nfunction isContractFieldType(value: unknown): boolean {\n if (!isPlainRecord(value)) return false;\n const kind = value['kind'];\n if (kind === 'scalar') {\n if (typeof value['codecId'] !== 'string') return false;\n const typeParams = value['typeParams'];\n if (typeParams !== undefined && !isPlainRecord(typeParams)) return false;\n return true;\n }\n if (kind === 'valueObject') {\n return typeof value['name'] === 'string';\n }\n if (kind === 'union') {\n const members = value['members'];\n if (!Array.isArray(members)) return false;\n return members.every((m) => isContractFieldType(m));\n }\n return false;\n}\n\nconst ContractFieldTypeSchema = type('unknown').narrow((value, ctx) =>\n isContractFieldType(value) ? true : ctx.mustBe('scalar, valueObject, or union field type'),\n);\n\nconst ModelFieldSchema = type({\n '+': 'reject',\n nullable: 'boolean',\n type: ContractFieldTypeSchema,\n 'many?': 'true',\n 'dict?': 'true',\n});\n\nconst ModelStorageFieldSchema = type({\n column: 'string',\n 'codecId?': 'string',\n 'nullable?': 'boolean',\n});\n\nconst ModelStorageSchema = type({\n table: 'string',\n fields: type({ '[string]': ModelStorageFieldSchema }),\n});\n\nconst ModelSchema = type({\n storage: ModelStorageSchema,\n 'fields?': type({ '[string]': ModelFieldSchema }),\n 'relations?': type({ '[string]': 'unknown' }),\n 'discriminator?': 'unknown',\n 'variants?': 'unknown',\n 'base?': 'string',\n 'owner?': 'string',\n});\n\nconst ContractMetaSchema = type({\n '[string]': 'unknown',\n});\n\n/**\n * Builds the full SQL contract schema. The storage subtree threads\n * pack contributions through {@link createSqlStorageSchema}; the rest\n * of the contract envelope is family-shared.\n */\nexport function createSqlContractSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n const storage = createSqlStorageSchema(fragments);\n return type({\n '+': 'reject',\n target: 'string',\n targetFamily: \"'sql'\",\n 'coreHash?': 'string',\n profileHash: 'string',\n 'capabilities?': 'Record<string, Record<string, boolean>>',\n 'extensionPacks?': 'Record<string, unknown>',\n 'meta?': ContractMetaSchema,\n 'roots?': 'Record<string, string>',\n models: type({ '[string]': ModelSchema }),\n 'valueObjects?': 'Record<string, unknown>',\n 'domain?': 'unknown',\n storage,\n 'execution?': ExecutionSchema,\n }) as Type<unknown>;\n}\n\nconst SqlContractSchema = createSqlContractSchema();\n\n// NOTE: StorageColumnSchema, StorageTableSchema, and StorageSchema use bare type()\n// instead of type.declare<T>().type() because the ColumnDefault union's value field\n// includes bigint | Date (runtime-only types after decoding) which cannot be expressed\n// in Arktype's JSON validation DSL. The `as SqlStorage` cast in validateStorage() bridges\n// the gap between the JSON-safe Arktype output and the runtime TypeScript type.\n\n/**\n * Validates the structural shape of SqlStorage using Arktype.\n *\n * @param value - The storage value to validate\n * @returns The validated storage if structure is valid\n * @throws Error if the storage structure is invalid\n */\nexport function validateStorage(value: unknown): SqlStorage {\n const result = StorageSchema(value);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Storage validation failed: ${messages}`);\n }\n // The arktype-validated shape matches `SqlStorageInput`\n // structurally. Funnel through the constructor so nested IR fields\n // (`types`) are normalised into class instances and the\n // branded `storageHash` is preserved on the returned `SqlStorage`.\n return new SqlStorage(result as SqlStorageInput);\n}\n\nexport function validateModel(value: unknown): unknown {\n const result = ModelSchema(value);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Model validation failed: ${messages}`);\n }\n return result;\n}\n\n/**\n * Structural arktype validation of an SQL contract envelope. Internal\n * helper for {@link validateSqlContractFully} — exposed only inside\n * this module, since the family seam-of-record is the\n * `SqlContractSerializerBase.deserializeContract` SPI.\n */\nfunction validateSqlContractStructure<T extends Contract<SqlStorage>>(\n value: unknown,\n contractSchema: Type<unknown>,\n): T {\n if (typeof value !== 'object' || value === null) {\n throw new ContractValidationError(\n 'Contract structural validation failed: value must be an object',\n 'structural',\n );\n }\n\n const rawValue = value as { targetFamily?: string };\n if (rawValue.targetFamily !== undefined && rawValue.targetFamily !== 'sql') {\n throw new ContractValidationError(\n `Unsupported target family: ${rawValue.targetFamily}`,\n 'structural',\n );\n }\n\n const contractResult = contractSchema(value);\n\n if (contractResult instanceof type.errors) {\n const messages = contractResult.map((p: { message: string }) => p.message).join('; ');\n throw new ContractValidationError(\n `Contract structural validation failed: ${messages}`,\n 'structural',\n );\n }\n\n // Arktype's inferred output type differs from T due to exactOptionalPropertyTypes\n // and branded hash types — the runtime value is structurally compatible after validation\n return contractResult as unknown as T;\n}\n\n/**\n * Validates semantic constraints on SqlStorage that cannot be expressed in Arktype schemas.\n *\n * Returns an array of human-readable error strings. Empty array = valid.\n *\n * Currently checks:\n * - duplicate named primary key / unique / index / foreign key objects within a table\n * - duplicate unique, index, or foreign key declarations within a table\n * - duplicate columns within primary key / unique / index definitions\n * - nullable columns in primary key definitions\n * - `setNull` referential action on a non-nullable FK column (would fail at runtime)\n * - `setDefault` referential action on a non-nullable FK column without a DEFAULT (would fail at runtime)\n */\nexport function validateStorageSemantics(storage: SqlStorage): string[] {\n const errors: string[] = [];\n\n for (const { namespaceId, tableName, table: rawTable } of eachStorageTable(storage)) {\n const table = rawTable as StorageTable;\n const namedObjects = new Map<string, string[]>();\n const registerNamedObject = (kind: string, name: string | undefined) => {\n if (!name) return;\n namedObjects.set(name, [...(namedObjects.get(name) ?? []), kind]);\n };\n\n registerNamedObject('primary key', table.primaryKey?.name);\n for (const unique of table.uniques) {\n registerNamedObject('unique constraint', unique.name);\n }\n for (const index of table.indexes) {\n registerNamedObject('index', index.name);\n }\n for (const fk of table.foreignKeys) {\n registerNamedObject('foreign key', fk.name);\n }\n\n for (const [name, kinds] of namedObjects) {\n if (kinds.length > 1) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": named object \"${name}\" is declared multiple times (${kinds.join(', ')})`,\n );\n }\n }\n\n if (table.primaryKey) {\n const duplicateColumn = findDuplicateValue(table.primaryKey.columns);\n if (duplicateColumn !== undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": primary key contains duplicate column \"${duplicateColumn}\"`,\n );\n }\n\n for (const columnName of table.primaryKey.columns) {\n const column = table.columns[columnName];\n if (column?.nullable === true) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": primary key column \"${columnName}\" is nullable; primary key columns must be NOT NULL`,\n );\n }\n }\n }\n\n const seenUniqueDefinitions = new Set<string>();\n for (const unique of table.uniques) {\n const duplicateColumn = findDuplicateValue(unique.columns);\n if (duplicateColumn !== undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": unique constraint contains duplicate column \"${duplicateColumn}\"`,\n );\n }\n\n const signature = JSON.stringify({ columns: unique.columns });\n if (seenUniqueDefinitions.has(signature)) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": duplicate unique constraint definition on columns [${unique.columns.join(', ')}]`,\n );\n continue;\n }\n seenUniqueDefinitions.add(signature);\n }\n\n const sortOptions = (o: Record<string, unknown> | undefined): Record<string, unknown> | null =>\n o ? Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b))) : null;\n\n const seenIndexDefinitions = new Set<string>();\n for (const index of table.indexes) {\n const duplicateColumn = findDuplicateValue(index.columns);\n if (duplicateColumn !== undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": index contains duplicate column \"${duplicateColumn}\"`,\n );\n }\n\n const signature = JSON.stringify({\n columns: index.columns,\n type: index.type ?? null,\n options: sortOptions(index.options),\n });\n if (seenIndexDefinitions.has(signature)) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": duplicate index definition on columns [${index.columns.join(', ')}]`,\n );\n continue;\n }\n seenIndexDefinitions.add(signature);\n }\n\n const seenForeignKeyDefinitions = new Set<string>();\n for (const fk of table.foreignKeys) {\n const signature = JSON.stringify({\n source: fk.source,\n target: fk.target,\n onDelete: fk.onDelete ?? null,\n onUpdate: fk.onUpdate ?? null,\n constraint: fk.constraint,\n index: fk.index,\n });\n if (seenForeignKeyDefinitions.has(signature)) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": duplicate foreign key definition on columns [${fk.source.columns.join(', ')}]`,\n );\n continue;\n }\n seenForeignKeyDefinitions.add(signature);\n }\n\n for (const fk of table.foreignKeys) {\n for (const colName of fk.source.columns) {\n const column = table.columns[colName];\n if (!column) continue;\n\n if (fk.onDelete === 'setNull' && !column.nullable) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onDelete setNull on foreign key column \"${colName}\" which is NOT NULL`,\n );\n }\n if (fk.onUpdate === 'setNull' && !column.nullable) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onUpdate setNull on foreign key column \"${colName}\" which is NOT NULL`,\n );\n }\n if (fk.onDelete === 'setDefault' && !column.nullable && column.default === undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onDelete setDefault on foreign key column \"${colName}\" which is NOT NULL and has no DEFAULT`,\n );\n }\n if (fk.onUpdate === 'setDefault' && !column.nullable && column.default === undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onUpdate setDefault on foreign key column \"${colName}\" which is NOT NULL and has no DEFAULT`,\n );\n }\n }\n }\n }\n\n return errors;\n}\n\n/**\n * SQL storage logical-consistency checks: every model.storage.table\n * resolves to a real table, every model.storage.fields[*].column\n * resolves to a real column, and value-object fields land on JSON-native\n * columns. Throws `ContractValidationError` on the first mismatch.\n */\nexport function validateModelStorageReferences(contract: Contract<SqlStorage>): void {\n const models = contract.models as Record<string, ContractModel<SqlModelStorage>>;\n for (const [modelName, model] of Object.entries(models)) {\n const storageTable = model.storage.table;\n\n const rawTable = findStorageTableByTableName(contract.storage, storageTable);\n if (rawTable === undefined) {\n throw new ContractValidationError(\n `Model \"${modelName}\" references non-existent table \"${storageTable}\"`,\n 'storage',\n );\n }\n\n const table = rawTable as StorageTable;\n\n const columnNames = new Set(Object.keys(table.columns));\n for (const [fieldName, field] of Object.entries(model.storage.fields)) {\n if (!columnNames.has(field.column)) {\n throw new ContractValidationError(\n `Model \"${modelName}\" field \"${fieldName}\" references non-existent column \"${field.column}\" in table \"${storageTable}\"`,\n 'storage',\n );\n }\n }\n\n const JSON_NATIVE_TYPES = new Set(['json', 'jsonb']);\n for (const [fieldName, domainField] of Object.entries(model.fields ?? {})) {\n const f = domainField as ContractField;\n if (f.type?.kind !== 'valueObject') continue;\n const storageField = model.storage.fields[fieldName];\n if (!storageField) continue;\n const column = table.columns[storageField.column];\n if (!column) continue;\n if (!JSON_NATIVE_TYPES.has(column.nativeType)) {\n throw new ContractValidationError(\n `Model \"${modelName}\" field \"${fieldName}\" is a value object but storage column \"${storageField.column}\" has nativeType \"${column.nativeType}\" (expected json or jsonb)`,\n 'storage',\n );\n }\n }\n }\n}\n\n/**\n * Cross-table consistency checks for SQL storage: primary key, unique,\n * index, and foreign key column references resolve to real columns;\n * NOT NULL columns don't carry a literal `null` default; FK column\n * counts match their referenced columns. Throws on the first mismatch.\n */\nexport function validateSqlStorageConsistency(contract: Contract<SqlStorage>): void {\n for (const { namespaceId, tableName, table: rawTable } of eachStorageTable(contract.storage)) {\n const table = rawTable as StorageTable;\n const columnNames = new Set(Object.keys(table.columns));\n\n if (table.primaryKey) {\n for (const colName of table.primaryKey.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" primaryKey references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n }\n\n for (const unique of table.uniques) {\n for (const colName of unique.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" unique constraint references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n }\n\n for (const index of table.indexes) {\n for (const colName of index.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n }\n\n for (const [colName, column] of Object.entries(table.columns)) {\n if (!column.nullable && column.default?.kind === 'literal' && column.default.value === null) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" column \"${colName}\" is NOT NULL but has a literal null default`,\n 'storage',\n );\n }\n }\n\n for (const fk of table.foreignKeys) {\n if (fk.source.namespaceId !== namespaceId || fk.source.tableName !== tableName) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" contains foreignKey with mismatched source coordinates (${fk.source.namespaceId}.${fk.source.tableName})`,\n 'storage',\n );\n }\n\n for (const colName of fk.source.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n\n const targetNamespace = contract.storage.namespaces[fk.target.namespaceId];\n const referencedRaw = targetNamespace?.tables?.[fk.target.tableName];\n if (referencedRaw === undefined) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey references non-existent table \"${fk.target.namespaceId}.${fk.target.tableName}\"`,\n 'storage',\n );\n }\n const referencedTable = referencedRaw as StorageTable;\n const referencedColumnNames = new Set(Object.keys(referencedTable.columns));\n for (const colName of fk.target.columns) {\n if (!referencedColumnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey references non-existent column \"${colName}\" in table \"${fk.target.tableName}\"`,\n 'storage',\n );\n }\n }\n\n if (fk.source.columns.length !== fk.target.columns.length) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey column count (${fk.source.columns.length}) does not match referenced column count (${fk.target.columns.length})`,\n 'storage',\n );\n }\n }\n }\n}\n\nexport interface ValidateSqlContractFullyOptions {\n /**\n * Precomputed structural schema to validate against. Built once at\n * serializer construction time when the family `ContractSerializer`\n * has folded pack-contributed `validatorSchema` fragments into the\n * per-namespace entry shape; absent for the family-default validator\n * path (no pack contributions). Falls back to the cached default\n * `SqlContractSchema` when omitted.\n */\n readonly contractSchema?: Type<unknown>;\n}\n\n/**\n * Full SQL contract validation: structural (arktype) +\n * framework-shared domain + SQL storage logical-consistency + SQL\n * storage semantic + model ↔ storage reference checks. Throws\n * `ContractValidationError` on the first failure. Returns the\n * validated flat-data shape; IR class hydration happens in the SPI\n * base on top of this helper.\n */\nexport function validateSqlContractFully<T extends Contract<SqlStorage>>(\n value: unknown,\n options?: ValidateSqlContractFullyOptions,\n): T {\n const stripped =\n typeof value === 'object' && value !== null\n ? (() => {\n const { schemaVersion: _, _generated: _g, ...rest } = value as Record<string, unknown>;\n return rest;\n })()\n : value;\n const schema = options?.contractSchema ?? SqlContractSchema;\n const validated = validateSqlContractStructure<T>(stripped, schema);\n validateContractDomain({\n roots: validated.roots,\n models: validated.models,\n ...(validated.valueObjects ? { valueObjects: validated.valueObjects } : {}),\n });\n validateSqlStorageConsistency(validated);\n const semanticErrors = validateStorageSemantics(validated.storage);\n if (semanticErrors.length > 0) {\n throw new ContractValidationError(\n `Contract semantic validation failed: ${semanticErrors.join('; ')}`,\n 'storage',\n );\n }\n validateModelStorageReferences(validated);\n return validated;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validators.mjs","names":["f","referencedTable"],"sources":["../src/validators.ts"],"sourcesContent":["import { ContractValidationError } from '@prisma-next/contract/contract-validation-error';\nimport {\n type Contract,\n type ContractField,\n type ContractModel,\n CrossReferenceSchema,\n} from '@prisma-next/contract/types';\nimport { validateContractDomain } from '@prisma-next/contract/validate-domain';\nimport { type Namespace, UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { type Type, type } from 'arktype';\nimport { buildSqlNamespaceMap } from './ir/build-sql-namespace';\nimport { SqlUnboundNamespace } from './ir/sql-unbound-namespace';\nimport {\n type ForeignKeyInput,\n type ForeignKeyReferenceInput,\n type PrimaryKeyInput,\n type ReferentialAction,\n type SqlModelStorage,\n SqlStorage,\n type SqlStorageInput,\n type StorageTable,\n type StorageTypeInstanceInput,\n type UniqueConstraintInput,\n} from './types';\n\ntype ColumnDefaultLiteral = {\n readonly kind: 'literal';\n readonly value: string | number | boolean | Record<string, unknown> | unknown[] | null;\n};\ntype ColumnDefaultFunction = { readonly kind: 'function'; readonly expression: string };\nconst literalKindSchema = type(\"'literal'\");\nconst functionKindSchema = type(\"'function'\");\nconst generatorKindSchema = type(\"'generator'\");\nconst generatorIdSchema = type('string').narrow((value, ctx) => {\n return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(value) ? true : ctx.mustBe('a flat generator id');\n});\n\nexport const ColumnDefaultLiteralSchema = type.declare<ColumnDefaultLiteral>().type({\n kind: literalKindSchema,\n value: 'string | number | boolean | null | unknown[] | Record<string, unknown>',\n});\n\nexport const ColumnDefaultFunctionSchema = type.declare<ColumnDefaultFunction>().type({\n kind: functionKindSchema,\n expression: 'string',\n});\n\nexport const ColumnDefaultSchema = ColumnDefaultLiteralSchema.or(ColumnDefaultFunctionSchema);\n\nconst ExecutionMutationDefaultValueSchema = type({\n '+': 'reject',\n kind: generatorKindSchema,\n id: generatorIdSchema,\n 'params?': 'Record<string, unknown>',\n});\n\nconst ExecutionMutationDefaultSchema = type({\n '+': 'reject',\n ref: {\n '+': 'reject',\n table: 'string',\n column: 'string',\n },\n 'onCreate?': ExecutionMutationDefaultValueSchema,\n 'onUpdate?': ExecutionMutationDefaultValueSchema,\n});\n\nconst ExecutionSchema = type({\n '+': 'reject',\n executionHash: 'string',\n mutations: {\n '+': 'reject',\n defaults: ExecutionMutationDefaultSchema.array().readonly(),\n },\n});\n\nconst StorageColumnSchema = type({\n '+': 'reject',\n nativeType: 'string',\n codecId: 'string',\n nullable: 'boolean',\n 'typeParams?': 'Record<string, unknown>',\n 'typeRef?': 'string',\n 'default?': ColumnDefaultSchema,\n}).narrow((col, ctx) => {\n if (col.typeParams !== undefined && col.typeRef !== undefined) {\n return ctx.mustBe('a column with either typeParams or typeRef, not both');\n }\n return true;\n});\n\n/**\n * Codec-triple entry persisted under `storage.types[name]`. Carries an\n * enumerable literal `kind: 'codec-instance'` discriminator so the\n * polymorphic slot dispatch can distinguish codec triples from\n * class-instance kinds (e.g. `'postgres-enum'`) sharing the slot.\n */\nconst StorageTypeInstanceSchema = type\n .declare<StorageTypeInstanceInput & { kind: 'codec-instance' }>()\n .type({\n kind: \"'codec-instance'\",\n codecId: 'string',\n nativeType: 'string',\n typeParams: 'Record<string, unknown>',\n });\n\n/**\n * Postgres native enum entry under `storage.namespaces[namespaceId].enum[name]`.\n * Document-scoped `storage.types` carries codec aliases only\n * (`DocumentScopedStorageTypeSchema`).\n */\nconst PostgresEnumTypeSchema = type({\n kind: \"'postgres-enum'\",\n 'name?': 'string',\n 'nativeType?': 'string',\n values: type.string.array().readonly(),\n});\n\n/** Document-scoped `storage.types`: codec triples only. */\nconst DocumentScopedStorageTypeSchema = StorageTypeInstanceSchema;\n\nconst PrimaryKeySchema = type.declare<PrimaryKeyInput>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nconst UniqueConstraintSchema = type.declare<UniqueConstraintInput>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nexport const IndexSchema = type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n 'type?': 'string',\n 'options?': 'Record<string, unknown>',\n});\n\nexport const ForeignKeyReferenceSchema = type({\n '+': 'reject',\n namespaceId: 'string',\n tableName: 'string',\n columns: type.string.array().readonly(),\n}) satisfies Type<ForeignKeyReferenceInput>;\n\nexport const ReferentialActionSchema = type\n .declare<ReferentialAction>()\n .type(\"'noAction' | 'restrict' | 'cascade' | 'setNull' | 'setDefault'\");\n\nexport const ForeignKeySchema = type.declare<ForeignKeyInput>().type({\n source: ForeignKeyReferenceSchema,\n target: ForeignKeyReferenceSchema,\n 'name?': 'string',\n 'onDelete?': ReferentialActionSchema,\n 'onUpdate?': ReferentialActionSchema,\n constraint: 'boolean',\n index: 'boolean',\n});\n\nconst StorageTableSchema = type({\n '+': 'reject',\n columns: type({ '[string]': StorageColumnSchema }),\n 'primaryKey?': PrimaryKeySchema,\n uniques: UniqueConstraintSchema.array().readonly(),\n indexes: IndexSchema.array().readonly(),\n foreignKeys: ForeignKeySchema.array().readonly(),\n});\n\n/**\n * Re-exported so target packs can register their `validatorSchema`\n * fragment without re-declaring the schema for the kinds the family\n * core already validates. Full extraction of enum-specific schemas\n * into the Postgres pack is a follow-up; today the symbol lives here.\n */\nexport { PostgresEnumTypeSchema };\n\n/**\n * Composes a hardcoded family `fallback` schema with optional\n * pack-contributed `fragments` keyed by the entry's `kind`\n * discriminator. The composition is **additive**, not substitutive:\n *\n * - No fragments registered → entries are validated by `fallback`\n * alone (the unchanged baseline).\n * - An entry's `kind` matches `fallbackKind` AND a fragment for that\n * kind is registered → the entry must pass **both** `fallback` and\n * the fragment. This preserves family-owned invariants (e.g. the\n * built-in `PostgresEnumType` shape) even when a pack contributes\n * its own schema for the same kind.\n * - An entry's `kind` matches a registered fragment for some\n * non-fallback kind → the fragment alone validates the entry.\n * `fallback` is family-specific (validates a single hardcoded kind)\n * and would reject any other kind, so it does not apply here.\n * - An entry's `kind` matches no fragment → fall through to\n * `fallback`.\n */\nfunction namespaceSlotEntrySchema(\n fallback: Type<unknown>,\n fallbackKind: string,\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n if (fragments === undefined || fragments.size === 0) {\n return fallback;\n }\n return type('unknown').narrow((entry, ctx) => {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n return ctx.mustBe('an object');\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string') {\n const fragment = fragments.get(kind);\n if (fragment !== undefined) {\n if (kind === fallbackKind) {\n const baseParsed = fallback(entry);\n if (baseParsed instanceof type.errors) {\n return ctx.reject({ expected: baseParsed.summary });\n }\n }\n const parsed = fragment(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n }\n }\n const parsed = fallback(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n });\n}\n\n/**\n * Builds the per-namespace entry schema for `storage.namespaces[id]`.\n * Pack-contributed `validatorSchema` fragments — keyed by the\n * descriptor's `discriminator` — validate each entry by matching the\n * entry's `kind` field on the `'enum?'` slot.\n */\nexport function createNamespaceEntrySchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n return type({\n '+': 'reject',\n id: 'string',\n 'kind?': 'string',\n 'tables?': type({ '[string]': StorageTableSchema }),\n 'enum?': type({\n '[string]': namespaceSlotEntrySchema(PostgresEnumTypeSchema, 'postgres-enum', fragments),\n }),\n }) as Type<unknown>;\n}\n\n/**\n * Builds the storage schema. Pack contributions reach the per-namespace\n * entry shape through {@link createNamespaceEntrySchema}; the\n * document-scoped `storage.types` slot (codec triples only) and the\n * storage hash stay family-shared.\n */\nexport function createSqlStorageSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n const namespaceEntry = createNamespaceEntrySchema(fragments);\n return type({\n '+': 'reject',\n storageHash: 'string',\n 'types?': type({ '[string]': DocumentScopedStorageTypeSchema }),\n // `__unbound__` is NOT required here: cross-namespace contracts can\n // declare only named namespaces (see cross-namespace FK fixtures). The\n // `__unbound__` brand on `SqlStorageInput['namespaces']` is kept sound at\n // construction time by injecting the unbound singleton when absent\n // (see `validateStorage` / `hydrateSqlStorage`), not by structural require.\n 'namespaces?': type({ '[string]': namespaceEntry }),\n }) as Type<unknown>;\n}\n\nconst StorageSchema = createSqlStorageSchema();\n\n// SQL-specific namespace walk shape (`tables` is the SQL family's idiom —\n// the framework `Namespace` interface no longer carries it). The wider\n// `object` table value keeps this helper structurally compatible with\n// `SqlNamespace` (whose tables narrow to `StorageTable`) and the JSON\n// envelope variants that lose class identity.\ntype NamespacedStorageWalk = {\n readonly namespaces: Readonly<\n Record<string, Namespace & { readonly tables?: Readonly<Record<string, object>> }>\n >;\n};\n\nfunction eachStorageTable(storage: NamespacedStorageWalk) {\n return Object.entries(storage.namespaces).flatMap(([namespaceId, ns]) =>\n Object.entries(ns.tables ?? {}).map(([tableName, table]) => ({\n namespaceId,\n tableName,\n table,\n })),\n );\n}\n\nfunction findStorageTableByTableName(storage: NamespacedStorageWalk, tableName: string): unknown {\n for (const ns of Object.values(storage.namespaces)) {\n const t = ns.tables?.[tableName];\n if (t !== undefined) {\n return t;\n }\n }\n return undefined;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction findDuplicateValue(values: readonly string[]): string | undefined {\n const seen = new Set<string>();\n for (const value of values) {\n if (seen.has(value)) {\n return value;\n }\n seen.add(value);\n }\n return undefined;\n}\n\nfunction isContractFieldType(value: unknown): boolean {\n if (!isPlainRecord(value)) return false;\n const kind = value['kind'];\n if (kind === 'scalar') {\n if (typeof value['codecId'] !== 'string') return false;\n const typeParams = value['typeParams'];\n if (typeParams !== undefined && !isPlainRecord(typeParams)) return false;\n return true;\n }\n if (kind === 'valueObject') {\n return typeof value['name'] === 'string';\n }\n if (kind === 'union') {\n const members = value['members'];\n if (!Array.isArray(members)) return false;\n return members.every((m) => isContractFieldType(m));\n }\n return false;\n}\n\nconst ContractFieldTypeSchema = type('unknown').narrow((value, ctx) =>\n isContractFieldType(value) ? true : ctx.mustBe('scalar, valueObject, or union field type'),\n);\n\nconst ModelFieldSchema = type({\n '+': 'reject',\n nullable: 'boolean',\n type: ContractFieldTypeSchema,\n 'many?': 'true',\n 'dict?': 'true',\n});\n\nconst ModelStorageFieldSchema = type({\n column: 'string',\n 'codecId?': 'string',\n 'nullable?': 'boolean',\n});\n\nconst ModelStorageSchema = type({\n table: 'string',\n fields: type({ '[string]': ModelStorageFieldSchema }),\n});\n\nconst ContractReferenceRelationSchema = type({\n '+': 'reject',\n to: CrossReferenceSchema,\n cardinality: \"'1:1' | '1:N' | 'N:1'\",\n on: type({\n '+': 'reject',\n localFields: type.string.array().readonly(),\n targetFields: type.string.array().readonly(),\n }),\n});\n\nconst ContractEmbedRelationSchema = type({\n '+': 'reject',\n to: CrossReferenceSchema,\n cardinality: \"'1:1' | '1:N'\",\n});\n\nconst ContractRelationSchema = ContractReferenceRelationSchema.or(ContractEmbedRelationSchema);\n\nconst ModelSchema = type({\n storage: ModelStorageSchema,\n 'fields?': type({ '[string]': ModelFieldSchema }),\n 'relations?': type({ '[string]': ContractRelationSchema }),\n 'discriminator?': 'unknown',\n 'variants?': 'unknown',\n 'base?': CrossReferenceSchema,\n 'owner?': 'string',\n});\n\nconst ContractMetaSchema = type({\n '[string]': 'unknown',\n});\n\n/**\n * Builds the full SQL contract schema. The storage subtree threads\n * pack contributions through {@link createSqlStorageSchema}; the rest\n * of the contract envelope is family-shared.\n */\nexport function createSqlContractSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n const storage = createSqlStorageSchema(fragments);\n return type({\n '+': 'reject',\n target: 'string',\n targetFamily: \"'sql'\",\n 'coreHash?': 'string',\n profileHash: 'string',\n 'capabilities?': 'Record<string, Record<string, boolean>>',\n 'extensionPacks?': 'Record<string, unknown>',\n 'meta?': ContractMetaSchema,\n 'roots?': type({ '[string]': CrossReferenceSchema }),\n domain: type({\n namespaces: type({\n '[string]': type({\n models: type({ '[string]': ModelSchema }),\n 'valueObjects?': 'Record<string, unknown>',\n }),\n }),\n }),\n storage,\n 'execution?': ExecutionSchema,\n }) as Type<unknown>;\n}\n\nconst SqlContractSchema = createSqlContractSchema();\n\n// NOTE: StorageColumnSchema, StorageTableSchema, and StorageSchema use bare type()\n// instead of type.declare<T>().type() because the ColumnDefault union's value field\n// includes bigint | Date (runtime-only types after decoding) which cannot be expressed\n// in Arktype's JSON validation DSL. The `as SqlStorage` cast in validateStorage() bridges\n// the gap between the JSON-safe Arktype output and the runtime TypeScript type.\n\n/**\n * Validates the structural shape of SqlStorage using Arktype.\n *\n * @param value - The storage value to validate\n * @returns The validated storage if structure is valid\n * @throws Error if the storage structure is invalid\n */\nexport function validateStorage(value: unknown): SqlStorage {\n const result = StorageSchema(value);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Storage validation failed: ${messages}`);\n }\n // Arktype validates the JSON-safe envelope, but the `ColumnDefault`\n // union carries runtime-only `bigint | Date` that the validation DSL\n // can't express (see NOTE above), so bridge the validated shape to the\n // input type. Construction below re-materialises nested IR fields.\n const validated = blindCast<\n SqlStorageInput & { readonly namespaces?: SqlStorageInput['namespaces'] },\n 'arktype validated the JSON envelope but its output type is unknown (ColumnDefault carries runtime-only bigint|Date); bridge to the input shape'\n >(result);\n const namespaces = buildSqlNamespaceMap(validated.namespaces ?? {});\n // The `__unbound__` brand is made true at construction: if the validated\n // namespaces omit the late-bound slot (e.g. a contract declaring only named\n // namespaces), inject the family unbound singleton rather than asserting a\n // shape that isn't there. Reconstructing the literal lets the branded\n // `SqlStorageInput['namespaces']` hold with no cast.\n const unbound = namespaces[UNBOUND_NAMESPACE_ID] ?? SqlUnboundNamespace.instance;\n return new SqlStorage({\n storageHash: validated.storageHash,\n ...ifDefined('types', validated.types),\n namespaces: { ...namespaces, [UNBOUND_NAMESPACE_ID]: unbound },\n });\n}\n\nexport function validateModel(value: unknown): unknown {\n const result = ModelSchema(value);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Model validation failed: ${messages}`);\n }\n return result;\n}\n\n/**\n * Structural arktype validation of an SQL contract envelope. Internal\n * helper for {@link validateSqlContractFully} — exposed only inside\n * this module, since the family seam-of-record is the\n * `SqlContractSerializerBase.deserializeContract` SPI.\n */\nfunction validateSqlContractStructure<T extends Contract<SqlStorage>>(\n value: unknown,\n contractSchema: Type<unknown>,\n): T {\n if (typeof value !== 'object' || value === null) {\n throw new ContractValidationError(\n 'Contract structural validation failed: value must be an object',\n 'structural',\n );\n }\n\n const rawValue = value as { targetFamily?: string };\n if (rawValue.targetFamily !== undefined && rawValue.targetFamily !== 'sql') {\n throw new ContractValidationError(\n `Unsupported target family: ${rawValue.targetFamily}`,\n 'structural',\n );\n }\n\n const contractResult = contractSchema(value);\n\n if (contractResult instanceof type.errors) {\n const messages = contractResult.map((p: { message: string }) => p.message).join('; ');\n throw new ContractValidationError(\n `Contract structural validation failed: ${messages}`,\n 'structural',\n );\n }\n\n // Arktype's inferred output type differs from T due to exactOptionalPropertyTypes\n // and branded hash types — the runtime value is structurally compatible after validation\n return contractResult as unknown as T;\n}\n\n/**\n * Validates semantic constraints on SqlStorage that cannot be expressed in Arktype schemas.\n *\n * Returns an array of human-readable error strings. Empty array = valid.\n *\n * Currently checks:\n * - duplicate named primary key / unique / index / foreign key objects within a table\n * - duplicate unique, index, or foreign key declarations within a table\n * - duplicate columns within primary key / unique / index definitions\n * - nullable columns in primary key definitions\n * - `setNull` referential action on a non-nullable FK column (would fail at runtime)\n * - `setDefault` referential action on a non-nullable FK column without a DEFAULT (would fail at runtime)\n */\nexport function validateStorageSemantics(storage: SqlStorage): string[] {\n const errors: string[] = [];\n\n for (const { namespaceId, tableName, table: rawTable } of eachStorageTable(storage)) {\n const table = rawTable as StorageTable;\n const namedObjects = new Map<string, string[]>();\n const registerNamedObject = (kind: string, name: string | undefined) => {\n if (!name) return;\n namedObjects.set(name, [...(namedObjects.get(name) ?? []), kind]);\n };\n\n registerNamedObject('primary key', table.primaryKey?.name);\n for (const unique of table.uniques) {\n registerNamedObject('unique constraint', unique.name);\n }\n for (const index of table.indexes) {\n registerNamedObject('index', index.name);\n }\n for (const fk of table.foreignKeys) {\n registerNamedObject('foreign key', fk.name);\n }\n\n for (const [name, kinds] of namedObjects) {\n if (kinds.length > 1) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": named object \"${name}\" is declared multiple times (${kinds.join(', ')})`,\n );\n }\n }\n\n if (table.primaryKey) {\n const duplicateColumn = findDuplicateValue(table.primaryKey.columns);\n if (duplicateColumn !== undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": primary key contains duplicate column \"${duplicateColumn}\"`,\n );\n }\n\n for (const columnName of table.primaryKey.columns) {\n const column = table.columns[columnName];\n if (column?.nullable === true) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": primary key column \"${columnName}\" is nullable; primary key columns must be NOT NULL`,\n );\n }\n }\n }\n\n const seenUniqueDefinitions = new Set<string>();\n for (const unique of table.uniques) {\n const duplicateColumn = findDuplicateValue(unique.columns);\n if (duplicateColumn !== undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": unique constraint contains duplicate column \"${duplicateColumn}\"`,\n );\n }\n\n const signature = JSON.stringify({ columns: unique.columns });\n if (seenUniqueDefinitions.has(signature)) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": duplicate unique constraint definition on columns [${unique.columns.join(', ')}]`,\n );\n continue;\n }\n seenUniqueDefinitions.add(signature);\n }\n\n const sortOptions = (o: Record<string, unknown> | undefined): Record<string, unknown> | null =>\n o ? Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b))) : null;\n\n const seenIndexDefinitions = new Set<string>();\n for (const index of table.indexes) {\n const duplicateColumn = findDuplicateValue(index.columns);\n if (duplicateColumn !== undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": index contains duplicate column \"${duplicateColumn}\"`,\n );\n }\n\n const signature = JSON.stringify({\n columns: index.columns,\n type: index.type ?? null,\n options: sortOptions(index.options),\n });\n if (seenIndexDefinitions.has(signature)) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": duplicate index definition on columns [${index.columns.join(', ')}]`,\n );\n continue;\n }\n seenIndexDefinitions.add(signature);\n }\n\n const seenForeignKeyDefinitions = new Set<string>();\n for (const fk of table.foreignKeys) {\n const signature = JSON.stringify({\n source: fk.source,\n target: fk.target,\n onDelete: fk.onDelete ?? null,\n onUpdate: fk.onUpdate ?? null,\n constraint: fk.constraint,\n index: fk.index,\n });\n if (seenForeignKeyDefinitions.has(signature)) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": duplicate foreign key definition on columns [${fk.source.columns.join(', ')}]`,\n );\n continue;\n }\n seenForeignKeyDefinitions.add(signature);\n }\n\n for (const fk of table.foreignKeys) {\n for (const colName of fk.source.columns) {\n const column = table.columns[colName];\n if (!column) continue;\n\n if (fk.onDelete === 'setNull' && !column.nullable) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onDelete setNull on foreign key column \"${colName}\" which is NOT NULL`,\n );\n }\n if (fk.onUpdate === 'setNull' && !column.nullable) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onUpdate setNull on foreign key column \"${colName}\" which is NOT NULL`,\n );\n }\n if (fk.onDelete === 'setDefault' && !column.nullable && column.default === undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onDelete setDefault on foreign key column \"${colName}\" which is NOT NULL and has no DEFAULT`,\n );\n }\n if (fk.onUpdate === 'setDefault' && !column.nullable && column.default === undefined) {\n errors.push(\n `Namespace \"${namespaceId}\" table \"${tableName}\": onUpdate setDefault on foreign key column \"${colName}\" which is NOT NULL and has no DEFAULT`,\n );\n }\n }\n }\n }\n\n return errors;\n}\n\n/**\n * SQL storage logical-consistency checks: every model.storage.table\n * resolves to a real table, every model.storage.fields[*].column\n * resolves to a real column, and value-object fields land on JSON-native\n * columns. Throws `ContractValidationError` on the first mismatch.\n */\nexport function validateModelStorageReferences(contract: Contract<SqlStorage>): void {\n for (const [namespaceId, namespace] of Object.entries(contract.domain.namespaces)) {\n const models = namespace.models as Record<string, ContractModel<SqlModelStorage>>;\n for (const [modelName, model] of Object.entries(models)) {\n const qualifiedName = `${namespaceId}:${modelName}`;\n const storageTable = model.storage.table;\n\n const rawTable = findStorageTableByTableName(contract.storage, storageTable);\n if (rawTable === undefined) {\n throw new ContractValidationError(\n `Model \"${qualifiedName}\" references non-existent table \"${storageTable}\"`,\n 'storage',\n );\n }\n\n const table = rawTable as StorageTable;\n\n const columnNames = new Set(Object.keys(table.columns));\n for (const [fieldName, field] of Object.entries(model.storage.fields)) {\n if (!columnNames.has(field.column)) {\n throw new ContractValidationError(\n `Model \"${qualifiedName}\" field \"${fieldName}\" references non-existent column \"${field.column}\" in table \"${storageTable}\"`,\n 'storage',\n );\n }\n }\n\n const JSON_NATIVE_TYPES = new Set(['json', 'jsonb']);\n for (const [fieldName, domainField] of Object.entries(model.fields ?? {})) {\n const f = domainField as ContractField;\n if (f.type?.kind !== 'valueObject') continue;\n const storageField = model.storage.fields[fieldName];\n if (!storageField) continue;\n const column = table.columns[storageField.column];\n if (!column) continue;\n if (!JSON_NATIVE_TYPES.has(column.nativeType)) {\n throw new ContractValidationError(\n `Model \"${qualifiedName}\" field \"${fieldName}\" is a value object but storage column \"${storageField.column}\" has nativeType \"${column.nativeType}\" (expected json or jsonb)`,\n 'storage',\n );\n }\n }\n }\n }\n}\n\n/**\n * Cross-table consistency checks for SQL storage: primary key, unique,\n * index, and foreign key column references resolve to real columns;\n * NOT NULL columns don't carry a literal `null` default; FK column\n * counts match their referenced columns. Throws on the first mismatch.\n */\nexport function validateSqlStorageConsistency(contract: Contract<SqlStorage>): void {\n for (const { namespaceId, tableName, table: rawTable } of eachStorageTable(contract.storage)) {\n const table = rawTable as StorageTable;\n const columnNames = new Set(Object.keys(table.columns));\n\n if (table.primaryKey) {\n for (const colName of table.primaryKey.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" primaryKey references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n }\n\n for (const unique of table.uniques) {\n for (const colName of unique.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" unique constraint references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n }\n\n for (const index of table.indexes) {\n for (const colName of index.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n }\n\n for (const [colName, column] of Object.entries(table.columns)) {\n if (!column.nullable && column.default?.kind === 'literal' && column.default.value === null) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" column \"${colName}\" is NOT NULL but has a literal null default`,\n 'storage',\n );\n }\n }\n\n for (const fk of table.foreignKeys) {\n if (fk.source.namespaceId !== namespaceId || fk.source.tableName !== tableName) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" contains foreignKey with mismatched source coordinates (${fk.source.namespaceId}.${fk.source.tableName})`,\n 'storage',\n );\n }\n\n for (const colName of fk.source.columns) {\n if (!columnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey references non-existent column \"${colName}\"`,\n 'storage',\n );\n }\n }\n\n const targetNamespace = contract.storage.namespaces[fk.target.namespaceId];\n const referencedRaw = targetNamespace?.tables?.[fk.target.tableName];\n if (referencedRaw === undefined) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey references non-existent table \"${fk.target.namespaceId}.${fk.target.tableName}\"`,\n 'storage',\n );\n }\n const referencedTable = referencedRaw as StorageTable;\n const referencedColumnNames = new Set(Object.keys(referencedTable.columns));\n for (const colName of fk.target.columns) {\n if (!referencedColumnNames.has(colName)) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey references non-existent column \"${colName}\" in table \"${fk.target.tableName}\"`,\n 'storage',\n );\n }\n }\n\n if (fk.source.columns.length !== fk.target.columns.length) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" foreignKey column count (${fk.source.columns.length}) does not match referenced column count (${fk.target.columns.length})`,\n 'storage',\n );\n }\n }\n }\n}\n\nexport interface ValidateSqlContractFullyOptions {\n /**\n * Precomputed structural schema to validate against. Built once at\n * serializer construction time when the family `ContractSerializer`\n * has folded pack-contributed `validatorSchema` fragments into the\n * per-namespace entry shape; absent for the family-default validator\n * path (no pack contributions). Falls back to the cached default\n * `SqlContractSchema` when omitted.\n */\n readonly contractSchema?: Type<unknown>;\n}\n\n/**\n * Full SQL contract validation: structural (arktype) +\n * framework-shared domain + SQL storage logical-consistency + SQL\n * storage semantic + model ↔ storage reference checks. Throws\n * `ContractValidationError` on the first failure. Returns the\n * validated flat-data shape; IR class hydration happens in the SPI\n * base on top of this helper.\n */\nexport function validateSqlContractFully<T extends Contract<SqlStorage>>(\n value: unknown,\n options?: ValidateSqlContractFullyOptions,\n): T {\n const stripped =\n typeof value === 'object' && value !== null\n ? (() => {\n const { schemaVersion: _, _generated: _g, ...rest } = value as Record<string, unknown>;\n return rest;\n })()\n : value;\n const schema = options?.contractSchema ?? SqlContractSchema;\n const validated = validateSqlContractStructure<T>(stripped, schema);\n validateContractDomain({\n roots: validated.roots,\n domain: validated.domain,\n });\n validateSqlStorageConsistency(validated);\n const semanticErrors = validateStorageSemantics(validated.storage);\n if (semanticErrors.length > 0) {\n throw new ContractValidationError(\n `Contract semantic validation failed: ${semanticErrors.join('; ')}`,\n 'storage',\n );\n }\n validateModelStorageReferences(validated);\n return validated;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-contract",
3
- "version": "0.11.0-dev.7",
3
+ "version": "0.11.0-dev.70",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "SQL contract types, validators, and IR factories for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/contract": "0.11.0-dev.7",
10
- "@prisma-next/framework-components": "0.11.0-dev.7",
9
+ "@prisma-next/contract": "0.11.0-dev.70",
10
+ "@prisma-next/framework-components": "0.11.0-dev.70",
11
+ "@prisma-next/utils": "0.11.0-dev.70",
11
12
  "arktype": "^2.2.0"
12
13
  },
13
14
  "devDependencies": {
14
- "@prisma-next/test-utils": "0.11.0-dev.7",
15
- "@prisma-next/tsconfig": "0.11.0-dev.7",
16
- "@prisma-next/tsdown": "0.11.0-dev.7",
15
+ "@prisma-next/test-utils": "0.11.0-dev.70",
16
+ "@prisma-next/tsconfig": "0.11.0-dev.70",
17
+ "@prisma-next/tsdown": "0.11.0-dev.70",
17
18
  "tsdown": "0.22.0",
18
19
  "typescript": "5.9.3",
19
20
  "vitest": "4.1.6"
@@ -23,6 +24,7 @@
23
24
  "src"
24
25
  ],
25
26
  "exports": {
27
+ "./canonicalization-hooks": "./dist/canonicalization-hooks.mjs",
26
28
  "./factories": "./dist/factories.mjs",
27
29
  "./index-type-validation": "./dist/index-type-validation.mjs",
28
30
  "./index-types": "./dist/index-types.mjs",
@@ -0,0 +1,32 @@
1
+ import type { PreserveEmptyPredicate, StorageSort } from '@prisma-next/contract/hashing';
2
+ import {
3
+ createPreserveEmptyPredicate,
4
+ createStorageSort,
5
+ type NamedArraySortTarget,
6
+ type PathPattern,
7
+ } from '@prisma-next/contract/hashing-utils';
8
+
9
+ const preserveEmptyPatterns = [
10
+ ['storage', 'namespaces', '*', 'tables'],
11
+ ['storage', 'namespaces', '*', 'tables', '*'],
12
+ ['storage', 'namespaces', '*', 'tables', '*', ['uniques', 'indexes', 'foreignKeys']],
13
+ ['storage', 'namespaces', '*', 'tables', '*', 'foreignKeys', ['constraint', 'index']],
14
+ ['storage', 'types', '*', 'typeParams'],
15
+ ] as const satisfies readonly PathPattern[];
16
+
17
+ const sortTargets = [
18
+ { path: ['namespaces', '*', 'tables', '*'], arrayKeys: ['indexes', 'uniques'] },
19
+ ] as const satisfies readonly NamedArraySortTarget[];
20
+
21
+ const shouldPreserveEmpty: PreserveEmptyPredicate =
22
+ createPreserveEmptyPredicate(preserveEmptyPatterns);
23
+
24
+ const sortStorage: StorageSort = createStorageSort(sortTargets);
25
+
26
+ export const sqlContractCanonicalizationHooks: {
27
+ readonly shouldPreserveEmpty: PreserveEmptyPredicate;
28
+ readonly sortStorage: StorageSort;
29
+ } = {
30
+ shouldPreserveEmpty,
31
+ sortStorage,
32
+ };
@@ -0,0 +1 @@
1
+ export { sqlContractCanonicalizationHooks } from '../canonicalization-hooks';
@@ -37,6 +37,8 @@ export type {
37
37
  } from '../types';
38
38
  export {
39
39
  applyFkDefaults,
40
+ buildSqlNamespace,
41
+ buildSqlNamespaceMap,
40
42
  CODEC_INSTANCE_KIND,
41
43
  DEFAULT_FK_CONSTRAINT,
42
44
  DEFAULT_FK_INDEX,