@prisma-next/sql-contract-ts 0.13.0-dev.3 → 0.13.0-dev.30

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.13.0-dev.3",
3
+ "version": "0.13.0-dev.30",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "SQL-specific TypeScript contract authoring surface for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/config": "0.13.0-dev.3",
10
- "@prisma-next/contract": "0.13.0-dev.3",
11
- "@prisma-next/contract-authoring": "0.13.0-dev.3",
12
- "@prisma-next/framework-components": "0.13.0-dev.3",
13
- "@prisma-next/sql-contract": "0.13.0-dev.3",
14
- "@prisma-next/utils": "0.13.0-dev.3",
9
+ "@prisma-next/config": "0.13.0-dev.30",
10
+ "@prisma-next/contract": "0.13.0-dev.30",
11
+ "@prisma-next/contract-authoring": "0.13.0-dev.30",
12
+ "@prisma-next/framework-components": "0.13.0-dev.30",
13
+ "@prisma-next/sql-contract": "0.13.0-dev.30",
14
+ "@prisma-next/utils": "0.13.0-dev.30",
15
15
  "arktype": "^2.2.0",
16
16
  "pathe": "^2.0.3",
17
17
  "ts-toolbelt": "^9.6.0"
18
18
  },
19
19
  "devDependencies": {
20
- "@prisma-next/test-utils": "0.13.0-dev.3",
21
- "@prisma-next/tsconfig": "0.13.0-dev.3",
20
+ "@prisma-next/test-utils": "0.13.0-dev.30",
21
+ "@prisma-next/tsconfig": "0.13.0-dev.30",
22
22
  "@types/pg": "8.20.0",
23
23
  "pg": "8.21.0",
24
- "@prisma-next/tsdown": "0.13.0-dev.3",
24
+ "@prisma-next/tsdown": "0.13.0-dev.30",
25
25
  "tsdown": "0.22.1",
26
26
  "typescript": "5.9.3",
27
27
  "vitest": "4.1.8"
@@ -6,7 +6,6 @@ import {
6
6
  import {
7
7
  asNamespaceId,
8
8
  type ColumnDefault,
9
- type ColumnDefaultLiteralInputValue,
10
9
  type Contract,
11
10
  type ContractEnum,
12
11
  type ContractField,
@@ -36,13 +35,10 @@ import {
36
35
  applyFkDefaults,
37
36
  buildSqlNamespace,
38
37
  type CheckConstraintInput,
39
- isPostgresEnumStorageEntry,
40
- type PostgresEnumStorageEntry,
41
38
  type SqlNamespaceTablesInput,
42
39
  SqlStorage,
43
40
  type SqlStorageInput,
44
41
  type StorageColumn,
45
- StorageTable,
46
42
  type StorageTableInput,
47
43
  type StorageTypeInstance,
48
44
  type StorageValueSetInput,
@@ -63,16 +59,15 @@ type DomainFieldRef =
63
59
  | { readonly kind: 'scalar'; readonly many?: boolean }
64
60
  | { readonly kind: 'valueObject'; readonly name: string; readonly many?: boolean };
65
61
 
66
- function encodeDefaultLiteralValue(
67
- value: ColumnDefaultLiteralInputValue,
68
- codecId: string,
69
- codecLookup?: CodecLookup,
70
- ): JsonValue {
62
+ function encodeViaCodec(value: unknown, codecId: string, codecLookup?: CodecLookup): JsonValue {
71
63
  const codec = codecLookup?.get(codecId);
72
64
  if (codec) {
73
65
  return codec.encodeJson(value);
74
66
  }
75
- return value as JsonValue;
67
+ return blindCast<
68
+ JsonValue,
69
+ 'no codec lookup at build time: literal/enum member value is already JSON-safe'
70
+ >(value);
76
71
  }
77
72
 
78
73
  function encodeColumnDefault(
@@ -85,7 +80,7 @@ function encodeColumnDefault(
85
80
  }
86
81
  return {
87
82
  kind: 'literal',
88
- value: encodeDefaultLiteralValue(defaultInput.value, codecId, codecLookup),
83
+ value: encodeViaCodec(defaultInput.value, codecId, codecLookup),
89
84
  };
90
85
  }
91
86
 
@@ -322,55 +317,6 @@ function ensureUnboundNamespaceSlot(
322
317
  });
323
318
  }
324
319
 
325
- const POSTGRES_ENUM_NAMESPACE_ID = 'public';
326
-
327
- function partitionStorageTypesForTarget(
328
- targetId: string,
329
- types: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
330
- namespaceTypes?: Readonly<Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>>,
331
- ): {
332
- readonly documentTypes: Record<string, StorageTypeInstance>;
333
- readonly namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>>;
334
- } {
335
- const documentTypes: Record<string, StorageTypeInstance> = {};
336
- const namespaceEnumTypesById: Record<string, Record<string, PostgresEnumStorageEntry>> = {};
337
- for (const [name, entry] of Object.entries(types)) {
338
- if (isPostgresEnumStorageEntry(entry)) {
339
- if (targetId !== 'postgres') {
340
- throw new Error(
341
- `buildSqlContractFromDefinition: postgres enum "${name}" is only valid when target is "postgres" (got "${targetId}").`,
342
- );
343
- }
344
- let slot = namespaceEnumTypesById[POSTGRES_ENUM_NAMESPACE_ID];
345
- if (slot === undefined) {
346
- slot = {};
347
- namespaceEnumTypesById[POSTGRES_ENUM_NAMESPACE_ID] = slot;
348
- }
349
- slot[name] = entry;
350
- continue;
351
- }
352
- documentTypes[name] = entry;
353
- }
354
- if (namespaceTypes !== undefined) {
355
- for (const [nsId, enumsInNs] of Object.entries(namespaceTypes)) {
356
- for (const [name, entry] of Object.entries(enumsInNs)) {
357
- if (targetId !== 'postgres') {
358
- throw new Error(
359
- `buildSqlContractFromDefinition: postgres enum "${name}" is only valid when target is "postgres" (got "${targetId}").`,
360
- );
361
- }
362
- let slot = namespaceEnumTypesById[nsId];
363
- if (slot === undefined) {
364
- slot = {};
365
- namespaceEnumTypesById[nsId] = slot;
366
- }
367
- slot[name] = entry;
368
- }
369
- }
370
- }
371
- return { documentTypes, namespaceEnumTypesById };
372
- }
373
-
374
320
  export function buildSqlContractFromDefinition(
375
321
  definition: ContractDefinition,
376
322
  codecLookup?: CodecLookup,
@@ -391,7 +337,7 @@ export function buildSqlContractFromDefinition(
391
337
  definition.models.map((m) => [`${resolveNamespaceId(m)}:${m.modelName}`, m]),
392
338
  );
393
339
 
394
- const tablesByNamespace: Record<string, Record<string, StorageTable>> = {};
340
+ const tablesByNamespace: Record<string, Record<string, StorageTableInput>> = {};
395
341
  const modelNameToNamespaceId = new Map<string, string>();
396
342
  const executionDefaults: ExecutionMutationDefault[] = [];
397
343
  const modelsByNamespace: Record<string, Record<string, ContractModel>> = {};
@@ -451,9 +397,9 @@ export function buildSqlContractFromDefinition(
451
397
  enumHandle !== undefined
452
398
  ? {
453
399
  plane: 'storage',
454
- entityKind: 'value-set',
400
+ entityKind: 'valueSet',
455
401
  namespaceId: defaultNamespaceId,
456
- name: enumHandle.enumName,
402
+ entityName: enumHandle.enumName,
457
403
  }
458
404
  : undefined;
459
405
  const domainValueSetRef: ValueSetRef | undefined =
@@ -462,7 +408,7 @@ export function buildSqlContractFromDefinition(
462
408
  plane: 'domain',
463
409
  entityKind: 'enum',
464
410
  namespaceId: defaultNamespaceId,
465
- name: enumHandle.enumName,
411
+ entityName: enumHandle.enumName,
466
412
  }
467
413
  : undefined;
468
414
 
@@ -604,7 +550,7 @@ export function buildSqlContractFromDefinition(
604
550
  `buildSqlContractFromDefinition: duplicate table "${tableName}" in namespace "${namespaceId}".`,
605
551
  );
606
552
  }
607
- nsTables[tableName] = new StorageTable(tableInput);
553
+ nsTables[tableName] = tableInput;
608
554
  }
609
555
 
610
556
  // --- Build contract model ---
@@ -725,13 +671,9 @@ export function buildSqlContractFromDefinition(
725
671
  // discriminator shape before hashing so the storageHash matches the
726
672
  // persisted JSON envelope produced from the SqlStorage class instance
727
673
  // (which always carries the discriminator).
728
- const rawStorageTypes = (definition.storageTypes ?? {}) as Record<
729
- string,
730
- StorageTypeInstance | PostgresEnumStorageEntry
731
- >;
732
- const storageTypes = Object.fromEntries(
674
+ const rawStorageTypes = definition.storageTypes ?? {};
675
+ const documentTypes: Record<string, StorageTypeInstance> = Object.fromEntries(
733
676
  Object.entries(rawStorageTypes).map(([name, entry]) => {
734
- if (isPostgresEnumStorageEntry(entry)) return [name, entry];
735
677
  if ((entry as { kind?: unknown }).kind === 'codec-instance') return [name, entry];
736
678
  return [
737
679
  name,
@@ -743,15 +685,7 @@ export function buildSqlContractFromDefinition(
743
685
  ];
744
686
  }),
745
687
  );
746
- const { documentTypes, namespaceEnumTypesById } = partitionStorageTypesForTarget(
747
- target,
748
- storageTypes,
749
- definition.namespaceTypes,
750
- );
751
688
  const namespaceCoordinateIds = collectStorageNamespaceCoordinateIds(definition);
752
- for (const id of Object.keys(namespaceEnumTypesById)) {
753
- namespaceCoordinateIds.add(id);
754
- }
755
689
 
756
690
  // Build per-namespace registries for `enumType()` handles.
757
691
  // All authored enums target the contract's default namespace.
@@ -771,7 +705,10 @@ export function buildSqlContractFromDefinition(
771
705
  }
772
706
  domainSlot[enumName] = {
773
707
  codecId: handle.codecId,
774
- members: handle.enumMembers,
708
+ members: handle.enumMembers.map((m) => ({
709
+ name: m.name,
710
+ value: encodeViaCodec(m.value, handle.codecId, codecLookup),
711
+ })),
775
712
  };
776
713
 
777
714
  let storageSlot = storageValueSetsByNs[nsId];
@@ -780,8 +717,8 @@ export function buildSqlContractFromDefinition(
780
717
  storageValueSetsByNs[nsId] = storageSlot;
781
718
  }
782
719
  storageSlot[enumName] = {
783
- kind: 'value-set',
784
- values: handle.values,
720
+ kind: 'valueSet',
721
+ values: handle.values.map((v) => encodeViaCodec(v, handle.codecId, codecLookup)),
785
722
  };
786
723
  }
787
724
 
@@ -792,7 +729,6 @@ export function buildSqlContractFromDefinition(
792
729
  >(
793
730
  Object.fromEntries(
794
731
  [...namespaceCoordinateIds].sort().map((id) => {
795
- const enumTypes = namespaceEnumTypesById[id];
796
732
  const valueSetEntries = storageValueSetsByNs[id];
797
733
  const nsInput: SqlNamespaceTablesInput = {
798
734
  id,
@@ -803,10 +739,7 @@ export function buildSqlContractFromDefinition(
803
739
  : {}),
804
740
  },
805
741
  };
806
- return [
807
- id,
808
- createNamespace ? createNamespace(nsInput, enumTypes) : buildSqlNamespace(nsInput),
809
- ];
742
+ return [id, createNamespace ? createNamespace(nsInput) : buildSqlNamespace(nsInput)];
810
743
  }),
811
744
  ),
812
745
  );
@@ -7,11 +7,7 @@ import type {
7
7
  TargetPackRef,
8
8
  } from '@prisma-next/framework-components/components';
9
9
  import type { Namespace } from '@prisma-next/framework-components/ir';
10
- import type {
11
- PostgresEnumStorageEntry,
12
- SqlNamespaceTablesInput,
13
- StorageTypeInstance,
14
- } from '@prisma-next/sql-contract/types';
10
+ import type { SqlNamespaceTablesInput, StorageTypeInstance } from '@prisma-next/sql-contract/types';
15
11
  import { blindCast } from '@prisma-next/utils/casts';
16
12
  import { ifDefined } from '@prisma-next/utils/defined';
17
13
  import { buildSqlContractFromDefinition } from './build-contract';
@@ -55,13 +51,14 @@ type ModelLike = {
55
51
  type ContractDefinition<
56
52
  Family extends FamilyPackRef<string>,
57
53
  Target extends TargetPackRef<'sql', string>,
58
- Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
54
+ Types extends Record<string, StorageTypeInstance>,
59
55
  Models extends Record<string, ModelLike>,
60
56
  ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
61
57
  Naming extends ContractInput['naming'] | undefined,
62
58
  StorageHash extends string | undefined,
63
59
  ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined,
64
60
  Namespaces extends readonly string[] | undefined = undefined,
61
+ Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
65
62
  > = {
66
63
  readonly family: Family;
67
64
  readonly target: Target;
@@ -75,7 +72,7 @@ type ContractDefinition<
75
72
  readonly types?: Types;
76
73
  readonly models?: Models;
77
74
  readonly codecLookup?: CodecLookup;
78
- readonly enums?: Record<string, EnumTypeHandle>;
75
+ readonly enums?: Enums;
79
76
  };
80
77
 
81
78
  type ContractScaffold<
@@ -86,6 +83,7 @@ type ContractScaffold<
86
83
  StorageHash extends string | undefined,
87
84
  ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined,
88
85
  Namespaces extends readonly string[] | undefined = undefined,
86
+ Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
89
87
  > = {
90
88
  readonly family: Family;
91
89
  readonly target: Target;
@@ -99,18 +97,20 @@ type ContractScaffold<
99
97
  readonly types?: never;
100
98
  readonly models?: never;
101
99
  readonly codecLookup?: CodecLookup;
102
- readonly enums?: Record<string, EnumTypeHandle>;
100
+ readonly enums?: Enums;
103
101
  };
104
102
 
105
103
  type ContractFactory<
106
104
  Family extends FamilyPackRef<string>,
107
105
  Target extends TargetPackRef<'sql', string>,
108
- Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
106
+ Types extends Record<string, StorageTypeInstance>,
109
107
  Models extends Record<string, ModelLike>,
110
108
  ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
109
+ Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
111
110
  > = (helpers: ComposedAuthoringHelpers<Family, Target, ExtensionPacks>) => {
112
111
  readonly types?: Types;
113
112
  readonly models?: Models;
113
+ readonly enums?: Enums;
114
114
  };
115
115
 
116
116
  function validateTargetPackRef(
@@ -300,10 +300,7 @@ function buildContractFromDsl<Definition extends ContractInput>(
300
300
  // Input for buildBoundContract — all fields from ContractInput except family/target
301
301
  // (those are injected by the builder, pre-bound at the call site).
302
302
  type BoundDefinitionInput<
303
- Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<
304
- never,
305
- never
306
- >,
303
+ Types extends Record<string, StorageTypeInstance> = Record<never, never>,
307
304
  Models extends Record<string, ModelLike> = Record<never, never>,
308
305
  ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined,
309
306
  Naming extends ContractInput['naming'] | undefined = undefined,
@@ -324,6 +321,20 @@ type BoundDefinitionInput<
324
321
  readonly enums?: Record<string, EnumTypeHandle>;
325
322
  };
326
323
 
324
+ // A bare `Record<string, EnumTypeHandle>` (no literal keys) is the widened
325
+ // default for a side that declared no enums; drop it so the merge keeps only
326
+ // literally-authored enum handles.
327
+ type LiteralEnums<E extends Record<string, EnumTypeHandle>> = string extends keyof E
328
+ ? Record<never, never>
329
+ : E;
330
+
331
+ // Merges enum handles authored on the scaffold definition with those returned
332
+ // from the factory callback. Either side may be the widened default (empty).
333
+ export type MergeEnums<
334
+ ScaffoldEnums extends Record<string, EnumTypeHandle>,
335
+ FactoryEnums extends Record<string, EnumTypeHandle>,
336
+ > = LiteralEnums<ScaffoldEnums> & LiteralEnums<FactoryEnums>;
337
+
327
338
  // Merges a bound input with the pre-bound family/target to produce a full ContractDefinition.
328
339
  type WithFamilyTarget<
329
340
  Input,
@@ -343,7 +354,7 @@ export function buildBoundContract<
343
354
  const F extends FamilyPackRef<string>,
344
355
  const T extends TargetPackRef<'sql', string>,
345
356
  const Definition extends BoundDefinitionInput<
346
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
357
+ Record<string, StorageTypeInstance>,
347
358
  Record<string, ModelLike>,
348
359
  Record<string, ExtensionPackRef<'sql', string>> | undefined,
349
360
  ContractInput['naming'] | undefined,
@@ -364,7 +375,7 @@ export function buildBoundContract<
364
375
  const F extends FamilyPackRef<string>,
365
376
  const T extends TargetPackRef<'sql', string>,
366
377
  const Definition extends BoundDefinitionInput<
367
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
378
+ Record<string, StorageTypeInstance>,
368
379
  Record<string, ModelLike>,
369
380
  Record<string, ExtensionPackRef<'sql', string>> | undefined,
370
381
  ContractInput['naming'] | undefined,
@@ -373,8 +384,9 @@ export function buildBoundContract<
373
384
  readonly string[] | undefined
374
385
  >,
375
386
  const Built extends {
376
- readonly types?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
387
+ readonly types?: Record<string, StorageTypeInstance>;
377
388
  readonly models?: Record<string, ModelLike>;
389
+ readonly enums?: Record<string, EnumTypeHandle>;
378
390
  },
379
391
  >(
380
392
  family: F,
@@ -397,8 +409,9 @@ export function buildBoundContract(
397
409
  Record<string, ExtensionPackRef<'sql', string>> | undefined
398
410
  >,
399
411
  ) => {
400
- readonly types?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
412
+ readonly types?: Record<string, StorageTypeInstance>;
401
413
  readonly models?: Record<string, ModelLike>;
414
+ readonly enums?: Record<string, EnumTypeHandle>;
402
415
  })
403
416
  | undefined,
404
417
  ) {
@@ -412,10 +425,12 @@ export function buildBoundContract(
412
425
  extensionPacks: definition.extensionPacks,
413
426
  }),
414
427
  );
428
+ const mergedEnums = { ...(definition.enums ?? {}), ...built.enums };
415
429
  return buildContractFromDsl({
416
430
  ...full,
417
431
  ...ifDefined('types', built.types),
418
432
  ...ifDefined('models', built.models),
433
+ ...ifDefined('enums', Object.keys(mergedEnums).length > 0 ? mergedEnums : undefined),
419
434
  });
420
435
  }
421
436
 
@@ -425,10 +440,7 @@ export function buildBoundContract(
425
440
  export function defineContract<
426
441
  const Family extends FamilyPackRef<string>,
427
442
  const Target extends TargetPackRef<'sql', string>,
428
- const Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<
429
- never,
430
- never
431
- >,
443
+ const Types extends Record<string, StorageTypeInstance> = Record<never, never>,
432
444
  const Models extends Record<string, ModelLike> = Record<never, never>,
433
445
  const ExtensionPacks extends
434
446
  | Record<string, ExtensionPackRef<'sql', string>>
@@ -437,6 +449,7 @@ export function defineContract<
437
449
  const StorageHash extends string | undefined = undefined,
438
450
  const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
439
451
  const Namespaces extends readonly string[] | undefined = undefined,
452
+ const Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
440
453
  >(
441
454
  definition: ContractDefinition<
442
455
  Family,
@@ -447,7 +460,8 @@ export function defineContract<
447
460
  Naming,
448
461
  StorageHash,
449
462
  ForeignKeyDefaults,
450
- Namespaces
463
+ Namespaces,
464
+ Enums
451
465
  >,
452
466
  ): SqlContractResult<
453
467
  ContractDefinition<
@@ -459,16 +473,14 @@ export function defineContract<
459
473
  Naming,
460
474
  StorageHash,
461
475
  ForeignKeyDefaults,
462
- Namespaces
476
+ Namespaces,
477
+ Enums
463
478
  >
464
479
  >;
465
480
  export function defineContract<
466
481
  const Family extends FamilyPackRef<string>,
467
482
  const Target extends TargetPackRef<'sql', string>,
468
- const Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<
469
- never,
470
- never
471
- >,
483
+ const Types extends Record<string, StorageTypeInstance> = Record<never, never>,
472
484
  const Models extends Record<string, ModelLike> = Record<never, never>,
473
485
  const ExtensionPacks extends
474
486
  | Record<string, ExtensionPackRef<'sql', string>>
@@ -477,6 +489,8 @@ export function defineContract<
477
489
  const StorageHash extends string | undefined = undefined,
478
490
  const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined,
479
491
  const Namespaces extends readonly string[] | undefined = undefined,
492
+ const ScaffoldEnums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
493
+ const FactoryEnums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>,
480
494
  >(
481
495
  definition: ContractScaffold<
482
496
  Family,
@@ -485,9 +499,10 @@ export function defineContract<
485
499
  Naming,
486
500
  StorageHash,
487
501
  ForeignKeyDefaults,
488
- Namespaces
502
+ Namespaces,
503
+ ScaffoldEnums
489
504
  >,
490
- factory: ContractFactory<Family, Target, Types, Models, ExtensionPacks>,
505
+ factory: ContractFactory<Family, Target, Types, Models, ExtensionPacks, FactoryEnums>,
491
506
  ): SqlContractResult<
492
507
  ContractDefinition<
493
508
  Family,
@@ -498,7 +513,8 @@ export function defineContract<
498
513
  Naming,
499
514
  StorageHash,
500
515
  ForeignKeyDefaults,
501
- Namespaces
516
+ Namespaces,
517
+ MergeEnums<ScaffoldEnums, FactoryEnums>
502
518
  >
503
519
  >;
504
520
  export function defineContract(
@@ -506,7 +522,7 @@ export function defineContract(
506
522
  factory?: ContractFactory<
507
523
  FamilyPackRef<string>,
508
524
  TargetPackRef<'sql', string>,
509
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
525
+ Record<string, StorageTypeInstance>,
510
526
  Record<string, ModelLike>,
511
527
  Record<string, ExtensionPackRef<'sql', string>> | undefined
512
528
  >,
@@ -8,7 +8,6 @@ import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/cod
8
8
  import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
9
9
  import type { Namespace } from '@prisma-next/framework-components/ir';
10
10
  import type {
11
- PostgresEnumStorageEntry,
12
11
  ReferentialAction,
13
12
  SqlNamespaceTablesInput,
14
13
  StorageTypeInstance,
@@ -162,33 +161,14 @@ export interface ContractDefinition {
162
161
  readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
163
162
  readonly storageHash?: string;
164
163
  readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
165
- readonly storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
166
- /**
167
- * Enum types declared inside a named `namespace { enum … }` block,
168
- * keyed first by namespace id then by type name. These are routed to
169
- * `storage.namespaces[nsId].entries.type` rather than the implicit fallback
170
- * namespace used for top-level `storageTypes` enums.
171
- */
172
- readonly namespaceTypes?: Readonly<
173
- Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>
174
- >;
164
+ readonly storageTypes?: Record<string, StorageTypeInstance>;
175
165
  /**
176
166
  * Declared namespace coordinates for this contract — populates
177
167
  * `SqlStorage.namespaces` together with `createNamespace`.
178
168
  */
179
169
  readonly namespaces?: readonly string[];
180
- /**
181
- * Target-supplied factory that materialises a `Namespace` concretion
182
- * for a declared namespace coordinate. Mirrors
183
- * `ContractInput.createNamespace`.
184
- *
185
- * The optional second argument carries target-specific enum types for the
186
- * namespace (e.g. postgres enum registrations keyed by type name).
187
- */
188
- readonly createNamespace?: (
189
- input: SqlNamespaceTablesInput,
190
- enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,
191
- ) => Namespace;
170
+ /** Target-supplied factory that materialises a `Namespace` concretion for a declared namespace coordinate. */
171
+ readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
192
172
  readonly models: readonly ModelNode[];
193
173
  readonly valueObjects?: readonly ValueObjectNode[];
194
174
  /**
@@ -16,11 +16,7 @@ import type {
16
16
  TargetPackRef,
17
17
  } from '@prisma-next/framework-components/components';
18
18
  import type { Namespace } from '@prisma-next/framework-components/ir';
19
- import type {
20
- PostgresEnumStorageEntry,
21
- SqlNamespaceTablesInput,
22
- StorageTypeInstance,
23
- } from '@prisma-next/sql-contract/types';
19
+ import type { SqlNamespaceTablesInput, StorageTypeInstance } from '@prisma-next/sql-contract/types';
24
20
  import { blindCast } from '@prisma-next/utils/casts';
25
21
  import { ifDefined } from '@prisma-next/utils/defined';
26
22
  import type { NamedConstraintSpec } from './authoring-type-utils';
@@ -34,7 +30,7 @@ export type NamingConfig = {
34
30
  readonly columns?: NamingStrategy;
35
31
  };
36
32
 
37
- type NamedStorageTypeRef = string | StorageTypeInstance | PostgresEnumStorageEntry | EnumTypeHandle;
33
+ type NamedStorageTypeRef = string | StorageTypeInstance | EnumTypeHandle;
38
34
 
39
35
  type NamedConstraintNameSpec<Name extends string = string> = {
40
36
  readonly name: Name;
@@ -338,6 +334,36 @@ export class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFie
338
334
  }
339
335
  }
340
336
 
337
+ export class EnumScalarFieldBuilder<
338
+ Handle extends EnumTypeHandle,
339
+ State extends AnyScalarFieldState = ScalarFieldState<Handle['codecId'], Handle, false, undefined>,
340
+ > extends ScalarFieldBuilder<State> {
341
+ readonly #handle: Handle;
342
+
343
+ constructor(state: State, handle: Handle) {
344
+ super(state);
345
+ this.#handle = handle;
346
+ }
347
+
348
+ override default(value: Handle['values'][number]): EnumScalarFieldBuilder<Handle, State> {
349
+ return blindCast<
350
+ EnumScalarFieldBuilder<Handle, State>,
351
+ 'object spread does not narrow the generic State conditional; runtime shape is correct'
352
+ >(
353
+ new EnumScalarFieldBuilder(
354
+ { ...this.build(), default: { kind: 'literal', value } },
355
+ this.#handle,
356
+ ),
357
+ );
358
+ }
359
+
360
+ override defaultSql(_expression: never): never {
361
+ throw new Error(
362
+ 'defaultSql is not available on an enum field; use .default(members.X) instead',
363
+ );
364
+ }
365
+ }
366
+
341
367
  function columnField<Descriptor extends ColumnTypeDescriptor>(
342
368
  descriptor: Descriptor,
343
369
  ): ScalarFieldBuilder<ScalarFieldState<Descriptor['codecId'], undefined, false, undefined>> {
@@ -368,21 +394,19 @@ function namedTypeField<TypeRef extends string>(
368
394
  function namedTypeField<TypeRef extends StorageTypeInstance>(
369
395
  typeRef: TypeRef,
370
396
  ): ScalarFieldBuilder<ScalarFieldState<TypeRef['codecId'], TypeRef, false, undefined>>;
371
- function namedTypeField<TypeRef extends PostgresEnumStorageEntry>(
372
- typeRef: TypeRef,
373
- ): ScalarFieldBuilder<ScalarFieldState<string, TypeRef, false, undefined>>;
374
397
  function namedTypeField<Handle extends EnumTypeHandle>(
375
398
  typeRef: Handle,
376
- ): ScalarFieldBuilder<ScalarFieldState<Handle['codecId'], Handle, false, undefined>>;
377
- function namedTypeField(
378
- typeRef: NamedStorageTypeRef,
379
- ): ScalarFieldBuilder<ScalarFieldState<string, NamedStorageTypeRef, false, undefined>> {
399
+ ): EnumScalarFieldBuilder<Handle>;
400
+ function namedTypeField(typeRef: NamedStorageTypeRef): ScalarFieldBuilder {
380
401
  if (isEnumTypeHandle(typeRef)) {
381
- return new ScalarFieldBuilder({
382
- kind: 'scalar',
402
+ return new EnumScalarFieldBuilder(
403
+ {
404
+ kind: 'scalar',
405
+ typeRef,
406
+ nullable: false,
407
+ },
383
408
  typeRef,
384
- nullable: false,
385
- });
409
+ );
386
410
  }
387
411
  return new ScalarFieldBuilder({
388
412
  kind: 'scalar',