@pothos/plugin-prisma 0.18.0 → 3.1.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.
Files changed (165) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +420 -315
  3. package/esm/field-builder.d.ts.map +1 -1
  4. package/esm/field-builder.js +19 -6
  5. package/esm/field-builder.js.map +1 -1
  6. package/esm/generator.js +4 -0
  7. package/esm/generator.js.map +1 -1
  8. package/esm/global-types.d.ts +23 -5
  9. package/esm/global-types.d.ts.map +1 -1
  10. package/esm/index.d.ts +4 -1
  11. package/esm/index.d.ts.map +1 -1
  12. package/esm/index.js +46 -1
  13. package/esm/index.js.map +1 -1
  14. package/esm/model-loader.d.ts +5 -6
  15. package/esm/model-loader.d.ts.map +1 -1
  16. package/esm/model-loader.js +18 -78
  17. package/esm/model-loader.js.map +1 -1
  18. package/esm/prisma-field-builder.d.ts +25 -6
  19. package/esm/prisma-field-builder.d.ts.map +1 -1
  20. package/esm/prisma-field-builder.js +86 -118
  21. package/esm/prisma-field-builder.js.map +1 -1
  22. package/esm/schema-builder.js +14 -4
  23. package/esm/schema-builder.js.map +1 -1
  24. package/esm/types.d.ts +74 -77
  25. package/esm/types.d.ts.map +1 -1
  26. package/esm/types.js +1 -0
  27. package/esm/types.js.map +1 -1
  28. package/esm/{cursors.d.ts → util/cursors.d.ts} +5 -5
  29. package/esm/util/cursors.d.ts.map +1 -0
  30. package/esm/{cursors.js → util/cursors.js} +0 -0
  31. package/esm/util/cursors.js.map +1 -0
  32. package/{lib/refs.d.ts → esm/util/datamodel.d.ts} +4 -8
  33. package/esm/util/datamodel.d.ts.map +1 -0
  34. package/esm/{refs.js → util/datamodel.js} +2 -25
  35. package/esm/util/datamodel.js.map +1 -0
  36. package/esm/util/deep-equal.d.ts +2 -0
  37. package/esm/util/deep-equal.d.ts.map +1 -0
  38. package/esm/util/deep-equal.js +39 -0
  39. package/esm/util/deep-equal.js.map +1 -0
  40. package/esm/util/loader-map.d.ts +6 -0
  41. package/esm/util/loader-map.d.ts.map +1 -0
  42. package/esm/{loader-map.js → util/loader-map.js} +10 -12
  43. package/esm/util/loader-map.js.map +1 -0
  44. package/esm/util/map-query.d.ts +6 -0
  45. package/esm/util/map-query.d.ts.map +1 -0
  46. package/esm/util/map-query.js +169 -0
  47. package/esm/util/map-query.js.map +1 -0
  48. package/esm/util/relation-map.d.ts +9 -0
  49. package/esm/util/relation-map.d.ts.map +1 -0
  50. package/esm/util/relation-map.js +20 -0
  51. package/esm/util/relation-map.js.map +1 -0
  52. package/esm/util/selections.d.ts +20 -0
  53. package/esm/util/selections.d.ts.map +1 -0
  54. package/esm/util/selections.js +139 -0
  55. package/esm/util/selections.js.map +1 -0
  56. package/lib/field-builder.d.ts.map +1 -1
  57. package/lib/field-builder.js +30 -13
  58. package/lib/field-builder.js.map +1 -1
  59. package/lib/generator.js +9 -1
  60. package/lib/generator.js.map +1 -1
  61. package/lib/global-types.d.ts +23 -5
  62. package/lib/global-types.d.ts.map +1 -1
  63. package/lib/index.d.ts +4 -1
  64. package/lib/index.d.ts.map +1 -1
  65. package/lib/index.js +50 -1
  66. package/lib/index.js.map +1 -1
  67. package/lib/model-loader.d.ts +5 -6
  68. package/lib/model-loader.d.ts.map +1 -1
  69. package/lib/model-loader.js +19 -79
  70. package/lib/model-loader.js.map +1 -1
  71. package/lib/prisma-field-builder.d.ts +25 -6
  72. package/lib/prisma-field-builder.d.ts.map +1 -1
  73. package/lib/prisma-field-builder.js +92 -124
  74. package/lib/prisma-field-builder.js.map +1 -1
  75. package/lib/schema-builder.js +22 -8
  76. package/lib/schema-builder.js.map +1 -1
  77. package/lib/types.d.ts +74 -77
  78. package/lib/types.d.ts.map +1 -1
  79. package/lib/types.js +2 -0
  80. package/lib/types.js.map +1 -1
  81. package/lib/{cursors.d.ts → util/cursors.d.ts} +5 -5
  82. package/lib/util/cursors.d.ts.map +1 -0
  83. package/lib/{cursors.js → util/cursors.js} +0 -0
  84. package/lib/util/cursors.js.map +1 -0
  85. package/{esm/refs.d.ts → lib/util/datamodel.d.ts} +4 -8
  86. package/lib/util/datamodel.d.ts.map +1 -0
  87. package/lib/{refs.js → util/datamodel.js} +3 -29
  88. package/lib/util/datamodel.js.map +1 -0
  89. package/lib/util/deep-equal.d.ts +2 -0
  90. package/lib/util/deep-equal.d.ts.map +1 -0
  91. package/lib/util/deep-equal.js +43 -0
  92. package/lib/util/deep-equal.js.map +1 -0
  93. package/lib/util/loader-map.d.ts +6 -0
  94. package/lib/util/loader-map.d.ts.map +1 -0
  95. package/lib/{loader-map.js → util/loader-map.js} +10 -12
  96. package/lib/util/loader-map.js.map +1 -0
  97. package/lib/util/map-query.d.ts +6 -0
  98. package/lib/util/map-query.d.ts.map +1 -0
  99. package/lib/util/map-query.js +175 -0
  100. package/lib/util/map-query.js.map +1 -0
  101. package/lib/util/relation-map.d.ts +9 -0
  102. package/lib/util/relation-map.d.ts.map +1 -0
  103. package/lib/util/relation-map.js +24 -0
  104. package/lib/util/relation-map.js.map +1 -0
  105. package/lib/util/selections.d.ts +20 -0
  106. package/lib/util/selections.d.ts.map +1 -0
  107. package/lib/util/selections.js +148 -0
  108. package/lib/util/selections.js.map +1 -0
  109. package/package.json +8 -8
  110. package/src/field-builder.ts +22 -5
  111. package/src/generator.ts +18 -0
  112. package/src/global-types.ts +59 -12
  113. package/src/index.ts +75 -1
  114. package/src/model-loader.ts +27 -106
  115. package/src/prisma-field-builder.ts +195 -152
  116. package/src/schema-builder.ts +28 -7
  117. package/src/types.ts +155 -102
  118. package/src/{cursors.ts → util/cursors.ts} +3 -3
  119. package/src/{refs.ts → util/datamodel.ts} +3 -44
  120. package/src/util/deep-equal.ts +51 -0
  121. package/src/{loader-map.ts → util/loader-map.ts} +13 -13
  122. package/src/util/map-query.ts +327 -0
  123. package/src/util/relation-map.ts +36 -0
  124. package/src/util/selections.ts +192 -0
  125. package/esm/cursors.d.ts.map +0 -1
  126. package/esm/cursors.js.map +0 -1
  127. package/esm/loader-map.d.ts +0 -6
  128. package/esm/loader-map.d.ts.map +0 -1
  129. package/esm/loader-map.js.map +0 -1
  130. package/esm/refs.d.ts.map +0 -1
  131. package/esm/refs.js.map +0 -1
  132. package/esm/util/index.d.ts +0 -5
  133. package/esm/util/index.d.ts.map +0 -1
  134. package/esm/util/index.js +0 -16
  135. package/esm/util/index.js.map +0 -1
  136. package/esm/util/map-includes.d.ts +0 -6
  137. package/esm/util/map-includes.d.ts.map +0 -1
  138. package/esm/util/map-includes.js +0 -184
  139. package/esm/util/map-includes.js.map +0 -1
  140. package/esm/util/merge-includes.d.ts +0 -3
  141. package/esm/util/merge-includes.d.ts.map +0 -1
  142. package/esm/util/merge-includes.js +0 -91
  143. package/esm/util/merge-includes.js.map +0 -1
  144. package/lib/cursors.d.ts.map +0 -1
  145. package/lib/cursors.js.map +0 -1
  146. package/lib/loader-map.d.ts +0 -6
  147. package/lib/loader-map.d.ts.map +0 -1
  148. package/lib/loader-map.js.map +0 -1
  149. package/lib/refs.d.ts.map +0 -1
  150. package/lib/refs.js.map +0 -1
  151. package/lib/util/index.d.ts +0 -5
  152. package/lib/util/index.d.ts.map +0 -1
  153. package/lib/util/index.js +0 -30
  154. package/lib/util/index.js.map +0 -1
  155. package/lib/util/map-includes.d.ts +0 -6
  156. package/lib/util/map-includes.d.ts.map +0 -1
  157. package/lib/util/map-includes.js +0 -189
  158. package/lib/util/map-includes.js.map +0 -1
  159. package/lib/util/merge-includes.d.ts +0 -3
  160. package/lib/util/merge-includes.d.ts.map +0 -1
  161. package/lib/util/merge-includes.js +0 -96
  162. package/lib/util/merge-includes.js.map +0 -1
  163. package/src/util/index.ts +0 -26
  164. package/src/util/map-includes.ts +0 -328
  165. package/src/util/merge-includes.ts +0 -121
