@prisma-next/sql-contract 0.11.0 → 0.12.0-dev.10

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 (37) hide show
  1. package/dist/canonicalization-hooks.d.mts +10 -0
  2. package/dist/canonicalization-hooks.d.mts.map +1 -0
  3. package/dist/canonicalization-hooks.mjs +58 -0
  4. package/dist/canonicalization-hooks.mjs.map +1 -0
  5. package/dist/factories.d.mts +1 -1
  6. package/dist/factories.d.mts.map +1 -1
  7. package/dist/factories.mjs +3 -2
  8. package/dist/factories.mjs.map +1 -1
  9. package/dist/index-type-validation.d.mts +1 -1
  10. package/dist/index-type-validation.mjs.map +1 -1
  11. package/dist/index-types-B1cf5N0F.d.mts.map +1 -1
  12. package/dist/index-types.mjs.map +1 -1
  13. package/dist/{types-DZpIXwK4.d.mts → types-Cx_5A_L0.d.mts} +22 -20
  14. package/dist/types-Cx_5A_L0.d.mts.map +1 -0
  15. package/dist/{types-L8p7B1dP.mjs → types-YQrDHy-b.mjs} +125 -112
  16. package/dist/types-YQrDHy-b.mjs.map +1 -0
  17. package/dist/types.d.mts +2 -2
  18. package/dist/types.mjs +2 -2
  19. package/dist/validators.d.mts +10 -9
  20. package/dist/validators.d.mts.map +1 -1
  21. package/dist/validators.mjs +81 -45
  22. package/dist/validators.mjs.map +1 -1
  23. package/package.json +19 -6
  24. package/src/canonicalization-hooks.ts +32 -0
  25. package/src/exports/canonicalization-hooks.ts +1 -0
  26. package/src/exports/types.ts +2 -0
  27. package/src/factories.ts +2 -2
  28. package/src/ir/build-sql-namespace.ts +89 -0
  29. package/src/ir/foreign-key-reference.ts +3 -2
  30. package/src/ir/postgres-enum-storage-entry.ts +2 -0
  31. package/src/ir/sql-storage.ts +13 -95
  32. package/src/ir/storage-column.ts +4 -1
  33. package/src/ir/storage-table.ts +4 -0
  34. package/src/types.ts +1 -0
  35. package/src/validators.ts +113 -56
  36. package/dist/types-DZpIXwK4.d.mts.map +0 -1
  37. package/dist/types-L8p7B1dP.mjs.map +0 -1
@@ -0,0 +1,10 @@
1
+ import { PreserveEmptyPredicate, StorageSort } from "@prisma-next/contract/hashing";
2
+
3
+ //#region src/canonicalization-hooks.d.ts
4
+ declare const sqlContractCanonicalizationHooks: {
5
+ readonly shouldPreserveEmpty: PreserveEmptyPredicate;
6
+ readonly sortStorage: StorageSort;
7
+ };
8
+ //#endregion
9
+ export { sqlContractCanonicalizationHooks };
10
+ //# sourceMappingURL=canonicalization-hooks.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalization-hooks.d.mts","names":[],"sources":["../src/canonicalization-hooks.ts"],"mappings":";;;cAyBa,gCAAA;EAAA,SACF,mBAAA,EAAqB,sBAAA;EAAA,SACrB,WAAA,EAAa,WAAW;AAAA"}
@@ -0,0 +1,58 @@
1
+ import { createPreserveEmptyPredicate, createStorageSort } from "@prisma-next/contract/hashing-utils";
2
+ const sqlContractCanonicalizationHooks = {
3
+ shouldPreserveEmpty: createPreserveEmptyPredicate([
4
+ [
5
+ "storage",
6
+ "namespaces",
7
+ "*",
8
+ "tables"
9
+ ],
10
+ [
11
+ "storage",
12
+ "namespaces",
13
+ "*",
14
+ "tables",
15
+ "*"
16
+ ],
17
+ [
18
+ "storage",
19
+ "namespaces",
20
+ "*",
21
+ "tables",
22
+ "*",
23
+ [
24
+ "uniques",
25
+ "indexes",
26
+ "foreignKeys"
27
+ ]
28
+ ],
29
+ [
30
+ "storage",
31
+ "namespaces",
32
+ "*",
33
+ "tables",
34
+ "*",
35
+ "foreignKeys",
36
+ ["constraint", "index"]
37
+ ],
38
+ [
39
+ "storage",
40
+ "types",
41
+ "*",
42
+ "typeParams"
43
+ ]
44
+ ]),
45
+ sortStorage: createStorageSort([{
46
+ path: [
47
+ "namespaces",
48
+ "*",
49
+ "tables",
50
+ "*"
51
+ ],
52
+ arrayKeys: ["indexes", "uniques"]
53
+ }])
54
+ };
55
+ //#endregion
56
+ export { sqlContractCanonicalizationHooks };
57
+
58
+ //# sourceMappingURL=canonicalization-hooks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalization-hooks.mjs","names":[],"sources":["../src/canonicalization-hooks.ts"],"sourcesContent":["import type { PreserveEmptyPredicate, StorageSort } from '@prisma-next/contract/hashing';\nimport {\n createPreserveEmptyPredicate,\n createStorageSort,\n type NamedArraySortTarget,\n type PathPattern,\n} from '@prisma-next/contract/hashing-utils';\n\nconst preserveEmptyPatterns = [\n ['storage', 'namespaces', '*', 'tables'],\n ['storage', 'namespaces', '*', 'tables', '*'],\n ['storage', 'namespaces', '*', 'tables', '*', ['uniques', 'indexes', 'foreignKeys']],\n ['storage', 'namespaces', '*', 'tables', '*', 'foreignKeys', ['constraint', 'index']],\n ['storage', 'types', '*', 'typeParams'],\n] as const satisfies readonly PathPattern[];\n\nconst sortTargets = [\n { path: ['namespaces', '*', 'tables', '*'], arrayKeys: ['indexes', 'uniques'] },\n] as const satisfies readonly NamedArraySortTarget[];\n\nconst shouldPreserveEmpty: PreserveEmptyPredicate =\n createPreserveEmptyPredicate(preserveEmptyPatterns);\n\nconst sortStorage: StorageSort = createStorageSort(sortTargets);\n\nexport const sqlContractCanonicalizationHooks: {\n readonly shouldPreserveEmpty: PreserveEmptyPredicate;\n readonly sortStorage: StorageSort;\n} = {\n shouldPreserveEmpty,\n sortStorage,\n};\n"],"mappings":";AAyBA,MAAa,mCAGT;CACF,qBARA,6BAA6B;EAZ7B;GAAC;GAAW;GAAc;GAAK;EAAQ;EACvC;GAAC;GAAW;GAAc;GAAK;GAAU;EAAG;EAC5C;GAAC;GAAW;GAAc;GAAK;GAAU;GAAK;IAAC;IAAW;IAAW;GAAa;EAAC;EACnF;GAAC;GAAW;GAAc;GAAK;GAAU;GAAK;GAAe,CAAC,cAAc,OAAO;EAAC;EACpF;GAAC;GAAW;GAAS;GAAK;EAAY;CAQT,CAQ7B;CACA,aAP+B,kBAAkB,CANjD;EAAE,MAAM;GAAC;GAAc;GAAK;GAAU;EAAG;EAAG,WAAW,CAAC,WAAW,SAAS;CAAE,CAM7B,CAOjD;AACF"}
@@ -1,4 +1,4 @@
1
- import { B as StorageColumnInput, F as StorageTable, J as ForeignKey, L as UniqueConstraint, U as PrimaryKey, V as Index, b as SqlModelStorage, f as ForeignKeyOptions, y as SqlModelFieldStorage, z as StorageColumn } from "./types-DZpIXwK4.mjs";
1
+ import { G as PrimaryKey, H as StorageColumnInput, L as StorageTable, U as Index, V as StorageColumn, X as ForeignKey, b as SqlModelStorage, f as ForeignKeyOptions, y as SqlModelFieldStorage, z as UniqueConstraint } from "./types-Cx_5A_L0.mjs";
2
2
  import { ScalarFieldType } from "@prisma-next/contract/types";
3
3
 
