@prisma-next/sql-contract-ts 0.12.0 → 0.13.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.
@@ -0,0 +1,306 @@
1
+ import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/codec';
2
+ import { blindCast } from '@prisma-next/utils/casts';
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // EnumMember — a single member declaration with literal type preservation
6
+ // ---------------------------------------------------------------------------
7
+
8
+ /**
9
+ * A single enum member produced by `member()`. The `Name` and `Value` generics
10
+ * are preserved as literal types so `enumType()` can carry the ordered value
11
+ * tuple in its return type. `Value` is whatever the codec dictates — its type
12
+ * is constrained at `enumType` against the codec's input type, not here.
13
+ */
14
+ export interface EnumMember<Name extends string, Value> {
15
+ readonly name: Name;
16
+ readonly value: Value;
17
+ }
18
+
19
+ /**
20
+ * Declare an enum member. The `value` defaults to `name` when omitted. The
21
+ * value is an unconstrained literal here; `enumType` constrains it against the
22
+ * codec's input type. Both generics are preserved as literals so downstream
23
+ * `enumType` carries the value union in its type; the value is serialized to its
24
+ * codec string form only at lowering.
25
+ */
26
+ export function member<const Name extends string>(name: Name): EnumMember<Name, Name>;
27
+ export function member<const Name extends string, const Value>(
28
+ name: Name,
29
+ value: Value,
30
+ ): EnumMember<Name, Value>;
31
+ export function member<const Name extends string, const Value = Name>(
32
+ name: Name,
33
+ value?: Value,
34
+ ): EnumMember<Name, Value> {
35
+ return {
36
+ name,
37
+ value: blindCast<
38
+ Value,
39
+ 'overload signatures enforce Value=Name when value is omitted; default generic Value=Name makes this safe'
40
+ >(value ?? name),
41
+ };
42
+ }
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Internal types for inferring the literal tuple from the members spread
46
+ // ---------------------------------------------------------------------------
47
+
48
+ type MembersToValues<Members extends readonly EnumMember<string, unknown>[]> = {
49
+ readonly [K in keyof Members]: Members[K] extends EnumMember<string, infer V> ? V : never;
50
+ };
51
+
52
+ type MembersToNames<Members extends readonly EnumMember<string, unknown>[]> = {
53
+ readonly [K in keyof Members]: Members[K] extends EnumMember<infer N, unknown> ? N : never;
54
+ };
55
+
56
+ type MembersAccessorMap<Members extends readonly EnumMember<string, unknown>[]> = {
57
+ readonly [M in Members[number] as M['name']]: M['value'];
58
+ };
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // EnumTypeHandle — the authoring handle returned by enumType()
62
+ // ---------------------------------------------------------------------------
63
+
64
+ /**
65
+ * Internal brand that identifies an EnumTypeHandle in the lowering pipeline.
66
+ * Not exported — callers only interact with `EnumTypeHandle`.
67
+ */
68
+ export const ENUM_TYPE_HANDLE_BRAND = Symbol('EnumTypeHandle');
69
+
70
+ /**
71
+ * Authoring handle returned by `enumType()`. Carries:
72
+ *
73
+ * - The ordered literal value tuple (`.values`) and name tuple (`.names`)
74
+ * so downstream type-tests can assert literal preservation.
75
+ * - A namespaced member accessor map (`.members`) to avoid collisions with
76
+ * `.values` / `.has` / `.nameOf` / `.ordinalOf`.
77
+ * - Runtime helpers `.has()`, `.nameOf()`, `.ordinalOf()`.
78
+ * - Internal metadata (`enumName`, `codecId`, `nativeType`,
79
+ * `enumMembers`) for the lowering pipeline.
80
+ *
81
+ * The type is generic over the ordered value tuple so callers that assign
82
+ * `const Role = enumType(...)` retain the literal tuple on `.values`.
83
+ */
84
+ export interface EnumTypeHandle<
85
+ Name extends string = string,
86
+ Values extends readonly unknown[] = readonly unknown[],
87
+ Names extends readonly string[] = readonly string[],
88
+ MembersMap extends Record<string, unknown> = Record<string, unknown>,
89
+ > {
90
+ /** Internal brand for lowering-pipeline detection. */
91
+ readonly [ENUM_TYPE_HANDLE_BRAND]: true;
92
+
93
+ /** The enum's declared name (used as the key in domain `enum` / storage `valueSet`). */
94
+ readonly enumName: Name;
95
+
96
+ /** codecId from the codec passed to `enumType`. */
97
+ readonly codecId: string;
98
+
99
+ /** nativeType from the codec passed to `enumType`. */
100
+ readonly nativeType: string;
101
+
102
+ /** Ordered member list for lowering (name + value pairs). */
103
+ readonly enumMembers: readonly { readonly name: string; readonly value: Values[number] }[];
104
+
105
+ /** Ordered literal value tuple. Declaration order is preserved. */
106
+ readonly values: Values;
107
+
108
+ /** Ordered literal name tuple. Declaration order is preserved. */
109
+ readonly names: Names;
110
+
111
+ /**
112
+ * Namespaced accessor map: `Role.members.User === 'user'`.
113
+ * Namespaced under `.members` to avoid collisions with `.values` / `.has`.
114
+ */
115
+ readonly members: MembersMap;
116
+
117
+ /** Returns `true` if `v` is a declared member value. */
118
+ has(v: Values[number]): boolean;
119
+
120
+ /** Returns the member name for a value, or `undefined` if not found. */
121
+ nameOf(v: Values[number]): string | undefined;
122
+
123
+ /** Returns the zero-based declaration index of a value, or `-1` if not found. */
124
+ ordinalOf(v: Values[number]): number;
125
+ }
126
+
127
+ // ---------------------------------------------------------------------------
128
+ // enumType()
129
+ // ---------------------------------------------------------------------------
130
+
131
+ /**
132
+ * A codec typemap: codecId → `{ input, output }`, the same shape the query
133
+ * lanes consume (e.g. `{ 'pg/text@1': { input: string }, 'pg/int4@1': { input: number } }`).
134
+ * The bound `enumType` wrappers supply the target pack's typemap; the core
135
+ * defaults to an empty map (no codec is known), so member values stay
136
+ * unconstrained.
137
+ */
138
+ export type CodecTypeMap = Record<string, { readonly input?: unknown }>;
139
+
140
+ /**
141
+ * The application input type the codec dictates for an enum's member values:
142
+ * looks `Codec['codecId']` up in the supplied codec typemap. When the codecId
143
+ * isn't in the map (the core's empty default, or an unknown codec) the input is
144
+ * unconstrained, so any member-value literal is accepted and inferred verbatim.
145
+ */
146
+ export type CodecInput<
147
+ CodecTypes extends CodecTypeMap,
148
+ Codec extends { readonly codecId: string },
149
+ > = Codec['codecId'] extends keyof CodecTypes
150
+ ? CodecTypes[Codec['codecId']] extends { readonly input: infer In }
151
+ ? In
152
+ : unknown
153
+ : unknown;
154
+
155
+ /**
156
+ * Declare a domain enum for use in TS-authoring contracts.
157
+ *
158
+ * - The codec is an explicit required argument — the `codecId` and
159
+ * `nativeType` are taken from the passed `ColumnTypeDescriptor` (e.g.
160
+ * `{ codecId: 'pg/text@1', nativeType: 'text' }` from a field preset
161
+ * output or a direct inline object).
162
+ * - `const` generics on the members spread preserve the ordered literal
163
+ * value tuple so `Role.values` is `readonly ['user','admin']`, not
164
+ * `string[]`.
165
+ * - Well-formedness assertions at construction: non-empty member list;
166
+ * unique names; unique values.
167
+ *
168
+ * The returned handle wires into `field.namedType(handle)` to set
169
+ * `valueSet` refs on both the domain field and the storage column.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * const Role = enumType('Role', { codecId: 'pg/text@1', nativeType: 'text' },
174
+ * member('User', 'user'),
175
+ * member('Admin', 'admin'),
176
+ * );
177
+ * // Role.values → readonly ['user', 'admin']
178
+ * // Role.members.User → 'user'
179
+ * ```
180
+ */
181
+ export function enumType<
182
+ CodecTypes extends CodecTypeMap = Record<string, never>,
183
+ const Name extends string = string,
184
+ const Codec extends Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'> = Pick<
185
+ ColumnTypeDescriptor,
186
+ 'codecId' | 'nativeType'
187
+ >,
188
+ const Members extends readonly [
189
+ EnumMember<string, CodecInput<CodecTypes, Codec>>,
190
+ ...EnumMember<string, CodecInput<CodecTypes, Codec>>[],
191
+ ] = readonly [EnumMember<string, CodecInput<CodecTypes, Codec>>],
192
+ >(
193
+ name: Name,
194
+ codec: Codec,
195
+ ...members: Members
196
+ ): EnumTypeHandle<
197
+ Name,
198
+ MembersToValues<[...Members]>,
199
+ MembersToNames<[...Members]>,
200
+ MembersAccessorMap<[...Members]>
201
+ >;
202
+ export function enumType(
203
+ name: string,
204
+ codec: Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'>,
205
+ ...members: EnumMember<string, unknown>[]
206
+ ): EnumTypeHandle;
207
+ export function enumType(
208
+ name: string,
209
+ codec: Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'>,
210
+ ...members: EnumMember<string, unknown>[]
211
+ ): EnumTypeHandle {
212
+ if (members.length === 0) {
213
+ throw new Error(`enumType("${name}"): must have at least one member.`);
214
+ }
215
+
216
+ const seenNames = new Set<string>();
217
+ const seenValues = new Set<string>();
218
+ for (const m of members) {
219
+ if (seenNames.has(m.name)) {
220
+ throw new Error(
221
+ `enumType("${name}"): duplicate member name "${m.name}". Member names must be unique.`,
222
+ );
223
+ }
224
+ seenNames.add(m.name);
225
+
226
+ const loweredValue = String(m.value);
227
+ if (seenValues.has(loweredValue)) {
228
+ throw new Error(
229
+ `enumType("${name}"): duplicate member value "${loweredValue}". Member values must be unique.`,
230
+ );
231
+ }
232
+ seenValues.add(loweredValue);
233
+ }
234
+
235
+ const values = Object.freeze(members.map((m) => m.value));
236
+ const names = Object.freeze(members.map((m) => m.name));
237
+ const enumMembers = Object.freeze(members.map((m) => ({ name: m.name, value: m.value })));
238
+
239
+ const membersAccessor = Object.freeze(Object.fromEntries(members.map((m) => [m.name, m.value])));
240
+
241
+ const valueSet = new Set(values);
242
+ const valueToName = new Map(members.map((m) => [m.value, m.name]));
243
+ const valueToOrdinal = new Map(values.map((v, i) => [v, i]));
244
+
245
+ return {
246
+ [ENUM_TYPE_HANDLE_BRAND]: true,
247
+ enumName: name,
248
+ codecId: codec.codecId,
249
+ nativeType: codec.nativeType,
250
+ enumMembers,
251
+ values,
252
+ names,
253
+ members: membersAccessor,
254
+ has: (v: unknown) => valueSet.has(v),
255
+ nameOf: (v: unknown) => valueToName.get(v),
256
+ ordinalOf: (v: unknown) => valueToOrdinal.get(v) ?? -1,
257
+ };
258
+ }
259
+
260
+ /**
261
+ * The signature of an `enumType` whose codec typemap is already bound — the
262
+ * shape a target-bound wrapper (e.g. `@prisma-next/postgres/contract-builder`)
263
+ * exposes. The member values are constrained to the codec's input type drawn
264
+ * from `CodecTypes` (so a `pg/text@1` codec rejects numeric members, etc.),
265
+ * while `Name`, `Codec`, and the member tuple still infer from the call.
266
+ */
267
+ export type BoundEnumType<CodecTypes extends CodecTypeMap> = <
268
+ const Name extends string,
269
+ const Codec extends Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'>,
270
+ const Members extends readonly [
271
+ EnumMember<string, CodecInput<CodecTypes, Codec>>,
272
+ ...EnumMember<string, CodecInput<CodecTypes, Codec>>[],
273
+ ],
274
+ >(
275
+ name: Name,
276
+ codec: Codec,
277
+ ...members: Members
278
+ ) => EnumTypeHandle<
279
+ Name,
280
+ MembersToValues<[...Members]>,
281
+ MembersToNames<[...Members]>,
282
+ MembersAccessorMap<[...Members]>
283
+ >;
284
+
285
+ /**
286
+ * Bind `enumType` to a target's codec typemap. The returned function is the
287
+ * same runtime `enumType`, retyped so member values are constrained to the
288
+ * codec's input type. Target packages call this with their pack's
289
+ * `ExtractCodecTypesFromPack<Pack>` to expose a codec-aware `enumType`.
290
+ */
291
+ export function bindEnumType<CodecTypes extends CodecTypeMap>(): BoundEnumType<CodecTypes> {
292
+ return enumType;
293
+ }
294
+
295
+ /**
296
+ * Returns true when the value is an `EnumTypeHandle` produced by
297
+ * `enumType()`. Used in the lowering pipeline to detect enum handles
298
+ * in field state without importing the BRAND symbol at every call site.
299
+ */
300
+ export function isEnumTypeHandle(value: unknown): value is EnumTypeHandle {
301
+ return (
302
+ typeof value === 'object' &&
303
+ value !== null &&
304
+ Reflect.get(value, ENUM_TYPE_HANDLE_BRAND) === true
305
+ );
306
+ }
@@ -2,12 +2,15 @@ export type {
2
2
  ComposedAuthoringHelpers,
3
3
  ContractInput,
4
4
  ContractModelBuilder,
5
+ MergeEnums,
5
6
  ModelLike,
6
7
  ScalarFieldBuilder,
7
8
  } from '../contract-builder';
