@prisma-next/sql-contract 0.9.0 → 0.10.0

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,4 +1,4 @@
1
- import { B as Index, H as PrimaryKey, I as UniqueConstraint, P as StorageTable, R as StorageColumn, b as SqlModelStorage, f as ForeignKeyOptions, q as ForeignKey, y as SqlModelFieldStorage, z as StorageColumnInput } from "./types-B0lbr9cb.mjs";
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-FVBrwvCz.mjs";
2
2
  import { ScalarFieldType } from "@prisma-next/contract/types";
3
3
 
4
4
  //#region src/factories.d.ts
@@ -6,9 +6,10 @@ declare function col(nativeType: string, codecId: string, nullable?: boolean): S
6
6
  declare function pk(...columns: readonly string[]): PrimaryKey;
7
7
  declare function unique(...columns: readonly string[]): UniqueConstraint;
8
8
  declare function index(...columns: readonly string[]): Index;
9
- declare function fk(columns: readonly string[], refTable: string, refColumns: readonly string[], opts?: ForeignKeyOptions & {
9
+ declare function fk(srcTableName: string, srcColumns: readonly string[], targetTableName: string, targetColumns: readonly string[], opts?: ForeignKeyOptions & {
10
10
  constraint?: boolean;
11
11
  index?: boolean;
12
+ namespaceId?: string;
12
13
  }): ForeignKey;
13
14
  declare function table(columns: Record<string, StorageColumn | StorageColumnInput>, opts?: {
14
15
  pk?: PrimaryKey;
@@ -1 +1 @@
1
- {"version":3,"file":"factories.d.mts","names":[],"sources":["../src/factories.ts"],"mappings":";;;;iBAegB,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,OAAA,qBACA,QAAA,UACA,UAAA,qBACA,IAAA,GAAO,iBAAA;EAAsB,UAAA;EAAsB,KAAA;AAAA,IAClD,UAAA;AAAA,iBAaa,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,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,4 +1,5 @@
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-iqFGDcJp.mjs";
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";
2
+ import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
2
3
  //#region src/factories.ts
3
4
  function col(nativeType, codecId, nullable = false) {
4
5
  return new StorageColumn({
@@ -16,16 +17,22 @@ function unique(...columns) {
16
17
  function index(...columns) {
17
18
  return new Index({ columns });
18
19
  }
19
- function fk(columns, refTable, refColumns, opts) {
20
+ function fk(srcTableName, srcColumns, targetTableName, targetColumns, opts) {
20
21
  const defaults = applyFkDefaults({
21
22
  constraint: opts?.constraint,
22
23
  index: opts?.index
23
24
  });
25
+ const namespaceId = opts?.namespaceId ?? UNBOUND_NAMESPACE_ID;
24
26
  return new ForeignKey({
25
- columns,
26
- references: {
27
- table: refTable,
28
- columns: refColumns
27
+ source: {
28
+ namespaceId,
29
+ tableName: srcTableName,
30
+ columns: srcColumns
31
+ },
32
+ target: {
33
+ namespaceId,
34
+ tableName: targetTableName,
35
+ columns: targetColumns
29
36
  },
30
37
  ...opts?.name !== void 0 && { name: opts.name },
31
38
  ...opts?.onDelete !== void 0 && { onDelete: opts.onDelete },
@@ -1 +1 @@
1
- {"version":3,"file":"factories.mjs","names":[],"sources":["../src/factories.ts"],"sourcesContent":["import type { ScalarFieldType } from '@prisma-next/contract/types';\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 columns: readonly string[],\n refTable: string,\n refColumns: readonly string[],\n opts?: ForeignKeyOptions & { constraint?: boolean; index?: boolean },\n): ForeignKey {\n const defaults = applyFkDefaults({ constraint: opts?.constraint, index: opts?.index });\n return new ForeignKey({\n columns,\n references: { table: refTable, columns: refColumns },\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":";;AAeA,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,SACA,UACA,YACA,MACY;CACZ,MAAM,WAAW,gBAAgB;EAAE,YAAY,MAAM;EAAY,OAAO,MAAM;EAAO,CAAC;CACtF,OAAO,IAAI,WAAW;EACpB;EACA,YAAY;GAAE,OAAO;GAAU,SAAS;GAAY;EACpD,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 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,4 +1,4 @@
1
- import { E as SqlStorage } from "./types-B0lbr9cb.mjs";
1
+ import { D as SqlStorage } from "./types-FVBrwvCz.mjs";
2
2
  import { a as IndexTypeRegistry } from "./index-types-B1cf5N0F.mjs";
3
3
  import { Contract } from "@prisma-next/contract/types";
4
4
 
@@ -2,14 +2,17 @@ import { ContractValidationError } from "@prisma-next/contract/contract-validati
2
2
  import { type } from "arktype";
3
3
  //#region src/index-type-validation.ts
4
4
  function validateIndexTypes(contract, indexTypeRegistry) {
5
- for (const [tableName, table] of Object.entries(contract.storage.tables)) for (const index of table.indexes) {
6
- if (index.type === void 0 && index.options !== void 0) throw new ContractValidationError(`Table "${tableName}" index on columns [${index.columns.join(", ")}] has options without a type`, "storage");
7
- if (index.type === void 0) continue;
8
- const entry = indexTypeRegistry.get(index.type);
9
- if (entry === void 0) throw new ContractValidationError(`Table "${tableName}" index on columns [${index.columns.join(", ")}] uses unregistered index type "${index.type}"`, "storage");
10
- const optionsValue = index.options ?? {};
11
- const result = entry.options(optionsValue);
12
- if (result instanceof type.errors) throw new ContractValidationError(`Table "${tableName}" index on columns [${index.columns.join(", ")}] has invalid options for type "${index.type}": ${result.summary}`, "storage");
5
+ for (const [namespaceId, ns] of Object.entries(contract.storage.namespaces)) for (const [tableName, rawTable] of Object.entries(ns.tables)) {
6
+ const table = rawTable;
7
+ for (const index of table.indexes) {
8
+ if (index.type === void 0 && index.options !== void 0) throw new ContractValidationError(`Namespace "${namespaceId}" table "${tableName}" index on columns [${index.columns.join(", ")}] has options without a type`, "storage");
9
+ if (index.type === void 0) continue;
10
+ const entry = indexTypeRegistry.get(index.type);
11
+ if (entry === void 0) throw new ContractValidationError(`Namespace "${namespaceId}" table "${tableName}" index on columns [${index.columns.join(", ")}] uses unregistered index type "${index.type}"`, "storage");
12
+ const optionsValue = index.options ?? {};
13
+ const result = entry.options(optionsValue);
14
+ if (result instanceof type.errors) throw new ContractValidationError(`Namespace "${namespaceId}" table "${tableName}" index on columns [${index.columns.join(", ")}] has invalid options for type "${index.type}": ${result.summary}`, "storage");
15
+ }
13
16
  }
14
17
  }
15
18
  //#endregion
@@ -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 } from './types';\n\nexport function validateIndexTypes(\n contract: Contract<SqlStorage>,\n indexTypeRegistry: IndexTypeRegistry,\n): void {\n for (const [tableName, table] of Object.entries(contract.storage.tables)) {\n for (const index of table.indexes) {\n if (index.type === undefined && index.options !== undefined) {\n throw new ContractValidationError(\n `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 `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 `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"],"mappings":";;;AAMA,SAAgB,mBACd,UACA,mBACM;CACN,KAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,SAAS,QAAQ,OAAO,EACtE,KAAK,MAAM,SAAS,MAAM,SAAS;EACjC,IAAI,MAAM,SAAS,KAAA,KAAa,MAAM,YAAY,KAAA,GAChD,MAAM,IAAI,wBACR,UAAU,UAAU,sBAAsB,MAAM,QAAQ,KAAK,KAAK,CAAC,+BACnE,UACD;EAEH,IAAI,MAAM,SAAS,KAAA,GAAW;EAC9B,MAAM,QAAQ,kBAAkB,IAAI,MAAM,KAAK;EAC/C,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,wBACR,UAAU,UAAU,sBAAsB,MAAM,QAAQ,KAAK,KAAK,CAAC,kCAAkC,MAAM,KAAK,IAChH,UACD;EAEH,MAAM,eAAe,MAAM,WAAW,EAAE;EACxC,MAAM,SAAS,MAAM,QAAQ,aAAa;EAC1C,IAAI,kBAAkB,KAAK,QACzB,MAAM,IAAI,wBACR,UAAU,UAAU,sBAAsB,MAAM,QAAQ,KAAK,KAAK,CAAC,kCAAkC,MAAM,KAAK,KAAK,OAAO,WAC5H,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,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"}
@@ -40,29 +40,31 @@ declare abstract class SqlNode extends IRNodeBase {
40
40
  constructor();
41
41
  }
42
42
  //#endregion
43
- //#region src/ir/foreign-key-references.d.ts
44
- interface ForeignKeyReferencesInput {
45
- readonly table: string;
43
+ //#region src/ir/foreign-key-reference.d.ts
44
+ interface ForeignKeyReferenceInput {
45
+ readonly namespaceId: string;
46
+ readonly tableName: string;
46
47
  readonly columns: readonly string[];
47
48
  }
48
49
  /**
49
- * SQL Contract IR node for the referenced side of a foreign key.
50
+ * SQL Contract IR node for one side (source or target) of a foreign-key
51
+ * declaration. Carries the full coordinate: namespace, table, and columns.
50
52
  *
51
- * The class is shaped around single-namespace references today; a
52
- * future milestone introduces a cross-namespace coordinate on top of
53
- * `(table, columns)` when namespace-keyed storage lands.
53
+ * Use `UNBOUND_NAMESPACE_ID` from `@prisma-next/framework-components/ir`
54
+ * as the sentinel `namespaceId` for single-namespace (unbound) references.
54
55
  */
55
- declare class ForeignKeyReferences extends SqlNode {
56
- readonly table: string;
56
+ declare class ForeignKeyReference extends SqlNode {
57
+ readonly namespaceId: string;
58
+ readonly tableName: string;
57
59
  readonly columns: readonly string[];
58
- constructor(input: ForeignKeyReferencesInput);
60
+ constructor(input: ForeignKeyReferenceInput);
59
61
  }
60
62
  //#endregion
61
63
  //#region src/ir/foreign-key.d.ts
62
64
  type ReferentialAction = 'noAction' | 'restrict' | 'cascade' | 'setNull' | 'setDefault';
63
65
  interface ForeignKeyInput {
64
- readonly columns: readonly string[];
65
- readonly references: ForeignKeyReferences | ForeignKeyReferencesInput;
66
+ readonly source: ForeignKeyReference | ForeignKeyReferenceInput;
67
+ readonly target: ForeignKeyReference | ForeignKeyReferenceInput;
66
68
  readonly name?: string;
67
69
  readonly onDelete?: ReferentialAction;
68
70
  readonly onUpdate?: ReferentialAction;
@@ -74,14 +76,18 @@ interface ForeignKeyInput {
74
76
  /**
75
77
  * SQL Contract IR node for a table-level foreign-key declaration.
76
78
  *
77
- * The nested `references` field is normalised to a
78
- * {@link ForeignKeyReferences} instance inside the constructor so
79
- * downstream walks see a uniform AST regardless of whether the input
80
- * was a JSON literal or an already-constructed class instance.
79
+ * Each FK carries explicit `source` and `target` {@link ForeignKeyReference}
80
+ * coordinates (namespace, table, columns). For single-namespace contracts the
81
+ * sentinel `UNBOUND_NAMESPACE_ID` appears on both sides.
82
+ *
83
+ * The nested references are normalised to {@link ForeignKeyReference}
84
+ * instances inside the constructor so downstream walks see a uniform AST
85
+ * regardless of whether the input was a JSON literal or an already-constructed
86
+ * class instance.
81
87
  */
82
88
  declare class ForeignKey extends SqlNode {
83
- readonly columns: readonly string[];
84
- readonly references: ForeignKeyReferences;
89
+ readonly source: ForeignKeyReference;
90
+ readonly target: ForeignKeyReference;
85
91
  readonly constraint: boolean;
86
92
  readonly index: boolean;
87
93
  readonly name?: string;
@@ -242,7 +248,8 @@ interface StorageTableInput {
242
248
  readonly foreignKeys: ReadonlyArray<ForeignKey | ForeignKeyInput>;
243
249
  }
244
250
  /**
245
- * SQL Contract IR node for a single table entry in `SqlStorage.tables`.
251
+ * SQL Contract IR node for a single table entry in a namespace's
252
+ * `tables` map.
246
253
  *
247
254
  * The constructor normalises nested IR-class fields (columns, primary
248
255
  * key, uniques, indexes, foreign keys) into the appropriate class
@@ -250,10 +257,7 @@ interface StorageTableInput {
250
257
  * the input was a JSON literal or an already-constructed class.
251
258
  *
252
259
  * The table's `name` is not on the class — tables are keyed by name in
253
- * the parent `SqlStorage.tables: Record<string, StorageTable>` map.
254
- * A future namespace-aware milestone will add a `namespaceId` field
255
- * when namespace-keyed storage lands; today's single-namespace shape
256
- * needs neither field.
260
+ * the parent namespace's `tables: Record<string, StorageTable>` map.
257
261
  */
258
262
  declare class StorageTable extends SqlNode {
259
263
  readonly columns: Readonly<Record<string, StorageColumn>>;
@@ -312,41 +316,42 @@ declare function isStorageTypeInstance(value: unknown): value is StorageTypeInst
312
316
  //#endregion
313
317
  //#region src/ir/sql-storage.d.ts
314
318
  /**
315
- * Polymorphic value type for `SqlStorage.types` entries (Decision 18,
316
- * Option B). The slot's framework alphabet is `StorageType` — codec
317
- * triples (`StorageTypeInstance` with `kind: 'codec-instance'`) and
318
- * target-specific IR class instances structurally satisfying
319
- * `PostgresEnumStorageEntry` (with `kind: 'postgres-enum'`) are the
320
- * two variants the SQL family ships today. The construction side also
321
- * accepts {@link StorageTypeInstanceInput} so callers can pass raw
322
- * codec triples; the constructor stamps the discriminator.
319
+ * Polymorphic value type for document-scoped `SqlStorage.types` entries
320
+ * (codec aliases / parameterised native type registrations). Postgres
321
+ * native enum registrations live under
322
+ * `storage.namespaces[namespaceId].types` instead.
323
323
  */
324
- type SqlStorageTypeEntry = StorageTypeInstance | PostgresEnumStorageEntry | StorageTypeInstanceInput;
324
+ type SqlStorageTypeEntry = StorageTypeInstance | StorageTypeInstanceInput | PostgresEnumStorageEntry;
325
+ interface SqlNamespaceTablesInput {
326
+ readonly id: string;
327
+ readonly tables?: Record<string, StorageTable | StorageTableInput>;
328
+ readonly types?: Record<string, PostgresEnumStorageEntry>;
329
+ }
325
330
  interface SqlStorageInput<THash extends string = string> {
326
331
  readonly storageHash: StorageHashBase<THash>;
327
- readonly tables: Record<string, StorageTable | StorageTableInput>;
328
332
  readonly types?: Record<string, SqlStorageTypeEntry>;
329
- readonly namespaces?: Readonly<Record<string, Namespace>>;
333
+ readonly namespaces?: Readonly<Record<string, Namespace | SqlNamespaceTablesInput>>;
330
334
  }
331
335
  /**
332
336
  * SQL Contract IR root node for the `storage` field.
333
337
  *
334
338
  * Single concrete family-shared class — both Postgres and SQLite
335
- * consume this same class today. Per-target storage subclasses are
339
+ * consume this class today. Per-target storage subclasses are
336
340
  * introduced when each target's namespace shape earns its
337
341
  * target-specific concretion (target-specific derived fields,
338
342
  * target-specific storage extensions).
339
343
  *
340
344
  * Honours the framework `Storage` interface: every SQL IR carries a
341
345
  * `namespaces` map keyed by namespace id. The default singleton
342
- * (`{ [UNSPECIFIED_NAMESPACE_ID]: SqlUnspecifiedNamespace.instance }`)
346
+ * (`{ [UNBOUND_NAMESPACE_ID]: SqlUnboundNamespace.instance }`)
343
347
  * binds every contract authored before per-target namespace concretions
344
- * land; per-target namespace classes (`PostgresSchema.unspecified`,
345
- * `SqliteUnspecifiedDatabase.instance`) earn their slots when each
348
+ * land; per-target namespace classes (`PostgresSchema.unbound`,
349
+ * `SqliteUnboundDatabase.instance`) earn their slots when each
346
350
  * target's namespace shape lands.
347
351
  *
348
- * The constructor normalises nested IR-class fields (`tables`, optional
349
- * `types`) into class instances so downstream walks see a uniform AST.
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.
350
355
  * `types` is polymorphic per Decision 18 Option B: codec-triple inputs
351
356
  * are stamped with `kind: 'codec-instance'`; class-instance kinds
352
357
  * (e.g. Postgres-enum entries satisfying `PostgresEnumStorageEntry`)
@@ -355,28 +360,35 @@ interface SqlStorageInput<THash extends string = string> {
355
360
  * responsibility (so the family base does not import target-specific
356
361
  * subclasses).
357
362
  */
363
+ type SqlNamespace = Namespace & {
364
+ readonly tables: Readonly<Record<string, StorageTable>>;
365
+ readonly types?: Readonly<Record<string, PostgresEnumStorageEntry>>;
366
+ };
358
367
  declare class SqlStorage<THash extends string = string> extends SqlNode implements Storage {
359
368
  readonly storageHash: StorageHashBase<THash>;
360
- readonly tables: Readonly<Record<string, StorageTable>>;
361
- readonly namespaces: Readonly<Record<string, Namespace>>;
369
+ readonly namespaces: Readonly<Record<string, SqlNamespace>> & {
370
+ readonly __unbound__: SqlNamespace;
371
+ };
362
372
  readonly types?: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;
363
373
  constructor(input: SqlStorageInput<THash>);
364
374
  }
365
375
  //#endregion
366
- //#region src/ir/sql-unspecified-namespace.d.ts
376
+ //#region src/ir/sql-unbound-namespace.d.ts
367
377
  /**
368
- * Family-layer placeholder for the SQL unspecified-namespace singleton.
378
+ * Family-layer placeholder for the SQL unbound-namespace singleton
379
+ * the late-bound slot whose binding the target resolves at connection
380
+ * time rather than at authoring time.
369
381
  *
370
382
  * SQL contracts honour the framework `Storage.namespaces` invariant from
371
383
  * the moment they appear in the IR. Today `SqlStorage` is family-shared
372
384
  * (Postgres + SQLite consume the same class); a per-target namespace
373
- * concretion (`PostgresSchema.unspecified`, `SqliteUnspecifiedDatabase.instance`)
385
+ * concretion (`PostgresSchema.unbound`, `SqliteUnboundDatabase.instance`)
374
386
  * earns its existence when each target's namespace shape lands. Until
375
387
  * then the family ships a single placeholder singleton so the JSON
376
388
  * envelope and runtime walk are honest at every layer.
377
389
  *
378
390
  * The `kind` discriminator is installed as a non-enumerable own property
379
- * so the JSON envelope reads `{ "id": "__unspecified__" }` — symmetric
391
+ * so the JSON envelope reads `{ "id": "__unbound__" }` — symmetric
380
392
  * with the family-level non-enumerable `kind` on `SqlNode` and bounded
381
393
  * to the minimum data the framework `Namespace` interface promises.
382
394
  *
@@ -392,9 +404,10 @@ declare class SqlStorage<THash extends string = string> extends SqlNode implemen
392
404
  * fields safely, lift `freezeNode` to a leaf-class `seal()` hook each
393
405
  * leaf calls explicitly at the end of its own constructor.
394
406
  */
395
- declare class SqlUnspecifiedNamespace extends NamespaceBase {
396
- static readonly instance: SqlUnspecifiedNamespace;
397
- readonly id: "__unspecified__";
407
+ declare class SqlUnboundNamespace extends NamespaceBase {
408
+ static readonly instance: SqlUnboundNamespace;
409
+ readonly id: "__unbound__";
410
+ readonly tables: Readonly<Record<string, StorageTable>>;
398
411
  readonly kind?: string;
399
412
  private constructor();
400
413
  }
@@ -494,5 +507,5 @@ type ExtractFieldOutputTypes<T> = FieldOutputTypesOf<ExtractTypeMapsFromContract
494
507
  type ExtractFieldInputTypes<T> = FieldInputTypesOf<ExtractTypeMapsFromContract<T>>;
495
508
  type ResolveCodecTypes<TContract, TTypeMaps> = [TTypeMaps] extends [never] ? ExtractCodecTypes<TContract> : CodecTypesOf<TTypeMaps>;
496
509
  //#endregion
497
- export { StorageTypeInstance as A, Index as B, TypeMapsPhantomKey as C, SqlStorageInput as D, SqlStorage as E, StorageTableInput as F, PostgresEnumStorageEntry as G, PrimaryKey as H, UniqueConstraint as I, ForeignKeyInput as J, isPostgresEnumStorageEntry as K, UniqueConstraintInput as L, isStorageTypeInstance as M, toStorageTypeInstance as N, SqlStorageTypeEntry as O, StorageTable as P, SqlNode as Q, StorageColumn as R, TypeMaps as S, SqlUnspecifiedNamespace as T, PrimaryKeyInput as U, IndexInput as V, POSTGRES_ENUM_KIND as W, ForeignKeyReferences as X, ReferentialAction as Y, ForeignKeyReferencesInput 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, StorageTypeInstanceInput as j, CODEC_INSTANCE_KIND as k, ExtractTypeMapsFromContract as l, QueryOperationSelfSpec as m, ContractWithTypeMaps as n, ExtractFieldInputTypes as o, QueryOperationReturn as p, ForeignKey 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, StorageColumnInput as z };
498
- //# sourceMappingURL=types-B0lbr9cb.d.mts.map
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-FVBrwvCz.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-FVBrwvCz.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/sql-unbound-namespace.ts","../src/types.ts"],"mappings":";;;;;;;;;AAkCA;;;;;;;;;;;;AC/BA;;;;;;;;;AAaA;;;;;;;uBDkBsB,OAAA,SAAgB,UAAA;EAAA,SAC3B,IAAA;;;;;UChCM,wBAAA;EAAA,SACN,WAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA;AAAA;;;;;;;;cAUE,mBAAA,SAA4B,OAAA;EAAA,SAC9B,WAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA;cAEG,KAAA,EAAO,wBAAA;AAAA;;;KCjBT,iBAAA;AAAA,UAEK,eAAA;EAAA,SACN,MAAA,EAAQ,mBAAA,GAAsB,wBAAA;EAAA,SAC9B,MAAA,EAAQ,mBAAA,GAAsB,wBAAA;EAAA,SAC9B,IAAA;EAAA,SACA,QAAA,GAAW,iBAAA;EAAA,SACX,QAAA,GAAW,iBAAA;EFuBgB;EAAA,SErB3B,UAAA;;WAEA,KAAA;AAAA;;;;ADZX;;;;;;;;;cC2Ba,UAAA,SAAmB,OAAA;EAAA,SACrB,MAAA,EAAQ,mBAAA;EAAA,SACR,MAAA,EAAQ,mBAAA;EAAA,SACR,UAAA;EAAA,SACA,KAAA;EAAA,SACQ,IAAA;EAAA,SACA,QAAA,GAAW,iBAAA;EAAA,SACX,QAAA,GAAW,iBAAA;cAEhB,KAAA,EAAO,eAAA;AAAA;;;;;;;AFLrB;;;;;;;;;;;cGjBa,kBAAA;AFdb;;;;;;;;;AAaA;;;AAbA,UE4BiB,wBAAA,SAAiC,WAAA;EAAA,SACvC,IAAA,SAAa,kBAAA;EAAA,SACb,IAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA;;;;;;;;WAQA,OAAA;AAAA;;;;;ADrCX;iBC6CgB,0BAAA,CAA2B,KAAA,YAAiB,KAAA,IAAS,wBAAA;;;UChDpD,eAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;AAAA;AJ6BX;;;AAAA,cIvBa,UAAA,SAAmB,OAAA;EAAA,SACrB,OAAA;EAAA,SACQ,IAAA;cAEL,KAAA,EAAO,eAAA;AAAA;;;UCZJ,UAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,OAAA,GAAU,MAAA;AAAA;;;;;;;;;cAWR,KAAA,SAAc,OAAA;EAAA,SAChB,OAAA;EAAA,SACQ,IAAA;EAAA,SACA,IAAA;EAAA,SACA,OAAA,GAAU,MAAA;cAEf,KAAA,EAAO,UAAA;AAAA;;;;;;ALUrB;;;;;;;UMpBiB,kBAAA;EAAA,SACN,UAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA,GAAa,MAAA;EAAA,SACb,OAAA;EAAA,SACA,OAAA,GAAU,aAAA;AAAA;;;;;;;ALJrB;;;;;;;cKoBa,aAAA,SAAsB,OAAA;EAAA,SACxB,UAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACQ,UAAA,GAAa,MAAA;EAAA,SACb,OAAA;EAAA,SACA,OAAA,GAAU,aAAA;cAEf,KAAA,EAAO,kBAAA;AAAA;;;UCzCJ,qBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;AAAA;AP6BX;;;AAAA,cOvBa,gBAAA,SAAyB,OAAA;EAAA,SAC3B,OAAA;EAAA,SACQ,IAAA;cAEL,KAAA,EAAO,qBAAA;AAAA;;;UCPJ,iBAAA;EAAA,SACN,OAAA,EAAS,MAAA,SAAe,aAAA,GAAgB,kBAAA;EAAA,SACxC,UAAA,GAAa,UAAA,GAAa,eAAA;EAAA,SAC1B,OAAA,EAAS,aAAA,CAAc,gBAAA,GAAmB,qBAAA;EAAA,SAC1C,OAAA,EAAS,aAAA,CAAc,KAAA,GAAQ,UAAA;EAAA,SAC/B,WAAA,EAAa,aAAA,CAAc,UAAA,GAAa,eAAA;AAAA;;;;;APVnD;;;;;;;;cOyBa,YAAA,SAAqB,OAAA;EAAA,SACvB,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,aAAA;EAAA,SACjC,OAAA,EAAS,aAAA,CAAc,gBAAA;EAAA,SACvB,OAAA,EAAS,aAAA,CAAc,KAAA;EAAA,SACvB,WAAA,EAAa,aAAA,CAAc,UAAA;EAAA,SACnB,UAAA,GAAa,UAAA;cAElB,KAAA,EAAO,iBAAA;AAAA;;;;;;;ARDrB;;;cSzBa,mBAAA;;;;;;;;;UAUI,mBAAA,SAA4B,WAAA;EAAA,SAClC,IAAA,SAAa,mBAAA;EAAA,SACb,OAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA,EAAY,MAAA;AAAA;;;;ARPvB;;UQeiB,wBAAA;EAAA,SACN,OAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA,EAAY,MAAA;AAAA;;;;;;iBAQP,qBAAA,CAAsB,KAAA,EAAO,wBAAA,GAA2B,mBAAA;;;;APtCxE;;iBOoDgB,qBAAA,CAAsB,KAAA,YAAiB,KAAA,IAAS,mBAAA;;;;;;;;;KC7BpD,mBAAA,GACR,mBAAA,GACA,wBAAA,GACA,wBAAA;AAAA,UAMa,uBAAA;EAAA,SACN,EAAA;EAAA,SACA,MAAA,GAAS,MAAA,SAAe,YAAA,GAAe,iBAAA;EAAA,SACvC,KAAA,GAAQ,MAAA,SAAe,wBAAA;AAAA;AAAA,UAGjB,eAAA;EAAA,SACN,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,KAAA,GAAQ,MAAA,SAAe,mBAAA;EAAA,SACvB,UAAA,GAAa,QAAA,CAAS,MAAA,SAAe,SAAA,GAAY,uBAAA;AAAA;;;;AT7B5D;;;;;;;;;;;;;;;;ACZA;;;;;AAEA;;;;KQkIY,YAAA,GAAe,SAAA;EAAA,SAChB,MAAA,EAAQ,QAAA,CAAS,MAAA,SAAe,YAAA;EAAA,SAChC,KAAA,GAAQ,QAAA,CAAS,MAAA,SAAe,wBAAA;AAAA;AAAA,cAG9B,UAAA,wCAAkD,OAAA,YAAmB,OAAA;EAAA,SACvE,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,YAAA;IAAA,SAClC,WAAA,EAAa,YAAA;EAAA;EAAA,SAEP,KAAA,GAAQ,QAAA,CAAS,MAAA,SAAe,mBAAA,GAAsB,wBAAA;cAE3D,KAAA,EAAO,eAAA,CAAgB,KAAA;AAAA;;;;;;AVlHrC;;;;;;;;;;;;AC/BA;;;;;;;;;AAaA;;;;;;cUqBa,mBAAA,SAA4B,aAAA;EAAA,gBACvB,QAAA,EAAU,mBAAA;EAAA,SAEjB,EAAA;EAAA,SACA,MAAA,EAAQ,QAAA,CAAS,MAAA,SAAe,YAAA;EAAA,SACxB,IAAA;EAAA,QAEV,WAAA,CAAA;AAAA;;;KCHG,iBAAA;EAAA,SACD,IAAA;EAAA,SACA,QAAA,GAAW,iBAAA;EAAA,SACX,QAAA,GAAW,iBAAA;AAAA;AAAA,KAGV,oBAAA;EAAA,SACD,MAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,eAAA;EAAA,SACD,KAAA;EAAA,SACA,MAAA,EAAQ,MAAA,SAAe,oBAAA;AAAA;AAAA,cAGrB,qBAAA;AAAA,cACA,gBAAA;AAAA,iBAEG,eAAA,CACd,EAAA;EAAM,UAAA;EAAkC,KAAA;AAAA,GACxC,gBAAA;EAAqB,UAAA;EAAkC,KAAA;AAAA;EACpD,UAAA;EAAqB,KAAA;AAAA;AAAA,KAOd,QAAA,qBACU,MAAA;EAAiB,MAAA;AAAA,KAAqB,MAAA,8CAC7B,MAAA,oBAA0B,MAAA,2CAC7B,MAAA,SAAe,MAAA,qBAA2B,MAAA,0CAC3C,MAAA,SAAe,MAAA,qBAA2B,MAAA;EAAA,SAE1D,UAAA,EAAY,WAAA;EAAA,SACZ,mBAAA,EAAqB,oBAAA;EAAA,SACrB,gBAAA,EAAkB,iBAAA;EAAA,SAClB,eAAA,EAAiB,gBAAA;AAAA;AAAA,KAGhB,YAAA,OAAmB,CAAA,oBAC3B,MAAA,kBACA,CAAA;EAAA,SAAqB,UAAA;AAAA,IACnB,CAAA,SAAU,MAAA;EAAiB,MAAA;AAAA,KACzB,CAAA,GACA,MAAA,kBACF,MAAA;;;;;;;;KASM,sBAAA;EAAA,SACG,OAAA;EAAA,SAA0B,MAAA;AAAA;EAAA,SAC1B,MAAA,WAAiB,UAAA;EAAA,SAAuB,OAAA;AAAA;;;;;;;AVtEvD;;KUgFY,oBAAA;EAAA,SACD,UAAA;IAAA,SAAuB,OAAA;IAAA,SAA0B,QAAA;EAAA;AAAA;AAAA,KAGhD,uBAAA;EAAA,SACD,IAAA,GAAO,sBAAA;EAAA,SACP,IAAA,MAAU,IAAA,cAAkB,oBAAA;AAAA;AAAA,KAG3B,sBAAA,aACE,MAAA;EAAA,SAA0B,KAAA;EAAA,SAAyB,MAAA;AAAA,cACrD,MAAA,SAAe,uBAAA,KACvB,CAAA;AAAA,KAEQ,uBAAA,GAA0B,MAAA,SAAe,uBAAA;AAAA,KAEzC,qBAAA,OAA4B,CAAA,oBACpC,MAAA,kBACA,CAAA;EAAA,SAAqB,mBAAA;AAAA,IACnB,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,kBACF,MAAA;AAAA,KAEM,kBAAA;AAAA,KAEA,oBAAA,yBAA6C,SAAA,oBACxC,kBAAA,IAAsB,SAAA;AAAA,KAG3B,2BAAA,MAAiC,kBAAA,eAAiC,CAAA,GAC1E,WAAA,CAAY,CAAA,CAAE,kBAAA,SAA2B,CAAA;AAAA,KAGjC,kBAAA,OAAyB,CAAA,oBACjC,MAAA,kBACA,CAAA;EAAA,SAAqB,gBAAA;AAAA,IACnB,CAAA,SAAU,MAAA,SAAe,MAAA,qBACvB,CAAA,GACA,MAAA,kBACF,MAAA;AAAA,KAEM,iBAAA,OAAwB,CAAA,oBAChC,MAAA,kBACA,CAAA;EAAA,SAAqB,eAAA;AAAA,IACnB,CAAA,SAAU,MAAA,SAAe,MAAA,qBACvB,CAAA,GACA,MAAA,kBACF,MAAA;AAAA,KAEM,iBAAA,MAAuB,YAAA,CAAa,2BAAA,CAA4B,CAAA;AAAA,KAChE,0BAAA,MAAgC,qBAAA,CAAsB,2BAAA,CAA4B,CAAA;AAAA,KAClF,uBAAA,MAA6B,kBAAA,CAAmB,2BAAA,CAA4B,CAAA;AAAA,KAC5E,sBAAA,MAA4B,iBAAA,CAAkB,2BAAA,CAA4B,CAAA;AAAA,KAE1E,iBAAA,0BAA2C,SAAA,oBACnD,iBAAA,CAAkB,SAAA,IAClB,YAAA,CAAa,SAAA"}
@@ -1,4 +1,4 @@
1
- import { IRNodeBase, NamespaceBase, UNSPECIFIED_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
1
+ import { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
2
2
  //#region src/ir/sql-node.ts
3
3
  /**
4
4
  * SQL family IR node base. Carries the family-level `kind` discriminator
@@ -45,20 +45,22 @@ var SqlNode = class extends IRNodeBase {
45
45
  }
46
46
  };
47
47
  //#endregion
48
- //#region src/ir/foreign-key-references.ts
48
+ //#region src/ir/foreign-key-reference.ts
49
49
  /**
50
- * SQL Contract IR node for the referenced side of a foreign key.
50
+ * SQL Contract IR node for one side (source or target) of a foreign-key
51
+ * declaration. Carries the full coordinate: namespace, table, and columns.
51
52
  *
52
- * The class is shaped around single-namespace references today; a
53
- * future milestone introduces a cross-namespace coordinate on top of
54
- * `(table, columns)` when namespace-keyed storage lands.
53
+ * Use `UNBOUND_NAMESPACE_ID` from `@prisma-next/framework-components/ir`
54
+ * as the sentinel `namespaceId` for single-namespace (unbound) references.
55
55
  */
56
- var ForeignKeyReferences = class extends SqlNode {
57
- table;
56
+ var ForeignKeyReference = class extends SqlNode {
57
+ namespaceId;
58
+ tableName;
58
59
  columns;
59
60
  constructor(input) {
60
61
  super();
61
- this.table = input.table;
62
+ this.namespaceId = input.namespaceId;
63
+ this.tableName = input.tableName;
62
64
  this.columns = input.columns;
63
65
  freezeNode(this);
64
66
  }
@@ -68,20 +70,24 @@ var ForeignKeyReferences = class extends SqlNode {
68
70
  /**
69
71
  * SQL Contract IR node for a table-level foreign-key declaration.
70
72
  *
71
- * The nested `references` field is normalised to a
72
- * {@link ForeignKeyReferences} instance inside the constructor so
73
- * downstream walks see a uniform AST regardless of whether the input
74
- * was a JSON literal or an already-constructed class instance.
73
+ * Each FK carries explicit `source` and `target` {@link ForeignKeyReference}
74
+ * coordinates (namespace, table, columns). For single-namespace contracts the
75
+ * sentinel `UNBOUND_NAMESPACE_ID` appears on both sides.
76
+ *
77
+ * The nested references are normalised to {@link ForeignKeyReference}
78
+ * instances inside the constructor so downstream walks see a uniform AST
79
+ * regardless of whether the input was a JSON literal or an already-constructed
80
+ * class instance.
75
81
  */
76
82
  var ForeignKey = class extends SqlNode {
77
- columns;
78
- references;
83
+ source;
84
+ target;
79
85
  constraint;
80
86
  index;
81
87
  constructor(input) {
82
88
  super();
83
- this.columns = input.columns;
84
- this.references = input.references instanceof ForeignKeyReferences ? input.references : new ForeignKeyReferences(input.references);
89
+ this.source = input.source instanceof ForeignKeyReference ? input.source : new ForeignKeyReference(input.source);
90
+ this.target = input.target instanceof ForeignKeyReference ? input.target : new ForeignKeyReference(input.target);
85
91
  this.constraint = input.constraint;
86
92
  this.index = input.index;
87
93
  if (input.name !== void 0) this.name = input.name;
@@ -153,20 +159,22 @@ var Index = class extends SqlNode {
153
159
  }
154
160
  };
155
161
  //#endregion
156
- //#region src/ir/sql-unspecified-namespace.ts
162
+ //#region src/ir/sql-unbound-namespace.ts
157
163
  /**
158
- * Family-layer placeholder for the SQL unspecified-namespace singleton.
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.
159
167
  *
160
168
  * SQL contracts honour the framework `Storage.namespaces` invariant from
161
169
  * the moment they appear in the IR. Today `SqlStorage` is family-shared
162
170
  * (Postgres + SQLite consume the same class); a per-target namespace
163
- * concretion (`PostgresSchema.unspecified`, `SqliteUnspecifiedDatabase.instance`)
171
+ * concretion (`PostgresSchema.unbound`, `SqliteUnboundDatabase.instance`)
164
172
  * earns its existence when each target's namespace shape lands. Until
165
173
  * then the family ships a single placeholder singleton so the JSON
166
174
  * envelope and runtime walk are honest at every layer.
167
175
  *
168
176
  * The `kind` discriminator is installed as a non-enumerable own property
169
- * so the JSON envelope reads `{ "id": "__unspecified__" }` — symmetric
177
+ * so the JSON envelope reads `{ "id": "__unbound__" }` — symmetric
170
178
  * with the family-level non-enumerable `kind` on `SqlNode` and bounded
171
179
  * to the minimum data the framework `Namespace` interface promises.
172
180
  *
@@ -182,9 +190,10 @@ var Index = class extends SqlNode {
182
190
  * fields safely, lift `freezeNode` to a leaf-class `seal()` hook each
183
191
  * leaf calls explicitly at the end of its own constructor.
184
192
  */
185
- var SqlUnspecifiedNamespace = class SqlUnspecifiedNamespace extends NamespaceBase {
186
- static instance = new SqlUnspecifiedNamespace();
187
- id = UNSPECIFIED_NAMESPACE_ID;
193
+ var SqlUnboundNamespace = class SqlUnboundNamespace extends NamespaceBase {
194
+ static instance = new SqlUnboundNamespace();
195
+ id = UNBOUND_NAMESPACE_ID;
196
+ tables = Object.freeze({});
188
197
  constructor() {
189
198
  super();
190
199
  Object.defineProperty(this, "kind", {
@@ -243,7 +252,8 @@ var UniqueConstraint = class extends SqlNode {
243
252
  //#endregion
244
253
  //#region src/ir/storage-table.ts
245
254
  /**
246
- * SQL Contract IR node for a single table entry in `SqlStorage.tables`.
255
+ * SQL Contract IR node for a single table entry in a namespace's
256
+ * `tables` map.
247
257
  *
248
258
  * The constructor normalises nested IR-class fields (columns, primary
249
259
  * key, uniques, indexes, foreign keys) into the appropriate class
@@ -251,10 +261,7 @@ var UniqueConstraint = class extends SqlNode {
251
261
  * the input was a JSON literal or an already-constructed class.
252
262
  *
253
263
  * The table's `name` is not on the class — tables are keyed by name in
254
- * the parent `SqlStorage.tables: Record<string, StorageTable>` map.
255
- * A future namespace-aware milestone will add a `namespaceId` field
256
- * when namespace-keyed storage lands; today's single-namespace shape
257
- * needs neither field.
264
+ * the parent namespace's `tables: Record<string, StorageTable>` map.
258
265
  */
259
266
  var StorageTable = class extends SqlNode {
260
267
  columns;
@@ -305,51 +312,55 @@ function isStorageTypeInstance(value) {
305
312
  }
306
313
  //#endregion
307
314
  //#region src/ir/sql-storage.ts
308
- const DEFAULT_NAMESPACES = Object.freeze({ [UNSPECIFIED_NAMESPACE_ID]: SqlUnspecifiedNamespace.instance });
309
- /**
310
- * SQL Contract IR root node for the `storage` field.
311
- *
312
- * Single concrete family-shared class — both Postgres and SQLite
313
- * consume this same class today. Per-target storage subclasses are
314
- * introduced when each target's namespace shape earns its
315
- * target-specific concretion (target-specific derived fields,
316
- * target-specific storage extensions).
317
- *
318
- * Honours the framework `Storage` interface: every SQL IR carries a
319
- * `namespaces` map keyed by namespace id. The default singleton
320
- * (`{ [UNSPECIFIED_NAMESPACE_ID]: SqlUnspecifiedNamespace.instance }`)
321
- * binds every contract authored before per-target namespace concretions
322
- * land; per-target namespace classes (`PostgresSchema.unspecified`,
323
- * `SqliteUnspecifiedDatabase.instance`) earn their slots when each
324
- * target's namespace shape lands.
325
- *
326
- * The constructor normalises nested IR-class fields (`tables`, optional
327
- * `types`) into class instances so downstream walks see a uniform AST.
328
- * `types` is polymorphic per Decision 18 Option B: codec-triple inputs
329
- * are stamped with `kind: 'codec-instance'`; class-instance kinds
330
- * (e.g. Postgres-enum entries satisfying `PostgresEnumStorageEntry`)
331
- * pass through; hydration of raw JSON class-instance entries (carrying
332
- * their narrower `kind` literal) is the per-target serializer's
333
- * responsibility (so the family base does not import target-specific
334
- * subclasses).
335
- */
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
+ }
336
346
  var SqlStorage = class extends SqlNode {
337
347
  storageHash;
338
- tables;
339
348
  namespaces;
340
349
  constructor(input) {
341
350
  super();
342
351
  this.storageHash = input.storageHash;
343
- this.tables = Object.freeze(Object.fromEntries(Object.entries(input.tables).map(([name, t]) => [name, t instanceof StorageTable ? t : new StorageTable(t)])));
344
- this.namespaces = input.namespaces ?? DEFAULT_NAMESPACES;
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);
345
356
  if (input.types !== void 0) this.types = Object.freeze(Object.fromEntries(Object.entries(input.types).map(([name, ti]) => [name, normaliseTypeEntry(name, ti)])));
346
357
  freezeNode(this);
347
358
  }
348
359
  };
349
360
  /**
350
- * Strict polymorphic-slot dispatch for `SqlStorage.types` entries
351
- * (TML-2536). Every entry must carry a recognised `kind` discriminator
352
- * — either `'codec-instance'` (codec triple, family-shared) or
361
+ * Strict polymorphic-slot dispatch for `SqlStorage.types` entries.
362
+ * Every entry must carry a recognised `kind` discriminator — either
363
+ * `'codec-instance'` (codec triple, family-shared) or
353
364
  * `'postgres-enum'` (target-specific IR class). Untagged or
354
365
  * unrecognised inputs throw a diagnostic naming the entry and its
355
366
  * `kind`, so format drift surfaces loudly at the deserializer
@@ -384,6 +395,6 @@ function applyFkDefaults(fk, overrideDefaults) {
384
395
  };
385
396
  }
386
397
  //#endregion
387
- export { ForeignKeyReferences as _, CODEC_INSTANCE_KIND as a, StorageTable as c, SqlUnspecifiedNamespace 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 };
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 };
388
399
 
389
- //# sourceMappingURL=types-iqFGDcJp.mjs.map
400
+ //# sourceMappingURL=types-L8p7B1dP.mjs.map