4
4
  //#region src/factories.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"factories.d.mts","names":[],"sources":["../src/factories.ts"],"mappings":";;;;iBAgBgB,GAAA,CAAI,UAAA,UAAoB,OAAA,UAAiB,QAAA,aAAmB,aAAA;AAAA,iBAI5D,EAAA,CAAA,GAAM,OAAA,sBAA6B,UAAA;AAAA,iBAInC,MAAA,CAAA,GAAU,OAAA,sBAA6B,gBAAA;AAAA,iBAIvC,KAAA,CAAA,GAAS,OAAA,sBAA6B,KAAA;AAAA,iBAItC,EAAA,CACd,YAAA,UACA,UAAA,qBACA,eAAA,UACA,aAAA,qBACA,IAAA,GAAO,iBAAA;EAAsB,UAAA;EAAsB,KAAA;EAAiB,WAAA;AAAA,IACnE,UAAA;AAAA,iBAca,KAAA,CACd,OAAA,EAAS,MAAA,SAAe,aAAA,GAAgB,kBAAA,GACxC,IAAA;EACE,EAAA,GAAK,UAAA;EACL,OAAA,YAAmB,gBAAA;EACnB,OAAA,YAAmB,KAAA;EACnB,GAAA,YAAe,UAAA;AAAA,IAEhB,YAAA;AAAA,iBAUa,KAAA,CACd,SAAA,UACA,MAAA,EAAQ,MAAA,SAAe,oBAAA,GACvB,SAAA,GAAW,MAAA;EAEX,OAAA,EAAS,eAAA;EACT,MAAA,EAAQ,MAAA;IAAA,SAA0B,QAAA;IAAA,SAA4B,IAAA,EAAM,eAAA;EAAA;EACpE,SAAA,EAAW,MAAA;AAAA"}
1
+ {"version":3,"file":"factories.d.mts","names":[],"sources":["../src/factories.ts"],"mappings":";;;;iBAgBgB,GAAA,CAAI,UAAA,UAAoB,OAAA,UAAiB,QAAA,aAAmB,aAAa;AAAA,iBAIzE,EAAA,CAAA,GAAM,OAAA,sBAA6B,UAAU;AAAA,iBAI7C,MAAA,CAAA,GAAU,OAAA,sBAA6B,gBAAgB;AAAA,iBAIvD,KAAA,CAAA,GAAS,OAAA,sBAA6B,KAAK;AAAA,iBAI3C,EAAA,CACd,YAAA,UACA,UAAA,qBACA,eAAA,UACA,aAAA,qBACA,IAAA,GAAO,iBAAA;EAAsB,UAAA;EAAsB,KAAA;EAAiB,WAAA;AAAA,IACnE,UAAU;AAAA,iBAcG,KAAA,CACd,OAAA,EAAS,MAAA,SAAe,aAAA,GAAgB,kBAAA,GACxC,IAAA;EACE,EAAA,GAAK,UAAA;EACL,OAAA,YAAmB,gBAAA;EACnB,OAAA,YAAmB,KAAA;EACnB,GAAA,YAAe,UAAA;AAAA,IAEhB,YAAA;AAAA,iBAUa,KAAA,CACd,SAAA,UACA,MAAA,EAAQ,MAAA,SAAe,oBAAA,GACvB,SAAA,GAAW,MAAA;EAEX,OAAA,EAAS,eAAA;EACT,MAAA,EAAQ,MAAA;IAAA,SAA0B,QAAA;IAAA,SAA4B,IAAA,EAAM,eAAA;EAAA;EACpE,SAAA,EAAW,MAAA;AAAA"}
@@ -1,5 +1,6 @@
1
- import { c as StorageTable, f as Index, g as ForeignKey, l as UniqueConstraint, p as PrimaryKey, r as applyFkDefaults, u as StorageColumn } from "./types-L8p7B1dP.mjs";
1
+ import { _ as ForeignKey, f as StorageTable, g as PrimaryKey, h as Index, m as StorageColumn, p as UniqueConstraint, r as applyFkDefaults } from "./types-YQrDHy-b.mjs";
2
2
  import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
3
+ import { asNamespaceId } from "@prisma-next/contract/types";
3
4
  //#region src/factories.ts