package/src/types.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  InterfaceParam,
11
11
  ListResolveValue,
12
12
  MaybePromise,
13
+ Normalize,
13
14
  ObjectRef,
14
15
  OutputShape,
15
16
  OutputType,
@@ -26,52 +27,17 @@ export interface PrismaDelegate {
26
27
  findUnique: (...args: any[]) => Promise<unknown>;
27
28
  }
28
29
 
29
- type RelationKeys<T> = {
30
- [K in keyof T]: T[K] extends (args: {}) => {
31
- then: (cb: (result: unknown) => unknown) => unknown;
32
- }
33
- ? K
34
- : never;
35
- }[keyof T];
36
-
37
- export type ModelTypes<Model extends {}> = Model extends {
38
- findUnique: (
39
- options: infer UniqueOptions & {
40
- where?: infer Where | null | undefined;
41
- select?: infer Select | null | undefined;
42
- } & (
43
- | {
44
- include?: infer Include | null | undefined;
45
- }
46
- | {}
47
- ),
48
- ) => infer Chain & {
49
- then: (cb: (result: infer Shape | null) => unknown) => unknown;
50
- };
51
- }
52
- ? PrismaModelTypes & {
53
- Shape: Shape;
54
- Include: unknown extends Include ? never : Include;
55
- Where: Where;
56
- Fields: keyof Select;
57
- ListRelation: ListRelationFields<Include> & string;
58
- Relations: {
59
- [RelationName in RelationKeys<Chain>]: Chain[RelationName] extends (args: {}) => {
60
- then: (cb: (result: infer Relation) => unknown) => unknown;
61
- }
62
- ? { Shape: Relation; Types: PrismaModelTypes }
63
- : never;
64
- };
65
- }
66
- : never;
30
+ export const prismaModelName = Symbol.for('Pothos.prismaModelName');
67
31
 
