@prisma-next/sql-contract-ts 0.11.0-dev.7 → 0.11.0-dev.71

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/package.json CHANGED
@@ -1,27 +1,27 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-contract-ts",
3
- "version": "0.11.0-dev.7",
3
+ "version": "0.11.0-dev.71",
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.7",
10
- "@prisma-next/contract": "0.11.0-dev.7",
11
- "@prisma-next/contract-authoring": "0.11.0-dev.7",
12
- "@prisma-next/framework-components": "0.11.0-dev.7",
13
- "@prisma-next/sql-contract": "0.11.0-dev.7",
14
- "@prisma-next/utils": "0.11.0-dev.7",
9
+ "@prisma-next/config": "0.11.0-dev.71",
10
+ "@prisma-next/contract": "0.11.0-dev.71",
11
+ "@prisma-next/contract-authoring": "0.11.0-dev.71",
12
+ "@prisma-next/framework-components": "0.11.0-dev.71",
13
+ "@prisma-next/sql-contract": "0.11.0-dev.71",
14
+ "@prisma-next/utils": "0.11.0-dev.71",
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.7",
21
- "@prisma-next/tsconfig": "0.11.0-dev.7",
20
+ "@prisma-next/test-utils": "0.11.0-dev.71",
21
+ "@prisma-next/tsconfig": "0.11.0-dev.71",
22
22
  "@types/pg": "8.20.0",
23
23
  "pg": "8.20.0",
24
- "@prisma-next/tsdown": "0.11.0-dev.7",
24
+ "@prisma-next/tsdown": "0.11.0-dev.71",
25
25
  "tsdown": "0.22.0",
26
26
  "typescript": "5.9.3",
27
27
  "vitest": "4.1.6"
@@ -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 { type Namespace, UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
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 models: Record<string, ContractModel> = {};
291
- const roots: Record<string, 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
- roots[tableName] = semanticModel.modelName;
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: relation.toModel,
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
- models[semanticModel.modelName] = {
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: Record<string, SqlNamespaceTablesInput | Namespace> = Object.fromEntries(
530
- [...namespaceCoordinateIds].sort().map((id) => {
531
- const enumTypes = namespaceEnumTypesById[id];
532
- const nsInput: SqlNamespaceTablesInput = {
533
- id,
534
- tables: tablesByNamespace[id] ?? {},
535
- ...ifDefined('enum', enumTypes),
536
- };
537
- return [id, createNamespace ? createNamespace(nsInput) : nsInput];
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 } as SqlStorageInput); // Builder types are wider than SqlStorageInput until SqlStorage normalises document types.
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 capabilities: Record<string, Record<string, boolean>> = definition.capabilities || {};
582
- const profileHash = computeProfileHash({ target, targetFamily, capabilities });
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
- models,
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,
@@ -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: {
@@ -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 buildSqlContractFromDefinition(
292
- buildContractDefinition(definition),
293
- definition.codecLookup,
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>;
@@ -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
@@ -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
@@ -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 DefinitionCapabilities<Definition> = Definition extends {
73
- readonly capabilities?: infer Capabilities extends Record<string, Record<string, boolean>>;
73
+ type ExtractPackCapabilities<P> = P extends {
74
+ readonly capabilities?: infer Caps extends Record<string, Record<string, boolean>>;
74
75
  }
75
- ? Capabilities
76
- : undefined;
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: string;
537
+ readonly namespaceId: NamespaceId;
513
538
  readonly tableName: string;
514
539
  readonly columns: readonly string[];
515
540
  };
516
541
  readonly target: {
517
- readonly namespaceId: string;
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 BuiltStorageTypes<Definition> = {
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: BuiltStorageTypes<Definition>;
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: DefinitionCapabilities<Definition> extends Record<
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>,
@@ -1,2 +1,6 @@
1
1
  export type { ContractConfig } from '@prisma-next/config/config-types';
2
- export { typescriptContract, typescriptContractFromPath } from '../config-types';
2
+ export {
3
+ emptyContract,
4
+ typescriptContract,
5
+ typescriptContractFromPath,
6
+ } from '../config-types';