@prisma-next/sql-contract-ts 0.12.0-dev.7 → 0.12.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.
@@ -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 {
@@ -12,6 +13,7 @@ import type {
12
13
  StorageTypeInstance,
13
14
  } from '@prisma-next/sql-contract/types';
14
15
  import { blindCast } from '@prisma-next/utils/casts';
16
+ import { ifDefined } from '@prisma-next/utils/defined';
15
17
  import { buildSqlContractFromDefinition } from './build-contract';
16
18
  import {
17
19
  type ComposedAuthoringHelpers,
@@ -20,6 +22,7 @@ import {
20
22
  import {
21
23
  type ContractInput,
22
24
  type ContractModelBuilder,
25
+ extensionModel,
23
26
  field,
24
27
  isContractInput,
25
28
  type ModelAttributesSpec,
@@ -32,6 +35,7 @@ import {
32
35
  } from './contract-dsl';
33
36
  import { buildContractDefinition } from './contract-lowering';
34
37
  import type { SqlContractResult } from './contract-types';
38
+ import type { EnumTypeHandle } from './enum-type';
35
39
 
36
40
  export { buildSqlContractFromDefinition } from './build-contract';
37
41
 
@@ -65,11 +69,13 @@ type ContractDefinition<
65
69
  readonly naming?: Naming;
66
70
  readonly storageHash?: StorageHash;
67
71
  readonly foreignKeyDefaults?: ForeignKeyDefaults;
72
+ readonly defaultControlPolicy?: ControlPolicy;
68
73
  readonly namespaces?: Namespaces;
69
74
  readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
70
75
  readonly types?: Types;
71
76
  readonly models?: Models;
72
77
  readonly codecLookup?: CodecLookup;
78
+ readonly enums?: Record<string, EnumTypeHandle>;
73
79
  };
74
80
 
75
81
  type ContractScaffold<
@@ -87,11 +93,13 @@ type ContractScaffold<
87
93
  readonly naming?: Naming;
88
94
  readonly storageHash?: StorageHash;
89
95
  readonly foreignKeyDefaults?: ForeignKeyDefaults;
96
+ readonly defaultControlPolicy?: ControlPolicy;
90
97
  readonly namespaces?: Namespaces;
91
98
  readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
92
99
  readonly types?: never;
93
100
  readonly models?: never;
94
101
  readonly codecLookup?: CodecLookup;
102
+ readonly enums?: Record<string, EnumTypeHandle>;
95
103
  };
96
104
 
97
105
  type ContractFactory<
@@ -289,6 +297,131 @@ function buildContractFromDsl<Definition extends ContractInput>(
289
297
  >(buildSqlContractFromDefinition(buildContractDefinition(definition), definition.codecLookup));
290
298
  }
291
299
 
300
+ // Input for buildBoundContract — all fields from ContractInput except family/target
301
+ // (those are injected by the builder, pre-bound at the call site).
302
+ type BoundDefinitionInput<
303
+ Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<
304
+ never,
305
+ never
306
+ >,
307
+ Models extends Record<string, ModelLike> = Record<never, never>,
308
+ ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined,
309
+ Naming extends ContractInput['naming'] | undefined = undefined,
310
+ StorageHash extends string | undefined = undefined,
311
+ ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
312
+ Namespaces extends readonly string[] | undefined = undefined,
313
+ > = {
314
+ readonly extensionPacks?: ExtensionPacks;
315
+ readonly naming?: Naming;
316
+ readonly storageHash?: StorageHash;
317
+ readonly foreignKeyDefaults?: ForeignKeyDefaults;
318
+ readonly defaultControlPolicy?: ControlPolicy;
319
+ readonly namespaces?: Namespaces;
320
+ readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
321
+ readonly types?: Types;
322
+ readonly models?: Models;
323
+ readonly codecLookup?: CodecLookup;
324
+ readonly enums?: Record<string, EnumTypeHandle>;
325
+ };
326
+
327
+ // Merges a bound input with the pre-bound family/target to produce a full ContractDefinition.
328
+ type WithFamilyTarget<
329
+ Input,
330
+ F extends FamilyPackRef<string>,
331
+ T extends TargetPackRef<'sql', string>,
332
+ > = Input & { readonly family: F; readonly target: T };
333
+
334
+ /**
335
+ * Shared builder that assembles a SqlContract with pre-bound family and target.
336
+ * Extension wrappers keep their own public overloads and delegate their impl body here;
337
+ * this is a plain overloaded function (not a factory returning an overloaded function)
338
+ * so no overloaded-function-return cast is needed.
339
+ *
340
+ * Overload 1: definition form (no factory).
341
+ */
342
+ export function buildBoundContract<
343
+ const F extends FamilyPackRef<string>,
344
+ const T extends TargetPackRef<'sql', string>,
345
+ const Definition extends BoundDefinitionInput<
346
+ Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
347
+ Record<string, ModelLike>,
348
+ Record<string, ExtensionPackRef<'sql', string>> | undefined,
349
+ ContractInput['naming'] | undefined,
350
+ string | undefined,
351
+ ForeignKeyDefaultsState | undefined,
352
+ readonly string[] | undefined
353
+ >,
354
+ >(
355
+ family: F,
356
+ target: T,
357
+ definition: Definition,
358
+ factory?: undefined,
359
+ ): SqlContractResult<WithFamilyTarget<Definition, F, T>>;
360
+ /**
361
+ * Overload 2: factory form.
362
+ */
363
+ export function buildBoundContract<
364
+ const F extends FamilyPackRef<string>,
365
+ const T extends TargetPackRef<'sql', string>,
366
+ const Definition extends BoundDefinitionInput<
367
+ Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
368
+ Record<string, ModelLike>,
369
+ Record<string, ExtensionPackRef<'sql', string>> | undefined,
370
+ ContractInput['naming'] | undefined,
371
+ string | undefined,
372
+ ForeignKeyDefaultsState | undefined,
373
+ readonly string[] | undefined
374
+ >,
375
+ const Built extends {
376
+ readonly types?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
377
+ readonly models?: Record<string, ModelLike>;
378
+ },
379
+ >(
380
+ family: F,
381
+ target: T,
382
+ definition: Definition,
383
+ factory: (
384
+ helpers: ComposedAuthoringHelpers<F, T, NonNullable<Definition['extensionPacks']>>,
385
+ ) => Built,
386
+ ): SqlContractResult<WithFamilyTarget<Definition & Built, F, T>>;
387
+ /** Implementation. */
388
+ export function buildBoundContract(
389
+ family: FamilyPackRef<string>,
390
+ target: TargetPackRef<'sql', string>,
391
+ definition: Omit<ContractInput, 'family' | 'target'>,
392
+ factory?:
393
+ | ((
394
+ helpers: ComposedAuthoringHelpers<
395
+ FamilyPackRef<string>,
396
+ TargetPackRef<'sql', string>,
397
+ Record<string, ExtensionPackRef<'sql', string>> | undefined
398
+ >,
399
+ ) => {
400
+ readonly types?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
401
+ readonly models?: Record<string, ModelLike>;
402
+ })
403
+ | undefined,
404
+ ) {
405
+ const full = { ...definition, family, target };
406
+
407
+ if (factory !== undefined) {
408
+ const built = factory(
409
+ createComposedAuthoringHelpers({
410
+ family,
411
+ target,
412
+ extensionPacks: definition.extensionPacks,
413
+ }),
414
+ );
415
+ return buildContractFromDsl({
416
+ ...full,
417
+ ...ifDefined('types', built.types),
418
+ ...ifDefined('models', built.models),
419
+ });
420
+ }
421
+
422
+ return buildContractFromDsl(full);
423
+ }
424
+
292
425
  export function defineContract<
293
426
  const Family extends FamilyPackRef<string>,
294
427
  const Target extends TargetPackRef<'sql', string>,
@@ -384,22 +517,10 @@ export function defineContract(
384
517
  );
385
518
  }
386
519
 
387
- if (!factory) {
388
- return buildContractFromDsl(definition);
520
+ if (factory !== undefined) {
521
+ return buildBoundContract(definition.family, definition.target, definition, factory);
389
522
  }
390
-
391
- const builtDefinition = {
392
- ...definition,
393
- ...factory(
394
- createComposedAuthoringHelpers({
395
- family: definition.family,
396
- target: definition.target,
397
- extensionPacks: definition.extensionPacks,
398
- }),
399
- ),
400
- };
401
-
402
- return buildContractFromDsl(builtDefinition);
523
+ return buildBoundContract(definition.family, definition.target, definition);
403
524
  }
404
525
 
405
526
  export type {
@@ -409,4 +530,4 @@ export type {
409
530
  ModelLike,
410
531
  ScalarFieldBuilder,
411
532
  };
412
- export { field, model, rel };
533
+ export { extensionModel, field, model, rel };
@@ -1,4 +1,8 @@
1
- import type { ColumnDefault, ExecutionMutationDefaultPhases } from '@prisma-next/contract/types';
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';
@@ -9,6 +13,7 @@ import type {
9
13
  SqlNamespaceTablesInput,
10
14
  StorageTypeInstance,
11
15
  } from '@prisma-next/sql-contract/types';
16
+ import type { EnumTypeHandle } from './enum-type';
12
17
 
13
18
  export type { ExecutionMutationDefaultPhases };
14
19
 
@@ -20,6 +25,8 @@ export interface FieldNode {
20
25
  readonly default?: ColumnDefault;
21
26
  readonly executionDefaults?: ExecutionMutationDefaultPhases;
22
27
  readonly many?: boolean;
28
+ /** Present when the field was authored with `field.namedType(enumHandle)`. */
29
+ readonly enumTypeHandle?: EnumTypeHandle;
23
30
  }
24
31
 
25
32
  export interface PrimaryKeyNode {
@@ -52,6 +59,12 @@ export interface ForeignKeyNode {
52
59
  * know the target namespace can stamp it explicitly.
53
60
  */
54
61
  readonly namespaceId?: string;
62
+ /**
63
+ * Contract-space identity of the referenced table. When present, the
64
+ * table lives in a different contract space (identified by this value)
65
+ * rather than the current contract. Absent for local FKs.
66
+ */
67
+ readonly spaceId?: string;
55
68
  };
56
69
  readonly name?: string;
57
70
  readonly onDelete?: ReferentialAction;
@@ -65,6 +78,17 @@ export interface RelationNode {
65
78
  readonly toModel: string;
66
79
  readonly toTable: string;
67
80
  readonly cardinality: '1:1' | '1:N' | 'N:1' | 'N:M';
81
+ /**
82
+ * Contract-space identity of the related model. When present, the
83
+ * related model lives in a different contract space. Absent for local
84
+ * (same-space) relations.
85
+ */
86
+ readonly spaceId?: string;
87
+ /**
88
+ * Namespace coordinate of the related model in the foreign space.
89
+ * Only set when `spaceId` is present.
90
+ */
91
+ readonly namespaceId?: string;
68
92
  readonly on: {
69
93
  readonly parentTable: string;
70
94
  readonly parentColumns: readonly string[];
@@ -113,10 +137,20 @@ export interface ModelNode {
113
137
  readonly indexes?: readonly IndexNode[];
114
138
  readonly foreignKeys?: readonly ForeignKeyNode[];
115
139
  readonly relations?: readonly RelationNode[];
140
+ readonly control?: ControlPolicy;
141
+ /**
142
+ * Single-table-inheritance variants share their base model's storage table:
143
+ * the variant's columns are materialised onto the base `ModelNode`, and this
144
+ * model contributes a domain model but no storage table of its own. When set,
145
+ * the assembler builds the domain model but skips creating a (shadow) storage
146
+ * table and a root for this model — the base owns both.
147
+ */
148
+ readonly sharesBaseTable?: boolean;
116
149
  }
117
150
 
118
151
  export interface ContractDefinition {
119
152
  readonly target: TargetPackRef<'sql', string>;
153
+ readonly defaultControlPolicy?: ControlPolicy;
120
154
  readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
121
155
  readonly storageHash?: string;
122
156
  readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
@@ -124,7 +158,7 @@ export interface ContractDefinition {
124
158
  /**
125
159
  * Enum types declared inside a named `namespace { enum … }` block,
126
160
  * keyed first by namespace id then by type name. These are routed to
127
- * `storage.namespaces[nsId].enum` rather than the implicit fallback
161
+ * `storage.namespaces[nsId].entries.type` rather than the implicit fallback
128
162
  * namespace used for top-level `storageTypes` enums.
129
163
  */
130
164
  readonly namespaceTypes?: Readonly<
@@ -139,8 +173,20 @@ export interface ContractDefinition {
139
173
  * Target-supplied factory that materialises a `Namespace` concretion
140
174
  * for a declared namespace coordinate. Mirrors
141
175
  * `ContractInput.createNamespace`.
176
+ *
177
+ * The optional second argument carries target-specific enum types for the
178
+ * namespace (e.g. postgres enum registrations keyed by type name).
142
179
  */
143
- readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
180
+ readonly createNamespace?: (
181
+ input: SqlNamespaceTablesInput,
182
+ enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,
183
+ ) => Namespace;
144
184
  readonly models: readonly ModelNode[];
145
185
  readonly valueObjects?: readonly ValueObjectNode[];
186
+ /**
187
+ * Domain enum handles authored via `enumType()`. Each entry lowers to a
188
+ * domain `enum` entry and a storage `valueSet` entry in the contract's
189
+ * default namespace.
190
+ */
191
+ readonly enums?: Record<string, EnumTypeHandle>;
146
192
  }