-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
72 lines (63 loc) · 2.75 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// [note] this logic is inspired by this discussion - https://github.com/prisma/prisma/discussions/12453
// that approach only takes first level of fields and will ignore nested fields.
// however, approach below is going recursively and changing all types till the very bottom.
/**
* Type `PrismaModels` returns Models with relations of your Prisma
*
* Example: `export type Models = PrismaModels<Prisma.ModelName, Prisma.TypeMap>`
*/
export type PrismaModels<
ModelName extends string,
TypeMap extends {model: Record<ModelName, {payload: TypeMapPayload}>},
> = {
[M in ModelName]: TransformPayload<TypeMap['model'][M]['payload']>;
};
/**
* Type `PrismaModelsClean` returns Models without relations (only fields) of your Prisma
*
* Example: `export type ModelsClean = PrismaModelsClean<Prisma.ModelName, Prisma.TypeMap>`
*/
export type PrismaModelsClean<
ModelName extends string,
TypeMap extends {model: Record<ModelName, {payload: TypeMapPayload}>},
> = {
[M in ModelName]: ExtractScalars<TypeMap['model'][M]['payload']>;
};
/**
* Type `PrismaEnums` returns Enums with format `type UserStatus = 'ACTIVE' | 'IN_REVIEW' | 'REJECTED'` of your $Enums (from Prisma)
*
* Example: `export type Enums = PrismaEnums<typeof $Enums>`
*/
export type PrismaEnums<$Enums extends Record<string, Record<string, string>>> = {
[K in keyof $Enums]: $Enums[K][keyof $Enums[K]];
};
// ========================
// ========= WALL =========
// ========================
// helpers
type ExcludeNull<T> = Exclude<T, null>;
type TypeMapPayload<T = any> = {objects: T; scalars: T};
type TypeMapObject = Record<string, RealPayload>;
type ExtractScalars<T extends TypeMapPayload> = T['scalars'];
type ExtractObjects<T extends TypeMapPayload> = T['objects'];
type OnePayload = TypeMapPayload | null;
type ManyPayloads = Array<TypeMapPayload>;
type RealPayload = OnePayload | ManyPayloads;
// trasformers
// payload_transformer = (T: TypeMapPayload) => T['scalars'] & objects_transformer(T['objects'])
type TransformPayload<T extends TypeMapPayload> = ExtractScalars<T> &
TransformObjects<ExtractObjects<T>>;
// objects_transformer = (o: TypeMapObject, k: Key) =>
// o[k] is payload[] -> [ i => o[k][i]['scalars] & objects_transformer(o[k][i]['objects']) ]
// o[k] is payload -> o[k]['scalars'] & objects_transformer(o[k]['objects'])
// o[k] is smth else -> o[k]
// o[k] is null -> unknown
type TransformObjects<O extends TypeMapObject> = {
[K in keyof O]: O[K] extends RealPayload
? O[K] extends ManyPayloads
? Array<ExtractScalars<O[K][number]> & TransformObjects<ExtractObjects<O[K][number]>>>
: O[K] extends OnePayload
? ExtractScalars<ExcludeNull<O[K]>> & TransformObjects<ExtractObjects<ExcludeNull<O[K]>>>
: unknown
: O[K];
};