@prisma-next/sql-contract-ts 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/dist/{build-contract-C-x2pfu4.mjs → build-contract-CQ4u83jx.mjs} +24 -54
- package/dist/build-contract-CQ4u83jx.mjs.map +1 -0
- package/dist/config-types.mjs +1 -1
- package/dist/contract-builder.d.mts +129 -63
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +48 -11
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +10 -10
- package/src/build-contract.ts +33 -91
- package/src/contract-builder.ts +47 -31
- package/src/contract-definition.ts +11 -23
- package/src/contract-dsl.ts +41 -17
- package/src/contract-lowering.ts +19 -26
- package/src/contract-types.ts +135 -32
- package/src/contract-warnings.ts +3 -6
- package/src/enum-type.ts +98 -28
- package/src/exports/contract-builder.ts +10 -2
- package/dist/build-contract-C-x2pfu4.mjs.map +0 -1
package/src/contract-dsl.ts
CHANGED
|
@@ -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 |
|
|
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
|
-
):
|
|
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
|
|
382
|
-
|
|
402
|
+
return new EnumScalarFieldBuilder(
|
|
403
|
+
{
|
|
404
|
+
kind: 'scalar',
|
|
405
|
+
typeRef,
|
|
406
|
+
nullable: false,
|
|
407
|
+
},
|
|
383
408
|
typeRef,
|
|
384
|
-
|
|
385
|
-
});
|
|
409
|
+
);
|
|
386
410
|
}
|
|
387
411
|
return new ScalarFieldBuilder({
|
|
388
412
|
kind: 'scalar',
|
package/src/contract-lowering.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { ColumnTypeDescriptor } from '@prisma-next/framework-components/codec';
|
|
2
2
|
import type { ExtensionPackRef } from '@prisma-next/framework-components/components';
|
|
3
|
-
import {
|
|
4
|
-
isPostgresEnumStorageEntry,
|
|
5
|
-
type PostgresEnumStorageEntry,
|
|
6
|
-
type StorageTypeInstance,
|
|
7
|
-
} from '@prisma-next/sql-contract/types';
|
|
3
|
+
import type { StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
8
4
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
9
5
|
import type {
|
|
10
6
|
ContractDefinition,
|
|
@@ -59,15 +55,15 @@ type RuntimeModelSpec = {
|
|
|
59
55
|
};
|
|
60
56
|
|
|
61
57
|
type RuntimeCollection = {
|
|
62
|
-
readonly storageTypes: Record<string, StorageTypeInstance
|
|
58
|
+
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
63
59
|
readonly models: Record<string, RuntimeModel>;
|
|
64
60
|
readonly modelSpecs: ReadonlyMap<string, RuntimeModelSpec>;
|
|
65
61
|
};
|
|
66
62
|
|
|
67
63
|
function buildStorageTypeReverseLookup(
|
|
68
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
69
|
-
): ReadonlyMap<StorageTypeInstance
|
|
70
|
-
const lookup = new Map<StorageTypeInstance
|
|
64
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
65
|
+
): ReadonlyMap<StorageTypeInstance, string> {
|
|
66
|
+
const lookup = new Map<StorageTypeInstance, string>();
|
|
71
67
|
for (const [key, instance] of Object.entries(storageTypes)) {
|
|
72
68
|
lookup.set(instance, key);
|
|
73
69
|
}
|
|
@@ -78,8 +74,8 @@ function resolveFieldDescriptor(
|
|
|
78
74
|
modelName: string,
|
|
79
75
|
fieldName: string,
|
|
80
76
|
fieldState: FieldStateOf<ScalarFieldBuilder>,
|
|
81
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
82
|
-
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance
|
|
77
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
78
|
+
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance, string>,
|
|
83
79
|
): ColumnTypeDescriptor {
|
|
84
80
|
if ('descriptor' in fieldState && fieldState.descriptor) {
|
|
85
81
|
return fieldState.descriptor;
|
|
@@ -96,9 +92,7 @@ function resolveFieldDescriptor(
|
|
|
96
92
|
const typeRef =
|
|
97
93
|
typeof fieldState.typeRef === 'string'
|
|
98
94
|
? fieldState.typeRef
|
|
99
|
-
: storageTypeReverseLookup.get(
|
|
100
|
-
fieldState.typeRef as StorageTypeInstance | PostgresEnumStorageEntry,
|
|
101
|
-
);
|
|
95
|
+
: storageTypeReverseLookup.get(fieldState.typeRef as StorageTypeInstance);
|
|
102
96
|
|
|
103
97
|
if (!typeRef) {
|
|
104
98
|
throw new Error(
|
|
@@ -113,11 +107,8 @@ function resolveFieldDescriptor(
|
|
|
113
107
|
);
|
|
114
108
|
}
|
|
115
109
|
|
|
116
|
-
const codecId = isPostgresEnumStorageEntry(referencedType)
|
|
117
|
-
? referencedType.codecId
|
|
118
|
-
: referencedType.codecId;
|
|
119
110
|
return {
|
|
120
|
-
codecId,
|
|
111
|
+
codecId: referencedType.codecId,
|
|
121
112
|
nativeType: referencedType.nativeType,
|
|
122
113
|
typeRef,
|
|
123
114
|
};
|
|
@@ -520,6 +511,7 @@ function lowerManyToManyRelation(
|
|
|
520
511
|
cardinality: 'N:M',
|
|
521
512
|
through: {
|
|
522
513
|
table: throughSpec.tableName,
|
|
514
|
+
...ifDefined('namespaceId', throughSpec.namespace),
|
|
523
515
|
parentColumns: mapFieldNamesToColumnNames(
|
|
524
516
|
throughSpec.modelName,
|
|
525
517
|
throughFromFields,
|
|
@@ -705,8 +697,8 @@ function resolveForeignKeyNodes(
|
|
|
705
697
|
function resolveModelNode(
|
|
706
698
|
spec: RuntimeModelSpec,
|
|
707
699
|
allSpecs: ReadonlyMap<string, RuntimeModelSpec>,
|
|
708
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
709
|
-
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance
|
|
700
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
701
|
+
storageTypeReverseLookup: ReadonlyMap<StorageTypeInstance, string>,
|
|
710
702
|
extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>,
|
|
711
703
|
): ModelNode {
|
|
712
704
|
const fields: FieldNode[] = [];
|
|
@@ -783,10 +775,7 @@ function resolveModelNode(
|
|
|
783
775
|
}
|
|
784
776
|
|
|
785
777
|
function collectRuntimeModelSpecs(definition: ContractInput): RuntimeCollection {
|
|
786
|
-
const storageTypes = { ...(definition.types ?? {}) } as Record<
|
|
787
|
-
string,
|
|
788
|
-
StorageTypeInstance | PostgresEnumStorageEntry
|
|
789
|
-
>;
|
|
778
|
+
const storageTypes = { ...(definition.types ?? {}) } as Record<string, StorageTypeInstance>;
|
|
790
779
|
const models = { ...(definition.models ?? {}) } as Record<string, RuntimeModel>;
|
|
791
780
|
|
|
792
781
|
emitTypedNamedTypeFallbackWarnings(models, storageTypes);
|
|
@@ -805,13 +794,17 @@ function collectRuntimeModelSpecs(definition: ContractInput): RuntimeCollection
|
|
|
805
794
|
const attributesSpec = modelDefinition.buildAttributesSpec();
|
|
806
795
|
const sqlSpec = modelDefinition.buildSqlSpec();
|
|
807
796
|
const tableName = sqlSpec?.table ?? applyNaming(modelName, definition.naming?.tables);
|
|
808
|
-
|
|
797
|
+
// Table names are unique per namespace, not globally. Key the collision
|
|
798
|
+
// check by a tuple so namespace/table boundaries remain unambiguous.
|
|
799
|
+
const namespaceId = modelDefinition.stageOne.namespace ?? definition.target.defaultNamespaceId;
|
|
800
|
+
const tableKey = JSON.stringify([namespaceId, tableName]);
|
|
801
|
+
const existingModel = tableOwners.get(tableKey);
|
|
809
802
|
if (existingModel) {
|
|
810
803
|
throw new Error(
|
|
811
804
|
`Models "${existingModel}" and "${modelName}" both map to table "${tableName}".`,
|
|
812
805
|
);
|
|
813
806
|
}
|
|
814
|
-
tableOwners.set(
|
|
807
|
+
tableOwners.set(tableKey, modelName);
|
|
815
808
|
|
|
816
809
|
const fieldToColumn: Record<string, string> = {};
|
|
817
810
|
const columnOwners = new Map<string, string>();
|
package/src/contract-types.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ColumnDefault,
|
|
3
3
|
Contract,
|
|
4
|
+
ContractEnum,
|
|
4
5
|
ContractRelation,
|
|
6
|
+
ContractValueObject,
|
|
5
7
|
NamespaceId,
|
|
6
8
|
StorageHashBase,
|
|
7
9
|
} from '@prisma-next/contract/types';
|
|
@@ -17,6 +19,7 @@ import type {
|
|
|
17
19
|
} from '@prisma-next/sql-contract/types';
|
|
18
20
|
import type { UnionToIntersection } from './authoring-type-utils';
|
|
19
21
|
import type { AttributeStageIdFieldNames, FieldStateOf, ScalarFieldBuilder } from './contract-dsl';
|
|
22
|
+
import type { EnumTypeHandle } from './enum-type';
|
|
20
23
|
|
|
21
24
|
export type ExtractCodecTypesFromPack<P> = P extends { __codecTypes?: infer C }
|
|
22
25
|
? C extends Record<string, { output: unknown }>
|
|
@@ -333,17 +336,39 @@ type ResolveNamedStorageType<Definition, TypeRef> =
|
|
|
333
336
|
: StorageTypeInstance
|
|
334
337
|
: StorageTypeInstance;
|
|
335
338
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
339
|
+
// An enum-typed field carries its `EnumTypeHandle` (an object with a `codecId`
|
|
340
|
+
// and `nativeType`, but no `kind`) as the field's `typeRef`. It is neither a
|
|
341
|
+
// string nor a registered `StorageType`, so the named-type lookup cannot reach
|
|
342
|
+
// it; `EnumFieldHandle` short-circuits the resolvers to read codec + native type
|
|
343
|
+
// straight off the handle, with no column type-ref (the enum name is carried
|
|
344
|
+
// elsewhere). The `[...] extends [never]` guard excludes plain column fields,
|
|
345
|
+
// whose `typeRef` is `never`.
|
|
346
|
+
type EnumFieldHandle<FieldState> = [FieldTypeRefOf<FieldState>] extends [never]
|
|
347
|
+
? never
|
|
348
|
+
: FieldTypeRefOf<FieldState> extends EnumTypeHandle
|
|
349
|
+
? FieldTypeRefOf<FieldState>
|
|
350
|
+
: never;
|
|
351
|
+
|
|
352
|
+
type EnumHandleDescriptor<Handle> = Handle extends {
|
|
353
|
+
readonly codecId: infer CodecId extends string;
|
|
354
|
+
readonly nativeType: infer NativeType extends string;
|
|
355
|
+
}
|
|
356
|
+
? { readonly codecId: CodecId; readonly nativeType: NativeType }
|
|
357
|
+
: never;
|
|
358
|
+
|
|
359
|
+
type ResolveFieldDescriptor<Definition, FieldState> = [EnumFieldHandle<FieldState>] extends [never]
|
|
360
|
+
? [FieldDescriptorOf<FieldState>] extends [never]
|
|
361
|
+
? ResolveNamedStorageType<Definition, FieldTypeRefOf<FieldState>>
|
|
362
|
+
: FieldDescriptorOf<FieldState>
|
|
363
|
+
: EnumHandleDescriptor<EnumFieldHandle<FieldState>>;
|
|
341
364
|
|
|
342
|
-
type ResolveFieldColumnTypeRef<Definition, FieldState> = [
|
|
365
|
+
type ResolveFieldColumnTypeRef<Definition, FieldState> = [EnumFieldHandle<FieldState>] extends [
|
|
343
366
|
never,
|
|
344
367
|
]
|
|
345
|
-
?
|
|
346
|
-
|
|
368
|
+
? [FieldTypeRefOf<FieldState>] extends [never]
|
|
369
|
+
? DescriptorTypeRef<FieldDescriptorOf<FieldState>>
|
|
370
|
+
: ResolveNamedStorageTypeKey<Definition, FieldTypeRefOf<FieldState>>
|
|
371
|
+
: undefined;
|
|
347
372
|
|
|
348
373
|
type ResolveFieldColumnTypeParams<Definition, FieldState> = [
|
|
349
374
|
ResolveFieldColumnTypeRef<Definition, FieldState>,
|
|
@@ -558,6 +583,37 @@ type BuiltStorageTables<Definition> = {
|
|
|
558
583
|
: Record<string, never>);
|
|
559
584
|
};
|
|
560
585
|
|
|
586
|
+
type DefinitionEnums<Definition> = Definition extends {
|
|
587
|
+
readonly enums?: infer E;
|
|
588
|
+
}
|
|
589
|
+
? Present<E> extends Record<string, EnumTypeHandle>
|
|
590
|
+
? // A bare `Record<string, EnumTypeHandle>` (no literal keys) is the
|
|
591
|
+
// widened default for a contract authored without enums; treat it as
|
|
592
|
+
// empty so `db.enums` carries only literally-authored enums.
|
|
593
|
+
string extends keyof Present<E>
|
|
594
|
+
? Record<never, never>
|
|
595
|
+
: Present<E>
|
|
596
|
+
: Record<never, never>
|
|
597
|
+
: Record<never, never>;
|
|
598
|
+
|
|
599
|
+
type EnumHandleAccessorType<Handle> =
|
|
600
|
+
Handle extends EnumTypeHandle<infer _Name, infer Values, infer Names, infer MembersMap>
|
|
601
|
+
? {
|
|
602
|
+
readonly values: Values;
|
|
603
|
+
readonly names: Names;
|
|
604
|
+
readonly members: MembersMap;
|
|
605
|
+
has(v: Values[number]): boolean;
|
|
606
|
+
nameOf(v: Values[number]): string | undefined;
|
|
607
|
+
ordinalOf(v: Values[number]): number;
|
|
608
|
+
}
|
|
609
|
+
: never;
|
|
610
|
+
|
|
611
|
+
type BuiltEnumAccessors<Definition> = {
|
|
612
|
+
readonly [K in keyof DefinitionEnums<Definition>]: EnumHandleAccessorType<
|
|
613
|
+
DefinitionEnums<Definition>[K]
|
|
614
|
+
>;
|
|
615
|
+
};
|
|
616
|
+
|
|
561
617
|
type BuiltDocumentScopedTypes<Definition> = {
|
|
562
618
|
readonly [K in keyof DefinitionTypes<Definition> as DefinitionTypes<Definition>[K] extends StorageTypeInstance
|
|
563
619
|
? K
|
|
@@ -573,6 +629,17 @@ type BuiltDomain<Definition> =
|
|
|
573
629
|
};
|
|
574
630
|
};
|
|
575
631
|
|
|
632
|
+
// Per-namespace domain entry carrying the precise per-model field/storage shapes
|
|
633
|
+
// for DSL inference. Modelled as an index signature (rather than enumerating
|
|
634
|
+
// namespace ids) so that any namespace coordinate resolves the full model map,
|
|
635
|
+
// matching how the authoring path lumps every model under the default storage
|
|
636
|
+
// namespace.
|
|
637
|
+
type BuiltDomainNamespace<Definition> = {
|
|
638
|
+
readonly models: BuiltModels<Definition>;
|
|
639
|
+
readonly valueObjects?: Record<string, ContractValueObject>;
|
|
640
|
+
readonly enum?: Record<string, ContractEnum>;
|
|
641
|
+
};
|
|
642
|
+
|
|
576
643
|
type DefaultStorageNamespaceId<Definition> =
|
|
577
644
|
DefinitionTargetId<Definition> extends 'postgres' ? 'public' : '__unbound__';
|
|
578
645
|
|
|
@@ -610,47 +677,83 @@ type BuiltStorage<Definition> = {
|
|
|
610
677
|
};
|
|
611
678
|
};
|
|
612
679
|
|
|
613
|
-
|
|
680
|
+
// The enum value union for an enum-typed field, or `never` for a non-enum
|
|
681
|
+
// field. The field's `typeRef` carries the authored `EnumTypeHandle`, whose
|
|
682
|
+
// `Values` tuple preserves the literal member values (text or numeric).
|
|
683
|
+
type EnumValueUnion<FieldState> = [FieldTypeRefOf<FieldState>] extends [
|
|
684
|
+
EnumTypeHandle<string, infer Values>,
|
|
685
|
+
]
|
|
686
|
+
? readonly unknown[] extends Values
|
|
687
|
+
? never
|
|
688
|
+
: Values[number]
|
|
689
|
+
: never;
|
|
690
|
+
|
|
691
|
+
// The codec's `output` / `input` JS type for a field's column, before
|
|
692
|
+
// nullability. `unknown` when the codec is not in the definition's codec map.
|
|
693
|
+
type CodecChannelType<
|
|
614
694
|
Definition,
|
|
615
695
|
ModelName extends ModelNames<Definition>,
|
|
616
696
|
FieldName extends ModelFieldNames<Definition, ModelName>,
|
|
697
|
+
Channel extends 'output' | 'input',
|
|
698
|
+
> = ModelStorageColumn<Definition, ModelName, FieldName>['codecId'] extends infer Id extends
|
|
699
|
+
keyof CodecTypesFromDefinition<Definition>
|
|
700
|
+
? CodecTypesFromDefinition<Definition>[Id] extends { readonly [K in Channel]: infer T }
|
|
701
|
+
? T
|
|
702
|
+
: unknown
|
|
703
|
+
: unknown;
|
|
704
|
+
|
|
705
|
+
// A field's read/write JS type: the enum value union when the field is
|
|
706
|
+
// enum-typed, otherwise the codec channel type, with column nullability applied.
|
|
707
|
+
type FieldChannelType<
|
|
708
|
+
Definition,
|
|
709
|
+
ModelName extends ModelNames<Definition>,
|
|
710
|
+
FieldName extends ModelFieldNames<Definition, ModelName>,
|
|
711
|
+
Channel extends 'output' | 'input',
|
|
617
712
|
> =
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
type
|
|
631
|
-
readonly [
|
|
632
|
-
readonly [
|
|
633
|
-
Definition,
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
713
|
+
| ([EnumValueUnion<ModelFieldState<Definition, ModelName, FieldName>>] extends [never]
|
|
714
|
+
? CodecChannelType<Definition, ModelName, FieldName, Channel>
|
|
715
|
+
: EnumValueUnion<ModelFieldState<Definition, ModelName, FieldName>>)
|
|
716
|
+
| (FieldNullableOf<ModelFieldState<Definition, ModelName, FieldName>> extends true
|
|
717
|
+
? null
|
|
718
|
+
: never);
|
|
719
|
+
|
|
720
|
+
// Nested by namespace coordinate (`{ [ns]: { [model]: { [field]: type } } }`)
|
|
721
|
+
// to mirror the emitter's namespace-nested `FieldOutputTypes` (and the
|
|
722
|
+
// `TypeMaps` constraint). The TS authoring path lumps every model under the
|
|
723
|
+
// target's default storage namespace (see `BuiltStorage`), so the per-model
|
|
724
|
+
// field-type map nests under that same coordinate.
|
|
725
|
+
type FieldChannelTypes<Definition, Channel extends 'output' | 'input'> = {
|
|
726
|
+
readonly [Ns in DefaultStorageNamespaceId<Definition>]: {
|
|
727
|
+
readonly [ModelName in ModelNames<Definition>]: {
|
|
728
|
+
readonly [FieldName in ModelFieldNames<Definition, ModelName>]: FieldChannelType<
|
|
729
|
+
Definition,
|
|
730
|
+
ModelName,
|
|
731
|
+
FieldName,
|
|
732
|
+
Channel
|
|
733
|
+
>;
|
|
734
|
+
};
|
|
637
735
|
};
|
|
638
736
|
};
|
|
639
737
|
|
|
640
738
|
export type SqlContractResult<Definition> = ContractWithTypeMaps<
|
|
641
|
-
Contract<BuiltStorage<Definition
|
|
739
|
+
Omit<Contract<BuiltStorage<Definition>>, 'domain'> & {
|
|
642
740
|
readonly target: DefinitionTargetId<Definition>;
|
|
643
741
|
readonly targetFamily: 'sql';
|
|
644
|
-
} & {
|
|
742
|
+
} & {
|
|
743
|
+
readonly domain: {
|
|
744
|
+
readonly namespaces: Readonly<Record<string, BuiltDomainNamespace<Definition>>>;
|
|
745
|
+
} & BuiltDomain<Definition>;
|
|
746
|
+
} & {
|
|
645
747
|
readonly extensionPacks: keyof DefinitionExtensionPacks<Definition> extends never
|
|
646
748
|
? Record<string, never>
|
|
647
749
|
: DefinitionExtensionPacks<Definition>;
|
|
648
750
|
readonly capabilities: DerivedCapabilities<Definition>;
|
|
751
|
+
readonly enumAccessors: BuiltEnumAccessors<Definition>;
|
|
649
752
|
},
|
|
650
753
|
TypeMaps<
|
|
651
754
|
CodecTypesFromDefinition<Definition>,
|
|
652
755
|
Record<string, never>,
|
|
653
|
-
|
|
654
|
-
|
|
756
|
+
FieldChannelTypes<Definition, 'output'>,
|
|
757
|
+
FieldChannelTypes<Definition, 'input'>
|
|
655
758
|
>
|
|
656
759
|
>;
|
package/src/contract-warnings.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
PostgresEnumStorageEntry,
|
|
3
|
-
StorageTypeInstance,
|
|
4
|
-
} from '@prisma-next/sql-contract/types';
|
|
1
|
+
import type { StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
5
2
|
import {
|
|
6
3
|
type ContractModelBuilder,
|
|
7
4
|
type ModelAttributesSpec,
|
|
@@ -28,7 +25,7 @@ type RuntimeModelSpec = {
|
|
|
28
25
|
};
|
|
29
26
|
|
|
30
27
|
type RuntimeCollection = {
|
|
31
|
-
readonly storageTypes: Record<string, StorageTypeInstance
|
|
28
|
+
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
32
29
|
readonly models: Record<string, RuntimeModel>;
|
|
33
30
|
readonly modelSpecs: ReadonlyMap<string, RuntimeModelSpec>;
|
|
34
31
|
};
|
|
@@ -136,7 +133,7 @@ function formatFallbackWarning(location: string, current: string, suggested: str
|
|
|
136
133
|
|
|
137
134
|
export function emitTypedNamedTypeFallbackWarnings(
|
|
138
135
|
models: Record<string, RuntimeModel>,
|
|
139
|
-
storageTypes: Record<string, StorageTypeInstance
|
|
136
|
+
storageTypes: Record<string, StorageTypeInstance>,
|
|
140
137
|
): void {
|
|
141
138
|
const warnings: string[] = [];
|
|
142
139
|
const warnedFields = new Set<string>();
|