8
9
  export {
10
+ buildBoundContract,
9
11
  buildSqlContractFromDefinition,
10
12
  defineContract,
13
+ extensionModel,
11
14
  field,
12
15
  model,
13
16
  rel,
@@ -22,3 +25,13 @@ export type {
22
25
  RelationNode,
23
26
  UniqueConstraintNode,
24
27
  } from '../contract-definition';
28
+ export type { TargetFieldRef } from '../contract-dsl';
29
+ export type { ExtractCodecTypesFromPack } from '../contract-types';
30
+ export type {
31
+ BoundEnumType,
32
+ CodecInput,
33
+ CodecTypeMap,
34
+ EnumMember,
35
+ EnumTypeHandle,
36
+ } from '../enum-type';
37
+ export { bindEnumType, enumType, member } from '../enum-type';
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-contract-BCYW3_wE.mjs","names":[],"sources":["../src/build-contract.ts"],"sourcesContent":["import {\n computeExecutionHash,\n computeProfileHash,\n computeStorageHash,\n} from '@prisma-next/contract/hashing';\nimport {\n asNamespaceId,\n type ColumnDefault,\n type ColumnDefaultLiteralInputValue,\n type Contract,\n type ContractField,\n type ContractModel,\n type ContractRelation,\n type ContractValueObject,\n type CrossReference,\n coreHash,\n crossRef,\n type ExecutionMutationDefault,\n type JsonValue,\n type StorageHashBase,\n} from '@prisma-next/contract/types';\nimport { type CapabilityMatrix, mergeCapabilityMatrices } from '@prisma-next/contract-authoring';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport { validateIndexTypes } from '@prisma-next/sql-contract/index-type-validation';\nimport {\n createIndexTypeRegistry,\n type IndexTypeMap,\n type IndexTypeRegistration,\n} from '@prisma-next/sql-contract/index-types';\nimport {\n applyFkDefaults,\n buildSqlNamespace,\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type SqlNamespaceTablesInput,\n SqlStorage,\n type SqlStorageInput,\n type StorageColumn,\n StorageTable,\n type StorageTableInput,\n type StorageTypeInstance,\n toStorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { validateStorageSemantics } from '@prisma-next/sql-contract/validators';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type {\n ContractDefinition,\n FieldNode,\n ModelNode,\n ValueObjectFieldNode,\n} from './contract-definition';\n\ntype DomainFieldRef =\n | { readonly kind: 'scalar'; readonly many?: boolean }\n | { readonly kind: 'valueObject'; readonly name: string; readonly many?: boolean };\n\nfunction encodeDefaultLiteralValue(\n value: ColumnDefaultLiteralInputValue,\n codecId: string,\n codecLookup?: CodecLookup,\n): JsonValue {\n const codec = codecLookup?.get(codecId);\n if (codec) {\n return codec.encodeJson(value);\n }\n return value as JsonValue;\n}\n\nfunction encodeColumnDefault(\n defaultInput: ColumnDefault,\n codecId: string,\n codecLookup?: CodecLookup,\n): ColumnDefault {\n if (defaultInput.kind === 'function') {\n return { kind: 'function', expression: defaultInput.expression };\n }\n return {\n kind: 'literal',\n value: encodeDefaultLiteralValue(defaultInput.value, codecId, codecLookup),\n };\n}\n\nfunction assertStorageSemantics(\n definition: ContractDefinition,\n contract: Contract<SqlStorage>,\n): void {\n const semanticErrors = validateStorageSemantics(contract.storage);\n if (semanticErrors.length > 0) {\n throw new Error(`Contract semantic validation failed: ${semanticErrors.join('; ')}`);\n }\n\n const indexTypeRegistry = createIndexTypeRegistry();\n const packsToRegister: ReadonlyArray<{ readonly id?: string; readonly indexTypes?: unknown }> = [\n definition.target,\n ...Object.values(definition.extensionPacks ?? {}),\n ];\n for (const pack of packsToRegister) {\n const registration = pack.indexTypes;\n if (registration === undefined) continue;\n if (\n typeof registration !== 'object' ||\n registration === null ||\n !Array.isArray((registration as { entries?: unknown }).entries)\n ) {\n throw new Error(\n `Pack \"${pack.id ?? '<unknown>'}\" declares \"indexTypes\" but its value is not an IndexTypeRegistration (expected an object with an \"entries\" array; got ${typeof registration}).`,\n );\n }\n for (const entry of (registration as IndexTypeRegistration<IndexTypeMap>).entries) {\n indexTypeRegistry.register(entry);\n }\n }\n validateIndexTypes(contract, indexTypeRegistry);\n}\n\nfunction assertKnownTargetModel(\n modelsByName: ReadonlyMap<string, ModelNode>,\n sourceModelName: string,\n targetModelName: string,\n context: string,\n): ModelNode {\n const targetModel = modelsByName.get(targetModelName);\n if (!targetModel) {\n throw new Error(\n `${context} on model \"${sourceModelName}\" references unknown model \"${targetModelName}\"`,\n );\n }\n return targetModel;\n}\n\nfunction assertTargetTableMatches(\n sourceModelName: string,\n targetModel: ModelNode,\n referencedTableName: string,\n context: string,\n): void {\n if (targetModel.tableName !== referencedTableName) {\n throw new Error(\n `${context} on model \"${sourceModelName}\" references table \"${referencedTableName}\" but model \"${targetModel.modelName}\" maps to \"${targetModel.tableName}\"`,\n );\n }\n}\n\nfunction isValueObjectField(\n field: FieldNode | ValueObjectFieldNode,\n): field is ValueObjectFieldNode {\n return 'valueObjectName' in field;\n}\n\nconst JSONB_CODEC_ID = 'pg/jsonb@1';\nconst JSONB_NATIVE_TYPE = 'jsonb';\n\nfunction resolveModelNamespaceId(\n model: ModelNode,\n modelNameToNamespaceId: ReadonlyMap<string, string>,\n targetId: string,\n): string {\n if (model.namespaceId !== undefined && model.namespaceId.length > 0) {\n return model.namespaceId;\n }\n return modelNameToNamespaceId.get(model.modelName) ?? defaultModelNamespaceId(targetId);\n}\n\nfunction buildStorageColumn(\n field: FieldNode | ValueObjectFieldNode,\n codecLookup?: CodecLookup,\n): StorageColumn {\n if (isValueObjectField(field)) {\n const encodedDefault =\n field.default !== undefined\n ? encodeColumnDefault(field.default, JSONB_CODEC_ID, codecLookup)\n : undefined;\n\n return {\n nativeType: JSONB_NATIVE_TYPE,\n codecId: JSONB_CODEC_ID,\n nullable: field.nullable,\n ...ifDefined('default', encodedDefault),\n };\n }\n\n if (field.many) {\n return {\n nativeType: JSONB_NATIVE_TYPE,\n codecId: JSONB_CODEC_ID,\n nullable: field.nullable,\n };\n }\n\n const codecId = field.descriptor.codecId;\n const encodedDefault =\n field.default !== undefined\n ? encodeColumnDefault(field.default, codecId, codecLookup)\n : undefined;\n\n return {\n nativeType: field.descriptor.nativeType,\n codecId,\n nullable: field.nullable,\n ...ifDefined('typeParams', field.descriptor.typeParams),\n ...ifDefined('default', encodedDefault),\n ...ifDefined('typeRef', field.descriptor.typeRef),\n };\n}\n\nfunction buildDomainField(\n field: FieldNode | ValueObjectFieldNode,\n column: StorageColumn,\n): ContractField {\n if (isValueObjectField(field)) {\n return {\n type: { kind: 'valueObject', name: field.valueObjectName },\n nullable: field.nullable,\n ...(field.many ? { many: true } : {}),\n };\n }\n\n return {\n type: {\n kind: 'scalar',\n codecId: column.codecId,\n ...ifDefined('typeParams', column.typeParams),\n },\n nullable: column.nullable,\n ...(field.many ? { many: true } : {}),\n };\n}\n\nfunction collectStorageNamespaceCoordinateIds(definition: ContractDefinition): Set<string> {\n const ids = new Set<string>();\n ids.add(defaultModelNamespaceId(definition.target.targetId));\n for (const id of definition.namespaces ?? []) {\n if (id.length > 0) {\n ids.add(id);\n }\n }\n for (const model of definition.models) {\n if (model.namespaceId !== undefined && model.namespaceId.length > 0) {\n ids.add(model.namespaceId);\n }\n }\n return ids;\n}\n\nconst POSTGRES_ENUM_NAMESPACE_ID = 'public';\nconst POSTGRES_DEFAULT_NAMESPACE_ID = 'public';\n\nfunction defaultModelNamespaceId(targetId: string): string {\n return targetId === 'postgres' ? POSTGRES_DEFAULT_NAMESPACE_ID : UNBOUND_NAMESPACE_ID;\n}\n\nfunction partitionStorageTypesForTarget(\n targetId: string,\n types: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,\n namespaceTypes?: Readonly<Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>>,\n): {\n readonly documentTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;\n readonly namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>>;\n} {\n const documentTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {};\n const namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>> = {};\n for (const [name, entry] of Object.entries(types)) {\n if (isPostgresEnumStorageEntry(entry)) {\n if (targetId !== 'postgres') {\n throw new Error(\n `buildSqlContractFromDefinition: postgres enum \"${name}\" is only valid when target is \"postgres\" (got \"${targetId}\").`,\n );\n }\n let slot = namespaceEnumTypesById[POSTGRES_ENUM_NAMESPACE_ID];\n if (slot === undefined) {\n slot = {};\n namespaceEnumTypesById[POSTGRES_ENUM_NAMESPACE_ID] = slot;\n }\n slot[name] = entry;\n continue;\n }\n documentTypes[name] = entry;\n }\n if (namespaceTypes !== undefined) {\n for (const [nsId, enumsInNs] of Object.entries(namespaceTypes)) {\n for (const [name, entry] of Object.entries(enumsInNs)) {\n if (targetId !== 'postgres') {\n throw new Error(\n `buildSqlContractFromDefinition: postgres enum \"${name}\" is only valid when target is \"postgres\" (got \"${targetId}\").`,\n );\n }\n let slot = namespaceEnumTypesById[nsId];\n if (slot === undefined) {\n slot = {};\n namespaceEnumTypesById[nsId] = slot;\n }\n slot[name] = entry;\n }\n }\n }\n return { documentTypes, namespaceEnumTypesById };\n}\n\nexport function buildSqlContractFromDefinition(\n definition: ContractDefinition,\n codecLookup?: CodecLookup,\n): Contract<SqlStorage> {\n const target = definition.target.targetId;\n const targetFamily = 'sql';\n const modelsByName = new Map(definition.models.map((m) => [m.modelName, m]));\n\n const tablesByNamespace: Record<string, Record<string, StorageTable>> = {};\n const tableNameToNamespaceId = new Map<string, string>();\n const modelNameToNamespaceId = new Map<string, string>();\n const executionDefaults: ExecutionMutationDefault[] = [];\n const modelsByNamespace: Record<string, Record<string, ContractModel>> = {};\n const roots: Record<string, CrossReference> = {};\n\n for (const semanticModel of definition.models) {\n const tableName = semanticModel.tableName;\n const namespaceId =\n semanticModel.namespaceId !== undefined && semanticModel.namespaceId.length > 0\n ? semanticModel.namespaceId\n : defaultModelNamespaceId(target);\n modelNameToNamespaceId.set(semanticModel.modelName, namespaceId);\n roots[tableName] = crossRef(semanticModel.modelName, namespaceId);\n\n // --- Build storage table ---\n\n const columns: Record<string, StorageColumn> = {};\n const fieldToColumn: Record<string, string> = {};\n const domainFields: Record<string, ContractField> = {};\n const domainFieldRefs: Record<string, DomainFieldRef> = {};\n\n for (const field of semanticModel.fields) {\n const executionDefaultPhases =\n field.executionDefaults?.onCreate || field.executionDefaults?.onUpdate\n ? field.executionDefaults\n : undefined;\n if (executionDefaultPhases) {\n if (field.default !== undefined) {\n throw new Error(\n `Field \"${semanticModel.modelName}.${field.fieldName}\" cannot define both default and executionDefaults.`,\n );\n }\n if (field.nullable) {\n throw new Error(\n `Field \"${semanticModel.modelName}.${field.fieldName}\" cannot be nullable when executionDefaults are present.`,\n );\n }\n }\n\n const column = buildStorageColumn(field, codecLookup);\n columns[field.columnName] = column;\n fieldToColumn[field.fieldName] = field.columnName;\n\n domainFields[field.fieldName] = buildDomainField(field, column);\n\n if (isValueObjectField(field)) {\n domainFieldRefs[field.fieldName] = {\n kind: 'valueObject',\n name: field.valueObjectName,\n ...(field.many ? { many: true } : {}),\n };\n } else if (field.many) {\n domainFieldRefs[field.fieldName] = { kind: 'scalar', many: true };\n }\n\n if (executionDefaultPhases) {\n executionDefaults.push({\n ref: { table: tableName, column: field.columnName },\n ...ifDefined('onCreate', executionDefaultPhases.onCreate),\n ...ifDefined('onUpdate', executionDefaultPhases.onUpdate),\n });\n }\n }\n\n const foreignKeys = (semanticModel.foreignKeys ?? []).map((fk) => {\n const targetModel = assertKnownTargetModel(\n modelsByName,\n semanticModel.modelName,\n fk.references.model,\n 'Foreign key',\n );\n assertTargetTableMatches(\n semanticModel.modelName,\n targetModel,\n fk.references.table,\n 'Foreign key',\n );\n const targetNamespaceId =\n fk.references.namespaceId ??\n (targetModel.namespaceId !== undefined && targetModel.namespaceId.length > 0\n ? targetModel.namespaceId\n : defaultModelNamespaceId(target));\n return {\n source: { namespaceId: asNamespaceId(namespaceId), tableName, columns: fk.columns },\n target: {\n namespaceId: asNamespaceId(targetNamespaceId),\n tableName: fk.references.table,\n columns: fk.references.columns,\n },\n ...applyFkDefaults(\n {\n ...ifDefined('constraint', fk.constraint),\n ...ifDefined('index', fk.index),\n },\n definition.foreignKeyDefaults,\n ),\n ...ifDefined('name', fk.name),\n ...ifDefined('onDelete', fk.onDelete),\n ...ifDefined('onUpdate', fk.onUpdate),\n };\n });\n\n const existingNs = tableNameToNamespaceId.get(tableName);\n if (existingNs !== undefined && existingNs !== namespaceId) {\n throw new Error(\n `buildSqlContractFromDefinition: table \"${tableName}\" is mapped in namespace \"${namespaceId}\" but already exists in namespace \"${existingNs}\".`,\n );\n }\n tableNameToNamespaceId.set(tableName, namespaceId);\n\n const tableInput: StorageTableInput = {\n columns,\n uniques: (semanticModel.uniques ?? []).map((u) => ({\n columns: u.columns,\n ...ifDefined('name', u.name),\n })),\n indexes: (semanticModel.indexes ?? []).map((i) => ({\n columns: i.columns,\n ...ifDefined('name', i.name),\n ...ifDefined('type', i.type),\n ...ifDefined('options', i.options),\n })),\n foreignKeys,\n ...(semanticModel.id\n ? {\n primaryKey: {\n columns: semanticModel.id.columns,\n ...ifDefined('name', semanticModel.id.name),\n },\n }\n : {}),\n };\n\n let nsTables = tablesByNamespace[namespaceId];\n if (nsTables === undefined) {\n nsTables = {};\n tablesByNamespace[namespaceId] = nsTables;\n }\n if (nsTables[tableName] !== undefined) {\n throw new Error(\n `buildSqlContractFromDefinition: duplicate table \"${tableName}\" in namespace \"${namespaceId}\".`,\n );\n }\n nsTables[tableName] = new StorageTable(tableInput);\n\n // --- Build contract model ---\n\n const storageFields: Record<string, { readonly column: string }> = {};\n for (const [fieldName, columnName] of Object.entries(fieldToColumn)) {\n storageFields[fieldName] = { column: columnName };\n }\n\n const columnToField = new Map(\n Object.entries(fieldToColumn).map(([field, col]) => [col, field]),\n );\n const modelRelations: Record<string, ContractRelation> = {};\n for (const relation of semanticModel.relations ?? []) {\n const targetModel = assertKnownTargetModel(\n modelsByName,\n semanticModel.modelName,\n relation.toModel,\n 'Relation',\n );\n assertTargetTableMatches(semanticModel.modelName, targetModel, relation.toTable, 'Relation');\n\n if (relation.cardinality === 'N:M' && !relation.through) {\n throw new Error(\n `Relation \"${semanticModel.modelName}.${relation.fieldName}\" with cardinality \"N:M\" requires through metadata`,\n );\n }\n\n const targetColumnToField = new Map(\n targetModel.fields.map((f) => [f.columnName, f.fieldName]),\n );\n\n modelRelations[relation.fieldName] = {\n to: crossRef(\n relation.toModel,\n resolveModelNamespaceId(targetModel, modelNameToNamespaceId, target),\n ),\n // RelationDefinition.cardinality includes 'N:M' which isn't in\n // ContractReferenceRelation yet — cast is needed until the contract\n // type is extended to cover many-to-many.\n cardinality: relation.cardinality as ContractRelation['cardinality'],\n on: {\n localFields: relation.on.parentColumns.map((col) => columnToField.get(col) ?? col),\n targetFields: relation.on.childColumns.map((col) => targetColumnToField.get(col) ?? col),\n },\n ...(relation.through\n ? {\n through: {\n table: relation.through.table,\n parentCols: relation.through.parentColumns,\n childCols: relation.through.childColumns,\n },\n }\n : undefined),\n };\n }\n\n let namespaceModels = modelsByNamespace[namespaceId];\n if (namespaceModels === undefined) {\n namespaceModels = {};\n modelsByNamespace[namespaceId] = namespaceModels;\n }\n namespaceModels[semanticModel.modelName] = {\n storage: {\n table: tableName,\n fields: storageFields,\n },\n fields: domainFields,\n relations: modelRelations,\n };\n }\n\n // --- Assemble contract ---\n\n // Normalise raw codec-triple inputs to the `kind: 'codec-instance'`\n // discriminator shape before hashing so the storageHash matches the\n // persisted JSON envelope produced from the SqlStorage class instance\n // (which always carries the discriminator).\n const rawStorageTypes = (definition.storageTypes ?? {}) as Record<\n string,\n StorageTypeInstance | PostgresEnumStorageEntry\n >;\n const storageTypes = Object.fromEntries(\n Object.entries(rawStorageTypes).map(([name, entry]) => {\n if (isPostgresEnumStorageEntry(entry)) return [name, entry];\n if ((entry as { kind?: unknown }).kind === 'codec-instance') return [name, entry];\n return [\n name,\n toStorageTypeInstance({\n codecId: entry.codecId,\n nativeType: entry.nativeType,\n typeParams: (entry as { typeParams?: Record<string, unknown> }).typeParams ?? {},\n }),\n ];\n }),\n );\n const { documentTypes, namespaceEnumTypesById } = partitionStorageTypesForTarget(\n target,\n storageTypes,\n definition.namespaceTypes,\n );\n const namespaceCoordinateIds = collectStorageNamespaceCoordinateIds(definition);\n for (const id of Object.keys(namespaceEnumTypesById)) {\n namespaceCoordinateIds.add(id);\n }\n const { createNamespace } = definition;\n const namespaces = blindCast<\n SqlStorageInput['namespaces'],\n 'contract authoring materialises each namespace coordinate from the model set and explicit namespace list'\n >(\n Object.fromEntries(\n [...namespaceCoordinateIds].sort().map((id) => {\n const enumTypes = namespaceEnumTypesById[id];\n const nsInput: SqlNamespaceTablesInput = {\n id,\n tables: tablesByNamespace[id] ?? {},\n ...ifDefined('enum', enumTypes),\n };\n return [id, createNamespace ? createNamespace(nsInput) : buildSqlNamespace(nsInput)];\n }),\n ),\n );\n const storageWithoutHash = {\n ...(Object.keys(documentTypes).length > 0 ? { types: documentTypes } : {}),\n namespaces,\n };\n const storageHash: StorageHashBase<string> = definition.storageHash\n ? coreHash(definition.storageHash)\n : computeStorageHash({\n target,\n targetFamily,\n storage: storageWithoutHash as Record<string, unknown>,\n ...sqlContractCanonicalizationHooks,\n });\n const storage = new SqlStorage({ ...storageWithoutHash, storageHash });\n\n const executionSection =\n executionDefaults.length > 0\n ? {\n mutations: {\n defaults: executionDefaults.sort((a, b) => {\n const tableCompare = a.ref.table.localeCompare(b.ref.table);\n if (tableCompare !== 0) {\n return tableCompare;\n }\n return a.ref.column.localeCompare(b.ref.column);\n }),\n },\n }\n : undefined;\n\n const extensionNamespaces = definition.extensionPacks\n ? Object.values(definition.extensionPacks).map((pack) => pack.id)\n : undefined;\n\n const extensionPacks: Record<string, unknown> = { ...(definition.extensionPacks || {}) };\n if (extensionNamespaces) {\n for (const namespace of extensionNamespaces) {\n if (!Object.hasOwn(extensionPacks, namespace)) {\n extensionPacks[namespace] = {};\n }\n }\n }\n\n const extensionPackCapabilitySources = definition.extensionPacks\n ? Object.values(definition.extensionPacks).map(\n (pack) => pack.capabilities as CapabilityMatrix | undefined,\n )\n : [];\n const capabilities = mergeCapabilityMatrices(\n definition.target.capabilities as CapabilityMatrix | undefined,\n ...extensionPackCapabilitySources,\n );\n // Internal `profileHash` computation is unchanged from `origin/main`: it\n // continues to fingerprint the author-declared capability subset. With\n // `capabilities` removed from the `defineContract` input that subset is\n // now always empty, so the hash naturally stabilises at `hash({})`.\n const profileHash = computeProfileHash({\n target,\n targetFamily,\n capabilities: {},\n });\n\n const executionWithHash = executionSection\n ? {\n ...executionSection,\n executionHash: computeExecutionHash({ target, targetFamily, execution: executionSection }),\n }\n : undefined;\n\n const valueObjects: Record<string, ContractValueObject> | undefined =\n definition.valueObjects && definition.valueObjects.length > 0\n ? Object.fromEntries(\n definition.valueObjects.map((vo) => [\n vo.name,\n {\n fields: Object.fromEntries(\n vo.fields.map((f) => [\n f.fieldName,\n isValueObjectField(f)\n ? {\n type: { kind: 'valueObject' as const, name: f.valueObjectName },\n nullable: f.nullable,\n ...(f.many ? { many: true } : {}),\n }\n : {\n type: {\n kind: 'scalar' as const,\n codecId: f.descriptor.codecId,\n ...ifDefined('typeParams', f.descriptor.typeParams),\n },\n nullable: f.nullable,\n },\n ]),\n ),\n },\n ]),\n )\n : undefined;\n\n const defaultNamespaceId = defaultModelNamespaceId(target);\n const domainNamespaceIds = new Set(Object.keys(modelsByNamespace));\n if (domainNamespaceIds.size === 0) {\n domainNamespaceIds.add(defaultNamespaceId);\n }\n if (valueObjects !== undefined) {\n domainNamespaceIds.add(defaultNamespaceId);\n }\n const domainNamespaces = Object.fromEntries(\n [...domainNamespaceIds].sort().map((namespaceId) => {\n const modelsInNs = modelsByNamespace[namespaceId] ?? {};\n const namespaceSlice =\n namespaceId === defaultNamespaceId && valueObjects !== undefined\n ? { models: modelsInNs, valueObjects }\n : { models: modelsInNs };\n return [namespaceId, namespaceSlice];\n }),\n );\n\n const contract: Contract<SqlStorage> = {\n target,\n targetFamily,\n domain: { namespaces: domainNamespaces },\n roots,\n storage,\n ...(executionWithHash ? { execution: executionWithHash } : {}),\n extensionPacks,\n capabilities,\n profileHash,\n meta: {},\n };\n\n assertStorageSemantics(definition, contract);\n\n return contract;\n}\n"],"mappings":"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"}