@prisma-next/sql-contract-ts 0.13.0-dev.28 → 0.13.0-dev.29
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.
- package/README.md +7 -4
- package/dist/{build-contract-BF35hPhu.mjs → build-contract-Bu6zubET.mjs} +5 -39
- package/dist/build-contract-Bu6zubET.mjs.map +1 -0
- package/dist/config-types.mjs +1 -1
- package/dist/contract-builder.d.mts +13 -28
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +3 -3
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +10 -10
- package/src/build-contract.ts +3 -70
- package/src/contract-builder.ts +11 -24
- package/src/contract-definition.ts +3 -23
- package/src/contract-dsl.ts +2 -9
- package/src/contract-lowering.ts +12 -24
- package/src/contract-warnings.ts +3 -6
- package/dist/build-contract-BF35hPhu.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/sql-contract-ts",
|
|
3
|
-
"version": "0.13.0-dev.
|
|
3
|
+
"version": "0.13.0-dev.29",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "SQL-specific TypeScript contract authoring surface for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/config": "0.13.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.13.0-dev.
|
|
11
|
-
"@prisma-next/contract-authoring": "0.13.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.13.0-dev.
|
|
13
|
-
"@prisma-next/sql-contract": "0.13.0-dev.
|
|
14
|
-
"@prisma-next/utils": "0.13.0-dev.
|
|
9
|
+
"@prisma-next/config": "0.13.0-dev.29",
|
|
10
|
+
"@prisma-next/contract": "0.13.0-dev.29",
|
|
11
|
+
"@prisma-next/contract-authoring": "0.13.0-dev.29",
|
|
12
|
+
"@prisma-next/framework-components": "0.13.0-dev.29",
|
|
13
|
+
"@prisma-next/sql-contract": "0.13.0-dev.29",
|
|
14
|
+
"@prisma-next/utils": "0.13.0-dev.29",
|
|
15
15
|
"arktype": "^2.2.0",
|
|
16
16
|
"pathe": "^2.0.3",
|
|
17
17
|
"ts-toolbelt": "^9.6.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@prisma-next/test-utils": "0.13.0-dev.
|
|
21
|
-
"@prisma-next/tsconfig": "0.13.0-dev.
|
|
20
|
+
"@prisma-next/test-utils": "0.13.0-dev.29",
|
|
21
|
+
"@prisma-next/tsconfig": "0.13.0-dev.29",
|
|
22
22
|
"@types/pg": "8.20.0",
|
|
23
23
|
"pg": "8.21.0",
|
|
24
|
-
"@prisma-next/tsdown": "0.13.0-dev.
|
|
24
|
+
"@prisma-next/tsdown": "0.13.0-dev.29",
|
|
25
25
|
"tsdown": "0.22.1",
|
|
26
26
|
"typescript": "5.9.3",
|
|
27
27
|
"vitest": "4.1.8"
|
package/src/build-contract.ts
CHANGED
|
@@ -35,8 +35,6 @@ import {
|
|
|
35
35
|
applyFkDefaults,
|
|
36
36
|
buildSqlNamespace,
|
|
37
37
|
type CheckConstraintInput,
|
|
38
|
-
isPostgresEnumStorageEntry,
|
|
39
|
-
type PostgresEnumStorageEntry,
|
|
40
38
|
type SqlNamespaceTablesInput,
|
|
41
39
|
SqlStorage,
|
|
42
40
|
type SqlStorageInput,
|
|
@@ -319,55 +317,6 @@ function ensureUnboundNamespaceSlot(
|
|
|
319
317
|
});
|
|
320
318
|
}
|
|
321
319
|
|
|
322
|
-
const POSTGRES_ENUM_NAMESPACE_ID = 'public';
|
|
323
|
-
|
|
324
|
-
function partitionStorageTypesForTarget(
|
|
325
|
-
targetId: string,
|
|
326
|
-
types: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
|
|
327
|
-
namespaceTypes?: Readonly<Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>>,
|
|
328
|
-
): {
|
|
329
|
-
readonly documentTypes: Record<string, StorageTypeInstance>;
|
|
330
|
-
readonly namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>>;
|
|
331
|
-
} {
|
|
332
|
-
const documentTypes: Record<string, StorageTypeInstance> = {};
|
|
333
|
-
const namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>> = {};
|
|
334
|
-
for (const [name, entry] of Object.entries(types)) {
|
|
335
|
-
if (isPostgresEnumStorageEntry(entry)) {
|
|
336
|
-
if (targetId !== 'postgres') {
|
|
337
|
-
throw new Error(
|
|
338
|
-
`buildSqlContractFromDefinition: postgres enum "${name}" is only valid when target is "postgres" (got "${targetId}").`,
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
let slot = namespaceEnumTypesById[POSTGRES_ENUM_NAMESPACE_ID];
|
|
342
|
-
if (slot === undefined) {
|
|
343
|
-
slot = {};
|
|
344
|
-
namespaceEnumTypesById[POSTGRES_ENUM_NAMESPACE_ID] = slot;
|
|
345
|
-
}
|
|
346
|
-
slot[name] = entry;
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
documentTypes[name] = entry;
|
|
350
|
-
}
|
|
351
|
-
if (namespaceTypes !== undefined) {
|
|
352
|
-
for (const [nsId, enumsInNs] of Object.entries(namespaceTypes)) {
|
|
353
|
-
for (const [name, entry] of Object.entries(enumsInNs)) {
|
|
354
|
-
if (targetId !== 'postgres') {
|
|
355
|
-
throw new Error(
|
|
356
|
-
`buildSqlContractFromDefinition: postgres enum "${name}" is only valid when target is "postgres" (got "${targetId}").`,
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
let slot = namespaceEnumTypesById[nsId];
|
|
360
|
-
if (slot === undefined) {
|
|
361
|
-
slot = {};
|
|
362
|
-
namespaceEnumTypesById[nsId] = slot;
|
|
363
|
-
}
|
|
364
|
-
slot[name] = entry;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
return { documentTypes, namespaceEnumTypesById };
|
|
369
|
-
}
|
|
370
|
-
|
|
371
320
|
export function buildSqlContractFromDefinition(
|
|
372
321
|
definition: ContractDefinition,
|
|
373
322
|
codecLookup?: CodecLookup,
|
|
@@ -722,13 +671,9 @@ export function buildSqlContractFromDefinition(
|
|
|
722
671
|
// discriminator shape before hashing so the storageHash matches the
|
|
723
672
|
// persisted JSON envelope produced from the SqlStorage class instance
|
|
724
673
|
// (which always carries the discriminator).
|
|
725
|
-
const rawStorageTypes =
|
|
726
|
-
|
|
727
|
-
StorageTypeInstance | PostgresEnumStorageEntry
|
|
728
|
-
>;
|
|
729
|
-
const storageTypes = Object.fromEntries(
|
|
674
|
+
const rawStorageTypes = definition.storageTypes ?? {};
|
|
675
|
+
const documentTypes: Record<string, StorageTypeInstance> = Object.fromEntries(
|
|
730
676
|
Object.entries(rawStorageTypes).map(([name, entry]) => {
|
|
731
|
-
if (isPostgresEnumStorageEntry(entry)) return [name, entry];
|
|
732
677
|
if ((entry as { kind?: unknown }).kind === 'codec-instance') return [name, entry];
|
|
733
678
|
return [
|
|
734
679
|
name,
|
|
@@ -740,15 +685,7 @@ export function buildSqlContractFromDefinition(
|
|
|
740
685
|
];
|
|
741
686
|
}),
|
|
742
687
|
);
|
|
743
|
-
const { documentTypes, namespaceEnumTypesById } = partitionStorageTypesForTarget(
|
|
744
|
-
target,
|
|
745
|
-
storageTypes,
|
|
746
|
-
definition.namespaceTypes,
|
|
747
|
-
);
|
|
748
688
|
const namespaceCoordinateIds = collectStorageNamespaceCoordinateIds(definition);
|
|
749
|
-
for (const id of Object.keys(namespaceEnumTypesById)) {
|
|
750
|
-
namespaceCoordinateIds.add(id);
|
|
751
|
-
}
|
|
752
689
|
|
|
753
690
|
// Build per-namespace registries for `enumType()` handles.
|
|
754
691
|
// All authored enums target the contract's default namespace.
|
|
@@ -792,7 +729,6 @@ export function buildSqlContractFromDefinition(
|
|
|
792
729
|
>(
|
|
793
730
|
Object.fromEntries(
|
|
794
731
|
[...namespaceCoordinateIds].sort().map((id) => {
|
|
795
|
-
const enumTypes = namespaceEnumTypesById[id];
|
|
796
732
|
const valueSetEntries = storageValueSetsByNs[id];
|
|
797
733
|
const nsInput: SqlNamespaceTablesInput = {
|
|
798
734
|
id,
|
|
@@ -803,10 +739,7 @@ export function buildSqlContractFromDefinition(
|
|
|
803
739
|
: {}),
|
|
804
740
|
},
|
|
805
741
|
};
|
|
806
|
-
return [
|
|
807
|
-
id,
|
|
808
|
-
createNamespace ? createNamespace(nsInput, enumTypes) : buildSqlNamespace(nsInput),
|
|
809
|
-
];
|
|
742
|
+
return [id, createNamespace ? createNamespace(nsInput) : buildSqlNamespace(nsInput)];
|
|
810
743
|
}),
|
|
811
744
|
),
|
|
812
745
|
);
|
package/src/contract-builder.ts
CHANGED
|
@@ -7,11 +7,7 @@ import type {
|
|
|
7
7
|
TargetPackRef,
|
|
8
8
|
} from '@prisma-next/framework-components/components';
|
|
9
9
|
import type { Namespace } from '@prisma-next/framework-components/ir';
|
|
10
|
-
import type {
|
|
11
|
-
PostgresEnumStorageEntry,
|
|
12
|
-
SqlNamespaceTablesInput,
|
|
13
|
-
StorageTypeInstance,
|
|
14
|
-
} from '@prisma-next/sql-contract/types';
|
|
10
|
+
import type { SqlNamespaceTablesInput, StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
15
11
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
16
12
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
17
13
|
import { buildSqlContractFromDefinition } from './build-contract';
|
|
@@ -55,7 +51,7 @@ type ModelLike = {
|
|
|
55
51
|
type ContractDefinition<
|
|
56
52
|
Family extends FamilyPackRef<string>,
|
|
57
53
|
Target extends TargetPackRef<'sql', string>,
|
|
58
|
-
Types extends Record<string, StorageTypeInstance
|
|
54
|
+
Types extends Record<string, StorageTypeInstance>,
|
|
59
55
|
Models extends Record<string, ModelLike>,
|
|
60
56
|
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
61
57
|
Naming extends ContractInput['naming'] | undefined,
|
|
@@ -107,7 +103,7 @@ type ContractScaffold<
|
|
|
107
103
|
type ContractFactory<
|
|
108
104
|
Family extends FamilyPackRef<string>,
|
|
109
105
|
Target extends TargetPackRef<'sql', string>,
|
|
110
|
-
Types extends Record<string, StorageTypeInstance
|
|
106
|
+
Types extends Record<string, StorageTypeInstance>,
|
|
111
107
|
Models extends Record<string, ModelLike>,
|
|
112
108
|
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
113
109
|
Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
|
|
@@ -304,10 +300,7 @@ function buildContractFromDsl<Definition extends ContractInput>(
|
|
|
304
300
|
// Input for buildBoundContract — all fields from ContractInput except family/target
|
|
305
301
|
// (those are injected by the builder, pre-bound at the call site).
|
|
306
302
|
type BoundDefinitionInput<
|
|
307
|
-
Types extends Record<string, StorageTypeInstance
|
|
308
|
-
never,
|
|
309
|
-
never
|
|
310
|
-
>,
|
|
303
|
+
Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
311
304
|
Models extends Record<string, ModelLike> = Record<never, never>,
|
|
312
305
|
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined,
|
|
313
306
|
Naming extends ContractInput['naming'] | undefined = undefined,
|
|
@@ -361,7 +354,7 @@ export function buildBoundContract<
|
|
|
361
354
|
const F extends FamilyPackRef<string>,
|
|
362
355
|
const T extends TargetPackRef<'sql', string>,
|
|
363
356
|
const Definition extends BoundDefinitionInput<
|
|
364
|
-
Record<string, StorageTypeInstance
|
|
357
|
+
Record<string, StorageTypeInstance>,
|
|
365
358
|
Record<string, ModelLike>,
|
|
366
359
|
Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
367
360
|
ContractInput['naming'] | undefined,
|
|
@@ -382,7 +375,7 @@ export function buildBoundContract<
|
|
|
382
375
|
const F extends FamilyPackRef<string>,
|
|
383
376
|
const T extends TargetPackRef<'sql', string>,
|
|
384
377
|
const Definition extends BoundDefinitionInput<
|
|
385
|
-
Record<string, StorageTypeInstance
|
|
378
|
+
Record<string, StorageTypeInstance>,
|
|
386
379
|
Record<string, ModelLike>,
|
|
387
380
|
Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
388
381
|
ContractInput['naming'] | undefined,
|
|
@@ -391,7 +384,7 @@ export function buildBoundContract<
|
|
|
391
384
|
readonly string[] | undefined
|
|
392
385
|
>,
|
|
393
386
|
const Built extends {
|
|
394
|
-
readonly types?: Record<string, StorageTypeInstance
|
|
387
|
+
readonly types?: Record<string, StorageTypeInstance>;
|
|
395
388
|
readonly models?: Record<string, ModelLike>;
|
|
396
389
|
readonly enums?: Record<string, EnumTypeHandle>;
|
|
397
390
|
},
|
|
@@ -416,7 +409,7 @@ export function buildBoundContract(
|
|
|
416
409
|
Record<string, ExtensionPackRef<'sql', string>> | undefined
|
|
417
410
|
>,
|
|
418
411
|
) => {
|
|
419
|
-
readonly types?: Record<string, StorageTypeInstance
|
|
412
|
+
readonly types?: Record<string, StorageTypeInstance>;
|
|
420
413
|
readonly models?: Record<string, ModelLike>;
|
|
421
414
|
readonly enums?: Record<string, EnumTypeHandle>;
|
|
422
415
|
})
|
|
@@ -447,10 +440,7 @@ export function buildBoundContract(
|
|
|
447
440
|
export function defineContract<
|
|
448
441
|
const Family extends FamilyPackRef<string>,
|
|
449
442
|
const Target extends TargetPackRef<'sql', string>,
|
|
450
|
-
const Types extends Record<string, StorageTypeInstance
|
|
451
|
-
never,
|
|
452
|
-
never
|
|
453
|
-
>,
|
|
443
|
+
const Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
454
444
|
const Models extends Record<string, ModelLike> = Record<never, never>,
|
|
455
445
|
const ExtensionPacks extends
|
|
456
446
|
| Record<string, ExtensionPackRef<'sql', string>>
|
|
@@ -490,10 +480,7 @@ export function defineContract<
|
|
|
490
480
|
export function defineContract<
|
|
491
481
|
const Family extends FamilyPackRef<string>,
|
|
492
482
|
const Target extends TargetPackRef<'sql', string>,
|
|
493
|
-
const Types extends Record<string, StorageTypeInstance
|
|
494
|
-
never,
|
|
495
|
-
never
|
|
496
|
-
>,
|
|
483
|
+
const Types extends Record<string, StorageTypeInstance> = Record<never, never>,
|
|
497
484
|
const Models extends Record<string, ModelLike> = Record<never, never>,
|
|
498
485
|
const ExtensionPacks extends
|
|
499
486
|
| Record<string, ExtensionPackRef<'sql', string>>
|
|
@@ -535,7 +522,7 @@ export function defineContract(
|
|
|
535
522
|
factory?: ContractFactory<
|
|
536
523
|
FamilyPackRef<string>,
|
|
537
524
|
TargetPackRef<'sql', string>,
|
|
538
|
-
Record<string, StorageTypeInstance
|
|
525
|
+
Record<string, StorageTypeInstance>,
|
|
539
526
|
Record<string, ModelLike>,
|
|
540
527
|
Record<string, ExtensionPackRef<'sql', string>> | undefined
|
|
541
528
|
>,
|
|
@@ -8,7 +8,6 @@ import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/cod
|
|
|
8
8
|
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
|
|
9
9
|
import type { Namespace } from '@prisma-next/framework-components/ir';
|
|
10
10
|
import type {
|
|
11
|
-
PostgresEnumStorageEntry,
|
|
12
11
|
ReferentialAction,
|
|
13
12
|
SqlNamespaceTablesInput,
|
|
14
13
|
StorageTypeInstance,
|
|
@@ -162,33 +161,14 @@ export interface ContractDefinition {
|
|
|
162
161
|
readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
|
|
163
162
|
readonly storageHash?: string;
|
|
164
163
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
165
|
-
readonly storageTypes?: Record<string, StorageTypeInstance
|
|
166
|
-
/**
|
|
167
|
-
* Enum types declared inside a named `namespace { enum … }` block,
|
|
168
|
-
* keyed first by namespace id then by type name. These are routed to
|
|
169
|
-
* `storage.namespaces[nsId].entries.type` rather than the implicit fallback
|
|
170
|
-
* namespace used for top-level `storageTypes` enums.
|
|
171
|
-
*/
|
|
172
|
-
readonly namespaceTypes?: Readonly<
|
|
173
|
-
Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>
|
|
174
|
-
>;
|
|
164
|
+
readonly storageTypes?: Record<string, StorageTypeInstance>;
|
|
175
165
|
/**
|
|
176
166
|
* Declared namespace coordinates for this contract — populates
|
|
177
167
|
* `SqlStorage.namespaces` together with `createNamespace`.
|
|
178
168
|
*/
|
|
179
169
|
readonly namespaces?: readonly string[];
|
|
180
|
-
/**
|
|
181
|
-
|
|
182
|
-
* for a declared namespace coordinate. Mirrors
|
|
183
|
-
* `ContractInput.createNamespace`.
|
|
184
|
-
*
|
|
185
|
-
* The optional second argument carries target-specific enum types for the
|
|
186
|
-
* namespace (e.g. postgres enum registrations keyed by type name).
|
|
187
|
-
*/
|
|
188
|
-
readonly createNamespace?: (
|
|
189
|
-
input: SqlNamespaceTablesInput,
|
|
190
|
-
enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,
|
|
191
|
-
) => Namespace;
|
|
170
|
+
/** Target-supplied factory that materialises a `Namespace` concretion for a declared namespace coordinate. */
|
|
171
|
+
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
192
172
|
readonly models: readonly ModelNode[];
|
|
193
173
|
readonly valueObjects?: readonly ValueObjectNode[];
|
|
194
174
|
/**
|
package/src/contract-dsl.ts
CHANGED
|
@@ -16,11 +16,7 @@ import type {
|
|
|
16
16
|
TargetPackRef,
|
|
17
17
|
} from '@prisma-next/framework-components/components';
|
|
18
18
|
import type { Namespace } from '@prisma-next/framework-components/ir';
|
|
19
|
-
import type {
|
|
20
|
-
PostgresEnumStorageEntry,
|
|
21
|
-
SqlNamespaceTablesInput,
|
|
22
|
-
StorageTypeInstance,
|
|
23
|
-
} from '@prisma-next/sql-contract/types';
|
|
19
|
+
import type { SqlNamespaceTablesInput, StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
24
20
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
25
21
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
26
22
|
import type { NamedConstraintSpec } from './authoring-type-utils';
|
|
@@ -34,7 +30,7 @@ export type NamingConfig = {
|
|
|
34
30
|
readonly columns?: NamingStrategy;
|
|
35
31
|
};
|
|
36
32
|
|
|
37
|
-
type NamedStorageTypeRef = string | StorageTypeInstance |
|
|
33
|
+
type NamedStorageTypeRef = string | StorageTypeInstance | EnumTypeHandle;
|
|
38
34
|
|
|
39
35
|
type NamedConstraintNameSpec<Name extends string = string> = {
|
|
40
36
|
readonly name: Name;
|
|
@@ -398,9 +394,6 @@ function namedTypeField<TypeRef extends string>(
|
|
|
398
394
|
function namedTypeField<TypeRef extends StorageTypeInstance>(
|
|
399
395
|
typeRef: TypeRef,
|
|
400
396
|
): ScalarFieldBuilder<ScalarFieldState<TypeRef['codecId'], TypeRef, false, undefined>>;
|
|
401
|
-
function namedTypeField<TypeRef extends PostgresEnumStorageEntry>(
|
|
402
|
-
typeRef: TypeRef,
|
|
403
|
-
): ScalarFieldBuilder<ScalarFieldState<string, TypeRef, false, undefined>>;
|
|
404
397
|
function namedTypeField<Handle extends EnumTypeHandle>(
|
|
405
398
|
typeRef: Handle,
|
|
406
399
|
): EnumScalarFieldBuilder<Handle>;
|
package/src/contract-lowering.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/codec';
|
|
2
2
|
import type { ExtensionPackRef } from '@prisma-next/framework-components/components';
|
|
3
|
-
import {
|
|
4
|
-
isPostgresEnumStorageEntry,
|
|
5
|
-
type PostgresEnumStorageEntry,
|
|
6
|
-
type StorageTypeInstance,
|
|
7
|
-
} from '@prisma-next/sql-contract/types';
|
|
3
|
+
import type { StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
8
4
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
9
5
|
import type {
|
|
10
6
|
ContractDefinition,
|
|
@@ -59,15 +55,15 @@ type RuntimeModelSpec = {
|
|
|
59
55
|
};
|
|
60
56
|
|
|
61
57
|
type RuntimeCollection = {
|
|
62
|
-
readonly storageTypes: Record<string, StorageTypeInstance
|
|
58
|
+
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
63
59
|
readonly models: Record<string, RuntimeModel>;
|
|
64
60
|
readonly modelSpecs: ReadonlyMap<string, RuntimeModelSpec>;
|
|
65
61
|
};
|
|
66
62
|
|
|
67
63
|
function buildStorageTypeReverseLookup(
|
|
68
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
69
|
-
): ReadonlyMap<StorageTypeInstance
|
|
70
|
-
const lookup = new Map<StorageTypeInstance
|
|
64
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
65
|
+
): ReadonlyMap<StorageTypeInstance, string> {
|
|
66
|
+
const lookup = new Map<StorageTypeInstance, string>();
|
|
71
67
|
for (const [key, instance] of Object.entries(storageTypes)) {
|
|
72
68
|
lookup.set(instance, key);
|
|
73
69
|
}
|
|
@@ -78,8 +74,8 @@ function resolveFieldDescriptor(
|
|
|
78
74
|
modelName: string,
|
|
79
75
|
fieldName: string,
|
|
80
76
|
fieldState: FieldStateOf<ScalarFieldBuilder>,
|
|
81
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
82
|
-
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance
|
|
77
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
78
|
+
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance, string>,
|
|
83
79
|
): ColumnTypeDescriptor {
|
|
84
80
|
if ('descriptor' in fieldState && fieldState.descriptor) {
|
|
85
81
|
return fieldState.descriptor;
|
|
@@ -96,9 +92,7 @@ function resolveFieldDescriptor(
|
|
|
96
92
|
const typeRef =
|
|
97
93
|
typeof fieldState.typeRef === 'string'
|
|
98
94
|
? fieldState.typeRef
|
|
99
|
-
: storageTypeReverseLookup.get(
|
|
100
|
-
fieldState.typeRef as StorageTypeInstance | PostgresEnumStorageEntry,
|
|
101
|
-
);
|
|
95
|
+
: storageTypeReverseLookup.get(fieldState.typeRef as StorageTypeInstance);
|
|
102
96
|
|
|
103
97
|
if (!typeRef) {
|
|
104
98
|
throw new Error(
|
|
@@ -113,11 +107,8 @@ function resolveFieldDescriptor(
|
|
|
113
107
|
);
|
|
114
108
|
}
|
|
115
109
|
|
|
116
|
-
const codecId = isPostgresEnumStorageEntry(referencedType)
|
|
117
|
-
? referencedType.codecId
|
|
118
|
-
: referencedType.codecId;
|
|
119
110
|
return {
|
|
120
|
-
codecId,
|
|
111
|
+
codecId: referencedType.codecId,
|
|
121
112
|
nativeType: referencedType.nativeType,
|
|
122
113
|
typeRef,
|
|
123
114
|
};
|
|
@@ -705,8 +696,8 @@ function resolveForeignKeyNodes(
|
|
|
705
696
|
function resolveModelNode(
|
|
706
697
|
spec: RuntimeModelSpec,
|
|
707
698
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
708
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
709
|
-
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance
|
|
699
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
700
|
+
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance, string>,
|
|
710
701
|
extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>,
|
|
711
702
|
): ModelNode {
|
|
712
703
|
const fields: FieldNode[] = [];
|
|
@@ -783,10 +774,7 @@ function resolveModelNode(
|
|
|
783
774
|
}
|
|
784
775
|
|
|
785
776
|
function collectRuntimeModelSpecs(definition: ContractInput): RuntimeCollection {
|
|
786
|
-
const storageTypes = { ...(definition.types ?? {}) } as Record<
|
|
787
|
-
string,
|
|
788
|
-
StorageTypeInstance | PostgresEnumStorageEntry
|
|
789
|
-
>;
|
|
777
|
+
const storageTypes = { ...(definition.types ?? {}) } as Record<string, StorageTypeInstance>;
|
|
790
778
|
const models = { ...(definition.models ?? {}) } as Record<string, RuntimeModel>;
|
|
791
779
|
|
|
792
780
|
emitTypedNamedTypeFallbackWarnings(models, storageTypes);
|
package/src/contract-warnings.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
PostgresEnumStorageEntry,
|
|
3
|
-
StorageTypeInstance,
|
|
4
|
-
} from '@prisma-next/sql-contract/types';
|
|
1
|
+
import type { StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
5
2
|
import {
|
|
6
3
|
type ContractModelBuilder,
|
|
7
4
|
type ModelAttributesSpec,
|
|
@@ -28,7 +25,7 @@ type RuntimeModelSpec = {
|
|
|
28
25
|
};
|
|
29
26
|
|
|
30
27
|
type RuntimeCollection = {
|
|
31
|
-
readonly storageTypes: Record<string, StorageTypeInstance
|
|
28
|
+
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
32
29
|
readonly models: Record<string, RuntimeModel>;
|
|
33
30
|
readonly modelSpecs: ReadonlyMap<string, RuntimeModelSpec>;
|
|
34
31
|
};
|
|
@@ -136,7 +133,7 @@ function formatFallbackWarning(location: string, current: string, suggested: str
|
|
|
136
133
|
|
|
137
134
|
export function emitTypedNamedTypeFallbackWarnings(
|
|
138
135
|
models: Record<string, RuntimeModel>,
|
|
139
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
136
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
140
137
|
): void {
|
|
141
138
|
const warnings: string[] = [];
|
|
142
139
|
const warnedFields = new Set<string>();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-contract-BF35hPhu.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 Contract,\n type ContractEnum,\n type ContractField,\n type ContractModel,\n type ContractRelation,\n type ContractRelationThrough,\n type ContractValueObject,\n type CrossReference,\n coreHash,\n crossRef,\n type ExecutionMutationDefault,\n type JsonValue,\n type StorageHashBase,\n type ValueSetRef,\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 type CheckConstraintInput,\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type SqlNamespaceTablesInput,\n SqlStorage,\n type SqlStorageInput,\n type StorageColumn,\n type StorageTableInput,\n type StorageTypeInstance,\n type StorageValueSetInput,\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 RelationNode,\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 encodeViaCodec(value: unknown, codecId: string, codecLookup?: CodecLookup): JsonValue {\n const codec = codecLookup?.get(codecId);\n if (codec) {\n return codec.encodeJson(value);\n }\n return blindCast<\n JsonValue,\n 'no codec lookup at build time: literal/enum member value is already JSON-safe'\n >(value);\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: encodeViaCodec(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 modelsByCoordinate: ReadonlyMap<string, ModelNode>,\n sourceModelName: string,\n targetModelName: string,\n targetNamespaceId: string | undefined,\n context: string,\n): ModelNode {\n const targetModel =\n targetNamespaceId !== undefined && targetNamespaceId.length > 0\n ? modelsByCoordinate.get(`${targetNamespaceId}:${targetModelName}`)\n : modelsByName.get(targetModelName);\n if (!targetModel) {\n const qualified =\n targetNamespaceId !== undefined && targetNamespaceId.length > 0\n ? `${targetNamespaceId}.${targetModelName}`\n : targetModelName;\n throw new Error(\n `${context} on model \"${sourceModelName}\" references unknown model \"${qualified}\"`,\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 defaultNamespaceId: string,\n): string {\n if (model.namespaceId !== undefined && model.namespaceId.length > 0) {\n return model.namespaceId;\n }\n return modelNameToNamespaceId.get(model.modelName) ?? defaultNamespaceId;\n}\n\nfunction buildThroughDescriptor(\n through: NonNullable<RelationNode['through']>,\n tableNamespaceByName: ReadonlyMap<string, string>,\n targetModel: ModelNode,\n modelName: string,\n fieldName: string,\n): ContractRelationThrough {\n const namespaceId = tableNamespaceByName.get(through.table);\n if (namespaceId === undefined) {\n throw new Error(\n `buildSqlContractFromDefinition: junction table \"${through.table}\" for relation \"${modelName}.${fieldName}\" is not a declared model.`,\n );\n }\n\n return {\n table: through.table,\n namespaceId,\n parentColumns: through.parentColumns,\n childColumns: through.childColumns,\n targetColumns: targetColumnsForJunction(targetModel, fieldName),\n };\n}\n\nfunction targetColumnsForJunction(targetModel: ModelNode, fieldName: string): readonly string[] {\n const primaryKeyColumns = targetModel.id?.columns;\n if (primaryKeyColumns && primaryKeyColumns.length > 0) {\n return primaryKeyColumns;\n }\n const firstUnique = targetModel.uniques?.find((u) => u.columns.length > 0);\n if (firstUnique) {\n return firstUnique.columns;\n }\n throw new Error(\n `M:N target model \"${targetModel.modelName}\" (relation field \"${fieldName}\") has no primary id or unique key to derive junction targetColumns.`,\n );\n}\n\nfunction buildStorageColumn(\n field: FieldNode | ValueObjectFieldNode,\n storageValueSetRef: ValueSetRef | undefined,\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 ...ifDefined('valueSet', storageValueSetRef),\n };\n}\n\nfunction buildDomainField(\n field: FieldNode | ValueObjectFieldNode,\n column: StorageColumn,\n domainValueSetRef: ValueSetRef | undefined,\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 ...ifDefined('valueSet', domainValueSetRef),\n };\n}\n\nfunction collectStorageNamespaceCoordinateIds(definition: ContractDefinition): Set<string> {\n const ids = new Set<string>();\n ids.add(definition.target.defaultNamespaceId);\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\nfunction ensureUnboundNamespaceSlot(\n namespaces: SqlStorageInput['namespaces'],\n createNamespace: ContractDefinition['createNamespace'],\n): SqlStorageInput['namespaces'] {\n if (Object.hasOwn(namespaces, UNBOUND_NAMESPACE_ID)) {\n return namespaces;\n }\n const unboundInput: SqlNamespaceTablesInput = {\n id: UNBOUND_NAMESPACE_ID,\n entries: { table: {} },\n };\n const unbound = createNamespace ? createNamespace(unboundInput) : buildSqlNamespace(unboundInput);\n return blindCast<\n SqlStorageInput['namespaces'],\n 'createNamespace may return a target namespace concretion; the unbound slot matches SqlNamespace at runtime'\n >({\n [UNBOUND_NAMESPACE_ID]: unbound,\n ...namespaces,\n });\n}\n\nconst POSTGRES_ENUM_NAMESPACE_ID = 'public';\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>;\n readonly namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>>;\n} {\n const documentTypes: Record<string, StorageTypeInstance> = {};\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 defaultNamespaceId = definition.target.defaultNamespaceId;\n const targetFamily = 'sql';\n const resolveNamespaceId = (m: ModelNode): string =>\n m.namespaceId !== undefined && m.namespaceId.length > 0 ? m.namespaceId : defaultNamespaceId;\n const modelsByName = new Map(definition.models.map((m) => [m.modelName, m]));\n const tableNamespaceByName = new Map(\n definition.models.map((m) => [\n m.tableName,\n m.namespaceId !== undefined && m.namespaceId.length > 0 ? m.namespaceId : defaultNamespaceId,\n ]),\n );\n const modelsByCoordinate = new Map(\n definition.models.map((m) => [`${resolveNamespaceId(m)}:${m.modelName}`, m]),\n );\n\n const tablesByNamespace: Record<string, Record<string, StorageTableInput>> = {};\n const modelNameToNamespaceId = new Map<string, string>();\n const executionDefaults: ExecutionMutationDefault[] = [];\n const modelsByNamespace: Record<string, Record<string, ContractModel>> = {};\n const rootEntries: Array<{\n readonly tableName: string;\n readonly namespaceId: string;\n readonly ref: CrossReference;\n }> = [];\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 : defaultNamespaceId;\n modelNameToNamespaceId.set(semanticModel.modelName, namespaceId);\n // STI variants share the base table; the base model already owns this\n // table name and its root, so the variant contributes neither.\n if (!semanticModel.sharesBaseTable) {\n rootEntries.push({\n tableName,\n namespaceId,\n ref: crossRef(semanticModel.modelName, namespaceId),\n });\n }\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 enumHandle = !isValueObjectField(field) ? field.enumTypeHandle : undefined;\n // Authored enums are always registered under the contract's defaultNamespaceId\n // (see the enum registration loop below), so refs must point there regardless\n // of which namespace the consuming model lives in.\n const storageValueSetRef: ValueSetRef | undefined =\n enumHandle !== undefined\n ? {\n plane: 'storage',\n entityKind: 'valueSet',\n namespaceId: defaultNamespaceId,\n entityName: enumHandle.enumName,\n }\n : undefined;\n const domainValueSetRef: ValueSetRef | undefined =\n enumHandle !== undefined\n ? {\n plane: 'domain',\n entityKind: 'enum',\n namespaceId: defaultNamespaceId,\n entityName: enumHandle.enumName,\n }\n : undefined;\n\n const column = buildStorageColumn(field, storageValueSetRef, codecLookup);\n columns[field.columnName] = column;\n fieldToColumn[field.fieldName] = field.columnName;\n\n domainFields[field.fieldName] = buildDomainField(field, column, domainValueSetRef);\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 if (fk.references.spaceId !== undefined) {\n // Cross-space FK: the target lives in a different contract space.\n // Skip local model lookup and carry the spaceId coordinate through.\n const targetNamespaceId = fk.references.namespaceId ?? defaultNamespaceId;\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 spaceId: fk.references.spaceId,\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 targetModel = assertKnownTargetModel(\n modelsByName,\n modelsByCoordinate,\n semanticModel.modelName,\n fk.references.model,\n fk.references.namespaceId,\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 : defaultNamespaceId);\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 // STI variants share the base table: their columns are already\n // materialised onto the base `ModelNode`, so the variant builds a domain\n // model (below) but no storage table of its own.\n if (!semanticModel.sharesBaseTable) {\n const checksForTable: CheckConstraintInput[] = Object.entries(columns).flatMap(\n ([columnName, col]) => {\n const valueSet = col.valueSet;\n return valueSet === undefined\n ? []\n : [{ name: `${tableName}_${columnName}_check`, column: columnName, valueSet }];\n },\n );\n\n const tableInput: StorageTableInput = {\n columns,\n ...ifDefined('control', semanticModel.control),\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 ...(checksForTable.length > 0 ? { checks: checksForTable } : {}),\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] = tableInput;\n }\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 // Cross-space relations have `spaceId` set — the target model lives in\n // a different contract space, so skip local model lookup and validation.\n if (relation.spaceId !== undefined) {\n const targetNamespaceId = relation.namespaceId ?? defaultNamespaceId;\n modelRelations[relation.fieldName] = {\n to: crossRef(relation.toModel, targetNamespaceId, relation.spaceId),\n // Cross-space belongsTo relations are always N:1 (the FK-owning side).\n cardinality: 'N:1',\n on: {\n localFields: relation.on.parentColumns.map((col) => columnToField.get(col) ?? col),\n // For cross-space targets the lowering carries field names directly\n // (no fieldToColumn map available for the remote model).\n targetFields: relation.on.childColumns,\n },\n };\n continue;\n }\n\n const targetModel = assertKnownTargetModel(\n modelsByName,\n modelsByCoordinate,\n semanticModel.modelName,\n relation.toModel,\n relation.toNamespaceId,\n 'Relation',\n );\n assertTargetTableMatches(semanticModel.modelName, targetModel, relation.toTable, 'Relation');\n\n const targetColumnToField = new Map(\n targetModel.fields.map((f) => [f.columnName, f.fieldName]),\n );\n\n const to = crossRef(\n relation.toModel,\n relation.toNamespaceId !== undefined && relation.toNamespaceId.length > 0\n ? relation.toNamespaceId\n : resolveModelNamespaceId(targetModel, modelNameToNamespaceId, defaultNamespaceId),\n );\n const 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\n if (relation.cardinality === 'N:M') {\n if (!relation.through) {\n throw new Error(\n `Relation \"${semanticModel.modelName}.${relation.fieldName}\" with cardinality \"N:M\" requires through metadata`,\n );\n }\n modelRelations[relation.fieldName] = {\n to,\n cardinality: 'N:M',\n on,\n through: buildThroughDescriptor(\n relation.through,\n tableNamespaceByName,\n targetModel,\n semanticModel.modelName,\n relation.fieldName,\n ),\n };\n } else {\n modelRelations[relation.fieldName] = { to, cardinality: relation.cardinality, on };\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 namespaceId,\n fields: storageFields,\n },\n fields: domainFields,\n relations: modelRelations,\n };\n }\n\n // --- Assemble contract ---\n\n // Aggregate roots are keyed by bare storage table name. When two models in\n // different namespaces map to the same bare table name, the bare key would\n // collide (last write wins, silently dropping a root), so those entries fall\n // back to a namespace-qualified key. Single-namespace contracts never\n // collide and keep their bare keys unchanged.\n const rootTableNameCounts = new Map<string, number>();\n for (const entry of rootEntries) {\n rootTableNameCounts.set(entry.tableName, (rootTableNameCounts.get(entry.tableName) ?? 0) + 1);\n }\n const roots: Record<string, CrossReference> = {};\n for (const entry of rootEntries) {\n const key =\n (rootTableNameCounts.get(entry.tableName) ?? 0) > 1\n ? `${entry.namespaceId}.${entry.tableName}`\n : entry.tableName;\n roots[key] = entry.ref;\n }\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\n // Build per-namespace registries for `enumType()` handles.\n // All authored enums target the contract's default namespace.\n const domainEnumsByNs: Record<string, Record<string, ContractEnum>> = {};\n const storageValueSetsByNs: Record<string, Record<string, StorageValueSetInput>> = {};\n for (const [enumName, handle] of Object.entries(definition.enums ?? {})) {\n if (enumName !== handle.enumName) {\n throw new Error(\n `enum declaration key \"${enumName}\" must match enumType name \"${handle.enumName}\". Aliases are not supported.`,\n );\n }\n const nsId = defaultNamespaceId;\n let domainSlot = domainEnumsByNs[nsId];\n if (domainSlot === undefined) {\n domainSlot = {};\n domainEnumsByNs[nsId] = domainSlot;\n }\n domainSlot[enumName] = {\n codecId: handle.codecId,\n members: handle.enumMembers.map((m) => ({\n name: m.name,\n value: encodeViaCodec(m.value, handle.codecId, codecLookup),\n })),\n };\n\n let storageSlot = storageValueSetsByNs[nsId];\n if (storageSlot === undefined) {\n storageSlot = {};\n storageValueSetsByNs[nsId] = storageSlot;\n }\n storageSlot[enumName] = {\n kind: 'valueSet',\n values: handle.values.map((v) => encodeViaCodec(v, handle.codecId, codecLookup)),\n };\n }\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 valueSetEntries = storageValueSetsByNs[id];\n const nsInput: SqlNamespaceTablesInput = {\n id,\n entries: {\n table: tablesByNamespace[id] ?? {},\n ...(valueSetEntries !== undefined && Object.keys(valueSetEntries).length > 0\n ? { valueSet: valueSetEntries }\n : {}),\n },\n };\n return [\n id,\n createNamespace ? createNamespace(nsInput, enumTypes) : buildSqlNamespace(nsInput),\n ];\n }),\n ),\n );\n const storageWithoutHash = {\n ...(Object.keys(documentTypes).length > 0 ? { types: documentTypes } : {}),\n namespaces: ensureUnboundNamespaceSlot(namespaces, createNamespace),\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 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 for (const nsId of Object.keys(domainEnumsByNs)) {\n domainNamespaceIds.add(nsId);\n }\n const domainNamespaces = Object.fromEntries(\n [...domainNamespaceIds].sort().map((namespaceId) => {\n const modelsInNs = modelsByNamespace[namespaceId] ?? {};\n const enumsInNs = domainEnumsByNs[namespaceId];\n const namespaceSlice = {\n models: modelsInNs,\n ...(namespaceId === defaultNamespaceId && valueObjects !== undefined\n ? { valueObjects }\n : {}),\n ...(enumsInNs !== undefined && Object.keys(enumsInNs).length > 0\n ? { enum: enumsInNs }\n : {}),\n };\n return [namespaceId, namespaceSlice];\n }),\n );\n\n const contract: Contract<SqlStorage> = {\n target,\n targetFamily,\n ...ifDefined('defaultControlPolicy', definition.defaultControlPolicy),\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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"}
|