@prisma-next/sql-contract-ts 0.11.0-dev.7 → 0.11.0-dev.70
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/dist/build-contract-BsUi_1u3.mjs +380 -0
- package/dist/build-contract-BsUi_1u3.mjs.map +1 -0
- package/dist/config-types.d.mts +6 -1
- package/dist/config-types.d.mts.map +1 -1
- package/dist/config-types.mjs +11 -1
- package/dist/config-types.mjs.map +1 -1
- package/dist/contract-builder.d.mts +31 -20
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +6 -354
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +10 -10
- package/src/build-contract.ts +94 -29
- package/src/config-types.ts +14 -0
- package/src/contract-builder.ts +8 -19
- package/src/contract-definition.ts +0 -1
- package/src/contract-dsl.ts +0 -2
- package/src/contract-lowering.ts +0 -1
- package/src/contract-types.ts +44 -15
- package/src/exports/config-types.ts +5 -1
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/sql-contract-ts",
|
|
3
|
-
"version": "0.11.0-dev.
|
|
3
|
+
"version": "0.11.0-dev.70",
|
|
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.11.0-dev.
|
|
10
|
-
"@prisma-next/contract": "0.11.0-dev.
|
|
11
|
-
"@prisma-next/contract-authoring": "0.11.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.11.0-dev.
|
|
13
|
-
"@prisma-next/sql-contract": "0.11.0-dev.
|
|
14
|
-
"@prisma-next/utils": "0.11.0-dev.
|
|
9
|
+
"@prisma-next/config": "0.11.0-dev.70",
|
|
10
|
+
"@prisma-next/contract": "0.11.0-dev.70",
|
|
11
|
+
"@prisma-next/contract-authoring": "0.11.0-dev.70",
|
|
12
|
+
"@prisma-next/framework-components": "0.11.0-dev.70",
|
|
13
|
+
"@prisma-next/sql-contract": "0.11.0-dev.70",
|
|
14
|
+
"@prisma-next/utils": "0.11.0-dev.70",
|
|
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.11.0-dev.
|
|
21
|
-
"@prisma-next/tsconfig": "0.11.0-dev.
|
|
20
|
+
"@prisma-next/test-utils": "0.11.0-dev.70",
|
|
21
|
+
"@prisma-next/tsconfig": "0.11.0-dev.70",
|
|
22
22
|
"@types/pg": "8.20.0",
|
|
23
23
|
"pg": "8.20.0",
|
|
24
|
-
"@prisma-next/tsdown": "0.11.0-dev.
|
|
24
|
+
"@prisma-next/tsdown": "0.11.0-dev.70",
|
|
25
25
|
"tsdown": "0.22.0",
|
|
26
26
|
"typescript": "5.9.3",
|
|
27
27
|
"vitest": "4.1.6"
|
package/src/build-contract.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
computeStorageHash,
|
|
5
5
|
} from '@prisma-next/contract/hashing';
|
|
6
6
|
import {
|
|
7
|
+
asNamespaceId,
|
|
7
8
|
type ColumnDefault,
|
|
8
9
|
type ColumnDefaultLiteralInputValue,
|
|
9
10
|
type Contract,
|
|
@@ -11,13 +12,17 @@ import {
|
|
|
11
12
|
type ContractModel,
|
|
12
13
|
type ContractRelation,
|
|
13
14
|
type ContractValueObject,
|
|
15
|
+
type CrossReference,
|
|
14
16
|
coreHash,
|
|
17
|
+
crossRef,
|
|
15
18
|
type ExecutionMutationDefault,
|
|
16
19
|
type JsonValue,
|
|
17
20
|
type StorageHashBase,
|
|
18
21
|
} from '@prisma-next/contract/types';
|
|
22
|
+
import { type CapabilityMatrix, mergeCapabilityMatrices } from '@prisma-next/contract-authoring';
|
|
19
23
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
20
|
-
import {
|
|
24
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
25
|
+
import { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';
|
|
21
26
|
import { validateIndexTypes } from '@prisma-next/sql-contract/index-type-validation';
|
|
22
27
|
import {
|
|
23
28
|
createIndexTypeRegistry,
|
|
@@ -26,6 +31,7 @@ import {
|
|
|
26
31
|
} from '@prisma-next/sql-contract/index-types';
|
|
27
32
|
import {
|
|
28
33
|
applyFkDefaults,
|
|
34
|
+
buildSqlNamespace,
|
|
29
35
|
isPostgresEnumStorageEntry,
|
|
30
36
|
type PostgresEnumStorageEntry,
|
|
31
37
|
type SqlNamespaceTablesInput,
|
|
@@ -38,6 +44,7 @@ import {
|
|
|
38
44
|
toStorageTypeInstance,
|
|
39
45
|
} from '@prisma-next/sql-contract/types';
|
|
40
46
|
import { validateStorageSemantics } from '@prisma-next/sql-contract/validators';
|
|
47
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
41
48
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
42
49
|
import type {
|
|
43
50
|
ContractDefinition,
|
|
@@ -146,6 +153,16 @@ function isValueObjectField(
|
|
|
146
153
|
const JSONB_CODEC_ID = 'pg/jsonb@1';
|
|
147
154
|
const JSONB_NATIVE_TYPE = 'jsonb';
|
|
148
155
|
|
|
156
|
+
function resolveModelNamespaceId(
|
|
157
|
+
model: ModelNode,
|
|
158
|
+
modelNameToNamespaceId: ReadonlyMap<string, string>,
|
|
159
|
+
): string {
|
|
160
|
+
if (model.namespaceId !== undefined && model.namespaceId.length > 0) {
|
|
161
|
+
return model.namespaceId;
|
|
162
|
+
}
|
|
163
|
+
return modelNameToNamespaceId.get(model.modelName) ?? UNBOUND_NAMESPACE_ID;
|
|
164
|
+
}
|
|
165
|
+
|
|
149
166
|
function buildStorageColumn(
|
|
150
167
|
field: FieldNode | ValueObjectFieldNode,
|
|
151
168
|
codecLookup?: CodecLookup,
|
|
@@ -286,13 +303,19 @@ export function buildSqlContractFromDefinition(
|
|
|
286
303
|
|
|
287
304
|
const tablesByNamespace: Record<string, Record<string, StorageTable>> = {};
|
|
288
305
|
const tableNameToNamespaceId = new Map<string, string>();
|
|
306
|
+
const modelNameToNamespaceId = new Map<string, string>();
|
|
289
307
|
const executionDefaults: ExecutionMutationDefault[] = [];
|
|
290
|
-
const
|
|
291
|
-
const roots: Record<string,
|
|
308
|
+
const modelsByNamespace: Record<string, Record<string, ContractModel>> = {};
|
|
309
|
+
const roots: Record<string, CrossReference> = {};
|
|
292
310
|
|
|
293
311
|
for (const semanticModel of definition.models) {
|
|
294
312
|
const tableName = semanticModel.tableName;
|
|
295
|
-
|
|
313
|
+
const namespaceId =
|
|
314
|
+
semanticModel.namespaceId !== undefined && semanticModel.namespaceId.length > 0
|
|
315
|
+
? semanticModel.namespaceId
|
|
316
|
+
: UNBOUND_NAMESPACE_ID;
|
|
317
|
+
modelNameToNamespaceId.set(semanticModel.modelName, namespaceId);
|
|
318
|
+
roots[tableName] = crossRef(semanticModel.modelName, namespaceId);
|
|
296
319
|
|
|
297
320
|
// --- Build storage table ---
|
|
298
321
|
|
|
@@ -344,11 +367,6 @@ export function buildSqlContractFromDefinition(
|
|
|
344
367
|
}
|
|
345
368
|
}
|
|
346
369
|
|
|
347
|
-
const namespaceId =
|
|
348
|
-
semanticModel.namespaceId !== undefined && semanticModel.namespaceId.length > 0
|
|
349
|
-
? semanticModel.namespaceId
|
|
350
|
-
: UNBOUND_NAMESPACE_ID;
|
|
351
|
-
|
|
352
370
|
const foreignKeys = (semanticModel.foreignKeys ?? []).map((fk) => {
|
|
353
371
|
const targetModel = assertKnownTargetModel(
|
|
354
372
|
modelsByName,
|
|
@@ -368,9 +386,9 @@ export function buildSqlContractFromDefinition(
|
|
|
368
386
|
? targetModel.namespaceId
|
|
369
387
|
: UNBOUND_NAMESPACE_ID);
|
|
370
388
|
return {
|
|
371
|
-
source: { namespaceId, tableName, columns: fk.columns },
|
|
389
|
+
source: { namespaceId: asNamespaceId(namespaceId), tableName, columns: fk.columns },
|
|
372
390
|
target: {
|
|
373
|
-
namespaceId: targetNamespaceId,
|
|
391
|
+
namespaceId: asNamespaceId(targetNamespaceId),
|
|
374
392
|
tableName: fk.references.table,
|
|
375
393
|
columns: fk.references.columns,
|
|
376
394
|
},
|
|
@@ -461,7 +479,10 @@ export function buildSqlContractFromDefinition(
|
|
|
461
479
|
);
|
|
462
480
|
|
|
463
481
|
modelRelations[relation.fieldName] = {
|
|
464
|
-
to:
|
|
482
|
+
to: crossRef(
|
|
483
|
+
relation.toModel,
|
|
484
|
+
resolveModelNamespaceId(targetModel, modelNameToNamespaceId),
|
|
485
|
+
),
|
|
465
486
|
// RelationDefinition.cardinality includes 'N:M' which isn't in
|
|
466
487
|
// ContractReferenceRelation yet — cast is needed until the contract
|
|
467
488
|
// type is extended to cover many-to-many.
|
|
@@ -482,7 +503,12 @@ export function buildSqlContractFromDefinition(
|
|
|
482
503
|
};
|
|
483
504
|
}
|
|
484
505
|
|
|
485
|
-
|
|
506
|
+
let namespaceModels = modelsByNamespace[namespaceId];
|
|
507
|
+
if (namespaceModels === undefined) {
|
|
508
|
+
namespaceModels = {};
|
|
509
|
+
modelsByNamespace[namespaceId] = namespaceModels;
|
|
510
|
+
}
|
|
511
|
+
namespaceModels[semanticModel.modelName] = {
|
|
486
512
|
storage: {
|
|
487
513
|
table: tableName,
|
|
488
514
|
fields: storageFields,
|
|
@@ -526,19 +552,24 @@ export function buildSqlContractFromDefinition(
|
|
|
526
552
|
namespaceCoordinateIds.add(id);
|
|
527
553
|
}
|
|
528
554
|
const { createNamespace } = definition;
|
|
529
|
-
const namespaces
|
|
530
|
-
[
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
555
|
+
const namespaces = blindCast<
|
|
556
|
+
SqlStorageInput['namespaces'],
|
|
557
|
+
'contract authoring always materialises the __unbound__ namespace coordinate'
|
|
558
|
+
>(
|
|
559
|
+
Object.fromEntries(
|
|
560
|
+
[...namespaceCoordinateIds].sort().map((id) => {
|
|
561
|
+
const enumTypes = namespaceEnumTypesById[id];
|
|
562
|
+
const nsInput: SqlNamespaceTablesInput = {
|
|
563
|
+
id,
|
|
564
|
+
tables: tablesByNamespace[id] ?? {},
|
|
565
|
+
...ifDefined('enum', enumTypes),
|
|
566
|
+
};
|
|
567
|
+
return [id, createNamespace ? createNamespace(nsInput) : buildSqlNamespace(nsInput)];
|
|
568
|
+
}),
|
|
569
|
+
),
|
|
539
570
|
);
|
|
540
571
|
const storageWithoutHash = {
|
|
541
|
-
types: documentTypes,
|
|
572
|
+
...(Object.keys(documentTypes).length > 0 ? { types: documentTypes } : {}),
|
|
542
573
|
namespaces,
|
|
543
574
|
};
|
|
544
575
|
const storageHash: StorageHashBase<string> = definition.storageHash
|
|
@@ -547,8 +578,9 @@ export function buildSqlContractFromDefinition(
|
|
|
547
578
|
target,
|
|
548
579
|
targetFamily,
|
|
549
580
|
storage: storageWithoutHash as Record<string, unknown>,
|
|
581
|
+
...sqlContractCanonicalizationHooks,
|
|
550
582
|
});
|
|
551
|
-
const storage = new SqlStorage({ ...storageWithoutHash, storageHash }
|
|
583
|
+
const storage = new SqlStorage({ ...storageWithoutHash, storageHash });
|
|
552
584
|
|
|
553
585
|
const executionSection =
|
|
554
586
|
executionDefaults.length > 0
|
|
@@ -578,8 +610,24 @@ export function buildSqlContractFromDefinition(
|
|
|
578
610
|
}
|
|
579
611
|
}
|
|
580
612
|
|
|
581
|
-
const
|
|
582
|
-
|
|
613
|
+
const extensionPackCapabilitySources = definition.extensionPacks
|
|
614
|
+
? Object.values(definition.extensionPacks).map(
|
|
615
|
+
(pack) => pack.capabilities as CapabilityMatrix | undefined,
|
|
616
|
+
)
|
|
617
|
+
: [];
|
|
618
|
+
const capabilities = mergeCapabilityMatrices(
|
|
619
|
+
definition.target.capabilities as CapabilityMatrix | undefined,
|
|
620
|
+
...extensionPackCapabilitySources,
|
|
621
|
+
);
|
|
622
|
+
// Internal `profileHash` computation is unchanged from `origin/main`: it
|
|
623
|
+
// continues to fingerprint the author-declared capability subset. With
|
|
624
|
+
// `capabilities` removed from the `defineContract` input that subset is
|
|
625
|
+
// now always empty, so the hash naturally stabilises at `hash({})`.
|
|
626
|
+
const profileHash = computeProfileHash({
|
|
627
|
+
target,
|
|
628
|
+
targetFamily,
|
|
629
|
+
capabilities: {},
|
|
630
|
+
});
|
|
583
631
|
|
|
584
632
|
const executionWithHash = executionSection
|
|
585
633
|
? {
|
|
@@ -618,14 +666,31 @@ export function buildSqlContractFromDefinition(
|
|
|
618
666
|
)
|
|
619
667
|
: undefined;
|
|
620
668
|
|
|
669
|
+
const domainNamespaceIds = new Set(Object.keys(modelsByNamespace));
|
|
670
|
+
if (domainNamespaceIds.size === 0) {
|
|
671
|
+
domainNamespaceIds.add(UNBOUND_NAMESPACE_ID);
|
|
672
|
+
}
|
|
673
|
+
if (valueObjects !== undefined) {
|
|
674
|
+
domainNamespaceIds.add(UNBOUND_NAMESPACE_ID);
|
|
675
|
+
}
|
|
676
|
+
const domainNamespaces = Object.fromEntries(
|
|
677
|
+
[...domainNamespaceIds].sort().map((namespaceId) => {
|
|
678
|
+
const modelsInNs = modelsByNamespace[namespaceId] ?? {};
|
|
679
|
+
const namespaceSlice =
|
|
680
|
+
namespaceId === UNBOUND_NAMESPACE_ID && valueObjects !== undefined
|
|
681
|
+
? { models: modelsInNs, valueObjects }
|
|
682
|
+
: { models: modelsInNs };
|
|
683
|
+
return [namespaceId, namespaceSlice];
|
|
684
|
+
}),
|
|
685
|
+
);
|
|
686
|
+
|
|
621
687
|
const contract: Contract<SqlStorage> = {
|
|
622
688
|
target,
|
|
623
689
|
targetFamily,
|
|
624
|
-
|
|
690
|
+
domain: { namespaces: domainNamespaces },
|
|
625
691
|
roots,
|
|
626
692
|
storage,
|
|
627
693
|
...(executionWithHash ? { execution: executionWithHash } : {}),
|
|
628
|
-
...ifDefined('valueObjects', valueObjects),
|
|
629
694
|
extensionPacks,
|
|
630
695
|
capabilities,
|
|
631
696
|
profileHash,
|
package/src/config-types.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { pathToFileURL } from 'node:url';
|
|
2
2
|
import type { ContractConfig } from '@prisma-next/config/config-types';
|
|
3
3
|
import type { Contract } from '@prisma-next/contract/types';
|
|
4
|
+
import type { TargetPackRef } from '@prisma-next/framework-components/components';
|
|
4
5
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
5
6
|
import { ok } from '@prisma-next/utils/result';
|
|
6
7
|
import { extname } from 'pathe';
|
|
8
|
+
import { buildSqlContractFromDefinition } from './build-contract';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Derives the emit output path from the TS contract input so artefacts land
|
|
@@ -17,6 +19,18 @@ function defaultOutputFromContractPath(contractPath: string): string {
|
|
|
17
19
|
return `${contractPath.slice(0, -ext.length)}.json`;
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
export function emptyContract(options: {
|
|
23
|
+
readonly output?: string;
|
|
24
|
+
readonly target: TargetPackRef<'sql', string>;
|
|
25
|
+
}): ContractConfig {
|
|
26
|
+
return {
|
|
27
|
+
source: {
|
|
28
|
+
load: async () => ok(buildSqlContractFromDefinition({ target: options.target, models: [] })),
|
|
29
|
+
},
|
|
30
|
+
...ifDefined('output', options.output),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
20
34
|
export function typescriptContract(contract: Contract, output?: string): ContractConfig {
|
|
21
35
|
return {
|
|
22
36
|
source: {
|
package/src/contract-builder.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
SqlNamespaceTablesInput,
|
|
12
12
|
StorageTypeInstance,
|
|
13
13
|
} from '@prisma-next/sql-contract/types';
|
|
14
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
14
15
|
import { buildSqlContractFromDefinition } from './build-contract';
|
|
15
16
|
import {
|
|
16
17
|
type ComposedAuthoringHelpers,
|
|
@@ -53,7 +54,6 @@ type ContractDefinition<
|
|
|
53
54
|
Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
|
|
54
55
|
Models extends Record<string, ModelLike>,
|
|
55
56
|
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
56
|
-
Capabilities extends Record<string, Record<string, boolean>> | undefined,
|
|
57
57
|
Naming extends ContractInput['naming'] | undefined,
|
|
58
58
|
StorageHash extends string | undefined,
|
|
59
59
|
ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined,
|
|
@@ -65,7 +65,6 @@ type ContractDefinition<
|
|
|
65
65
|
readonly naming?: Naming;
|
|
66
66
|
readonly storageHash?: StorageHash;
|
|
67
67
|
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
68
|
-
readonly capabilities?: Capabilities;
|
|
69
68
|
readonly namespaces?: Namespaces;
|
|
70
69
|
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
71
70
|
readonly types?: Types;
|
|
@@ -77,7 +76,6 @@ type ContractScaffold<
|
|
|
77
76
|
Family extends FamilyPackRef<string>,
|
|
78
77
|
Target extends TargetPackRef<'sql', string>,
|
|
79
78
|
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
|
|
80
|
-
Capabilities extends Record<string, Record<string, boolean>> | undefined,
|
|
81
79
|
Naming extends ContractInput['naming'] | undefined,
|
|
82
80
|
StorageHash extends string | undefined,
|
|
83
81
|
ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined,
|
|
@@ -89,9 +87,10 @@ type ContractScaffold<
|
|
|
89
87
|
readonly naming?: Naming;
|
|
90
88
|
readonly storageHash?: StorageHash;
|
|
91
89
|
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
92
|
-
readonly capabilities?: Capabilities;
|
|
93
90
|
readonly namespaces?: Namespaces;
|
|
94
91
|
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
92
|
+
readonly types?: never;
|
|
93
|
+
readonly models?: never;
|
|
95
94
|
readonly codecLookup?: CodecLookup;
|
|
96
95
|
};
|
|
97
96
|
|
|
@@ -274,11 +273,7 @@ function validateExtensionPackRefs(
|
|
|
274
273
|
|
|
275
274
|
function buildContractFromDsl<Definition extends ContractInput>(
|
|
276
275
|
definition: Definition,
|
|
277
|
-
): SqlContractResult<Definition
|
|
278
|
-
|
|
279
|
-
function buildContractFromDsl(
|
|
280
|
-
definition: ContractInput,
|
|
281
|
-
): ReturnType<typeof buildSqlContractFromDefinition> {
|
|
276
|
+
): SqlContractResult<Definition> {
|
|
282
277
|
validateTargetPackRef(definition.family, definition.target);
|
|
283
278
|
validateExtensionPackRefs(definition.target, definition.extensionPacks);
|
|
284
279
|
validateNamespaceDeclarations(definition.target, definition.namespaces);
|
|
@@ -288,10 +283,10 @@ function buildContractFromDsl(
|
|
|
288
283
|
(definition.models ?? {}) as Record<string, ModelLike>,
|
|
289
284
|
);
|
|
290
285
|
|
|
291
|
-
return
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
);
|
|
286
|
+
return blindCast<
|
|
287
|
+
SqlContractResult<Definition>,
|
|
288
|
+
'buildSqlContractFromDefinition return type is wide; SqlContractResult conditional resolves correctly at runtime for any concrete Definition'
|
|
289
|
+
>(buildSqlContractFromDefinition(buildContractDefinition(definition), definition.codecLookup));
|
|
295
290
|
}
|
|
296
291
|
|
|
297
292
|
export function defineContract<
|
|
@@ -305,7 +300,6 @@ export function defineContract<
|
|
|
305
300
|
const ExtensionPacks extends
|
|
306
301
|
| Record<string, ExtensionPackRef<'sql', string>>
|
|
307
302
|
| undefined = undefined,
|
|
308
|
-
const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
|
|
309
303
|
const Naming extends ContractInput['naming'] | undefined = undefined,
|
|
310
304
|
const StorageHash extends string | undefined = undefined,
|
|
311
305
|
const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
|
|
@@ -317,7 +311,6 @@ export function defineContract<
|
|
|
317
311
|
Types,
|
|
318
312
|
Models,
|
|
319
313
|
ExtensionPacks,
|
|
320
|
-
Capabilities,
|
|
321
314
|
Naming,
|
|
322
315
|
StorageHash,
|
|
323
316
|
ForeignKeyDefaults,
|
|
@@ -330,7 +323,6 @@ export function defineContract<
|
|
|
330
323
|
Types,
|
|
331
324
|
Models,
|
|
332
325
|
ExtensionPacks,
|
|
333
|
-
Capabilities,
|
|
334
326
|
Naming,
|
|
335
327
|
StorageHash,
|
|
336
328
|
ForeignKeyDefaults,
|
|
@@ -348,7 +340,6 @@ export function defineContract<
|
|
|
348
340
|
const ExtensionPacks extends
|
|
349
341
|
| Record<string, ExtensionPackRef<'sql', string>>
|
|
350
342
|
| undefined = undefined,
|
|
351
|
-
const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
|
|
352
343
|
const Naming extends ContractInput['naming'] | undefined = undefined,
|
|
353
344
|
const StorageHash extends string | undefined = undefined,
|
|
354
345
|
const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
|
|
@@ -358,7 +349,6 @@ export function defineContract<
|
|
|
358
349
|
Family,
|
|
359
350
|
Target,
|
|
360
351
|
ExtensionPacks,
|
|
361
|
-
Capabilities,
|
|
362
352
|
Naming,
|
|
363
353
|
StorageHash,
|
|
364
354
|
ForeignKeyDefaults,
|
|
@@ -372,7 +362,6 @@ export function defineContract<
|
|
|
372
362
|
Types,
|
|
373
363
|
Models,
|
|
374
364
|
ExtensionPacks,
|
|
375
|
-
Capabilities,
|
|
376
365
|
Naming,
|
|
377
366
|
StorageHash,
|
|
378
367
|
ForeignKeyDefaults,
|
|
@@ -118,7 +118,6 @@ export interface ModelNode {
|
|
|
118
118
|
export interface ContractDefinition {
|
|
119
119
|
readonly target: TargetPackRef<'sql', string>;
|
|
120
120
|
readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
|
|
121
|
-
readonly capabilities?: Record<string, Record<string, boolean>>;
|
|
122
121
|
readonly storageHash?: string;
|
|
123
122
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
124
123
|
readonly storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
|
package/src/contract-dsl.ts
CHANGED
|
@@ -1209,7 +1209,6 @@ export type ContractInput<
|
|
|
1209
1209
|
>
|
|
1210
1210
|
> = Record<never, never>,
|
|
1211
1211
|
ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined,
|
|
1212
|
-
Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
|
|
1213
1212
|
> = {
|
|
1214
1213
|
readonly family: Family;
|
|
1215
1214
|
readonly target: Target;
|
|
@@ -1217,7 +1216,6 @@ export type ContractInput<
|
|
|
1217
1216
|
readonly naming?: NamingConfig;
|
|
1218
1217
|
readonly storageHash?: string;
|
|
1219
1218
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
1220
|
-
readonly capabilities?: Capabilities;
|
|
1221
1219
|
/**
|
|
1222
1220
|
* Declared namespace coordinates the contract recognises. Per-model
|
|
1223
1221
|
* `namespace` references must reference an entry in this list (or the
|
package/src/contract-lowering.ts
CHANGED
|
@@ -708,7 +708,6 @@ export function buildContractDefinition(definition: ContractInput): ContractDefi
|
|
|
708
708
|
return {
|
|
709
709
|
target: definition.target,
|
|
710
710
|
...(definition.extensionPacks ? { extensionPacks: definition.extensionPacks } : {}),
|
|
711
|
-
...(definition.capabilities ? { capabilities: definition.capabilities } : {}),
|
|
712
711
|
...(definition.storageHash ? { storageHash: definition.storageHash } : {}),
|
|
713
712
|
...(definition.foreignKeyDefaults ? { foreignKeyDefaults: definition.foreignKeyDefaults } : {}),
|
|
714
713
|
...(Object.keys(collection.storageTypes).length > 0
|
package/src/contract-types.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
ColumnDefault,
|
|
3
3
|
Contract,
|
|
4
4
|
ContractRelation,
|
|
5
|
+
NamespaceId,
|
|
5
6
|
StorageHashBase,
|
|
6
7
|
} from '@prisma-next/contract/types';
|
|
7
8
|
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
|
|
@@ -69,11 +70,35 @@ type DefinitionExtensionPacks<Definition> = Definition extends {
|
|
|
69
70
|
? Packs
|
|
70
71
|
: Record<never, never>;
|
|
71
72
|
|
|
72
|
-
type
|
|
73
|
-
readonly capabilities?: infer
|
|
73
|
+
type ExtractPackCapabilities<P> = P extends {
|
|
74
|
+
readonly capabilities?: infer Caps extends Record<string, Record<string, boolean>>;
|
|
74
75
|
}
|
|
75
|
-
?
|
|
76
|
-
:
|
|
76
|
+
? Caps
|
|
77
|
+
: never;
|
|
78
|
+
|
|
79
|
+
type MergeExtensionPackCapabilities<Packs> =
|
|
80
|
+
Packs extends Record<string, unknown>
|
|
81
|
+
? keyof Packs extends never
|
|
82
|
+
? Record<string, never>
|
|
83
|
+
: UnionToIntersection<
|
|
84
|
+
{
|
|
85
|
+
[K in keyof Packs]: ExtractPackCapabilities<Packs[K]>;
|
|
86
|
+
}[keyof Packs]
|
|
87
|
+
>
|
|
88
|
+
: Record<string, never>;
|
|
89
|
+
|
|
90
|
+
type Defaulted<T, Fallback> = [T] extends [never] ? Fallback : T;
|
|
91
|
+
|
|
92
|
+
// Build-time capability derivation no longer reads an author-declared
|
|
93
|
+
// `capabilities` block — that field was removed from the `defineContract`
|
|
94
|
+
// input. The build-time matrix is the merge of the target pack's caps and
|
|
95
|
+
// every extension pack's caps; adapter and driver caps are layered in by
|
|
96
|
+
// `enrichContract` at CLI emit time.
|
|
97
|
+
type DerivedCapabilities<Definition> = Defaulted<
|
|
98
|
+
ExtractPackCapabilities<DefinitionTarget<Definition>>,
|
|
99
|
+
Record<string, never>
|
|
100
|
+
> &
|
|
101
|
+
MergeExtensionPackCapabilities<DefinitionExtensionPacks<Definition>>;
|
|
77
102
|
|
|
78
103
|
type DefinitionTargetId<Definition> = Definition extends {
|
|
79
104
|
readonly target: TargetPackRef<'sql', infer Target>;
|
|
@@ -509,12 +534,12 @@ type BuiltStorageTables<Definition> = {
|
|
|
509
534
|
readonly indexes: ReadonlyArray<Index>;
|
|
510
535
|
readonly foreignKeys: ReadonlyArray<{
|
|
511
536
|
readonly source: {
|
|
512
|
-
readonly namespaceId:
|
|
537
|
+
readonly namespaceId: NamespaceId;
|
|
513
538
|
readonly tableName: string;
|
|
514
539
|
readonly columns: readonly string[];
|
|
515
540
|
};
|
|
516
541
|
readonly target: {
|
|
517
|
-
readonly namespaceId:
|
|
542
|
+
readonly namespaceId: NamespaceId;
|
|
518
543
|
readonly tableName: string;
|
|
519
544
|
readonly columns: readonly string[];
|
|
520
545
|
};
|
|
@@ -538,15 +563,24 @@ type BuiltStorageTables<Definition> = {
|
|
|
538
563
|
: Record<string, never>);
|
|
539
564
|
};
|
|
540
565
|
|
|
541
|
-
type
|
|
566
|
+
type BuiltDocumentScopedTypes<Definition> = {
|
|
542
567
|
readonly [K in keyof DefinitionTypes<Definition> as DefinitionTypes<Definition>[K] extends PostgresEnumStorageEntry
|
|
543
568
|
? never
|
|
544
569
|
: K]: DefinitionTypes<Definition>[K];
|
|
545
570
|
};
|
|
546
571
|
|
|
572
|
+
type BuiltDomain<Definition> =
|
|
573
|
+
BuiltDocumentScopedTypes<Definition> extends Record<never, never>
|
|
574
|
+
? Record<string, never>
|
|
575
|
+
: {
|
|
576
|
+
readonly __unbound__: {
|
|
577
|
+
readonly types: BuiltDocumentScopedTypes<Definition>;
|
|
578
|
+
};
|
|
579
|
+
};
|
|
580
|
+
|
|
547
581
|
type BuiltStorage<Definition> = {
|
|
548
582
|
readonly storageHash: StorageHashBase<string>;
|
|
549
|
-
readonly types
|
|
583
|
+
readonly types?: BuiltDocumentScopedTypes<Definition>;
|
|
550
584
|
// SQL contracts always carry a literal `__unbound__` namespace whose tables
|
|
551
585
|
// slot is narrowed to the actual built table shape so downstream DSL
|
|
552
586
|
// surfaces (TableProxyContract, Ref, SelectBuilder) keep literal-keyed
|
|
@@ -604,16 +638,11 @@ export type SqlContractResult<Definition> = ContractWithTypeMaps<
|
|
|
604
638
|
Contract<BuiltStorage<Definition>, BuiltModels<Definition>> & {
|
|
605
639
|
readonly target: DefinitionTargetId<Definition>;
|
|
606
640
|
readonly targetFamily: 'sql';
|
|
607
|
-
} & {
|
|
641
|
+
} & { readonly domain: BuiltDomain<Definition> } & {
|
|
608
642
|
readonly extensionPacks: keyof DefinitionExtensionPacks<Definition> extends never
|
|
609
643
|
? Record<string, never>
|
|
610
644
|
: DefinitionExtensionPacks<Definition>;
|
|
611
|
-
readonly capabilities:
|
|
612
|
-
string,
|
|
613
|
-
Record<string, boolean>
|
|
614
|
-
>
|
|
615
|
-
? DefinitionCapabilities<Definition>
|
|
616
|
-
: Record<string, Record<string, boolean>>;
|
|
645
|
+
readonly capabilities: DerivedCapabilities<Definition>;
|
|
617
646
|
},
|
|
618
647
|
TypeMaps<
|
|
619
648
|
CodecTypesFromDefinition<Definition>,
|