@pothos/plugin-prisma 3.54.0 → 3.55.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 (76) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +42 -1
  3. package/dts/connection-helpers.d.ts +3 -3
  4. package/dts/connection-helpers.d.ts.map +1 -1
  5. package/dts/global-types.d.ts +12 -4
  6. package/dts/global-types.d.ts.map +1 -1
  7. package/dts/index.d.ts +3 -1
  8. package/dts/index.d.ts.map +1 -1
  9. package/dts/interface-ref.d.ts +10 -0
  10. package/dts/interface-ref.d.ts.map +1 -0
  11. package/dts/model-loader.d.ts +7 -7
  12. package/dts/model-loader.d.ts.map +1 -1
  13. package/dts/prisma-field-builder.d.ts +4 -4
  14. package/dts/prisma-field-builder.d.ts.map +1 -1
  15. package/dts/types.d.ts +23 -7
  16. package/dts/types.d.ts.map +1 -1
  17. package/dts/util/datamodel.d.ts +3 -3
  18. package/dts/util/datamodel.d.ts.map +1 -1
  19. package/dts/util/map-query.d.ts.map +1 -1
  20. package/esm/connection-helpers.d.ts +3 -3
  21. package/esm/connection-helpers.d.ts.map +1 -1
  22. package/esm/connection-helpers.js.map +1 -1
  23. package/esm/global-types.d.ts +18 -10
  24. package/esm/global-types.d.ts.map +1 -1
  25. package/esm/global-types.js.map +1 -1
  26. package/esm/index.d.ts +3 -1
  27. package/esm/index.d.ts.map +1 -1
  28. package/esm/index.js +48 -3
  29. package/esm/index.js.map +1 -1
  30. package/esm/interface-ref.d.ts +10 -0
  31. package/esm/interface-ref.d.ts.map +1 -0
  32. package/esm/interface-ref.js +26 -0
  33. package/esm/interface-ref.js.map +1 -0
  34. package/esm/model-loader.d.ts +7 -7
  35. package/esm/model-loader.d.ts.map +1 -1
  36. package/esm/model-loader.js.map +1 -1
  37. package/esm/prisma-field-builder.d.ts +4 -4
  38. package/esm/prisma-field-builder.d.ts.map +1 -1
  39. package/esm/prisma-field-builder.js +3 -3
  40. package/esm/prisma-field-builder.js.map +1 -1
  41. package/esm/schema-builder.js +27 -0
  42. package/esm/schema-builder.js.map +1 -1
  43. package/esm/types.d.ts +25 -9
  44. package/esm/types.d.ts.map +1 -1
  45. package/esm/util/datamodel.d.ts +3 -3
  46. package/esm/util/datamodel.d.ts.map +1 -1
  47. package/esm/util/datamodel.js +3 -2
  48. package/esm/util/datamodel.js.map +1 -1
  49. package/esm/util/map-query.d.ts.map +1 -1
  50. package/esm/util/map-query.js +17 -12
  51. package/esm/util/map-query.js.map +1 -1
  52. package/lib/connection-helpers.js.map +1 -1
  53. package/lib/index.js +50 -2
  54. package/lib/index.js.map +1 -1
  55. package/lib/interface-ref.js +36 -0
  56. package/lib/interface-ref.js.map +1 -0
  57. package/lib/model-loader.js.map +1 -1
  58. package/lib/prisma-field-builder.js +3 -3
  59. package/lib/prisma-field-builder.js.map +1 -1
  60. package/lib/schema-builder.js +27 -0
  61. package/lib/schema-builder.js.map +1 -1
  62. package/lib/util/datamodel.js +3 -2
  63. package/lib/util/datamodel.js.map +1 -1
  64. package/lib/util/map-query.js +16 -11
  65. package/lib/util/map-query.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/connection-helpers.ts +6 -6
  68. package/src/global-types.ts +36 -11
  69. package/src/index.ts +56 -2
  70. package/src/interface-ref.ts +18 -0
  71. package/src/model-loader.ts +13 -7
  72. package/src/prisma-field-builder.ts +7 -10
  73. package/src/schema-builder.ts +44 -1
  74. package/src/types.ts +66 -9
  75. package/src/util/datamodel.ts +8 -3
  76. package/src/util/map-query.ts +32 -13
