@prisma-next/sql-contract-ts 0.12.0-dev.4 → 0.12.0-dev.41
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 +8 -0
- package/dist/{build-contract-BCYW3_wE.mjs → build-contract-CGOSImpk.mjs} +34 -23
- package/dist/build-contract-CGOSImpk.mjs.map +1 -0
- package/dist/config-types.d.mts +7 -3
- package/dist/config-types.d.mts.map +1 -1
- package/dist/config-types.mjs +12 -9
- package/dist/config-types.mjs.map +1 -1
- package/dist/contract-builder.d.mts +23 -12
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +4 -2
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +10 -10
- package/src/build-contract.ts +41 -18
- package/src/config-types.ts +24 -6
- package/src/contract-builder.ts +3 -0
- package/src/contract-definition.ts +15 -3
- package/src/contract-dsl.ts +3 -0
- package/src/contract-lowering.ts +2 -0
- package/src/contract-types.ts +17 -21
- package/dist/build-contract-BCYW3_wE.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.12.0-dev.
|
|
3
|
+
"version": "0.12.0-dev.41",
|
|
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.12.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.12.0-dev.
|
|
11
|
-
"@prisma-next/contract-authoring": "0.12.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.12.0-dev.
|
|
13
|
-
"@prisma-next/sql-contract": "0.12.0-dev.
|
|
14
|
-
"@prisma-next/utils": "0.12.0-dev.
|
|
9
|
+
"@prisma-next/config": "0.12.0-dev.41",
|
|
10
|
+
"@prisma-next/contract": "0.12.0-dev.41",
|
|
11
|
+
"@prisma-next/contract-authoring": "0.12.0-dev.41",
|
|
12
|
+
"@prisma-next/framework-components": "0.12.0-dev.41",
|
|
13
|
+
"@prisma-next/sql-contract": "0.12.0-dev.41",
|
|
14
|
+
"@prisma-next/utils": "0.12.0-dev.41",
|
|
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.12.0-dev.
|
|
21
|
-
"@prisma-next/tsconfig": "0.12.0-dev.
|
|
20
|
+
"@prisma-next/test-utils": "0.12.0-dev.41",
|
|
21
|
+
"@prisma-next/tsconfig": "0.12.0-dev.41",
|
|
22
22
|
"@types/pg": "8.20.0",
|
|
23
23
|
"pg": "8.20.0",
|
|
24
|
-
"@prisma-next/tsdown": "0.12.0-dev.
|
|
24
|
+
"@prisma-next/tsdown": "0.12.0-dev.41",
|
|
25
25
|
"tsdown": "0.22.0",
|
|
26
26
|
"typescript": "5.9.3",
|
|
27
27
|
"vitest": "4.1.6"
|
package/src/build-contract.ts
CHANGED
|
@@ -156,12 +156,12 @@ const JSONB_NATIVE_TYPE = 'jsonb';
|
|
|
156
156
|
function resolveModelNamespaceId(
|
|
157
157
|
model: ModelNode,
|
|
158
158
|
modelNameToNamespaceId: ReadonlyMap<string, string>,
|
|
159
|
-
|
|
159
|
+
defaultNamespaceId: string,
|
|
160
160
|
): string {
|
|
161
161
|
if (model.namespaceId !== undefined && model.namespaceId.length > 0) {
|
|
162
162
|
return model.namespaceId;
|
|
163
163
|
}
|
|
164
|
-
return modelNameToNamespaceId.get(model.modelName) ??
|
|
164
|
+
return modelNameToNamespaceId.get(model.modelName) ?? defaultNamespaceId;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
function buildStorageColumn(
|
|
@@ -231,7 +231,7 @@ function buildDomainField(
|
|
|
231
231
|
|
|
232
232
|
function collectStorageNamespaceCoordinateIds(definition: ContractDefinition): Set<string> {
|
|
233
233
|
const ids = new Set<string>();
|
|
234
|
-
ids.add(
|
|
234
|
+
ids.add(definition.target.defaultNamespaceId);
|
|
235
235
|
for (const id of definition.namespaces ?? []) {
|
|
236
236
|
if (id.length > 0) {
|
|
237
237
|
ids.add(id);
|
|
@@ -245,22 +245,38 @@ function collectStorageNamespaceCoordinateIds(definition: ContractDefinition): S
|
|
|
245
245
|
return ids;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
function ensureUnboundNamespaceSlot(
|
|
249
|
+
namespaces: SqlStorageInput['namespaces'],
|
|
250
|
+
createNamespace: ContractDefinition['createNamespace'],
|
|
251
|
+
): SqlStorageInput['namespaces'] {
|
|
252
|
+
if (Object.hasOwn(namespaces, UNBOUND_NAMESPACE_ID)) {
|
|
253
|
+
return namespaces;
|
|
254
|
+
}
|
|
255
|
+
const unboundInput: SqlNamespaceTablesInput = {
|
|
256
|
+
id: UNBOUND_NAMESPACE_ID,
|
|
257
|
+
entries: { table: {} },
|
|
258
|
+
};
|
|
259
|
+
const unbound = createNamespace ? createNamespace(unboundInput) : buildSqlNamespace(unboundInput);
|
|
260
|
+
return blindCast<
|
|
261
|
+
SqlStorageInput['namespaces'],
|
|
262
|
+
'createNamespace may return a target namespace concretion; the unbound slot matches SqlNamespace at runtime'
|
|
263
|
+
>({
|
|
264
|
+
[UNBOUND_NAMESPACE_ID]: unbound,
|
|
265
|
+
...namespaces,
|
|
266
|
+
});
|
|
253
267
|
}
|
|
254
268
|
|
|
269
|
+
const POSTGRES_ENUM_NAMESPACE_ID = 'public';
|
|
270
|
+
|
|
255
271
|
function partitionStorageTypesForTarget(
|
|
256
272
|
targetId: string,
|
|
257
273
|
types: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
|
|
258
274
|
namespaceTypes?: Readonly<Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>>,
|
|
259
275
|
): {
|
|
260
|
-
readonly documentTypes: Record<string, StorageTypeInstance
|
|
276
|
+
readonly documentTypes: Record<string, StorageTypeInstance>;
|
|
261
277
|
readonly namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>>;
|
|
262
278
|
} {
|
|
263
|
-
const documentTypes: Record<string, StorageTypeInstance
|
|
279
|
+
const documentTypes: Record<string, StorageTypeInstance> = {};
|
|
264
280
|
const namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>> = {};
|
|
265
281
|
for (const [name, entry] of Object.entries(types)) {
|
|
266
282
|
if (isPostgresEnumStorageEntry(entry)) {
|
|
@@ -304,6 +320,7 @@ export function buildSqlContractFromDefinition(
|
|
|
304
320
|
codecLookup?: CodecLookup,
|
|
305
321
|
): Contract<SqlStorage> {
|
|
306
322
|
const target = definition.target.targetId;
|
|
323
|
+
const defaultNamespaceId = definition.target.defaultNamespaceId;
|
|
307
324
|
const targetFamily = 'sql';
|
|
308
325
|
const modelsByName = new Map(definition.models.map((m) => [m.modelName, m]));
|
|
309
326
|
|
|
@@ -319,7 +336,7 @@ export function buildSqlContractFromDefinition(
|
|
|
319
336
|
const namespaceId =
|
|
320
337
|
semanticModel.namespaceId !== undefined && semanticModel.namespaceId.length > 0
|
|
321
338
|
? semanticModel.namespaceId
|
|
322
|
-
:
|
|
339
|
+
: defaultNamespaceId;
|
|
323
340
|
modelNameToNamespaceId.set(semanticModel.modelName, namespaceId);
|
|
324
341
|
roots[tableName] = crossRef(semanticModel.modelName, namespaceId);
|
|
325
342
|
|
|
@@ -390,7 +407,7 @@ export function buildSqlContractFromDefinition(
|
|
|
390
407
|
fk.references.namespaceId ??
|
|
391
408
|
(targetModel.namespaceId !== undefined && targetModel.namespaceId.length > 0
|
|
392
409
|
? targetModel.namespaceId
|
|
393
|
-
:
|
|
410
|
+
: defaultNamespaceId);
|
|
394
411
|
return {
|
|
395
412
|
source: { namespaceId: asNamespaceId(namespaceId), tableName, columns: fk.columns },
|
|
396
413
|
target: {
|
|
@@ -421,6 +438,7 @@ export function buildSqlContractFromDefinition(
|
|
|
421
438
|
|
|
422
439
|
const tableInput: StorageTableInput = {
|
|
423
440
|
columns,
|
|
441
|
+
...ifDefined('control', semanticModel.control),
|
|
424
442
|
uniques: (semanticModel.uniques ?? []).map((u) => ({
|
|
425
443
|
columns: u.columns,
|
|
426
444
|
...ifDefined('name', u.name),
|
|
@@ -487,7 +505,7 @@ export function buildSqlContractFromDefinition(
|
|
|
487
505
|
modelRelations[relation.fieldName] = {
|
|
488
506
|
to: crossRef(
|
|
489
507
|
relation.toModel,
|
|
490
|
-
resolveModelNamespaceId(targetModel, modelNameToNamespaceId,
|
|
508
|
+
resolveModelNamespaceId(targetModel, modelNameToNamespaceId, defaultNamespaceId),
|
|
491
509
|
),
|
|
492
510
|
// RelationDefinition.cardinality includes 'N:M' which isn't in
|
|
493
511
|
// ContractReferenceRelation yet — cast is needed until the contract
|
|
@@ -517,6 +535,7 @@ export function buildSqlContractFromDefinition(
|
|
|
517
535
|
namespaceModels[semanticModel.modelName] = {
|
|
518
536
|
storage: {
|
|
519
537
|
table: tableName,
|
|
538
|
+
namespaceId,
|
|
520
539
|
fields: storageFields,
|
|
521
540
|
},
|
|
522
541
|
fields: domainFields,
|
|
@@ -567,16 +586,20 @@ export function buildSqlContractFromDefinition(
|
|
|
567
586
|
const enumTypes = namespaceEnumTypesById[id];
|
|
568
587
|
const nsInput: SqlNamespaceTablesInput = {
|
|
569
588
|
id,
|
|
570
|
-
|
|
571
|
-
|
|
589
|
+
entries: {
|
|
590
|
+
table: tablesByNamespace[id] ?? {},
|
|
591
|
+
},
|
|
572
592
|
};
|
|
573
|
-
return [
|
|
593
|
+
return [
|
|
594
|
+
id,
|
|
595
|
+
createNamespace ? createNamespace(nsInput, enumTypes) : buildSqlNamespace(nsInput),
|
|
596
|
+
];
|
|
574
597
|
}),
|
|
575
598
|
),
|
|
576
599
|
);
|
|
577
600
|
const storageWithoutHash = {
|
|
578
601
|
...(Object.keys(documentTypes).length > 0 ? { types: documentTypes } : {}),
|
|
579
|
-
namespaces,
|
|
602
|
+
namespaces: ensureUnboundNamespaceSlot(namespaces, createNamespace),
|
|
580
603
|
};
|
|
581
604
|
const storageHash: StorageHashBase<string> = definition.storageHash
|
|
582
605
|
? coreHash(definition.storageHash)
|
|
@@ -672,7 +695,6 @@ export function buildSqlContractFromDefinition(
|
|
|
672
695
|
)
|
|
673
696
|
: undefined;
|
|
674
697
|
|
|
675
|
-
const defaultNamespaceId = defaultModelNamespaceId(target);
|
|
676
698
|
const domainNamespaceIds = new Set(Object.keys(modelsByNamespace));
|
|
677
699
|
if (domainNamespaceIds.size === 0) {
|
|
678
700
|
domainNamespaceIds.add(defaultNamespaceId);
|
|
@@ -694,6 +716,7 @@ export function buildSqlContractFromDefinition(
|
|
|
694
716
|
const contract: Contract<SqlStorage> = {
|
|
695
717
|
target,
|
|
696
718
|
targetFamily,
|
|
719
|
+
...ifDefined('defaultControlPolicy', definition.defaultControlPolicy),
|
|
697
720
|
domain: { namespaces: domainNamespaces },
|
|
698
721
|
roots,
|
|
699
722
|
storage,
|
package/src/config-types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pathToFileURL } from 'node:url';
|
|
2
2
|
import type { ContractConfig } from '@prisma-next/config/config-types';
|
|
3
|
-
import
|
|
3
|
+
import { applySpecifierDefaultControlPolicy } from '@prisma-next/contract/apply-specifier-default-control-policy';
|
|
4
|
+
import type { Contract, ControlPolicy } from '@prisma-next/contract/types';
|
|
4
5
|
import type { TargetPackRef } from '@prisma-next/framework-components/components';
|
|
5
6
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
6
7
|
import { ok } from '@prisma-next/utils/result';
|
|
@@ -19,22 +20,35 @@ function defaultOutputFromContractPath(contractPath: string): string {
|
|
|
19
20
|
return `${contractPath.slice(0, -ext.length)}.json`;
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
export interface TypeScriptContractSpecifierOptions {
|
|
24
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
export function emptyContract(options: {
|
|
23
28
|
readonly output?: string;
|
|
24
29
|
readonly target: TargetPackRef<'sql', string>;
|
|
30
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
25
31
|
}): ContractConfig {
|
|
26
32
|
return {
|
|
27
33
|
source: {
|
|
28
|
-
load: async () =>
|
|
34
|
+
load: async () => {
|
|
35
|
+
const built = buildSqlContractFromDefinition({ target: options.target, models: [] });
|
|
36
|
+
return ok(applySpecifierDefaultControlPolicy(built, options.defaultControlPolicy));
|
|
37
|
+
},
|
|
29
38
|
},
|
|
30
39
|
...ifDefined('output', options.output),
|
|
31
40
|
};
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
export function typescriptContract(
|
|
43
|
+
export function typescriptContract(
|
|
44
|
+
contract: Contract,
|
|
45
|
+
output?: string,
|
|
46
|
+
options?: TypeScriptContractSpecifierOptions,
|
|
47
|
+
): ContractConfig {
|
|
35
48
|
return {
|
|
36
49
|
source: {
|
|
37
|
-
load: async () =>
|
|
50
|
+
load: async () =>
|
|
51
|
+
ok(applySpecifierDefaultControlPolicy(contract, options?.defaultControlPolicy)),
|
|
38
52
|
},
|
|
39
53
|
// The in-memory variant has no input path to anchor on; fall through to
|
|
40
54
|
// the global default in `normalizeContractConfig` when caller doesn't pin it.
|
|
@@ -42,7 +56,11 @@ export function typescriptContract(contract: Contract, output?: string): Contrac
|
|
|
42
56
|
};
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
export function typescriptContractFromPath(
|
|
59
|
+
export function typescriptContractFromPath(
|
|
60
|
+
contractPath: string,
|
|
61
|
+
output?: string,
|
|
62
|
+
options?: TypeScriptContractSpecifierOptions,
|
|
63
|
+
): ContractConfig {
|
|
46
64
|
return {
|
|
47
65
|
source: {
|
|
48
66
|
inputs: [contractPath],
|
|
@@ -60,7 +78,7 @@ export function typescriptContractFromPath(contractPath: string, output?: string
|
|
|
60
78
|
`typescriptContractFromPath: module at "${absolutePath}" has no "default" or "contract" export.`,
|
|
61
79
|
);
|
|
62
80
|
}
|
|
63
|
-
return ok(contract);
|
|
81
|
+
return ok(applySpecifierDefaultControlPolicy(contract, options?.defaultControlPolicy));
|
|
64
82
|
},
|
|
65
83
|
},
|
|
66
84
|
output: output ?? defaultOutputFromContractPath(contractPath),
|
package/src/contract-builder.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ControlPolicy } from '@prisma-next/contract/types';
|
|
1
2
|
import type { ForeignKeyDefaultsState } from '@prisma-next/contract-authoring';
|
|
2
3
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
3
4
|
import type {
|
|
@@ -65,6 +66,7 @@ type ContractDefinition<
|
|
|
65
66
|
readonly naming?: Naming;
|
|
66
67
|
readonly storageHash?: StorageHash;
|
|
67
68
|
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
69
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
68
70
|
readonly namespaces?: Namespaces;
|
|
69
71
|
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
70
72
|
readonly types?: Types;
|
|
@@ -87,6 +89,7 @@ type ContractScaffold<
|
|
|
87
89
|
readonly naming?: Naming;
|
|
88
90
|
readonly storageHash?: StorageHash;
|
|
89
91
|
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
92
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
90
93
|
readonly namespaces?: Namespaces;
|
|
91
94
|
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
92
95
|
readonly types?: never;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ColumnDefault,
|
|
3
|
+
ControlPolicy,
|
|
4
|
+
ExecutionMutationDefaultPhases,
|
|
5
|
+
} from '@prisma-next/contract/types';
|
|
2
6
|
import type { ForeignKeyDefaultsState } from '@prisma-next/contract-authoring';
|
|
3
7
|
import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/codec';
|
|
4
8
|
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
|
|
@@ -113,10 +117,12 @@ export interface ModelNode {
|
|
|
113
117
|
readonly indexes?: readonly IndexNode[];
|
|
114
118
|
readonly foreignKeys?: readonly ForeignKeyNode[];
|
|
115
119
|
readonly relations?: readonly RelationNode[];
|
|
120
|
+
readonly control?: ControlPolicy;
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
export interface ContractDefinition {
|
|
119
124
|
readonly target: TargetPackRef<'sql', string>;
|
|
125
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
120
126
|
readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
|
|
121
127
|
readonly storageHash?: string;
|
|
122
128
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
@@ -124,7 +130,7 @@ export interface ContractDefinition {
|
|
|
124
130
|
/**
|
|
125
131
|
* Enum types declared inside a named `namespace { enum … }` block,
|
|
126
132
|
* keyed first by namespace id then by type name. These are routed to
|
|
127
|
-
* `storage.namespaces[nsId].
|
|
133
|
+
* `storage.namespaces[nsId].entries.type` rather than the implicit fallback
|
|
128
134
|
* namespace used for top-level `storageTypes` enums.
|
|
129
135
|
*/
|
|
130
136
|
readonly namespaceTypes?: Readonly<
|
|
@@ -139,8 +145,14 @@ export interface ContractDefinition {
|
|
|
139
145
|
* Target-supplied factory that materialises a `Namespace` concretion
|
|
140
146
|
* for a declared namespace coordinate. Mirrors
|
|
141
147
|
* `ContractInput.createNamespace`.
|
|
148
|
+
*
|
|
149
|
+
* The optional second argument carries target-specific enum types for the
|
|
150
|
+
* namespace (e.g. postgres enum registrations keyed by type name).
|
|
142
151
|
*/
|
|
143
|
-
readonly createNamespace?: (
|
|
152
|
+
readonly createNamespace?: (
|
|
153
|
+
input: SqlNamespaceTablesInput,
|
|
154
|
+
enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,
|
|
155
|
+
) => Namespace;
|
|
144
156
|
readonly models: readonly ModelNode[];
|
|
145
157
|
readonly valueObjects?: readonly ValueObjectNode[];
|
|
146
158
|
}
|
package/src/contract-dsl.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ColumnDefault,
|
|
3
3
|
ColumnDefaultLiteralInputValue,
|
|
4
|
+
ControlPolicy,
|
|
4
5
|
ExecutionMutationDefaultPhases,
|
|
5
6
|
ExecutionMutationDefaultValue,
|
|
6
7
|
} from '@prisma-next/contract/types';
|
|
@@ -785,6 +786,7 @@ export type ModelAttributesSpec = {
|
|
|
785
786
|
|
|
786
787
|
export type SqlStageSpec = {
|
|
787
788
|
readonly table?: string;
|
|
789
|
+
readonly control?: ControlPolicy;
|
|
788
790
|
readonly indexes?: readonly IndexConstraint[];
|
|
789
791
|
readonly foreignKeys?: readonly ForeignKeyConstraint[];
|
|
790
792
|
};
|
|
@@ -1216,6 +1218,7 @@ export type ContractInput<
|
|
|
1216
1218
|
readonly naming?: NamingConfig;
|
|
1217
1219
|
readonly storageHash?: string;
|
|
1218
1220
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
1221
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
1219
1222
|
/**
|
|
1220
1223
|
* Declared namespace coordinates the contract recognises. Per-model
|
|
1221
1224
|
* `namespace` references must reference an entry in this list (or the
|
package/src/contract-lowering.ts
CHANGED
|
@@ -614,6 +614,7 @@ function resolveModelNode(
|
|
|
614
614
|
...(indexes.length > 0 ? { indexes } : {}),
|
|
615
615
|
...(foreignKeys.length > 0 ? { foreignKeys } : {}),
|
|
616
616
|
...(relations.length > 0 ? { relations } : {}),
|
|
617
|
+
...ifDefined('control', spec.sqlSpec?.control),
|
|
617
618
|
};
|
|
618
619
|
}
|
|
619
620
|
|
|
@@ -707,6 +708,7 @@ export function buildContractDefinition(definition: ContractInput): ContractDefi
|
|
|
707
708
|
|
|
708
709
|
return {
|
|
709
710
|
target: definition.target,
|
|
711
|
+
...ifDefined('defaultControlPolicy', definition.defaultControlPolicy),
|
|
710
712
|
...(definition.extensionPacks ? { extensionPacks: definition.extensionPacks } : {}),
|
|
711
713
|
...(definition.storageHash ? { storageHash: definition.storageHash } : {}),
|
|
712
714
|
...(definition.foreignKeyDefaults ? { foreignKeyDefaults: definition.foreignKeyDefaults } : {}),
|
package/src/contract-types.ts
CHANGED
|
@@ -6,11 +6,11 @@ import type {
|
|
|
6
6
|
StorageHashBase,
|
|
7
7
|
} from '@prisma-next/contract/types';
|
|
8
8
|
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
|
|
9
|
+
import type { StorageType } from '@prisma-next/framework-components/ir';
|
|
9
10
|
import type { IndexTypeRegistration } from '@prisma-next/sql-contract/index-types';
|
|
10
11
|
import type {
|
|
11
12
|
ContractWithTypeMaps,
|
|
12
13
|
Index,
|
|
13
|
-
PostgresEnumStorageEntry,
|
|
14
14
|
ReferentialAction,
|
|
15
15
|
StorageTypeInstance,
|
|
16
16
|
TypeMaps,
|
|
@@ -144,10 +144,7 @@ type DefinitionNamespaces<Definition> = Definition extends {
|
|
|
144
144
|
type DefinitionTypes<Definition> = Definition extends {
|
|
145
145
|
readonly types?: unknown;
|
|
146
146
|
}
|
|
147
|
-
? Present<Definition['types']> extends Record<
|
|
148
|
-
string,
|
|
149
|
-
StorageTypeInstance | PostgresEnumStorageEntry
|
|
150
|
-
>
|
|
147
|
+
? Present<Definition['types']> extends Record<string, StorageType>
|
|
151
148
|
? Present<Definition['types']>
|
|
152
149
|
: Record<never, never>
|
|
153
150
|
: Record<never, never>;
|
|
@@ -311,10 +308,7 @@ type DescriptorTypeRef<Descriptor> = Descriptor extends {
|
|
|
311
308
|
? TypeRef
|
|
312
309
|
: undefined;
|
|
313
310
|
|
|
314
|
-
type LookupNamedStorageTypeKeyByValue<
|
|
315
|
-
Definition,
|
|
316
|
-
TypeRef extends StorageTypeInstance | PostgresEnumStorageEntry,
|
|
317
|
-
> = {
|
|
311
|
+
type LookupNamedStorageTypeKeyByValue<Definition, TypeRef extends StorageType> = {
|
|
318
312
|
[TypeName in keyof DefinitionTypes<Definition> & string]: [TypeRef] extends [
|
|
319
313
|
DefinitionTypes<Definition>[TypeName],
|
|
320
314
|
]
|
|
@@ -326,7 +320,7 @@ type LookupNamedStorageTypeKeyByValue<
|
|
|
326
320
|
|
|
327
321
|
type ResolveNamedStorageTypeKey<Definition, TypeRef> = TypeRef extends string
|
|
328
322
|
? TypeRef
|
|
329
|
-
: TypeRef extends
|
|
323
|
+
: TypeRef extends StorageType
|
|
330
324
|
? [LookupNamedStorageTypeKeyByValue<Definition, TypeRef>] extends [never]
|
|
331
325
|
? string
|
|
332
326
|
: LookupNamedStorageTypeKeyByValue<Definition, TypeRef>
|
|
@@ -564,9 +558,9 @@ type BuiltStorageTables<Definition> = {
|
|
|
564
558
|
};
|
|
565
559
|
|
|
566
560
|
type BuiltDocumentScopedTypes<Definition> = {
|
|
567
|
-
readonly [K in keyof DefinitionTypes<Definition> as DefinitionTypes<Definition>[K] extends
|
|
568
|
-
?
|
|
569
|
-
:
|
|
561
|
+
readonly [K in keyof DefinitionTypes<Definition> as DefinitionTypes<Definition>[K] extends StorageTypeInstance
|
|
562
|
+
? K
|
|
563
|
+
: never]: DefinitionTypes<Definition>[K];
|
|
570
564
|
};
|
|
571
565
|
|
|
572
566
|
type BuiltDomain<Definition> =
|
|
@@ -586,19 +580,20 @@ type BuiltStorage<Definition> = {
|
|
|
586
580
|
readonly types?: BuiltDocumentScopedTypes<Definition>;
|
|
587
581
|
// The primary namespace key is target-specific: Postgres uses `public` (the
|
|
588
582
|
// default schema), all other SQL targets use `__unbound__`. The namespace
|
|
589
|
-
// carries the narrowed
|
|
583
|
+
// carries the narrowed `entries.table` shape so downstream DSL surfaces keep
|
|
590
584
|
// literal-keyed access without an optional-narrowing dance. The shape is
|
|
591
585
|
// described inline (rather than intersecting with `SqlStorage['namespaces']`)
|
|
592
586
|
// so its `Readonly<Record<string, Namespace>>` index signature doesn't
|
|
593
|
-
// collapse
|
|
594
|
-
//
|
|
595
|
-
//
|
|
587
|
+
// collapse slot keys to `string`. The literal object is still structurally
|
|
588
|
+
// assignable to `SqlStorage['namespaces']` because every value satisfies the
|
|
589
|
+
// framework `Namespace` interface.
|
|
596
590
|
readonly namespaces: {
|
|
597
591
|
readonly [K in DefaultStorageNamespaceId<Definition>]: {
|
|
598
592
|
readonly id: K;
|
|
599
593
|
readonly kind: string;
|
|
600
|
-
readonly
|
|
601
|
-
|
|
594
|
+
readonly entries: {
|
|
595
|
+
readonly table: BuiltStorageTables<Definition>;
|
|
596
|
+
};
|
|
602
597
|
};
|
|
603
598
|
} & {
|
|
604
599
|
readonly [Ns in Exclude<
|
|
@@ -607,8 +602,9 @@ type BuiltStorage<Definition> = {
|
|
|
607
602
|
>]: {
|
|
608
603
|
readonly id: Ns;
|
|
609
604
|
readonly kind: string;
|
|
610
|
-
readonly
|
|
611
|
-
|
|
605
|
+
readonly entries: {
|
|
606
|
+
readonly table: Record<never, never>;
|
|
607
|
+
};
|
|
612
608
|
};
|
|
613
609
|
};
|
|
614
610
|
};
|
|
@@ -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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"}
|