68
32
  export interface PrismaModelTypes {
69
33
  Name: string;
70
34
  Shape: {};
71
35
  Include: unknown;
36
+ Select: unknown;
72
37
  Where: {};
73
38
  Fields: string;
74
39
  ListRelations: string;
40
+ RelationName: string;
75
41
  Relations: Record<
76
42
  string,
77
43
  {
@@ -81,52 +47,97 @@ export interface PrismaModelTypes {
81
47
  >;
82
48
  }
83
49
 
84
- export type ListRelationFields<T> = {
85
- [K in keyof T]: T[K] extends infer Option
86
- ? Option extends { orderBy?: unknown }
87
- ? K
50
+ type ExtractModel<Types extends SchemaTypes, ParentShape> = ParentShape extends {
51
+ [prismaModelName]?: infer Name;
52
+ }
53
+ ? Types['PrismaTypes'][Name & keyof Types['PrismaTypes']] extends infer Model
54
+ ? Model extends PrismaModelTypes
55
+ ? Model
88
56
  : never
89
- : never;
90
- }[keyof T];
57
+ : never
58
+ : never;
59
+
60
+ export type PrismaObjectFieldOptions<
61
+ Types extends SchemaTypes,
62
+ ParentShape,
63
+ Type extends TypeParam<Types>,
64
+ Nullable extends FieldNullability<Type>,
65
+ Args extends InputFieldMap,
66
+ Select,
67
+ ResolveReturnShape,
68
+ > = PothosSchemaTypes.ObjectFieldOptions<
69
+ Types,
70
+ unknown extends Select
71
+ ? ParentShape
72
+ : ParentShape &
73
+ ShapeFromSelection<
74
+ ExtractModel<Types, ParentShape>,
75
+ { select: Select extends (...args: any[]) => infer S ? S : Select }
76
+ >,
77
+ Type,
78
+ Nullable,
79
+ Args,
80
+ ResolveReturnShape
81
+ > & {
82
+ select?: Select &
83
+ (
84
+ | ExtractModel<Types, ParentShape>['Select']
85
+ | ((
86
+ args: InputShapeFromFields<Args>,
87
+ ctx: Types['Context'],
88
+ ) => ExtractModel<Types, ParentShape>['Select'])
89
+ );
90
+ };
91
91
 
92
- export type PrismaObjectFieldsShape<
92
+ type PrismaObjectFieldsShape<
93
93
  Types extends SchemaTypes,
94
94
  Model extends PrismaModelTypes,
95
95
  NeedsResolve extends boolean,
96
96
  Shape extends object,
97
- > = (t: PrismaObjectFieldBuilder<Types, Model, NeedsResolve, Shape>) => FieldMap;
98
-
99
- export type ShapeFromInclude<Model extends PrismaModelTypes, Include> = {} extends Include
100
- ? Model['Shape']
101
- : {
102
- [K in keyof Include &
103
- keyof Model['Relations']]: Model['Relations'][K]['Shape'] extends infer RelationShape
104
- ? RelationShape extends (infer ItemShape)[]
105
- ? (ItemShape &
106
- (Include[K] extends { include?: infer NestedInclude & object }
107
- ? ShapeFromInclude<Model['Relations'][K]['Types'], NestedInclude>
108
- : {}))[]
109
- : RelationShape &
110
- (
111
- | (Include[K] extends { include?: infer NestedInclude & object }
112
- ? ShapeFromInclude<Model['Relations'][K]['Types'], NestedInclude>
113
- : {})
114
- | null
115
- )
116
- : never;
117
- };
97
+ Select,
98
+ > = Model['Select'] extends Select
99
+ ? (t: PrismaObjectFieldBuilder<Types, Model, NeedsResolve, Shape>) => FieldMap
100
+ : (t: PrismaSelectionFieldBuilder<Types, Model, Shape>) => FieldMap;
118
101
 
119
- export type ShapeWithInclude<
102
+ type PrismaSelectionFieldBuilder<
103
+ Types extends SchemaTypes,
120
104
  Model extends PrismaModelTypes,
121
- Include extends Model['Include'],
122
- > = Model['Shape'] & ([Include] extends [never] ? {} : ShapeFromInclude<Model, Include>);
105
+ Shape extends object,
106
+ > = PrismaObjectFieldBuilder<Types, Model, false, Shape>;
107
+
108
+ interface BaseSelection {
109
+ include?: unknown;
110
+ select?: unknown;
111
+ }
112
+
113
+ export type SelectedKeys<T> = { [K in keyof T]: T[K] extends false ? never : K }[keyof T];
114
+
115
+ export type ShapeFromSelection<Model extends PrismaModelTypes, Selection> = Normalize<
116
+ Selection extends BaseSelection
117
+ ? unknown extends Selection['select']
118
+ ? Model['Shape'] & RelationShapeFromInclude<Model, Selection['include']>
119
+ : Pick<Model['Shape'], SelectedKeys<Selection['select']>> &
120
+ RelationShapeFromInclude<Model, Selection['select']>
121
+ : Model['Shape']
122
+ >;
123
+
124
+ type RelationShapeFromInclude<Model extends PrismaModelTypes, Include> = Normalize<{
125
+ [K in SelectedKeys<Include> as K extends Model['RelationName']
126
+ ? K
127
+ : never]: K extends keyof Model['Relations']
128
+ ? Model['Relations'][K]['Shape'] extends unknown[]
129
+ ? ShapeFromSelection<Model['Relations'][K]['Types'], Include[K]>[]
130
+ : ShapeFromSelection<Model['Relations'][K]['Types'], Include[K]>
131
+ : unknown;
132
+ }>;
123
133
 
124
134
  export type PrismaObjectTypeOptions<
125
135
  Types extends SchemaTypes,
126
136
  Model extends PrismaModelTypes,
127
137
  Interfaces extends InterfaceParam<Types>[],
128
138
  FindUnique,
129
- Include extends Model['Include'],
139
+ Include,
140
+ Select,
130
141
  Shape extends object,
131
142
  > = NameOrVariant &
132
143
  Omit<
@@ -134,13 +145,28 @@ export type PrismaObjectTypeOptions<
134
145
  | PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
135
146
  'fields'
136
147
  > & {
137
- include?: Include;
138
- fields?: PrismaObjectFieldsShape<Types, Model, FindUnique extends null ? true : false, Shape>;
139
- findUnique: FindUnique &
140
- (((parent: Shape, context: Types['Context']) => Model['Where']) | null);
141
- };
148
+ fields?: PrismaObjectFieldsShape<
149
+ Types,
150
+ Model,
151
+ FindUnique extends null ? true : false,
152
+ Shape & (FindUnique extends null ? {} : { [prismaModelName]?: Model['Name'] }),
153
+ Select
154
+ >;
155
+ } & (
156
+ | {
157
+ include?: Include & Model['Include'];
158
+ select?: never;
159
+ findUnique: FindUnique &
160
+ (((parent: Shape, context: Types['Context']) => Model['Where']) | null);
161
+ }
162
+ | {
163
+ select: Model['Select'] & Select;
164
+ include?: never;
165
+ findUnique: (parent: Shape, context: Types['Context']) => Model['Where'];
166
+ }
167
+ );
142
168
 
143
- export type NameOrVariant =
169
+ type NameOrVariant =
144
170
  | {
145
171
  name?: never;
146
172
  variant?: string;
@@ -154,7 +180,8 @@ export type PrismaNodeOptions<
154
180
  Types extends SchemaTypes,
155
181
  Model extends PrismaModelTypes,
156
182
  Interfaces extends InterfaceParam<Types>[],
157
- Include extends Model['Include'],
183
+ Include,
184
+ Select,
158
185
  Shape extends object,
159
186
  > = NameOrVariant &
160
187
  Omit<
@@ -162,7 +189,6 @@ export type PrismaNodeOptions<
162
189
  | PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
163
190
  'fields' | 'isTypeOf'
164
191
  > & {
165
- include?: Include;
166
192
  id: Omit<
167
193
  FieldOptionsFromKind<
168
194
  Types,
@@ -178,11 +204,26 @@ export type PrismaNodeOptions<
178
204
  > & {
179
205
  resolve: (parent: Shape, context: Types['Context']) => MaybePromise<OutputShape<Types, 'ID'>>;
180
206
  };
181
- fields?: PrismaObjectFieldsShape<Types, Model, false, Shape>;
207
+ fields?: PrismaObjectFieldsShape<
208
+ Types,
209
+ Model,
210
+ false,
211
+ Shape & { [prismaModelName]?: Model['Name'] },
212
+ Select
213
+ >;
182
214
  findUnique: (id: string, context: Types['Context']) => Model['Where'];
183
- };
215
+ } & (
216
+ | {
217
+ include?: Include & Model['Include'];
218
+ select?: never;
219
+ }
220
+ | {
221
+ select: Model['Select'] & Select;
222
+ include?: never;
223
+ }
224
+ );
184
225
 
185
- export type QueryForField<
226
+ type QueryForField<
186
227
  Types extends SchemaTypes,
187
228
  Args extends InputFieldMap,
188
229
  Include,
@@ -195,18 +236,19 @@ export type QueryForField<
195
236
  ) => Omit<Include, 'include' | 'select'>)