4
5
  function col(nativeType, codecId, nullable = false) {
5
6
  return new StorageColumn({
@@ -22,7 +23,7 @@ function fk(srcTableName, srcColumns, targetTableName, targetColumns, opts) {
22
23
  constraint: opts?.constraint,
23
24
  index: opts?.index
24
25
  });
25
- const namespaceId = opts?.namespaceId ?? UNBOUND_NAMESPACE_ID;
26
+ const namespaceId = asNamespaceId(opts?.namespaceId ?? UNBOUND_NAMESPACE_ID);
26
27
  return new ForeignKey({
27
28
  source: {
28
29
  namespaceId,
@@ -1 +1 @@
1
- {"version":3,"file":"factories.mjs","names":[],"sources":["../src/factories.ts"],"sourcesContent":["import type { ScalarFieldType } from '@prisma-next/contract/types';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport {\n applyFkDefaults,\n ForeignKey,\n type ForeignKeyOptions,\n Index,\n PrimaryKey,\n type SqlModelFieldStorage,\n type SqlModelStorage,\n StorageColumn,\n type StorageColumnInput,\n StorageTable,\n UniqueConstraint,\n} from './types';\n\nexport function col(nativeType: string, codecId: string, nullable = false): StorageColumn {\n return new StorageColumn({ nativeType, codecId, nullable });\n}\n\nexport function pk(...columns: readonly string[]): PrimaryKey {\n return new PrimaryKey({ columns });\n}\n\nexport function unique(...columns: readonly string[]): UniqueConstraint {\n return new UniqueConstraint({ columns });\n}\n\nexport function index(...columns: readonly string[]): Index {\n return new Index({ columns });\n}\n\nexport function fk(\n srcTableName: string,\n srcColumns: readonly string[],\n targetTableName: string,\n targetColumns: readonly string[],\n opts?: ForeignKeyOptions & { constraint?: boolean; index?: boolean; namespaceId?: string },\n): ForeignKey {\n const defaults = applyFkDefaults({ constraint: opts?.constraint, index: opts?.index });\n const namespaceId = opts?.namespaceId ?? UNBOUND_NAMESPACE_ID;\n return new ForeignKey({\n source: { namespaceId, tableName: srcTableName, columns: srcColumns },\n target: { namespaceId, tableName: targetTableName, columns: targetColumns },\n ...(opts?.name !== undefined && { name: opts.name }),\n ...(opts?.onDelete !== undefined && { onDelete: opts.onDelete }),\n ...(opts?.onUpdate !== undefined && { onUpdate: opts.onUpdate }),\n constraint: defaults.constraint,\n index: defaults.index,\n });\n}\n\nexport function table(\n columns: Record<string, StorageColumn | StorageColumnInput>,\n opts?: {\n pk?: PrimaryKey;\n uniques?: readonly UniqueConstraint[];\n indexes?: readonly Index[];\n fks?: readonly ForeignKey[];\n },\n): StorageTable {\n return new StorageTable({\n columns,\n ...(opts?.pk !== undefined && { primaryKey: opts.pk }),\n uniques: opts?.uniques ?? [],\n indexes: opts?.indexes ?? [],\n foreignKeys: opts?.fks ?? [],\n });\n}\n\nexport function model(\n tableName: string,\n fields: Record<string, SqlModelFieldStorage>,\n relations: Record<string, unknown> = {},\n): {\n storage: SqlModelStorage;\n fields: Record<string, { readonly nullable: boolean; readonly type: ScalarFieldType }>;\n relations: Record<string, unknown>;\n} {\n const storage: SqlModelStorage = { table: tableName, fields };\n const domainFields = Object.fromEntries(\n Object.entries(fields).map(([name, field]) => [\n name,\n {\n nullable: field.nullable ?? false,\n type: { kind: 'scalar' as const, codecId: field.codecId ?? 'core/unknown@1' },\n },\n ]),\n ) as Record<string, { nullable: boolean; type: ScalarFieldType }>;\n return {\n storage,\n fields: domainFields,\n relations,\n };\n}\n"],"mappings":";;;AAgBA,SAAgB,IAAI,YAAoB,SAAiB,WAAW,OAAsB;CACxF,OAAO,IAAI,cAAc;EAAE;EAAY;EAAS;EAAU,CAAC;;AAG7D,SAAgB,GAAG,GAAG,SAAwC;CAC5D,OAAO,IAAI,WAAW,EAAE,SAAS,CAAC;;AAGpC,SAAgB,OAAO,GAAG,SAA8C;CACtE,OAAO,IAAI,iBAAiB,EAAE,SAAS,CAAC;;AAG1C,SAAgB,MAAM,GAAG,SAAmC;CAC1D,OAAO,IAAI,MAAM,EAAE,SAAS,CAAC;;AAG/B,SAAgB,GACd,cACA,YACA,iBACA,eACA,MACY;CACZ,MAAM,WAAW,gBAAgB;EAAE,YAAY,MAAM;EAAY,OAAO,MAAM;EAAO,CAAC;CACtF,MAAM,cAAc,MAAM,eAAe;CACzC,OAAO,IAAI,WAAW;EACpB,QAAQ;GAAE;GAAa,WAAW;GAAc,SAAS;GAAY;EACrE,QAAQ;GAAE;GAAa,WAAW;GAAiB,SAAS;GAAe;EAC3E,GAAI,MAAM,SAAS,KAAA,KAAa,EAAE,MAAM,KAAK,MAAM;EACnD,GAAI,MAAM,aAAa,KAAA,KAAa,EAAE,UAAU,KAAK,UAAU;EAC/D,GAAI,MAAM,aAAa,KAAA,KAAa,EAAE,UAAU,KAAK,UAAU;EAC/D,YAAY,SAAS;EACrB,OAAO,SAAS;EACjB,CAAC;;AAGJ,SAAgB,MACd,SACA,MAMc;CACd,OAAO,IAAI,aAAa;EACtB;EACA,GAAI,MAAM,OAAO,KAAA,KAAa,EAAE,YAAY,KAAK,IAAI;EACrD,SAAS,MAAM,WAAW,EAAE;EAC5B,SAAS,MAAM,WAAW,EAAE;EAC5B,aAAa,MAAM,OAAO,EAAE;EAC7B,CAAC;;AAGJ,SAAgB,MACd,WACA,QACA,YAAqC,EAAE,EAKvC;CAWA,OAAO;EACL,SAAA;GAXiC,OAAO;GAAW;GAW5C;EACP,QAXmB,OAAO,YAC1B,OAAO,QAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,WAAW,CAC5C,MACA;GACE,UAAU,MAAM,YAAY;GAC5B,MAAM;IAAE,MAAM;IAAmB,SAAS,MAAM,WAAW;IAAkB;GAC9E,CACF,CAAC,CAIkB;EACpB;EACD"}
1
+ {"version":3,"file":"factories.mjs","names":[],"sources":["../src/factories.ts"],"sourcesContent":["import { asNamespaceId, type ScalarFieldType } from '@prisma-next/contract/types';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport {\n applyFkDefaults,\n ForeignKey,\n type ForeignKeyOptions,\n Index,\n PrimaryKey,\n type SqlModelFieldStorage,\n type SqlModelStorage,\n StorageColumn,\n type StorageColumnInput,\n StorageTable,\n UniqueConstraint,\n} from './types';\n\nexport function col(nativeType: string, codecId: string, nullable = false): StorageColumn {\n return new StorageColumn({ nativeType, codecId, nullable });\n}\n\nexport function pk(...columns: readonly string[]): PrimaryKey {\n return new PrimaryKey({ columns });\n}\n\nexport function unique(...columns: readonly string[]): UniqueConstraint {\n return new UniqueConstraint({ columns });\n}\n\nexport function index(...columns: readonly string[]): Index {\n return new Index({ columns });\n}\n\nexport function fk(\n srcTableName: string,\n srcColumns: readonly string[],\n targetTableName: string,\n targetColumns: readonly string[],\n opts?: ForeignKeyOptions & { constraint?: boolean; index?: boolean; namespaceId?: string },\n): ForeignKey {\n const defaults = applyFkDefaults({ constraint: opts?.constraint, index: opts?.index });\n const namespaceId = asNamespaceId(opts?.namespaceId ?? UNBOUND_NAMESPACE_ID);\n return new ForeignKey({\n source: { namespaceId, tableName: srcTableName, columns: srcColumns },\n target: { namespaceId, tableName: targetTableName, columns: targetColumns },\n ...(opts?.name !== undefined && { name: opts.name }),\n ...(opts?.onDelete !== undefined && { onDelete: opts.onDelete }),\n ...(opts?.onUpdate !== undefined && { onUpdate: opts.onUpdate }),\n constraint: defaults.constraint,\n index: defaults.index,\n });\n}\n\nexport function table(\n columns: Record<string, StorageColumn | StorageColumnInput>,\n opts?: {\n pk?: PrimaryKey;\n uniques?: readonly UniqueConstraint[];\n indexes?: readonly Index[];\n fks?: readonly ForeignKey[];\n },\n): StorageTable {\n return new StorageTable({\n columns,\n ...(opts?.pk !== undefined && { primaryKey: opts.pk }),\n uniques: opts?.uniques ?? [],\n indexes: opts?.indexes ?? [],\n foreignKeys: opts?.fks ?? [],\n });\n}\n\nexport function model(\n tableName: string,\n fields: Record<string, SqlModelFieldStorage>,\n relations: Record<string, unknown> = {},\n): {\n storage: SqlModelStorage;\n fields: Record<string, { readonly nullable: boolean; readonly type: ScalarFieldType }>;\n relations: Record<string, unknown>;\n} {\n const storage: SqlModelStorage = { table: tableName, fields };\n const domainFields = Object.fromEntries(\n Object.entries(fields).map(([name, field]) => [\n name,\n {\n nullable: field.nullable ?? false,\n type: { kind: 'scalar' as const, codecId: field.codecId ?? 'core/unknown@1' },\n },\n ]),\n ) as Record<string, { nullable: boolean; type: ScalarFieldType }>;\n return {\n storage,\n fields: domainFields,\n relations,\n };\n}\n"],"mappings":";;;;AAgBA,SAAgB,IAAI,YAAoB,SAAiB,WAAW,OAAsB;CACxF,OAAO,IAAI,cAAc;EAAE;EAAY;EAAS;CAAS,CAAC;AAC5D;AAEA,SAAgB,GAAG,GAAG,SAAwC;CAC5D,OAAO,IAAI,WAAW,EAAE,QAAQ,CAAC;AACnC;AAEA,SAAgB,OAAO,GAAG,SAA8C;CACtE,OAAO,IAAI,iBAAiB,EAAE,QAAQ,CAAC;AACzC;AAEA,SAAgB,MAAM,GAAG,SAAmC;CAC1D,OAAO,IAAI,MAAM,EAAE,QAAQ,CAAC;AAC9B;AAEA,SAAgB,GACd,cACA,YACA,iBACA,eACA,MACY;CACZ,MAAM,WAAW,gBAAgB;EAAE,YAAY,MAAM;EAAY,OAAO,MAAM;CAAM,CAAC;CACrF,MAAM,cAAc,cAAc,MAAM,eAAe,oBAAoB;CAC3E,OAAO,IAAI,WAAW;EACpB,QAAQ;GAAE;GAAa,WAAW;GAAc,SAAS;EAAW;EACpE,QAAQ;GAAE;GAAa,WAAW;GAAiB,SAAS;EAAc;EAC1E,GAAI,MAAM,SAAS,KAAA,KAAa,EAAE,MAAM,KAAK,KAAK;EAClD,GAAI,MAAM,aAAa,KAAA,KAAa,EAAE,UAAU,KAAK,SAAS;EAC9D,GAAI,MAAM,aAAa,KAAA,KAAa,EAAE,UAAU,KAAK,SAAS;EAC9D,YAAY,SAAS;EACrB,OAAO,SAAS;CAClB,CAAC;AACH;AAEA,SAAgB,MACd,SACA,MAMc;CACd,OAAO,IAAI,aAAa;EACtB;EACA,GAAI,MAAM,OAAO,KAAA,KAAa,EAAE,YAAY,KAAK,GAAG;EACpD,SAAS,MAAM,WAAW,CAAC;EAC3B,SAAS,MAAM,WAAW,CAAC;EAC3B,aAAa,MAAM,OAAO,CAAC;CAC7B,CAAC;AACH;AAEA,SAAgB,MACd,WACA,QACA,YAAqC,CAAC,GAKtC;CAWA,OAAO;EACL,SAAA;GAXiC,OAAO;GAAW;EAW7C;EACN,QAXmB,OAAO,YAC1B,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,MAAM,WAAW,CAC5C,MACA;GACE,UAAU,MAAM,YAAY;GAC5B,MAAM;IAAE,MAAM;IAAmB,SAAS,MAAM,WAAW;GAAiB;EAC9E,CACF,CAAC,CAIkB;EACnB;CACF;AACF"}
@@ -1,4 +1,4 @@
1
- import { D as SqlStorage } from "./types-DZpIXwK4.mjs";
1
+ import { k as SqlStorage } from "./types-Cx_5A_L0.mjs";
2
2
  import { a as IndexTypeRegistry } from "./index-types-B1cf5N0F.mjs";
3
3
  import { Contract } from "@prisma-next/contract/types";
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"index-type-validation.mjs","names":[],"sources":["../src/index-type-validation.ts"],"sourcesContent":["import { ContractValidationError } from '@prisma-next/contract/contract-validation-error';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { type } from 'arktype';\nimport type { IndexTypeRegistry } from './index-types';\nimport type { SqlStorage, StorageTable } from './types';\n\nexport function validateIndexTypes(\n contract: Contract<SqlStorage>,\n indexTypeRegistry: IndexTypeRegistry,\n): void {\n for (const [namespaceId, ns] of Object.entries(contract.storage.namespaces)) {\n for (const [tableName, rawTable] of Object.entries(ns.tables)) {\n const table = rawTable as StorageTable;\n for (const index of table.indexes) {\n if (index.type === undefined && index.options !== undefined) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index on columns [${index.columns.join(', ')}] has options without a type`,\n 'storage',\n );\n }\n if (index.type === undefined) continue;\n const entry = indexTypeRegistry.get(index.type);\n if (entry === undefined) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index on columns [${index.columns.join(', ')}] uses unregistered index type \"${index.type}\"`,\n 'storage',\n );\n }\n const optionsValue = index.options ?? {};\n const result = entry.options(optionsValue);\n if (result instanceof type.errors) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index on columns [${index.columns.join(', ')}] has invalid options for type \"${index.type}\": ${result.summary}`,\n 'storage',\n );\n }\n }\n }\n }\n}\n"],"mappings":";;;AAMA,SAAgB,mBACd,UACA,mBACM;CACN,KAAK,MAAM,CAAC,aAAa,OAAO,OAAO,QAAQ,SAAS,QAAQ,WAAW,EACzE,KAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,GAAG,OAAO,EAAE;EAC7D,MAAM,QAAQ;EACd,KAAK,MAAM,SAAS,MAAM,SAAS;GACjC,IAAI,MAAM,SAAS,KAAA,KAAa,MAAM,YAAY,KAAA,GAChD,MAAM,IAAI,wBACR,cAAc,YAAY,WAAW,UAAU,sBAAsB,MAAM,QAAQ,KAAK,KAAK,CAAC,+BAC9F,UACD;GAEH,IAAI,MAAM,SAAS,KAAA,GAAW;GAC9B,MAAM,QAAQ,kBAAkB,IAAI,MAAM,KAAK;GAC/C,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,wBACR,cAAc,YAAY,WAAW,UAAU,sBAAsB,MAAM,QAAQ,KAAK,KAAK,CAAC,kCAAkC,MAAM,KAAK,IAC3I,UACD;GAEH,MAAM,eAAe,MAAM,WAAW,EAAE;GACxC,MAAM,SAAS,MAAM,QAAQ,aAAa;GAC1C,IAAI,kBAAkB,KAAK,QACzB,MAAM,IAAI,wBACR,cAAc,YAAY,WAAW,UAAU,sBAAsB,MAAM,QAAQ,KAAK,KAAK,CAAC,kCAAkC,MAAM,KAAK,KAAK,OAAO,WACvJ,UACD"}
1
+ {"version":3,"file":"index-type-validation.mjs","names":[],"sources":["../src/index-type-validation.ts"],"sourcesContent":["import { ContractValidationError } from '@prisma-next/contract/contract-validation-error';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { type } from 'arktype';\nimport type { IndexTypeRegistry } from './index-types';\nimport type { SqlStorage, StorageTable } from './types';\n\nexport function validateIndexTypes(\n contract: Contract<SqlStorage>,\n indexTypeRegistry: IndexTypeRegistry,\n): void {\n for (const [namespaceId, ns] of Object.entries(contract.storage.namespaces)) {\n for (const [tableName, rawTable] of Object.entries(ns.tables)) {\n const table = rawTable as StorageTable;\n for (const index of table.indexes) {\n if (index.type === undefined && index.options !== undefined) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index on columns [${index.columns.join(', ')}] has options without a type`,\n 'storage',\n );\n }\n if (index.type === undefined) continue;\n const entry = indexTypeRegistry.get(index.type);\n if (entry === undefined) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index on columns [${index.columns.join(', ')}] uses unregistered index type \"${index.type}\"`,\n 'storage',\n );\n }\n const optionsValue = index.options ?? {};\n const result = entry.options(optionsValue);\n if (result instanceof type.errors) {\n throw new ContractValidationError(\n `Namespace \"${namespaceId}\" table \"${tableName}\" index on columns [${index.columns.join(', ')}] has invalid options for type \"${index.type}\": ${result.summary}`,\n 'storage',\n );\n }\n }\n }\n }\n}\n"],"mappings":";;;AAMA,SAAgB,mBACd,UACA,mBACM;CACN,KAAK,MAAM,CAAC,aAAa,OAAO,OAAO,QAAQ,SAAS,QAAQ,UAAU,GACxE,KAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,GAAG,MAAM,GAAG;EAC7D,MAAM,QAAQ;EACd,KAAK,MAAM,SAAS,MAAM,SAAS;GACjC,IAAI,MAAM,SAAS,KAAA,KAAa,MAAM,YAAY,KAAA,GAChD,MAAM,IAAI,wBACR,cAAc,YAAY,WAAW,UAAU,sBAAsB,MAAM,QAAQ,KAAK,IAAI,EAAE,+BAC9F,SACF;GAEF,IAAI,MAAM,SAAS,KAAA,GAAW;GAC9B,MAAM,QAAQ,kBAAkB,IAAI,MAAM,IAAI;GAC9C,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,wBACR,cAAc,YAAY,WAAW,UAAU,sBAAsB,MAAM,QAAQ,KAAK,IAAI,EAAE,kCAAkC,MAAM,KAAK,IAC3I,SACF;GAEF,MAAM,eAAe,MAAM,WAAW,CAAC;GACvC,MAAM,SAAS,MAAM,QAAQ,YAAY;GACzC,IAAI,kBAAkB,KAAK,QACzB,MAAM,IAAI,wBACR,cAAc,YAAY,WAAW,UAAU,sBAAsB,MAAM,QAAQ,KAAK,IAAI,EAAE,kCAAkC,MAAM,KAAK,KAAK,OAAO,WACvJ,SACF;EAEJ;CACF;AAEJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-types-B1cf5N0F.d.mts","names":[],"sources":["../src/index-types.ts"],"mappings":";;;UAEiB,cAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA,EAAS,IAAA,CAAK,QAAA;AAAA;AAAA,KAGb,YAAA;EAAA,SAAoD,OAAA;AAAA;AAAA,UAE/C,qBAAA,cAAmC,YAAA,GAAe,MAAA;EAAA,SACxD,UAAA,EAAY,IAAA;EAAA,SACZ,OAAA,EAAS,aAAA,CAAc,cAAA;AAAA;AAAA,UAGjB,gBAAA,cAA8B,YAAA,GAAe,MAAA,wBACpD,qBAAA,CAAsB,IAAA;EAC9B,GAAA,6BACE,WAAA,EAAa,IAAA,EACb,KAAA;IAAA,SAAkB,OAAA,EAAS,IAAA,CAAK,KAAA;EAAA,IAC/B,gBAAA,CAAiB,IAAA,GAAO,MAAA,CAAO,IAAA;IAAA,SAAiB,OAAA,EAAS,KAAA;EAAA;AAAA;AAAA,iBA0B9C,gBAAA,CAAA,GAAoB,gBAAA,CAAiB,MAAA;AAAA,UAIpC,iBAAA;EACf,QAAA,CAAS,KAAA,EAAO,cAAA;EAChB,GAAA,CAAI,WAAA,WAAsB,cAAA;EAC1B,GAAA,CAAI,WAAA;AAAA;AAAA,iBAsBU,uBAAA,CAAA,GAA2B,iBAAA"}
1
+ {"version":3,"file":"index-types-B1cf5N0F.d.mts","names":[],"sources":["../src/index-types.ts"],"mappings":";;;UAEiB,cAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA,EAAS,IAAI,CAAC,QAAA;AAAA;AAAA,KAGb,YAAA;EAAA,SAAoD,OAAO;AAAA;AAAA,UAEtD,qBAAA,cAAmC,YAAA,GAAe,MAAA;EAAA,SACxD,UAAA,EAAY,IAAA;EAAA,SACZ,OAAA,EAAS,aAAA,CAAc,cAAA;AAAA;AAAA,UAGjB,gBAAA,cAA8B,YAAA,GAAe,MAAA,wBACpD,qBAAA,CAAsB,IAAA;EAC9B,GAAA,6BACE,WAAA,EAAa,IAAA,EACb,KAAA;IAAA,SAAkB,OAAA,EAAS,IAAA,CAAK,KAAA;EAAA,IAC/B,gBAAA,CAAiB,IAAA,GAAO,MAAA,CAAO,IAAA;IAAA,SAAiB,OAAA,EAAS,KAAA;EAAA;AAAA;AAAA,iBA0B9C,gBAAA,CAAA,GAAoB,gBAAgB,CAAC,MAAA;AAAA,UAIpC,iBAAA;EACf,QAAA,CAAS,KAAA,EAAO,cAAA;EAChB,GAAA,CAAI,WAAA,WAAsB,cAAc;EACxC,GAAA,CAAI,WAAA;AAAA;AAAA,iBAsBU,uBAAA,CAAA,GAA2B,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-types.mjs","names":[],"sources":["../src/index-types.ts"],"sourcesContent":["import type { Type } from 'arktype';\n\nexport interface IndexTypeEntry<TOptions = unknown> {\n readonly type: string;\n readonly options: Type<TOptions>;\n}\n\nexport type IndexTypeMap = { readonly [K in string]: { readonly options: unknown } };\n\nexport interface IndexTypeRegistration<TMap extends IndexTypeMap = Record<never, never>> {\n readonly IndexTypes: TMap;\n readonly entries: ReadonlyArray<IndexTypeEntry>;\n}\n\nexport interface IndexTypeBuilder<TMap extends IndexTypeMap = Record<never, never>>\n extends IndexTypeRegistration<TMap> {\n add<TLit extends string, TOpts>(\n typeLiteral: TLit,\n entry: { readonly options: Type<TOpts> },\n ): IndexTypeBuilder<TMap & Record<TLit, { readonly options: TOpts }>>;\n}\n\nclass IndexTypeBuilderImpl<TMap extends IndexTypeMap> implements IndexTypeBuilder<TMap> {\n readonly entries: ReadonlyArray<IndexTypeEntry>;\n readonly IndexTypes: TMap;\n\n constructor(entries: ReadonlyArray<IndexTypeEntry>) {\n this.entries = entries;\n this.IndexTypes = {} as TMap;\n }\n\n add<TLit extends string, TOpts>(\n typeLiteral: TLit,\n entry: { readonly options: Type<TOpts> },\n ): IndexTypeBuilder<TMap & Record<TLit, { readonly options: TOpts }>> {\n if (this.entries.some((e) => e.type === typeLiteral)) {\n throw new Error(`Index type \"${typeLiteral}\" is already declared in this builder`);\n }\n return new IndexTypeBuilderImpl<TMap & Record<TLit, { readonly options: TOpts }>>([\n ...this.entries,\n { type: typeLiteral, options: entry.options as Type<unknown> },\n ]);\n }\n}\n\nexport function defineIndexTypes(): IndexTypeBuilder<Record<never, never>> {\n return new IndexTypeBuilderImpl([]);\n}\n\nexport interface IndexTypeRegistry {\n register(entry: IndexTypeEntry): void;\n get(typeLiteral: string): IndexTypeEntry | undefined;\n has(typeLiteral: string): boolean;\n}\n\nclass IndexTypeRegistryImpl implements IndexTypeRegistry {\n private readonly entries = new Map<string, IndexTypeEntry>();\n\n register(entry: IndexTypeEntry): void {\n if (this.entries.has(entry.type)) {\n throw new Error(`Index type \"${entry.type}\" is already registered`);\n }\n this.entries.set(entry.type, entry);\n }\n\n get(typeLiteral: string): IndexTypeEntry | undefined {\n return this.entries.get(typeLiteral);\n }\n\n has(typeLiteral: string): boolean {\n return this.entries.has(typeLiteral);\n }\n}\n\nexport function createIndexTypeRegistry(): IndexTypeRegistry {\n return new IndexTypeRegistryImpl();\n}\n"],"mappings":";AAsBA,IAAM,uBAAN,MAAM,qBAAkF;CACtF;CACA;CAEA,YAAY,SAAwC;EAClD,KAAK,UAAU;EACf,KAAK,aAAa,EAAE;;CAGtB,IACE,aACA,OACoE;EACpE,IAAI,KAAK,QAAQ,MAAM,MAAM,EAAE,SAAS,YAAY,EAClD,MAAM,IAAI,MAAM,eAAe,YAAY,uCAAuC;EAEpF,OAAO,IAAI,qBAAuE,CAChF,GAAG,KAAK,SACR;GAAE,MAAM;GAAa,SAAS,MAAM;GAA0B,CAC/D,CAAC;;;AAIN,SAAgB,mBAA2D;CACzE,OAAO,IAAI,qBAAqB,EAAE,CAAC;;AASrC,IAAM,wBAAN,MAAyD;CACvD,0BAA2B,IAAI,KAA6B;CAE5D,SAAS,OAA6B;EACpC,IAAI,KAAK,QAAQ,IAAI,MAAM,KAAK,EAC9B,MAAM,IAAI,MAAM,eAAe,MAAM,KAAK,yBAAyB;EAErE,KAAK,QAAQ,IAAI,MAAM,MAAM,MAAM;;CAGrC,IAAI,aAAiD;EACnD,OAAO,KAAK,QAAQ,IAAI,YAAY;;CAGtC,IAAI,aAA8B;EAChC,OAAO,KAAK,QAAQ,IAAI,YAAY;;;AAIxC,SAAgB,0BAA6C;CAC3D,OAAO,IAAI,uBAAuB"}
1
+ {"version":3,"file":"index-types.mjs","names":[],"sources":["../src/index-types.ts"],"sourcesContent":["import type { Type } from 'arktype';\n\nexport interface IndexTypeEntry<TOptions = unknown> {\n readonly type: string;\n readonly options: Type<TOptions>;\n}\n\nexport type IndexTypeMap = { readonly [K in string]: { readonly options: unknown } };\n\nexport interface IndexTypeRegistration<TMap extends IndexTypeMap = Record<never, never>> {\n readonly IndexTypes: TMap;\n readonly entries: ReadonlyArray<IndexTypeEntry>;\n}\n\nexport interface IndexTypeBuilder<TMap extends IndexTypeMap = Record<never, never>>\n extends IndexTypeRegistration<TMap> {\n add<TLit extends string, TOpts>(\n typeLiteral: TLit,\n entry: { readonly options: Type<TOpts> },\n ): IndexTypeBuilder<TMap & Record<TLit, { readonly options: TOpts }>>;\n}\n\nclass IndexTypeBuilderImpl<TMap extends IndexTypeMap> implements IndexTypeBuilder<TMap> {\n readonly entries: ReadonlyArray<IndexTypeEntry>;\n readonly IndexTypes: TMap;\n\n constructor(entries: ReadonlyArray<IndexTypeEntry>) {\n this.entries = entries;\n this.IndexTypes = {} as TMap;\n }\n\n add<TLit extends string, TOpts>(\n typeLiteral: TLit,\n entry: { readonly options: Type<TOpts> },\n ): IndexTypeBuilder<TMap & Record<TLit, { readonly options: TOpts }>> {\n if (this.entries.some((e) => e.type === typeLiteral)) {\n throw new Error(`Index type \"${typeLiteral}\" is already declared in this builder`);\n }\n return new IndexTypeBuilderImpl<TMap & Record<TLit, { readonly options: TOpts }>>([\n ...this.entries,\n { type: typeLiteral, options: entry.options as Type<unknown> },\n ]);\n }\n}\n\nexport function defineIndexTypes(): IndexTypeBuilder<Record<never, never>> {\n return new IndexTypeBuilderImpl([]);\n}\n\nexport interface IndexTypeRegistry {\n register(entry: IndexTypeEntry): void;\n get(typeLiteral: string): IndexTypeEntry | undefined;\n has(typeLiteral: string): boolean;\n}\n\nclass IndexTypeRegistryImpl implements IndexTypeRegistry {\n private readonly entries = new Map<string, IndexTypeEntry>();\n\n register(entry: IndexTypeEntry): void {\n if (this.entries.has(entry.type)) {\n throw new Error(`Index type \"${entry.type}\" is already registered`);\n }\n this.entries.set(entry.type, entry);\n }\n\n get(typeLiteral: string): IndexTypeEntry | undefined {\n return this.entries.get(typeLiteral);\n }\n\n has(typeLiteral: string): boolean {\n return this.entries.has(typeLiteral);\n }\n}\n\nexport function createIndexTypeRegistry(): IndexTypeRegistry {\n return new IndexTypeRegistryImpl();\n}\n"],"mappings":";AAsBA,IAAM,uBAAN,MAAM,qBAAkF;CACtF;CACA;CAEA,YAAY,SAAwC;EAClD,KAAK,UAAU;EACf,KAAK,aAAa,CAAC;CACrB;CAEA,IACE,aACA,OACoE;EACpE,IAAI,KAAK,QAAQ,MAAM,MAAM,EAAE,SAAS,WAAW,GACjD,MAAM,IAAI,MAAM,eAAe,YAAY,sCAAsC;EAEnF,OAAO,IAAI,qBAAuE,CAChF,GAAG,KAAK,SACR;GAAE,MAAM;GAAa,SAAS,MAAM;EAAyB,CAC/D,CAAC;CACH;AACF;AAEA,SAAgB,mBAA2D;CACzE,OAAO,IAAI,qBAAqB,CAAC,CAAC;AACpC;AAQA,IAAM,wBAAN,MAAyD;CACvD,0BAA2B,IAAI,IAA4B;CAE3D,SAAS,OAA6B;EACpC,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,GAC7B,MAAM,IAAI,MAAM,eAAe,MAAM,KAAK,wBAAwB;EAEpE,KAAK,QAAQ,IAAI,MAAM,MAAM,KAAK;CACpC;CAEA,IAAI,aAAiD;EACnD,OAAO,KAAK,QAAQ,IAAI,WAAW;CACrC;CAEA,IAAI,aAA8B;EAChC,OAAO,KAAK,QAAQ,IAAI,WAAW;CACrC;AACF;AAEA,SAAgB,0BAA6C;CAC3D,OAAO,IAAI,sBAAsB;AACnC"}
@@ -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, ControlPolicy, 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);
@@ -138,6 +138,7 @@ interface PostgresEnumStorageEntry extends StorageType {
138
138
  * present on raw JSON envelopes).
139
139
  */
140
140
  readonly codecId: string;
141
+ readonly control?: ControlPolicy;
141
142
  }
142
143
  /**
143
144
  * Narrow a polymorphic `StorageType` entry to the Postgres-enum shape
@@ -201,6 +202,7 @@ interface StorageColumnInput {
201
202
  readonly typeParams?: Record<string, unknown>;
202
203
  readonly typeRef?: string;
203
204
  readonly default?: ColumnDefault;
205
+ readonly control?: ControlPolicy;
204
206
  }
205
207
  /**
206
208
  * SQL Contract IR node for a single column entry in `StorageTable.columns`.
@@ -222,6 +224,7 @@ declare class StorageColumn extends SqlNode {
222
224
  readonly typeParams?: Record<string, unknown>;
223
225
  readonly typeRef?: string;
224
226
  readonly default?: ColumnDefault;
227
+ readonly control?: ControlPolicy;
225
228
  constructor(input: StorageColumnInput);
226
229
  }
227
230
  //#endregion
@@ -246,6 +249,7 @@ interface StorageTableInput {
246
249
  readonly uniques: ReadonlyArray<UniqueConstraint | UniqueConstraintInput>;
247
250
  readonly indexes: ReadonlyArray<Index | IndexInput>;
248
251
  readonly foreignKeys: ReadonlyArray<ForeignKey | ForeignKeyInput>;
252
+ readonly control?: ControlPolicy;
249
253
  }
250
254
  /**
251
255
  * SQL Contract IR node for a single table entry in a namespace's
@@ -265,6 +269,7 @@ declare class StorageTable extends SqlNode {
265
269
  readonly indexes: ReadonlyArray<Index>;
266
270
  readonly foreignKeys: ReadonlyArray<ForeignKey>;
267
271
  readonly primaryKey?: PrimaryKey;
272
+ readonly control?: ControlPolicy;
268
273
  constructor(input: StorageTableInput);
269
274
  }
270
275
  //#endregion
@@ -319,18 +324,18 @@ declare function isStorageTypeInstance(value: unknown): value is StorageTypeInst
319
324
  * Polymorphic value type for document-scoped `SqlStorage.types` entries
320
325
  * (codec aliases / parameterised native type registrations). Postgres
321
326
  * native enum registrations live under
322
- * `storage.namespaces[namespaceId].types` instead.
327
+ * `storage.namespaces[namespaceId].enum` instead.
323
328
  */
324
329
  type SqlStorageTypeEntry = StorageTypeInstance | StorageTypeInstanceInput | PostgresEnumStorageEntry;
325
330
  interface SqlNamespaceTablesInput {
326
331
  readonly id: string;
327
332
  readonly tables?: Record<string, StorageTable | StorageTableInput>;
328
- readonly types?: Record<string, PostgresEnumStorageEntry>;
333
+ readonly enum?: Record<string, PostgresEnumStorageEntry>;
329
334
  }
330
335
  interface SqlStorageInput<THash extends string = string> {
331
336
  readonly storageHash: StorageHashBase<THash>;
332
337
  readonly types?: Record<string, SqlStorageTypeEntry>;
333
- readonly namespaces?: Readonly<Record<string, Namespace | SqlNamespaceTablesInput>>;
338
+ readonly namespaces: Readonly<Record<string, SqlNamespace>>;
334
339
  }
335
340
  /**
336
341
  * SQL Contract IR root node for the `storage` field.
@@ -342,16 +347,11 @@ interface SqlStorageInput<THash extends string = string> {
342
347
  * target-specific storage extensions).
343
348
  *
344
349
  * 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.
350
+ * `namespaces` map keyed by namespace id. Callers must supply fully
351
+ * constructed `Namespace` instances construction discipline lives
352
+ * in the authoring builders and deserializer hydration paths.
351
353
  *
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.
354
+ * The constructor normalises optional `types` into class instances.
355
355
  * `types` is polymorphic per Decision 18 Option B: codec-triple inputs
356
356
  * are stamped with `kind: 'codec-instance'`; class-instance kinds
357
357
  * (e.g. Postgres-enum entries satisfying `PostgresEnumStorageEntry`)
@@ -362,17 +362,19 @@ interface SqlStorageInput<THash extends string = string> {
362
362
  */
363
363
  type SqlNamespace = Namespace & {
364
364
  readonly tables: Readonly<Record<string, StorageTable>>;
365
- readonly types?: Readonly<Record<string, PostgresEnumStorageEntry>>;
365
+ readonly enum?: Readonly<Record<string, PostgresEnumStorageEntry>>;
366
366
  };
367
367
  declare class SqlStorage<THash extends string = string> extends SqlNode implements Storage {
368
368
  readonly storageHash: StorageHashBase<THash>;
369
- readonly namespaces: Readonly<Record<string, SqlNamespace>> & {
370
- readonly __unbound__: SqlNamespace;
371
- };
369
+ readonly namespaces: Readonly<Record<string, SqlNamespace>>;
372
370
  readonly types?: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;
373
371
  constructor(input: SqlStorageInput<THash>);
374
372
  }
375
373
  //#endregion
374
+ //#region src/ir/build-sql-namespace.d.ts
375
+ declare function buildSqlNamespace(input: SqlNamespaceTablesInput): SqlNamespace;
376
+ declare function buildSqlNamespaceMap(namespaces: Readonly<Record<string, Namespace | SqlNamespaceTablesInput>>): Readonly<Record<string, SqlNamespace>>;
377
+ //#endregion
376
378
  //#region src/ir/sql-unbound-namespace.d.ts
377
379
  /**
378
380
  * Family-layer placeholder for the SQL unbound-namespace singleton —
@@ -507,5 +509,5 @@ type ExtractFieldOutputTypes<T> = FieldOutputTypesOf<ExtractTypeMapsFromContract
507
509
  type ExtractFieldInputTypes<T> = FieldInputTypesOf<ExtractTypeMapsFromContract<T>>;
508
510
  type ResolveCodecTypes<TContract, TTypeMaps> = [TTypeMaps] extends [never] ? ExtractCodecTypes<TContract> : CodecTypesOf<TTypeMaps>;
509
511
  //#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-DZpIXwK4.d.mts.map
512
+ 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 };
513
+ //# sourceMappingURL=types-Cx_5A_L0.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-Cx_5A_L0.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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"}
@@ -1,4 +1,53 @@
1
1
  import { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
2
+ import { blindCast, castAs } from "@prisma-next/utils/casts";
3
+ import { asNamespaceId } from "@prisma-next/contract/types";
4
+ //#region src/ir/sql-unbound-namespace.ts
5
+ /**
6
+ * Family-layer placeholder for the SQL unbound-namespace singleton —
7
+ * the late-bound slot whose binding the target resolves at connection
8
+ * time rather than at authoring time.
9
+ *
10
+ * SQL contracts honour the framework `Storage.namespaces` invariant from
11
+ * the moment they appear in the IR. Today `SqlStorage` is family-shared
12
+ * (Postgres + SQLite consume the same class); a per-target namespace
13
+ * concretion (`PostgresSchema.unbound`, `SqliteUnboundDatabase.instance`)
14
+ * earns its existence when each target's namespace shape lands. Until
15
+ * then the family ships a single placeholder singleton so the JSON
16
+ * envelope and runtime walk are honest at every layer.
17
+ *
18
+ * The `kind` discriminator is installed as a non-enumerable own property
19
+ * so the JSON envelope reads `{ "id": "__unbound__" }` — symmetric
20
+ * with the family-level non-enumerable `kind` on `SqlNode` and bounded
21
+ * to the minimum data the framework `Namespace` interface promises.
22
+ *
23
+ * **Freeze-trap warning.** The leaf constructor calls
24
+ * `freezeNode(this)` after installing `kind`. The leaf-class shape
25
+ * works today only because `NamespaceBase` does NOT freeze in its
26
+ * constructor — the `Object.defineProperty(this, 'kind', …)` call after
27
+ * `super()` succeeds because the instance is still mutable at that
28
+ * point. Subclasses that add instance fields will still hit the freeze
29
+ * trap once leaf-class `freezeNode(this)` runs; and if a future
30
+ * framework change lifts the freeze to `NamespaceBase`, even the
31
+ * `defineProperty` here would silently fail. To add subclass instance
32
+ * fields safely, lift `freezeNode` to a leaf-class `seal()` hook each
33
+ * leaf calls explicitly at the end of its own constructor.
34
+ */
35
+ var SqlUnboundNamespace = class SqlUnboundNamespace extends NamespaceBase {
36
+ static instance = new SqlUnboundNamespace();
37
+ id = UNBOUND_NAMESPACE_ID;
38
+ tables = Object.freeze({});
39
+ constructor() {
40
+ super();
41
+ Object.defineProperty(this, "kind", {
42
+ value: "sql-namespace",
43
+ writable: false,
44
+ enumerable: false,
45
+ configurable: true
46
+ });
47
+ freezeNode(this);
48
+ }
49
+ };
50
+ //#endregion
2
51
  //#region src/ir/sql-node.ts
3
52
  /**
4
53
  * SQL family IR node base. Carries the family-level `kind` discriminator
@@ -59,7 +108,7 @@ var ForeignKeyReference = class extends SqlNode {
59
108
  columns;
60
109
  constructor(input) {
61
110
  super();
62
- this.namespaceId = input.namespaceId;
111
+ this.namespaceId = asNamespaceId(input.namespaceId);
63
112
  this.tableName = input.tableName;
64
113
  this.columns = input.columns;
65
114
  freezeNode(this);
@@ -97,33 +146,6 @@ var ForeignKey = class extends SqlNode {
97
146
  }
98
147
  };
99
148
  //#endregion
100
- //#region src/ir/postgres-enum-storage-entry.ts
101
- /**
102
- * Discriminator literal for the Postgres-enum variant on the polymorphic
103
- * `SqlStorage.types` slot.
104
- *
105
- * Enums are a target-level concept: Postgres ships native
106
- * `CREATE TYPE … AS ENUM` while other SQL targets approximate enums via
107
- * constraints. The literal lives at the SQL family layer because every
108
- * SQL-family consumer (verifier, planner, lowering, …) needs to
109
- * discriminate enum-typed slot entries from codec-typed ones. The
110
- * concrete IR class (`PostgresEnumType`) lives in the target-postgres
111
- * package and implements this structural contract; cross-domain
112
- * layering rules forbid the SQL family from importing the concrete
113
- * target class directly, so the discriminator and structural interface
114
- * carry the dispatch.
115
- */
116
- const POSTGRES_ENUM_KIND = "postgres-enum";
117
- /**
118
- * Narrow a polymorphic `StorageType` entry to the Postgres-enum shape
119
- * via its enumerable `kind` discriminator. Type guard returns true for
120
- * both live `PostgresEnumType` instances and raw JSON envelopes.
121
- */
122
- function isPostgresEnumStorageEntry(value) {
123
- if (typeof value !== "object" || value === null) return false;
124
- return value.kind === POSTGRES_ENUM_KIND;
125
- }
126
- //#endregion
127
149
  //#region src/ir/primary-key.ts
128
150
  /**
129
151
  * SQL Contract IR node for a table's primary-key constraint.
@@ -159,53 +181,6 @@ var Index = class extends SqlNode {
159
181
  }
160
182
  };
161
183
  //#endregion
162
- //#region src/ir/sql-unbound-namespace.ts
163
- /**
164
- * Family-layer placeholder for the SQL unbound-namespace singleton —
165
- * the late-bound slot whose binding the target resolves at connection
166
- * time rather than at authoring time.
167
- *
168
- * SQL contracts honour the framework `Storage.namespaces` invariant from
169
- * the moment they appear in the IR. Today `SqlStorage` is family-shared
170
- * (Postgres + SQLite consume the same class); a per-target namespace
171
- * concretion (`PostgresSchema.unbound`, `SqliteUnboundDatabase.instance`)
172
- * earns its existence when each target's namespace shape lands. Until
173
- * then the family ships a single placeholder singleton so the JSON
174
- * envelope and runtime walk are honest at every layer.
175
- *
176
- * The `kind` discriminator is installed as a non-enumerable own property
177
- * so the JSON envelope reads `{ "id": "__unbound__" }` — symmetric
178
- * with the family-level non-enumerable `kind` on `SqlNode` and bounded
179
- * to the minimum data the framework `Namespace` interface promises.
180
- *
181
- * **Freeze-trap warning.** The leaf constructor calls
182
- * `freezeNode(this)` after installing `kind`. The leaf-class shape
183
- * works today only because `NamespaceBase` does NOT freeze in its
184
- * constructor — the `Object.defineProperty(this, 'kind', …)` call after
185
- * `super()` succeeds because the instance is still mutable at that
186
- * point. Subclasses that add instance fields will still hit the freeze
187
- * trap once leaf-class `freezeNode(this)` runs; and if a future
188
- * framework change lifts the freeze to `NamespaceBase`, even the
189
- * `defineProperty` here would silently fail. To add subclass instance
190
- * fields safely, lift `freezeNode` to a leaf-class `seal()` hook each
191
- * leaf calls explicitly at the end of its own constructor.
192
- */
193
- var SqlUnboundNamespace = class SqlUnboundNamespace extends NamespaceBase {
194
- static instance = new SqlUnboundNamespace();
195
- id = UNBOUND_NAMESPACE_ID;
196
- tables = Object.freeze({});
197
- constructor() {
198
- super();
199
- Object.defineProperty(this, "kind", {
200
- value: "sql-namespace",
201
- writable: false,
202
- enumerable: false,
203
- configurable: true
204
- });
205
- freezeNode(this);
206
- }
207
- };
208
- //#endregion
209
184
  //#region src/ir/storage-column.ts
210
185
  /**
211
186
  * SQL Contract IR node for a single column entry in `StorageTable.columns`.
@@ -232,6 +207,7 @@ var StorageColumn = class extends SqlNode {
232
207
  if (input.typeParams !== void 0) this.typeParams = input.typeParams;
233
208
  if (input.typeRef !== void 0) this.typeRef = input.typeRef;
234
209
  if (input.default !== void 0) this.default = input.default;
210
+ if (input.control !== void 0) this.control = input.control;
235
211
  freezeNode(this);
236
212
  }
237
213
  };
@@ -275,9 +251,80 @@ var StorageTable = class extends SqlNode {
275
251
  this.uniques = Object.freeze(input.uniques.map((u) => u instanceof UniqueConstraint ? u : new UniqueConstraint(u)));
276
252
  this.indexes = Object.freeze(input.indexes.map((i) => i instanceof Index ? i : new Index(i)));
277
253
  this.foreignKeys = Object.freeze(input.foreignKeys.map((fk) => fk instanceof ForeignKey ? fk : new ForeignKey(fk)));
254
+ if (input.control !== void 0) this.control = input.control;
255
+ freezeNode(this);
256
+ }
257
+ };
258
+ //#endregion
259
+ //#region src/ir/build-sql-namespace.ts
260
+ const SQL_NAMESPACE_KIND = "sql-namespace";
261
+ function isMaterializedSqlNamespace(ns) {
262
+ if (typeof ns !== "object" || ns === null) return false;
263
+ const proto = Object.getPrototypeOf(ns);
264
+ if (proto === Object.prototype || proto === null) return false;
265
+ return ns.kind === SQL_NAMESPACE_KIND;
266
+ }
267
+ var SqlBoundNamespace = class SqlBoundNamespace extends NamespaceBase {
268
+ id;
269
+ tables;
270
+ static fromTablesInput(input) {
271
+ const tableCount = Object.keys(input.tables ?? {}).length;
272
+ const enumCount = Object.keys(input.enum ?? {}).length;
273
+ if (input.id === UNBOUND_NAMESPACE_ID && tableCount === 0 && enumCount === 0) return castAs(SqlUnboundNamespace.instance);
274
+ return castAs(new SqlBoundNamespace(input));
275
+ }
276
+ constructor(input) {
277
+ super();
278
+ this.id = input.id;
279
+ this.tables = Object.freeze(Object.fromEntries(Object.entries(input.tables ?? {}).map(([name, t]) => [name, t instanceof StorageTable ? t : new StorageTable(t)])));
280
+ if (input.enum !== void 0 && Object.keys(input.enum).length > 0) Object.defineProperty(this, "enum", {
281
+ value: Object.freeze({ ...input.enum }),
282
+ writable: false,
283
+ enumerable: true,
284
+ configurable: false
285
+ });
286
+ Object.defineProperty(this, "kind", {
287
+ value: SQL_NAMESPACE_KIND,
288
+ writable: false,
289
+ enumerable: false,
290
+ configurable: true
291
+ });
278
292
  freezeNode(this);
279
293
  }
280
294
  };
295
+ function buildSqlNamespace(input) {
296
+ return SqlBoundNamespace.fromTablesInput(input);
297
+ }
298
+ function buildSqlNamespaceMap(namespaces) {
299
+ return Object.fromEntries(Object.entries(namespaces).map(([nsKey, ns]) => [nsKey, isMaterializedSqlNamespace(ns) ? blindCast(ns) : SqlBoundNamespace.fromTablesInput(ns)]));
300
+ }
301
+ //#endregion
302
+ //#region src/ir/postgres-enum-storage-entry.ts
303
+ /**
304
+ * Discriminator literal for the Postgres-enum variant on the polymorphic
305
+ * `SqlStorage.types` slot.
306
+ *
307
+ * Enums are a target-level concept: Postgres ships native
308
+ * `CREATE TYPE … AS ENUM` while other SQL targets approximate enums via
309
+ * constraints. The literal lives at the SQL family layer because every
310
+ * SQL-family consumer (verifier, planner, lowering, …) needs to
311
+ * discriminate enum-typed slot entries from codec-typed ones. The
312
+ * concrete IR class (`PostgresEnumType`) lives in the target-postgres
313
+ * package and implements this structural contract; cross-domain
314
+ * layering rules forbid the SQL family from importing the concrete
315
+ * target class directly, so the discriminator and structural interface
316
+ * carry the dispatch.
317
+ */
318
+ const POSTGRES_ENUM_KIND = "postgres-enum";
319
+ /**
320
+ * Narrow a polymorphic `StorageType` entry to the Postgres-enum shape
321
+ * via its enumerable `kind` discriminator. Type guard returns true for
322
+ * both live `PostgresEnumType` instances and raw JSON envelopes.
323
+ */
324
+ function isPostgresEnumStorageEntry(value) {
325
+ if (typeof value !== "object" || value === null) return false;
326
+ return value.kind === POSTGRES_ENUM_KIND;
327
+ }
281
328
  //#endregion
282
329
  //#region src/ir/storage-type-instance.ts
283
330
  /**
@@ -312,47 +359,13 @@ function isStorageTypeInstance(value) {
312
359
  }
313
360
  //#endregion
314
361
  //#region src/ir/sql-storage.ts
315
- const DEFAULT_NAMESPACES = Object.freeze({ [UNBOUND_NAMESPACE_ID]: SqlUnboundNamespace.instance });
316
- var SqlNamespacePayload = class extends NamespaceBase {
317
- id;
318
- tables;
319
- constructor(input) {
320
- super();
321
- this.id = input.id;
322
- this.tables = Object.freeze(Object.fromEntries(Object.entries(input.tables ?? {}).map(([name, t]) => [name, t instanceof StorageTable ? t : new StorageTable(t)])));
323
- if (input.types !== void 0 && Object.keys(input.types).length > 0) Object.defineProperty(this, "types", {
324
- value: Object.freeze({ ...input.types }),
325
- writable: false,
326
- enumerable: true,
327
- configurable: false
328
- });
329
- Object.defineProperty(this, "kind", {
330
- value: "sql-namespace",
331
- writable: false,
332
- enumerable: false,
333
- configurable: true
334
- });
335
- freezeNode(this);
336
- }
337
- };
338
- function normaliseNamespaceEntry(nsKey, ns) {
339
- if (ns instanceof NamespaceBase) return ns;
340
- const input = ns;
341
- const tableCount = Object.keys(input.tables ?? {}).length;
342
- const typeCount = Object.keys(input.types ?? {}).length;
343
- if (nsKey === UNBOUND_NAMESPACE_ID && tableCount === 0 && typeCount === 0) return SqlUnboundNamespace.instance;
344
- return new SqlNamespacePayload(input);
345
- }
346
362
  var SqlStorage = class extends SqlNode {
347
363
  storageHash;
348
364
  namespaces;
349
365
  constructor(input) {
350
366
  super();
351
367
  this.storageHash = input.storageHash;
352
- const inputNamespaces = input.namespaces ?? DEFAULT_NAMESPACES;
353
- const normalised = Object.fromEntries(Object.entries(inputNamespaces).map(([nsKey, ns]) => [nsKey, normaliseNamespaceEntry(nsKey, ns)]));
354
- if (!normalised[UNBOUND_NAMESPACE_ID]) normalised[UNBOUND_NAMESPACE_ID] = SqlUnboundNamespace.instance;
355
- this.namespaces = Object.freeze(normalised);
368
+ this.namespaces = Object.freeze(input.namespaces);
356
369
  if (input.types !== void 0) this.types = Object.freeze(Object.fromEntries(Object.entries(input.types).map(([name, ti]) => [name, normaliseTypeEntry(name, ti)])));
357
370
  freezeNode(this);
358
371
  }
@@ -395,6 +408,6 @@ function applyFkDefaults(fk, overrideDefaults) {
395
408
  };
396
409
  }
397
410
  //#endregion
398
- export { ForeignKeyReference as _, CODEC_INSTANCE_KIND as a, StorageTable as c, SqlUnboundNamespace as d, Index as f, ForeignKey as g, isPostgresEnumStorageEntry as h, SqlStorage as i, UniqueConstraint as l, POSTGRES_ENUM_KIND as m, DEFAULT_FK_INDEX as n, isStorageTypeInstance as o, PrimaryKey as p, applyFkDefaults as r, toStorageTypeInstance as s, DEFAULT_FK_CONSTRAINT as t, StorageColumn as u, SqlNode as v };
411
+ export { ForeignKey as _, CODEC_INSTANCE_KIND as a, SqlUnboundNamespace as b, POSTGRES_ENUM_KIND as c, buildSqlNamespaceMap as d, StorageTable as f, PrimaryKey as g, Index as h, SqlStorage as i, isPostgresEnumStorageEntry as l, StorageColumn as m, DEFAULT_FK_INDEX as n, isStorageTypeInstance as o, UniqueConstraint as p, applyFkDefaults as r, toStorageTypeInstance as s, DEFAULT_FK_CONSTRAINT as t, buildSqlNamespace as u, ForeignKeyReference as v, SqlNode as y };
399
412
 
400
- //# sourceMappingURL=types-L8p7B1dP.mjs.map
413
+ //# sourceMappingURL=types-YQrDHy-b.mjs.map