package/src/index.ts CHANGED
@@ -6,6 +6,8 @@ import SchemaBuilder, {
6
6
  BasePlugin,
7
7
  BuildCache,
8
8
  PothosOutputFieldConfig,
9
+ PothosSchemaError,
10
+ PothosTypeConfig,
9
11
  SchemaTypes,
10
12
  } from '@pothos/core';
11
13
  import { ModelLoader } from './model-loader';
@@ -17,6 +19,7 @@ import { getLoaderMapping, setLoaderMappings } from './util/loader-map';
17
19
  import { queryFromInfo, selectionStateFromInfo } from './util/map-query';
18
20
 
19
21
  export { prismaConnectionHelpers } from './connection-helpers';
22
+ export { PrismaInterfaceRef } from './interface-ref';
20
23
  export { PrismaNodeRef } from './node-ref';
21
24
  export { PrismaObjectRef } from './object-ref';
22
25
  export * from './types';
@@ -47,6 +50,37 @@ export class PrismaPlugin<Types extends SchemaTypes> extends BasePlugin<Types> {
47
50
  super(cache, pluginName);
48
51
  }
49
52
 
53
+ override onTypeConfig(typeConfig: PothosTypeConfig): PothosTypeConfig {
54
+ if (typeConfig.kind !== 'Object' && typeConfig.kind !== 'Interface') {
55
+ return typeConfig;
56
+ }
57
+
58
+ let model = typeConfig.extensions?.pothosPrismaModel as string | undefined;
59
+
60
+ typeConfig.interfaces.forEach((iface) => {
61
+ const interfaceModel = this.buildCache.getTypeConfig(iface, 'Interface').extensions
62
+ ?.pothosPrismaModel as string | undefined;
63
+
64
+ if (interfaceModel) {
65
+ if (model && model !== interfaceModel) {
66
+ throw new PothosSchemaError(
67
+ `PrismaObjects must be based on the same prisma model as any PrismaInterfaces they extend. ${typeConfig.name} uses ${model} and ${iface.name} uses ${interfaceModel}`,
68
+ );
69
+ }
70
+
71
+ model = interfaceModel;
72
+ }
73
+ });
74
+
75
+ return {
76
+ ...typeConfig,
77
+ extensions: {
78
+ ...typeConfig.extensions,
79
+ pothosPrismaModel: model,
80
+ },
81
+ };
82
+ }
83
+
50
84
  override onOutputFieldConfig(
51
85
  fieldConfig: PothosOutputFieldConfig<Types>,
52
86
  ): PothosOutputFieldConfig<Types> | null {
@@ -85,7 +119,7 @@ export class PrismaPlugin<Types extends SchemaTypes> extends BasePlugin<Types> {
85
119
  return resolver;
86
120
  }
87
121
 
88
- const parentConfig = this.buildCache.getTypeConfig(fieldConfig.parentType, 'Object');
122
+ const parentConfig = this.buildCache.getTypeConfig(fieldConfig.parentType);
89
123
  const loadedCheck = fieldConfig.extensions?.pothosPrismaLoaded as
90
124
  | undefined
91
125
  | ((val: unknown) => boolean);
@@ -97,8 +131,28 @@ export class PrismaPlugin<Types extends SchemaTypes> extends BasePlugin<Types> {
97
131
  | undefined
98
132
  | ((query: {}, parent: unknown, args: {}, context: {}, info: {}) => unknown);
99
133
 
134
+ const parentTypes = new Set([fieldConfig.parentType]);
135
+
136
+ if (parentConfig.kind === 'Interface' || parentConfig.kind === 'Object') {
137
+ parentConfig.interfaces.forEach((iface) => {
138
+ const interfaceConfig = this.buildCache.getTypeConfig(iface, 'Interface');
139
+ if (interfaceConfig.extensions?.pothosPrismaModel) {
140
+ parentTypes.add(interfaceConfig.name);
141
+ }
142
+ });
143
+ }
144
+
100
145
  return (parent, args, context, info) => {
101
- const mapping = getLoaderMapping(context, info.path, info.parentType.name);
146
+ let mapping = getLoaderMapping(context, info.path, info.parentType.name);
147
+
148
+ if (!mapping) {
149
+ for (const parentType of parentTypes) {
150
+ mapping = getLoaderMapping(context, info.path, parentType);
151
+ if (mapping) {
152
+ break;
153
+ }
154
+ }
155
+ }
102
156
 
103
157
  if ((!loadedCheck || loadedCheck(parent)) && mapping) {
104
158
  setLoaderMappings(context, info, mapping);
@@ -0,0 +1,18 @@
1
+ import { InterfaceRef } from '@pothos/core';
2
+ import { prismaModelKey, PrismaObjectRef } from './object-ref';
3
+ import type { PrismaModelTypes } from './types';
4
+
5
+ export type PrismaRef<Model extends PrismaModelTypes, T = {}> =
6
+ | PrismaObjectRef<Model, T>
7
+ | PrismaInterfaceRef<Model, T>;
8
+
9
+ export class PrismaInterfaceRef<Model extends PrismaModelTypes, T = {}> extends InterfaceRef<T> {
10
+ [prismaModelKey]!: Model;
11
+ modelName: string;
12
+
13
+ constructor(name: string, modelName: string) {
14
+ super(name);
15
+
16
+ this.modelName = modelName;
17
+ }
18
+ }
@@ -1,4 +1,10 @@
1
- import { createContextCache, ObjectRef, PothosSchemaError, SchemaTypes } from '@pothos/core';
1
+ import {
2
+ createContextCache,
3
+ InterfaceRef,
4
+ ObjectRef,
5
+ PothosSchemaError,
6
+ SchemaTypes,
7
+ } from '@pothos/core';
2
8
  import { getDelegateFromModel, getModel } from './util/datamodel';
3
9
  import { getClient } from './util/get-client';
4
10
  import {
@@ -32,7 +38,7 @@ export class ModelLoader {
32
38
  }
33
39
 
34
40
  static forRef<Types extends SchemaTypes>(
35
- ref: ObjectRef<unknown>,
41
+ ref: ObjectRef<unknown> | InterfaceRef<unknown>,
36
42
  modelName: string,
37
43
  findUnique: ((model: Record<string, unknown>, ctx: {}) => unknown) | undefined,
38
44
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
@@ -78,7 +84,7 @@ export class ModelLoader {
78
84
  }
79
85
 
80
86
  static getDefaultFindBy<Types extends SchemaTypes>(
81
- ref: ObjectRef<unknown>,
87
+ ref: ObjectRef<unknown> | InterfaceRef<unknown>,
82
88
  modelName: string,
83
89
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
84
90
  ) {
@@ -115,7 +121,7 @@ export class ModelLoader {
115
121
  }
116
122
 
117
123
  static getDefaultFindUnique<Types extends SchemaTypes>(
118
- ref: ObjectRef<unknown>,
124
+ ref: ObjectRef<unknown> | InterfaceRef<unknown>,
119
125
  modelName: string,
120
126
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
121
127
  ): (model: Record<string, unknown>) => {} {
@@ -125,7 +131,7 @@ export class ModelLoader {
125
131
  }
126
132
 
127
133
  static getDefaultIDSelection<Types extends SchemaTypes>(
128
- ref: ObjectRef<unknown>,
134
+ ref: ObjectRef<unknown> | InterfaceRef<unknown>,
129
135
  modelName: string,
130
136
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
131
137
  ): Record<string, boolean> {
@@ -145,7 +151,7 @@ export class ModelLoader {
145
151
  }
146
152
 
147
153
  static getCursorSelection<Types extends SchemaTypes>(
148
- ref: ObjectRef<unknown>,
154
+ ref: ObjectRef<unknown> | InterfaceRef<unknown>,
149
155
  modelName: string,
150
156
  cursor: string,
151
157
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
@@ -174,7 +180,7 @@ export class ModelLoader {
174
180
  }
175
181
 
176
182
  static getFindUniqueForField<Types extends SchemaTypes>(
177
- ref: ObjectRef<unknown>,
183
+ ref: ObjectRef<unknown> | InterfaceRef<unknown>,
178
184
  modelName: string,
179
185
  fieldName: string,
180
186
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
@@ -18,8 +18,8 @@ import {
18
18
  ShapeFromTypeParam,
19
19
  TypeParam,
20
20
  } from '@pothos/core';
21
+ import { PrismaRef } from './interface-ref';
21
22
  import { ModelLoader } from './model-loader';
22
- import { PrismaObjectRef } from './object-ref';
23
23
  import {
24
24
  PrismaConnectionShape,
25
25
  PrismaModelTypes,
@@ -367,8 +367,9 @@ export class PrismaObjectFieldBuilder<
367
367
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
368
368
  model: string,
369
369
  fieldMap: FieldMap,
370
+ graphqlKind: PothosSchemaTypes.PothosKindToGraphQLType[FieldKind] = 'Object',
370
371
  ) {
371
- super(name, builder, 'PrismaObject', 'Object');
372
+ super(name, builder, 'PrismaObject', graphqlKind);
372
373
 
373
374
  this.model = model;
374
375
  this.prismaFieldMap = fieldMap;
@@ -473,18 +474,14 @@ export class PrismaObjectFieldBuilder<
473
474
  }) as FieldRef<number, 'Object'>;
474
475
  }
475
476
 
476
- variant<
477
- Variant extends Model['Name'] | PrismaObjectRef<Model>,
478
- Args extends InputFieldMap,
479
- Nullable,
480
- >(
477
+ variant<Variant extends Model['Name'] | PrismaRef<Model>, Args extends InputFieldMap, Nullable>(
481
478
  variant: Variant,
482
479
  ...allArgs: NormalizeArgs<
483
480
  [
484
481
  options: VariantFieldOptions<
485
482
  Types,
486
483
  Model,
487
- Variant extends PrismaObjectRef<Model> ? Variant : PrismaObjectRef<Model>,
484
+ Variant extends PrismaRef<Model> ? Variant : PrismaRef<Model>,
488
485
  Args,
489
486
  Nullable,
490
487
  Shape
@@ -493,7 +490,7 @@ export class PrismaObjectFieldBuilder<
493
490
  >
494
491
  ): FieldRef<Model['Shape'], 'Object'> {
495
492
  const [{ isNull, nullable, ...options } = {} as never] = allArgs;
496
- const ref: PrismaObjectRef<PrismaModelTypes> =
493
+ const ref: PrismaRef<PrismaModelTypes> =
497
494
  typeof variant === 'string' ? getRefFromModel(variant, this.builder) : variant;
498
495
 
499
496
  const selfSelect = (args: object, context: object, nestedQuery: (query: unknown) => unknown) =>
@@ -550,7 +547,7 @@ export class PrismaObjectFieldBuilder<
550
547
  ) {
551
548
  const [name, options = {} as never] = args;
552
549
 
553
- const typeConfig = this.builder.configStore.getTypeConfig(this.typename, 'Object');
550
+ const typeConfig = this.builder.configStore.getTypeConfig(this.typename);
554
551
  const usingSelect = !!typeConfig.extensions?.pothosPrismaSelect;
555
552
 
556
553
  return this.exposeField<Type, Nullable, never>(name as never, {
@@ -9,6 +9,7 @@ import SchemaBuilder, {
9
9
  PothosError,
10
10
  SchemaTypes,
11
11
  } from '@pothos/core';
12
+ import { PrismaInterfaceRef } from './interface-ref';
12
13
  import { ModelLoader } from './model-loader';
13
14
  import { PrismaNodeRef } from './node-ref';
14
15
  import { PrismaObjectRef } from './object-ref';
@@ -29,7 +30,7 @@ schemaBuilderProto.prismaObject = function prismaObject(
29
30
  ) {
30
31
  const ref = options.variant
31
32
  ? new PrismaObjectRef(options.variant, type)
32
- : getRefFromModel(type, this);
33
+ : (getRefFromModel(type, this) as PrismaObjectRef<PrismaModelTypes>);
33
34
  const name = options.variant ?? options.name ?? type;
34
35
  const fieldMap = getRelationMap(getDMMF(this)).get(type)!;
35
36
  const idSelection = ModelLoader.getDefaultIDSelection(ref, type, this);
@@ -64,6 +65,48 @@ schemaBuilderProto.prismaObject = function prismaObject(
64
65
  return ref as never;
65
66
  };
66
67
 
68
+ schemaBuilderProto.prismaInterface = function prismaInterface(
69
+ type,
70
+ { fields, findUnique, select, include, description, ...options },
71
+ ) {
72
+ const ref = options.variant
73
+ ? new PrismaInterfaceRef(options.variant, type)
74
+ : (getRefFromModel(type, this, 'interface') as PrismaInterfaceRef<PrismaModelTypes>);
75
+ const name = options.variant ?? options.name ?? type;
76
+ const fieldMap = getRelationMap(getDMMF(this)).get(type)!;
77
+ const idSelection = ModelLoader.getDefaultIDSelection(ref, type, this);
78
+
79
+ ref.name = name;
80
+
81
+ this.interfaceType(ref, {
82
+ ...(options as {}),
83
+ description: getModelDescription(type, this, description),
84
+ extensions: {
85
+ ...options.extensions,
86
+ pothosPrismaInclude: include,
87
+ pothosPrismaModel: type,
88
+ pothosPrismaFieldMap: fieldMap,
89
+ pothosPrismaSelect: select && { ...idSelection, ...(select as {}) },
90
+ pothosPrismaLoader: ModelLoader.forRef(ref, type, findUnique as never, this),
91
+ },
92
+ name,
93
+ fields: fields
94
+ ? () =>
95
+ fields(
96
+ new PrismaObjectFieldBuilder(
97
+ name,
98
+ this,
99
+ type,
100
+ getRelationMap(getDMMF(this)).get(type)!,
101
+ 'Interface',
102
+ ),
103
+ )
104
+ : undefined,
105
+ });
106
+
107
+ return ref as never;
108
+ };
109
+
67
110
  schemaBuilderProto.prismaNode = function prismaNode(
68
111
  this: PothosSchemaTypes.SchemaBuilder<SchemaTypes> & {
69
112
  nodeInterfaceRef?: () => InterfaceRef<unknown>;
package/src/types.ts CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  typeBrandKey,
22
22
  TypeParam,
23
23
  } from '@pothos/core';
24
- import { PrismaObjectRef } from './object-ref';
24
+ import { PrismaInterfaceRef, PrismaRef } from './interface-ref';
25
25
  import type { PrismaObjectFieldBuilder } from './prisma-field-builder';
26
26
 
27
27
  export interface PrismaDelegate {
@@ -228,6 +228,60 @@ export type PrismaObjectTypeOptions<
228
228
  > = PrismaObjectRefOptions<Types, Model, FindUnique, Include, Select, Shape> &
229
229
  PrismaObjectImplementationOptions<Types, Model, Interfaces, FindUnique, Select, Shape>;
230
230
 
231
+ export type PrismaInterfaceRefOptions<
232
+ Types extends SchemaTypes,
233
+ Model extends PrismaModelTypes,
234
+ FindUnique,
235
+ Include,
236
+ Select,
237
+ Shape extends object,
238
+ > = NameOrVariant &
239
+ (
240
+ | {
241
+ include?: Include & Model['Include'];
242
+ select?: never;
243
+ findUnique?: FindUnique &
244
+ (((parent: Shape, context: Types['Context']) => Model['WhereUnique']) | null);
245
+ }
246
+ | {
247
+ select: Model['Select'] & Select;
248
+ include?: never;
249
+ findUnique?: (parent: Shape, context: Types['Context']) => Model['WhereUnique'];
250
+ }
251
+ );
252
+
253
+ export type PrismaInterfaceImplementationOptions<
254
+ Types extends SchemaTypes,
255
+ Model extends PrismaModelTypes,
256
+ Interfaces extends InterfaceParam<Types>[],
257
+ FindUnique,
258
+ Select,
259
+ Shape extends object,
260
+ > = Omit<
261
+ PothosSchemaTypes.InterfaceTypeOptions<Types, Shape, Interfaces>,
262
+ 'fields' | 'description'
263
+ > & {
264
+ description?: string | false;
265
+ fields?: PrismaObjectFieldsShape<
266
+ Types,
267
+ Model,
268
+ FindUnique extends null ? true : false,
269
+ Shape & (FindUnique extends null ? {} : { [prismaModelName]?: Model['Name'] }),
270
+ Select
271
+ >;
272
+ };
273
+
274
+ export type PrismaInterfaceTypeOptions<
275
+ Types extends SchemaTypes,
276
+ Model extends PrismaModelTypes,
277
+ Interfaces extends InterfaceParam<Types>[],
278
+ FindUnique,
279
+ Include,
280
+ Select,
281
+ Shape extends object,
282
+ > = PrismaInterfaceRefOptions<Types, Model, FindUnique, Include, Select, Shape> &
283
+ PrismaInterfaceImplementationOptions<Types, Model, Interfaces, FindUnique, Select, Shape>;
284
+
231
285
  type NameOrVariant =
232
286
  | {
233
287
  name?: never;
@@ -394,14 +448,14 @@ export type RelatedFieldOptions<
394
448
  >;
395
449
  }) & {
396
450
  description?: string | false;
397
- type?: PrismaObjectRef<TypesForRelation<Types, Model, Field>>;
451
+ type?: PrismaRef<TypesForRelation<Types, Model, Field>>;
398
452
  query?: QueryForField<Types, Args, Model['Include'][Field & keyof Model['Include']]>;
399
453
  };
400
454
 
401
455
  export type VariantFieldOptions<
402
456
  Types extends SchemaTypes,
403
457
  Model extends PrismaModelTypes,
404
- Variant extends PrismaObjectRef<Model>,
458
+ Variant extends PrismaRef<Model>,
405
459
  Args extends InputFieldMap,
406
460
  isNull,
407
461
  Shape,
@@ -458,10 +512,10 @@ export type PrismaFieldOptions<
458
512
  Types extends SchemaTypes,
459
513
  ParentShape,
460
514
  Type extends
461
- | PrismaObjectRef<PrismaModelTypes>
515
+ | PrismaRef<PrismaModelTypes>
462
516
  | keyof Types['PrismaTypes']
463
517
  | [keyof Types['PrismaTypes']]
464
- | [PrismaObjectRef<PrismaModelTypes>],
518
+ | [PrismaRef<PrismaModelTypes>],
465
519
  Model extends PrismaModelTypes,
466
520
  Param extends TypeParam<Types>,
467
521
  Args extends InputFieldMap,
@@ -494,10 +548,10 @@ export type PrismaFieldWithInputOptions<
494
548
  Args extends Record<string, InputFieldRef<unknown, 'Arg'>>,
495
549
  Fields extends Record<string, InputFieldRef<unknown, 'InputObject'>>,
496
550
  Type extends
497
- | PrismaObjectRef<PrismaModelTypes>
551
+ | PrismaRef<PrismaModelTypes>
498
552
  | keyof Types['PrismaTypes']
499
553
  | [keyof Types['PrismaTypes']]
500
- | [PrismaObjectRef<PrismaModelTypes>],
554
+ | [PrismaRef<PrismaModelTypes>],
501
555
  Model extends PrismaModelTypes,
502
556
  Param extends TypeParam<Types>,
503
557
  Nullable extends FieldNullability<Param>,
@@ -562,7 +616,10 @@ export type PrismaFieldResolver<
562
616
  export type PrismaConnectionFieldOptions<
563
617
  Types extends SchemaTypes,
564
618
  ParentShape,
565
- Type extends PrismaObjectRef<PrismaModelTypes> | keyof Types['PrismaTypes'],
619
+ Type extends
620
+ | PrismaRef<PrismaModelTypes>
621
+ | PrismaInterfaceRef<PrismaModelTypes>
622
+ | keyof Types['PrismaTypes'],
566
623
  Model extends PrismaModelTypes,
567
624
  Param extends OutputType<Types>,
568
625
  Nullable extends boolean,
@@ -665,7 +722,7 @@ export type RelatedConnectionOptions<
665
722
  ? {
666
723
  description?: string | false;
667
724
  query?: QueryForField<Types, Args, Model['Include'][Field & keyof Model['Include']]>;
668
- type?: PrismaObjectRef<TypesForRelation<Types, Model, Field>>;
725
+ type?: PrismaRef<TypesForRelation<Types, Model, Field>>;
669
726
  cursor: CursorFromRelation<Model, Field>;
670
727
  defaultSize?: number | ((args: ConnectionArgs, ctx: Types['Context']) => number);
671
728
  maxSize?: number | ((args: ConnectionArgs, ctx: Types['Context']) => number);
@@ -1,9 +1,10 @@
1
1
  import { ObjectRef, PothosSchemaError, SchemaTypes } from '@pothos/core';
2
+ import { PrismaInterfaceRef, PrismaRef } from '../interface-ref';
2
3
  import { PrismaObjectRef } from '../object-ref';
3
4
  import { PrismaClient, PrismaDelegate, PrismaModelTypes } from '../types';
4
5
  import { getDMMF } from './get-client';
5
6
 
6
- export const refMap = new WeakMap<object, Map<string, PrismaObjectRef<PrismaModelTypes>>>();
7
+ export const refMap = new WeakMap<object, Map<string, PrismaRef<PrismaModelTypes>>>();
7
8
  export const findUniqueMap = new WeakMap<
8
9
  object,
9
10
  Map<ObjectRef<unknown>, ((args: unknown, ctx: {}) => unknown) | null>
@@ -17,14 +18,18 @@ export const includeForRefMap = new WeakMap<
17
18
  export function getRefFromModel<Types extends SchemaTypes>(
18
19
  name: string,
19
20
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
20
- ): PrismaObjectRef<PrismaModelTypes> {
21
+ type: 'object' | 'interface' = 'object',
22
+ ): PrismaRef<PrismaModelTypes> {
21
23
  if (!refMap.has(builder)) {
22
24
  refMap.set(builder, new Map());
23
25
  }
24
26
  const cache = refMap.get(builder)!;
25
27
 
26
28
  if (!cache.has(name)) {
27
- cache.set(name, new PrismaObjectRef(name, name));
29
+ cache.set(
30
+ name,
31
+ type === 'object' ? new PrismaObjectRef(name, name) : new PrismaInterfaceRef(name, name),
32
+ );
28
33
  }
29
34
 
30
35
  return cache.get(name)!;
@@ -6,10 +6,12 @@ import {
6
6
  getArgumentValues,
7
7
  getNamedType,
8
8
  GraphQLField,
9
+ GraphQLInterfaceType,
9
10
  GraphQLNamedType,
10
11
  GraphQLObjectType,
11
12
  GraphQLResolveInfo,
12
13
  InlineFragmentNode,
14
+ isInterfaceType,
13
15
  isObjectType,
14
16
  Kind,
15
17
  SelectionSetNode,
@@ -84,7 +86,7 @@ function addTypeSelectionsForField(
84
86
  return;
85
87
  }
86
88
 
87
- if (!isObjectType(type)) {
89
+ if (!(isObjectType(type) || isInterfaceType(type))) {
88
90
  return;
89
91
  }
90
92
 
@@ -143,7 +145,7 @@ function resolveIndirectInclude(
143
145
  for (const sel of selection.selectionSet.selections) {
144
146
  switch (sel.kind) {
145
147
  case Kind.FIELD:
146
- if (sel.name.value === include.name && isObjectType(type)) {
148
+ if (sel.name.value === include.name && (isObjectType(type) || isInterfaceType(type))) {
147
149
  const returnType = getNamedType(type.getFields()[sel.name.value].type);
148
150
 
149
151
  resolveIndirectInclude(
@@ -196,13 +198,14 @@ function resolveIndirectInclude(
196
198
  }
197
199
 
198
200
  function addNestedSelections(
199
- type: GraphQLObjectType,
201
+ type: GraphQLObjectType | GraphQLInterfaceType,
200
202
  context: object,
201
203
  info: GraphQLResolveInfo,
202
204
  state: SelectionState,
203
205
  selections: SelectionSetNode,
204
206
  indirectPath: string[],
205
207
  ) {
208
+ let parentType = type;
206
209
  for (const selection of selections.selections) {
207
210
  switch (selection.kind) {
208
211
  case Kind.FIELD:
@@ -210,12 +213,19 @@ function addNestedSelections(
210
213
 
211
214
  continue;
212
215
  case Kind.FRAGMENT_SPREAD:
213
- if (info.fragments[selection.name.value].typeCondition.name.value !== type.name) {
216
+ parentType = info.schema.getType(
217
+ info.fragments[selection.name.value].typeCondition.name.value,
218
+ )! as GraphQLObjectType;
219
+ if (
220
+ isObjectType(type)
221
+ ? parentType.name !== type.name
222
+ : parentType.extensions?.pothosPrismaModel !== type.extensions.pothosPrismaModel
223
+ ) {
214
224
  continue;
215
225
  }
216
226
 
217
227
  addNestedSelections(
218
- type,
228
+ parentType,
219
229
  context,
220
230
  info,
221
231
  state,
@@ -226,11 +236,18 @@ function addNestedSelections(
226
236
  continue;
227
237
 
228
238
  case Kind.INLINE_FRAGMENT:
229
- if (selection.typeCondition && selection.typeCondition.name.value !== type.name) {
239
+ parentType = selection.typeCondition
240
+ ? (info.schema.getType(selection.typeCondition.name.value) as GraphQLObjectType)
241
+ : type;
242
+ if (
243
+ isObjectType(type)
244
+ ? parentType.name !== type.name
245
+ : parentType.extensions?.pothosPrismaModel !== type.extensions.pothosPrismaModel
246
+ ) {
230
247
  continue;
231
248
  }
232
249
 
233
- addNestedSelections(type, context, info, state, selection.selectionSet, indirectPath);
250
+ addNestedSelections(parentType, context, info, state, selection.selectionSet, indirectPath);
234
251
 
235
252
  continue;
236
253
 
@@ -243,7 +260,7 @@ function addNestedSelections(
243
260
  }
244
261
 
245
262
  function addFieldSelection(
246
- type: GraphQLObjectType,
263
+ type: GraphQLObjectType | GraphQLInterfaceType,
247
264
  context: object,
248
265
  info: GraphQLResolveInfo,
249
266
  state: SelectionState,
@@ -454,8 +471,10 @@ export function selectionStateFromInfo(
454
471
 
455
472
  const state = createStateForType(type, info);
456
473
 
457
- if (!isObjectType(type)) {
458
- throw new PothosValidationError('Prisma plugin can only resolve includes for object types');
474
+ if (!(isObjectType(type) || isInterfaceType(type))) {
475
+ throw new PothosValidationError(
476
+ 'Prisma plugin can only resolve includes for object and interface types',
477
+ );
459
478
  }
460
479
 
461
480
  addFieldSelection(type, context, info, state, info.fieldNodes[0], []);
@@ -503,7 +522,7 @@ function normalizeInclude(path: string[], type: GraphQLNamedType): IndirectInclu
503
522
 
504
523
  const normalized: { name: string; type: string }[] = [];
505
524
 
506
- if (!isObjectType(currentType)) {
525
+ if (!(isObjectType(currentType) || isInterfaceType(currentType))) {
507
526
  throw new PothosValidationError(`Expected ${currentType} to be an Object type`);
508
527
  }
509
528
 
@@ -516,8 +535,8 @@ function normalizeInclude(path: string[], type: GraphQLNamedType): IndirectInclu
516
535
 
517
536
  currentType = getNamedType(field.type);
518
537
 
519
- if (!isObjectType(currentType)) {
520
- throw new PothosValidationError(`Expected ${currentType} to be an Object type`);
538
+ if (!(isObjectType(currentType) || isInterfaceType(currentType))) {
539
+ throw new PothosValidationError(`Expected ${currentType} to be an Object or Interface type`);
521
540
  }
522
541
 
523
542
  normalized.push({ name: fieldName, type: currentType.name });