196
237
  : never;
197
238
 
198
- export type IncludeFromRelation<
239
+ type QueryFromRelation<
199
240
  Model extends PrismaModelTypes,
200
241
  Field extends keyof Model['Include'],
201
242
  > = Model['Include'][Field] extends infer Include
202
243
  ? Include extends {
203
- include?: infer T;
244
+ include?: infer I;
245
+ select?: infer S;
204
246
  }
205
- ? NonNullable<T>
247
+ ? { include?: NonNullable<I>; select?: NonNullable<S> }
206
248
  : never
207
249
  : never;
208
250
 
209
- export type CursorFromRelation<
251
+ type CursorFromRelation<
210
252
  Model extends PrismaModelTypes,
211
253
  Field extends Model['ListRelations'],
212
254
  > = Field extends keyof Model['Include']
@@ -217,7 +259,7 @@ export type CursorFromRelation<
217
259
  : never
218
260
  : never;
219
261
 
220
- export type RefForRelation<
262
+ type RefForRelation<
221
263
  Model extends PrismaModelTypes,
222
264
  Field extends keyof Model['Relations'],
223
265
  > = Model['Relations'][Field] extends unknown[]
@@ -247,7 +289,7 @@ export type RelatedFieldOptions<
247
289
  (NeedsResolve extends false
248
290
  ? {
249
291
  resolve?: (
250
- query: { include?: IncludeFromRelation<Model, Field & keyof Model['Include']> },
292
+ query: QueryFromRelation<Model, Field & keyof Model['Include']>,
251
293
  parent: Shape,
252
294
  args: InputShapeFromFields<Args>,
253
295
  context: Types['Context'],
@@ -258,7 +300,7 @@ export type RelatedFieldOptions<
258
300
  }
259
301
  : {
260
302
  resolve: (
261
- query: { include?: IncludeFromRelation<Model, Field & keyof Model['Include']> },
303
+ query: QueryFromRelation<Model, Field & keyof Model['Include']>,
262
304
  parent: Shape,
263
305
  args: InputShapeFromFields<Args>,
264
306
  context: Types['Context'],
@@ -401,6 +443,12 @@ export type PrismaConnectionFieldOptions<
401
443
  context: Types['Context'],
402
444
  info: GraphQLResolveInfo,
403
445
  ) => MaybePromise<Model['Shape'][]>;
446
+ totalCount?: (
447
+ parent: ParentShape,
448
+ args: InputShapeFromFields<Args> & PothosSchemaTypes.DefaultConnectionArguments,
449
+ context: Types['Context'],
450
+ info: GraphQLResolveInfo,
451
+ ) => MaybePromise<number>;
404
452
  };
405
453
 
406
454
  export type RelatedConnectionOptions<
@@ -472,31 +520,36 @@ export type RelatedConnectionOptions<
472
520
 
473
521
  export type WithBrand<T> = T & { [typeBrandKey]: string };
474
522
 
475
- export type IncludeMap = Record<string, Record<string, unknown> | boolean>;
523
+ export type IncludeMap = Record<string, SelectionMap | boolean>;
476
524
 
477
- export interface IncludeCounts {
478
- current: Record<string, boolean>;
479
- parent: Record<string, boolean>;
525
+ export interface SelectionMap {
526
+ select?: Record<string, SelectionMap | boolean>;
527
+ include?: Record<string, SelectionMap | boolean>;
528
+ where?: {};
480
529
  }
481
530
 
531
+ export type FieldSelection =
532
+ | Record<string, SelectionMap | boolean>
533
+ | ((
534
+ args: object,
535
+ context: object,
536
+ query: (
537
+ selection: SelectionMap | boolean | ((args: object, context: object) => SelectionMap),
538
+ ) => SelectionMap | boolean,
539
+ ) => SelectionMap);
540
+
482
541
  export type LoaderMappings = Record<
483
542
  string,
484
543
  {
485
544
  field: string;
486
- alias?: string;
487
545
  mappings: LoaderMappings;
488
546
  indirectPath: string[];
489
- }[]
547
+ }
490
548
  >;
491
549
 
492
- export interface SubFieldInclude {
493
- type?: string;
494
- name: string;
495
- }
496
-
497
- export interface IndirectLoadMap {
498
- subFields: SubFieldInclude[];
499
- path: string[];
550
+ export interface IndirectInclude {
551
+ getType: () => string;
552
+ path: { type?: string; name: string }[];
500
553
  }
501
554
 
502
555
  export type ShapeFromConnection<T> = T extends { shape: unknown } ? T['shape'] : never;
@@ -75,7 +75,7 @@ export function parseCompositeCursor(fields: string[]) {
75
75
  };
76
76
  }
77
77
 
78
- interface PrismaCursorConnectionQueryOptions {
78
+ export interface PrismaCursorConnectionQueryOptions {
79
79
  args: PothosSchemaTypes.DefaultConnectionArguments;
80
80
  defaultSize?: number;
81
81
  maxSize?: number;
@@ -84,7 +84,7 @@ interface PrismaCursorConnectionQueryOptions {
84
84
 
85
85
  interface ResolvePrismaCursorConnectionOptions extends PrismaCursorConnectionQueryOptions {
86
86
  query: {};
87
- totalCount?: number;
87
+ totalCount?: number | (() => MaybePromise<number>);
88
88
  }
89
89
 
90
90
  export function prismaCursorConnectionQuery({
@@ -139,7 +139,7 @@ export function wrapConnectionResult<T extends {}>(
139
139
  args: PothosSchemaTypes.DefaultConnectionArguments,
140
140
  take: number,
141
141
  cursor: (node: T) => string,
142
- totalCount?: number,
142
+ totalCount?: number | (() => MaybePromise<number>),
143
143
  ) {
144
144
  const gotFullResults = results.length === Math.abs(take);
145
145
  const hasNextPage = args.before ? true : gotFullResults;
@@ -1,9 +1,8 @@
1
1
  import { ObjectRef, SchemaTypes } from '@pothos/core';
2
- import { Prisma } from '../tests/client';
2
+ import { Prisma } from '../../tests/client';
3
+ import { PrismaObjectRef } from '../object-ref';
4
+ import { PrismaDelegate, PrismaModelTypes } from '../types';
3
5
  import { formatCursor, parseCompositeCursor, parseRawCursor } from './cursors';
4
- import { PrismaObjectRef } from './object-ref';
5
- import { PrismaDelegate } from './types';
6
- import { PrismaModelTypes } from '.';
7
6
 
8
7
  export const refMap = new WeakMap<object, Map<string, PrismaObjectRef<PrismaModelTypes>>>();
9
8
  export const findUniqueMap = new WeakMap<
@@ -32,36 +31,6 @@ export function getRefFromModel<Types extends SchemaTypes>(
32
31
  return cache.get(name)!;
33
32
  }
34
33
 
35
- export function getFindUniqueForRef<Types extends SchemaTypes>(
36
- ref: ObjectRef<unknown>,
37
- builder: PothosSchemaTypes.SchemaBuilder<Types>,
38
- ) {
39
- if (!findUniqueMap.has(builder)) {
40
- findUniqueMap.set(builder, new Map());
41
- }
42
- const cache = findUniqueMap.get(builder)!;
43
-
44
- if (!cache.has(ref)) {
45
- return null;
46
- }
47
-
48
- return cache.get(ref)! as (args: unknown, context: Types['Context']) => unknown;
49
- }
50
-
51
- export function setFindUniqueForRef<Types extends SchemaTypes>(
52
- ref: ObjectRef<unknown>,
53
- builder: PothosSchemaTypes.SchemaBuilder<Types>,
54
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
- findUnique: ((args: any, context: Types['Context']) => unknown) | null,
56
- ) {
57
- if (!findUniqueMap.has(builder)) {
58
- findUniqueMap.set(builder, new Map());
59
- }
60
- const cache = findUniqueMap.get(builder)!;
61
-
62
- cache.set(ref, findUnique);
63
- }
64
-
65
34
  export function getRelation<Types extends SchemaTypes>(
66
35
  name: string,
67
36
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
@@ -126,16 +95,6 @@ export function getCursorParser<Types extends SchemaTypes>(
126
95
  });
127
96
  }
128
97
 
129
- export function getRelatedDelegate<Types extends SchemaTypes>(
130
- name: string,
131
- builder: PothosSchemaTypes.SchemaBuilder<Types>,
132
- relation: string,
133
- ) {
134
- const fieldData = getRelation(name, builder, relation);
135
-
136
- return fieldData.type;
137
- }
138
-
139
98
  export function getDelegateFromModel(client: Record<string, unknown>, model: string) {
140
99
  const lowerCase = `${model.slice(0, 1).toLowerCase()}${model.slice(1)}`;
141
100
 
@@ -0,0 +1,51 @@
1
+ /* eslint-disable no-continue */
2
+ export function deepEqual(left: unknown, right: unknown, ignore?: Set<string>) {
3
+ if (left === right) {
4
+ return true;
5
+ }
6
+
7
+ if (left && right && typeof left === 'object' && typeof right === 'object') {
8
+ if (Array.isArray(left)) {
9
+ if (!Array.isArray(right)) {
10
+ return false;
11
+ }
12
+
13
+ const { length } = left;
14
+
15
+ if (right.length !== length) {
16
+ return false;
17
+ }
18
+
19
+ for (let i = 0; i < length; i += 1) {
20
+ if (!deepEqual(left[i], right[i])) {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ return true;
26
+ }
27
+
28
+ const keys = Object.keys(left);
29
+ const keyLength = keys.length;
30
+
31
+ if (keyLength !== Object.keys(right).length) {
32
+ return false;
33
+ }
34
+
35
+ for (const key of keys) {
36
+ if (ignore?.has(key)) {
37
+ continue;
38
+ }
39
+
40
+ if (
41
+ !deepEqual((left as Record<string, unknown>)[key], (right as Record<string, unknown>)[key])
42
+ ) {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ return true;
48
+ }
49
+
50
+ return false;
51
+ }
@@ -1,10 +1,11 @@
1
- import { GraphQLResolveInfo } from 'graphql';
1
+ import { GraphQLNamedType, GraphQLResolveInfo } from 'graphql';
2
2
  import { createContextCache } from '@pothos/core';
3
- import { LoaderMappings } from './types';
3
+ import { LoaderMappings } from '../types';
4
+ import { getIndirectType } from './map-query';
4
5
 
5
6
  const cache = createContextCache((ctx) => new Map<string, LoaderMappings>());
6
7
 
7
- export function cacheKey(path: GraphQLResolveInfo['path'], subPath: string[]) {
8
+ export function cacheKey(type: string, path: GraphQLResolveInfo['path'], subPath: string[]) {
8
9
  let key = '';
9
10
  let current: GraphQLResolveInfo['path'] | undefined = path;
10
11
 
@@ -19,30 +20,29 @@ export function cacheKey(path: GraphQLResolveInfo['path'], subPath: string[]) {
19
20
  key = `${key}.${entry}`;
20
21
  }
21
22
 
22
- return key;
23
+ return `${type}@${key}`;
23
24
  }
24
25
 
25
26
  export function setLoaderMappings(
26
27
  ctx: object,
27
- path: GraphQLResolveInfo['path'],
28
+ info: GraphQLResolveInfo,
28
29
  value: LoaderMappings,
30
+ type: GraphQLNamedType,
29
31
  ) {
30
32
  Object.keys(value).forEach((field) => {
31
33
  const map = cache(ctx);
32
34
 
33
- for (const mapping of value[field]) {
34
- const selectionName = mapping.alias ?? mapping.field;
35
- const subPath = [...mapping.indirectPath, selectionName];
36
- const key = cacheKey(path, subPath);
35
+ const mapping = value[field];
36
+ const subPath = [...mapping.indirectPath, field];
37
+ const key = cacheKey(getIndirectType(type, info).name, info.path, subPath);
37
38
 
38
- map.set(key, mapping.mappings);
39
- }
39
+ map.set(key, mapping.mappings);
40
40
  });
41
41
  }
42
42
 
43
- export function getLoaderMapping(ctx: object, path: GraphQLResolveInfo['path']) {
43
+ export function getLoaderMapping(ctx: object, path: GraphQLResolveInfo['path'], type: string) {
44
44
  const map = cache(ctx);
45
- const key = cacheKey(path, []);
45
+ const key = cacheKey(type, path, []);
46
46
 
47
47
  return map.get(key) ?? null;
48
48
  }