@pothos/plugin-prisma 0.15.2 → 0.16.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 (88) hide show
  1. package/.turbo/turbo-build.log +5 -5
  2. package/.turbo/turbo-test.log +8 -7
  3. package/.turbo/turbo-type.log +2 -2
  4. package/CHANGELOG.md +6 -0
  5. package/esm/field-builder.d.ts.map +1 -1
  6. package/esm/field-builder.js +5 -3
  7. package/esm/field-builder.js.map +1 -1
  8. package/esm/generator.js +1 -0
  9. package/esm/generator.js.map +1 -1
  10. package/esm/global-types.d.ts +5 -4
  11. package/esm/global-types.d.ts.map +1 -1
  12. package/esm/model-loader.d.ts +2 -1
  13. package/esm/model-loader.d.ts.map +1 -1
  14. package/esm/model-loader.js +23 -11
  15. package/esm/model-loader.js.map +1 -1
  16. package/esm/node-ref.d.ts +4 -2
  17. package/esm/node-ref.d.ts.map +1 -1
  18. package/esm/node-ref.js +3 -2
  19. package/esm/node-ref.js.map +1 -1
  20. package/esm/object-ref.d.ts +7 -0
  21. package/esm/object-ref.d.ts.map +1 -0
  22. package/esm/object-ref.js +5 -0
  23. package/esm/object-ref.js.map +1 -0
  24. package/esm/prisma-field-builder.d.ts +6 -0
  25. package/esm/prisma-field-builder.d.ts.map +1 -1
  26. package/esm/prisma-field-builder.js +33 -5
  27. package/esm/prisma-field-builder.js.map +1 -1
  28. package/esm/refs.d.ts +4 -2
  29. package/esm/refs.d.ts.map +1 -1
  30. package/esm/refs.js +2 -1
  31. package/esm/refs.js.map +1 -1
  32. package/esm/schema-builder.js +7 -11
  33. package/esm/schema-builder.js.map +1 -1
  34. package/esm/types.d.ts +15 -5
  35. package/esm/types.d.ts.map +1 -1
  36. package/esm/util/map-includes.d.ts +1 -0
  37. package/esm/util/map-includes.d.ts.map +1 -1
  38. package/esm/util/map-includes.js +23 -6
  39. package/esm/util/map-includes.js.map +1 -1
  40. package/lib/field-builder.d.ts.map +1 -1
  41. package/lib/field-builder.js +5 -3
  42. package/lib/field-builder.js.map +1 -1
  43. package/lib/generator.js +1 -0
  44. package/lib/generator.js.map +1 -1
  45. package/lib/global-types.d.ts +5 -4
  46. package/lib/global-types.d.ts.map +1 -1
  47. package/lib/model-loader.d.ts +2 -1
  48. package/lib/model-loader.d.ts.map +1 -1
  49. package/lib/model-loader.js +23 -11
  50. package/lib/model-loader.js.map +1 -1
  51. package/lib/node-ref.d.ts +4 -2
  52. package/lib/node-ref.d.ts.map +1 -1
  53. package/lib/node-ref.js +2 -1
  54. package/lib/node-ref.js.map +1 -1
  55. package/lib/object-ref.d.ts +7 -0
  56. package/lib/object-ref.d.ts.map +1 -0
  57. package/lib/object-ref.js +9 -0
  58. package/lib/object-ref.js.map +1 -0
  59. package/lib/prisma-field-builder.d.ts +6 -0
  60. package/lib/prisma-field-builder.d.ts.map +1 -1
  61. package/lib/prisma-field-builder.js +32 -4
  62. package/lib/prisma-field-builder.js.map +1 -1
  63. package/lib/refs.d.ts +4 -2
  64. package/lib/refs.d.ts.map +1 -1
  65. package/lib/refs.js +2 -1
  66. package/lib/refs.js.map +1 -1
  67. package/lib/schema-builder.js +7 -11
  68. package/lib/schema-builder.js.map +1 -1
  69. package/lib/types.d.ts +15 -5
  70. package/lib/types.d.ts.map +1 -1
  71. package/lib/util/map-includes.d.ts +1 -0
  72. package/lib/util/map-includes.d.ts.map +1 -1
  73. package/lib/util/map-includes.js +24 -7
  74. package/lib/util/map-includes.js.map +1 -1
  75. package/package.json +1 -1
  76. package/src/field-builder.ts +7 -5
  77. package/src/generator.ts +7 -0
  78. package/src/global-types.ts +17 -6
  79. package/src/model-loader.ts +30 -13
  80. package/src/node-ref.ts +7 -2
  81. package/src/object-ref.ts +8 -0
  82. package/src/prisma-field-builder.ts +52 -3
  83. package/src/refs.ts +5 -3
  84. package/src/schema-builder.ts +4 -7
  85. package/src/types.ts +63 -35
  86. package/src/util/map-includes.ts +35 -3
  87. package/tsconfig.tsbuildinfo +1 -1
  88. package/generated.ts +0 -54
@@ -13,6 +13,7 @@ import {
13
13
  ShapeFromTypeParam,
14
14
  } from '@pothos/core';
15
15
  import PrismaNodeRef from './node-ref';
16
+ import { prismaModelKey, PrismaObjectRef } from './object-ref';
16
17
  import {
17
18
  PrismaConnectionFieldOptions,
18
19
  PrismaFieldOptions,
@@ -58,7 +59,7 @@ declare global {
58
59
  >(
59
60
  name: Name,
60
61
  options: PrismaObjectTypeOptions<Types, Model, Interfaces, FindUnique, Include, Shape>,
61
- ) => ObjectRef<Shape>;
62
+ ) => PrismaObjectRef<Model, Shape>;
62
63
 
63
64
  prismaNode: 'relay' extends PluginName
64
65
  ? <
@@ -70,7 +71,7 @@ declare global {
70
71
  >(
71
72
  name: Name,
72
73
  options: PrismaNodeOptions<Types, Model, Interfaces, Include, Shape>,
73
- ) => PrismaNodeRef<Shape>
74
+ ) => PrismaNodeRef<Model, Shape>
74
75
  : '@pothos/plugin-relay is required to use this method';
75
76
  }
76
77
 
@@ -81,15 +82,23 @@ declare global {
81
82
  > {
82
83
  prismaField: <
83
84
  Args extends InputFieldMap,
84
- TypeParam extends keyof Types['PrismaTypes'] | [keyof Types['PrismaTypes']],
85
+ TypeParam extends
86
+ | PrismaObjectRef<PrismaModelTypes>
87
+ | keyof Types['PrismaTypes']
88
+ | [keyof Types['PrismaTypes']]
89
+ | [PrismaObjectRef<PrismaModelTypes>],
85
90
  Nullable extends FieldNullability<Type>,
86
91
  ResolveReturnShape,
87
- Type extends TypeParam extends [keyof Types['PrismaTypes']]
92
+ Type extends TypeParam extends [unknown]
88
93
  ? [ObjectRef<Model['Shape']>]
89
94
  : ObjectRef<Model['Shape']>,
90
95
  Model extends PrismaModelTypes = PrismaModelTypes &
91
96
  (TypeParam extends [keyof Types['PrismaTypes']]
92
97
  ? Types['PrismaTypes'][TypeParam[0]]
98
+ : TypeParam extends [PrismaObjectRef<PrismaModelTypes>]
99
+ ? TypeParam[0][typeof prismaModelKey]
100
+ : TypeParam extends PrismaObjectRef<PrismaModelTypes>
101
+ ? TypeParam[typeof prismaModelKey]
93
102
  : TypeParam extends keyof Types['PrismaTypes']
94
103
  ? Types['PrismaTypes'][TypeParam]
95
104
  : never),
@@ -109,11 +118,13 @@ declare global {
109
118
 
110
119
  prismaConnection: 'relay' extends PluginName
111
120
  ? <
112
- Type extends keyof Types['PrismaTypes'],
121
+ Type extends PrismaObjectRef<PrismaModelTypes> | keyof Types['PrismaTypes'],
113
122
  Nullable extends boolean,
114
123
  ResolveReturnShape,
115
124
  Args extends InputFieldMap = {},
116
- Model extends PrismaModelTypes = PrismaModelTypes & Types['PrismaTypes'][Type],
125
+ Model extends PrismaModelTypes = Type extends PrismaObjectRef<infer T>
126
+ ? T
127
+ : PrismaModelTypes & Types['PrismaTypes'][Type & keyof Types['PrismaTypes']],
117
128
  >(
118
129
  ...args: NormalizeArgs<
119
130
  [
@@ -66,6 +66,20 @@ export class ModelLoader {
66
66
  return (result._count as Record<string, number>)[relation];
67
67
  }
68
68
 
69
+ async loadSelf(include: unknown, context: {}) {
70
+ for (const entry of this.staged) {
71
+ const merged = mergeIncludes(entry.include, include as Record<string, unknown>);
72
+
73
+ if (merged) {
74
+ entry.include = merged as Record<string, unknown>;
75
+
76
+ return entry.promise;
77
+ }
78
+ }
79
+
80
+ return this.initLoad(null, include, context);
81
+ }
82
+
69
83
  async loadRelation(relation: string, include: unknown, context: {}) {
70
84
  let promise;
71
85
  for (const entry of this.staged) {
@@ -96,18 +110,21 @@ export class ModelLoader {
96
110
  return result[relation];
97
111
  }
98
112
 
99
- async initLoad(relation: string, includeArg: unknown, context: {}, count = false) {
100
- const include: Record<string, unknown> = count
101
- ? {
102
- _count: {
103
- select: {
104
- [relation]: true,
105
- },
106
- },
107
- }
108
- : {
109
- [relation]: includeArg,
110
- };
113
+ async initLoad(relation: string | null, includeArg: unknown, context: {}, count = false) {
114
+ const include: Record<string, unknown> =
115
+ (relation &&
116
+ (count
117
+ ? {
118
+ _count: {
119
+ select: {
120
+ [relation]: true,
121
+ },
122
+ },
123
+ }
124
+ : {
125
+ [relation]: includeArg,
126
+ })) ||
127
+ {};
111
128
 
112
129
  const promise = new Promise<Record<string, unknown>>((resolve, reject) => {
113
130
  setTimeout(() => {
@@ -117,7 +134,7 @@ export class ModelLoader {
117
134
  this.delegate.findUnique({
118
135
  rejectOnNotFound: true,
119
136
  where: { ...(this.findUnique(this.model, context) as {}) },
120
- include,
137
+ include: Object.keys(include).length > 0 ? include : undefined,
121
138
  } as never) as Promise<Record<string, unknown>>,
122
139
  );
123
140
  }, 0);
package/src/node-ref.ts CHANGED
@@ -1,7 +1,12 @@
1
- import { abstractReturnShapeKey, brandWithType, ObjectRef, typeBrandKey } from '@pothos/core';
1
+ import { abstractReturnShapeKey, brandWithType, typeBrandKey } from '@pothos/core';
2
+ import { PrismaObjectRef } from './object-ref';
2
3
  import { WithBrand } from './types';
4
+ import { PrismaModelTypes } from '.';
3
5
 
4
- export default class PrismaNodeRef<T> extends ObjectRef<T, T> {
6
+ export default class PrismaNodeRef<Model extends PrismaModelTypes, T> extends PrismaObjectRef<
7
+ Model,
8
+ T
9
+ > {
5
10
  [abstractReturnShapeKey]: WithBrand<T>;
6
11
 
7
12
  addBrand<V extends T | T[]>(
@@ -0,0 +1,8 @@
1
+ import { ObjectRef } from '@pothos/core';
2
+ import { PrismaModelTypes } from '.';
3
+
4
+ export const prismaModelKey = Symbol.for('Pothos.prismaModelKey');
5
+
6
+ export class PrismaObjectRef<Model extends PrismaModelTypes, T = {}> extends ObjectRef<T> {
7
+ [prismaModelKey]: Model;
8
+ }
@@ -13,6 +13,7 @@ import {
13
13
  import { prismaCursorConnectionQuery, wrapConnectionResult } from './cursors';
14
14
  import { getLoaderMapping, setLoaderMappings } from './loader-map';
15
15
  import { ModelLoader } from './model-loader';
16
+ import { PrismaObjectRef } from './object-ref';
16
17
  import { getDelegateFromModel, getFindUniqueForRef, getRefFromModel, getRelation } from './refs';
17
18
  import {
18
19
  PrismaDelegate,
@@ -21,7 +22,8 @@ import {
21
22
  RelatedFieldOptions,
22
23
  RelationCountOptions,
23
24
  } from './types';
24
- import { queryFromInfo } from './util';
25
+ import { queryFromInfo, SELF_RELATION } from './util';
26
+ import { VariantFieldOptions } from '.';
25
27
 
26
28
  export class PrismaObjectFieldBuilder<
27
29
  Types extends SchemaTypes,
@@ -69,6 +71,7 @@ export class PrismaObjectFieldBuilder<
69
71
  totalCount,
70
72
  ...options
71
73
  }: {
74
+ type?: ObjectRef<unknown, unknown>;
72
75
  totalCount?: boolean;
73
76
  maxSize?: number;
74
77
  defaultSize?: number;
@@ -84,7 +87,7 @@ export class PrismaObjectFieldBuilder<
84
87
  const parentRef = getRefFromModel(this.model, this.builder);
85
88
  const relationTypeName =
86
89
  typeof relationField.type === 'string' ? relationField.type : relationField.type.name;
87
- const ref = getRefFromModel(relationTypeName, this.builder);
90
+ const ref = options.type ?? getRefFromModel(relationTypeName, this.builder);
88
91
  const findUnique = getFindUniqueForRef(parentRef, this.builder);
89
92
  const loaderCache = ModelLoader.forModel(this.model, this.builder);
90
93
  let typeName: string | undefined;
@@ -232,7 +235,7 @@ export class PrismaObjectFieldBuilder<
232
235
  const parentRef = getRefFromModel(this.model, this.builder);
233
236
  const relationTypeName =
234
237
  typeof relationField.type === 'string' ? relationField.type : relationField.type.name;
235
- const ref = getRefFromModel(relationTypeName, this.builder);
238
+ const ref = options.type ?? getRefFromModel(relationTypeName, this.builder);
236
239
  const findUnique = getFindUniqueForRef(parentRef, this.builder);
237
240
  const loaderCache = ModelLoader.forModel(this.model, this.builder);
238
241
 
@@ -321,4 +324,50 @@ export class PrismaObjectFieldBuilder<
321
324
  },
322
325
  }) as FieldRef<number, 'Object'>;
323
326
  }
327
+
328
+ variant<Variant extends Model['Name'] | PrismaObjectRef<Model>>(
329
+ ...allArgs: NormalizeArgs<
330
+ [
331
+ variant: Variant,
332
+ options?: VariantFieldOptions<
333
+ Types,
334
+ Model,
335
+ Variant extends PrismaObjectRef<Model> ? Variant : PrismaObjectRef<Model>
336
+ >,
337
+ ]
338
+ >
339
+ ): FieldRef<Model['Shape'], 'Object'> {
340
+ const [variant, options = {} as never] = allArgs;
341
+ const ref: PrismaObjectRef<PrismaModelTypes> =
342
+ typeof variant === 'string' ? getRefFromModel(variant, this.builder) : variant;
343
+ const parentRef = getRefFromModel(this.model, this.builder);
344
+ const findUnique = getFindUniqueForRef(parentRef, this.builder);
345
+ const loaderCache = ModelLoader.forModel(this.model, this.builder);
346
+
347
+ return this.field({
348
+ ...options,
349
+ type: ref,
350
+ extensions: {
351
+ ...options.extensions,
352
+ pothosPrismaRelation: SELF_RELATION,
353
+ },
354
+ resolve: (parent, args, context, info) => {
355
+ const mapping = getLoaderMapping(context, info.path);
356
+
357
+ if (mapping) {
358
+ setLoaderMappings(context, info.path, mapping);
359
+
360
+ return parent as never;
361
+ }
362
+
363
+ const queryOptions = queryFromInfo(context, info);
364
+
365
+ if (!findUnique) {
366
+ throw new Error(`Missing findUnique for Prisma type ${this.model}`);
367
+ }
368
+
369
+ return loaderCache(parent).loadSelf(queryOptions, context) as never;
370
+ },
371
+ }) as FieldRef<Model['Shape'], 'Object'>;
372
+ }
324
373
  }
package/src/refs.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { ObjectRef, SchemaTypes } from '@pothos/core';
2
2
  import { Prisma } from '../tests/client';
3
+ import { PrismaObjectRef } from './object-ref';
3
4
  import { PrismaDelegate } from './types';
5
+ import { PrismaModelTypes } from '.';
4
6
 
5
- export const refMap = new WeakMap<object, Map<string, ObjectRef<unknown>>>();
7
+ export const refMap = new WeakMap<object, Map<string, PrismaObjectRef<PrismaModelTypes>>>();
6
8
  export const findUniqueMap = new WeakMap<
7
9
  object,
8
10
  Map<ObjectRef<unknown>, ((args: unknown, ctx: {}) => unknown) | null>
@@ -16,14 +18,14 @@ export const includeForRefMap = new WeakMap<
16
18
  export function getRefFromModel<Types extends SchemaTypes>(
17
19
  name: string,
18
20
  builder: PothosSchemaTypes.SchemaBuilder<Types>,
19
- ): ObjectRef<unknown> {
21
+ ): PrismaObjectRef<PrismaModelTypes> {
20
22
  if (!refMap.has(builder)) {
21
23
  refMap.set(builder, new Map());
22
24
  }
23
25
  const cache = refMap.get(builder)!;
24
26
 
25
27
  if (!cache.has(name)) {
26
- cache.set(name, builder.objectRef(name));
28
+ cache.set(name, new PrismaObjectRef(name));
27
29
  }
28
30
 
29
31
  return cache.get(name)!;
@@ -18,8 +18,8 @@ import { queryFromInfo } from './util';
18
18
  const schemaBuilderProto = SchemaBuilder.prototype as PothosSchemaTypes.SchemaBuilder<SchemaTypes>;
19
19
 
20
20
  schemaBuilderProto.prismaObject = function prismaObject(type, { fields, findUnique, ...options }) {
21
- const ref = getRefFromModel(type, this);
22
- const name = options.name ?? type;
21
+ const ref = options.variant ? this.objectRef(options.variant) : getRefFromModel(type, this);
22
+ const name = options.variant ?? options.name ?? type;
23
23
 
24
24
  ref.name = name;
25
25
 
@@ -53,6 +53,7 @@ schemaBuilderProto.prismaNode = function prismaNode(
53
53
  {
54
54
  findUnique,
55
55
  name,
56
+ variant,
56
57
  ...options
57
58
  }: PrismaNodeOptions<SchemaTypes, ModelTypes<PrismaDelegate>, [], never, {}>,
58
59
  ) {
@@ -62,16 +63,12 @@ schemaBuilderProto.prismaNode = function prismaNode(
62
63
  throw new TypeError('builder.prismaNode requires @pothos/plugin-relay to be installed');
63
64
  }
64
65
 
65
- const typeName = name ?? type;
66
+ const typeName = variant ?? name ?? type;
66
67
  const delegate = getDelegateFromModel(this.options.prisma.client, type);
67
68
  const nodeRef = new PrismaNodeRef(typeName);
68
69
  const extendedOptions = {
69
70
  ...options,
70
71
  interfaces: [interfaceRef, ...(options.interfaces ?? [])],
71
- extensions: {
72
- ...options.extensions,
73
- pothosPrismaInclude: options.include,
74
- },
75
72
  isTypeOf: (val: unknown) => nodeRef.hasBrand(val),
76
73
  findUnique: (parent: unknown, context: {}) =>
77
74
  findUnique(options.id.resolve(parent as never, context) as string, context),
package/src/types.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  TypeParam,
21
21
  } from '@pothos/core';
22
22
  import { PrismaObjectFieldBuilder } from './field-builder';
23
+ import { PrismaObjectRef } from './object-ref';
23
24
 
24
25
  export interface PrismaDelegate {
25
26
  findUnique: (...args: any[]) => Promise<unknown>;
@@ -65,6 +66,7 @@ export type ModelTypes<Model extends {}> = Model extends {
65
66
  : never;
66
67
 
67
68
  export interface PrismaModelTypes {
69
+ Name: string;
68
70
  Shape: {};
69
71
  Include: unknown;
70
72
  Where: {};
@@ -126,16 +128,27 @@ export type PrismaObjectTypeOptions<
126
128
  FindUnique,
127
129
  Include extends Model['Include'],
128
130
  Shape extends object,
129
- > = Omit<
130
- | PothosSchemaTypes.ObjectTypeOptions<Types, Shape>
131
- | PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
132
- 'fields'
133
- > & {
134
- name?: string;
135
- include?: Include;
136
- fields?: PrismaObjectFieldsShape<Types, Model, FindUnique extends null ? true : false, Shape>;
137
- findUnique: FindUnique & (((parent: Shape, context: Types['Context']) => Model['Where']) | null);
138
- };
131
+ > = NameOrVariant &
132
+ Omit<
133
+ | PothosSchemaTypes.ObjectTypeOptions<Types, Shape>
134
+ | PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
135
+ 'fields'
136
+ > & {
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
+ };
142
+
143
+ export type NameOrVariant =
144
+ | {
145
+ name?: never;
146
+ variant?: string;
147
+ }
148
+ | {
149
+ name?: string;
150
+ variant?: never;
151
+ };
139
152
 
140
153
  export type PrismaNodeOptions<
141
154
  Types extends SchemaTypes,
@@ -143,31 +156,31 @@ export type PrismaNodeOptions<
143
156
  Interfaces extends InterfaceParam<Types>[],
144
157
  Include extends Model['Include'],
145
158
  Shape extends object,
146
- > = Omit<
147
- | PothosSchemaTypes.ObjectTypeOptions<Types, Shape>
148
- | PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
149
- 'fields' | 'isTypeOf'
150
- > & {
151
- name?: string;
152
- include?: Include;
153
- id: Omit<
154
- FieldOptionsFromKind<
155
- Types,
156
- Shape,
157
- 'ID',
158
- false,
159
- {},
160
- 'Object',
161
- OutputShape<Types, 'ID'>,
162
- MaybePromise<OutputShape<Types, 'ID'>>
163
- >,
164
- 'args' | 'nullable' | 'resolve' | 'type'
159
+ > = NameOrVariant &
160
+ Omit<
161
+ | PothosSchemaTypes.ObjectTypeOptions<Types, Shape>
162
+ | PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
163
+ 'fields' | 'isTypeOf'
165
164
  > & {
166
- resolve: (parent: Shape, context: Types['Context']) => MaybePromise<OutputShape<Types, 'ID'>>;
165
+ include?: Include;
166
+ id: Omit<
167
+ FieldOptionsFromKind<
168
+ Types,
169
+ Shape,
170
+ 'ID',
171
+ false,
172
+ {},
173
+ 'Object',
174
+ OutputShape<Types, 'ID'>,
175
+ MaybePromise<OutputShape<Types, 'ID'>>
176
+ >,
177
+ 'args' | 'nullable' | 'resolve' | 'type'
178
+ > & {
179
+ resolve: (parent: Shape, context: Types['Context']) => MaybePromise<OutputShape<Types, 'ID'>>;
180
+ };
181
+ fields?: PrismaObjectFieldsShape<Types, Model, false, Shape>;
182
+ findUnique: (id: string, context: Types['Context']) => Model['Where'];
167
183
  };
168
- fields?: PrismaObjectFieldsShape<Types, Model, false, Shape>;
169
- findUnique: (id: string, context: Types['Context']) => Model['Where'];
170
- };
171
184
 
172
185
  export type QueryForField<
173
186
  Types extends SchemaTypes,
@@ -254,9 +267,19 @@ export type RelatedFieldOptions<
254
267
  ShapeWithNullability<Types, Model['Relations'][Field]['Shape'], Nullable>
255
268
  >;
256
269
  }) & {
270
+ type?: PrismaObjectRef<Model['Relations'][Field]['Types']>;
257
271
  query?: QueryForField<Types, Args, Model['Include'][Field & keyof Model['Include']]>;
258
272
  };
259
273
 
274
+ export type VariantFieldOptions<
275
+ Types extends SchemaTypes,
276
+ Model extends PrismaModelTypes,
277
+ Variant extends PrismaObjectRef<Model>,
278
+ > = Omit<
279
+ PothosSchemaTypes.ObjectFieldOptions<Types, Model['Shape'], Variant, false, {}, Model['Shape']>,
280
+ 'resolve' | 'type'
281
+ >;
282
+
260
283
  export type RelationCountOptions<
261
284
  Types extends SchemaTypes,
262
285
  Shape,
@@ -286,7 +309,11 @@ export type RelationCountOptions<
286
309
  export type PrismaFieldOptions<
287
310
  Types extends SchemaTypes,
288
311
  ParentShape,
289
- Type extends keyof Types['PrismaTypes'] | [keyof Types['PrismaTypes']],
312
+ Type extends
313
+ | PrismaObjectRef<PrismaModelTypes>
314
+ | keyof Types['PrismaTypes']
315
+ | [keyof Types['PrismaTypes']]
316
+ | [PrismaObjectRef<PrismaModelTypes>],
290
317
  Model extends PrismaModelTypes,
291
318
  Param extends TypeParam<Types>,
292
319
  Args extends InputFieldMap,
@@ -325,7 +352,7 @@ export type PrismaFieldOptions<
325
352
  export type PrismaConnectionFieldOptions<
326
353
  Types extends SchemaTypes,
327
354
  ParentShape,
328
- Type extends keyof Types['PrismaTypes'],
355
+ Type extends PrismaObjectRef<PrismaModelTypes> | keyof Types['PrismaTypes'],
329
356
  Model extends PrismaModelTypes,
330
357
  Param extends OutputType<Types>,
331
358
  Nullable extends boolean,
@@ -406,6 +433,7 @@ export type RelatedConnectionOptions<
406
433
  'resolve' | 'type'
407
434
  > & {
408
435
  query?: QueryForField<Types, Args, Model['Include'][Field & keyof Model['Include']]>;
436
+ type?: PrismaObjectRef<Model['Relations'][Field]['Types']>;
409
437
  cursor: CursorFromRelation<Model, Field>;
410
438
  defaultSize?: number;
411
439
  maxSize?: number;
@@ -22,6 +22,8 @@ import {
22
22
  } from '../types';
23
23
  import { mergeIncludes, resolveIndirectType } from '.';
24
24
 
25
+ export const SELF_RELATION = '@self';
26
+
25
27
  function handleField(
26
28
  ctx: object,
27
29
  info: GraphQLResolveInfo,
@@ -108,7 +110,8 @@ function handleField(
108
110
  query = query(args, ctx);
109
111
  }
110
112
 
111
- const existingInclude = includes[relationName];
113
+ const existingInclude =
114
+ relationName === SELF_RELATION ? { include: includes } : includes[relationName];
112
115
 
113
116
  query = { ...(query as {}), include: newIncludes };
114
117
 
@@ -120,6 +123,10 @@ function handleField(
120
123
  }
121
124
  }
122
125
 
126
+ if (!mappings[relationName]) {
127
+ mappings[relationName] = [];
128
+ }
129
+
123
130
  const nestedIncludes = (query as { include: IncludeMap }).include;
124
131
  const nestedMappings: LoaderMappings = {};
125
132
  const nestedCounts: IncludeCounts = {
@@ -127,8 +134,33 @@ function handleField(
127
134
  parent: counts.current,
128
135
  };
129
136
 
130
- if (!mappings[relationName]) {
131
- mappings[relationName] = [];
137
+ if (relationName === SELF_RELATION) {
138
+ mappings[relationName].push({
139
+ field: selection.name.value,
140
+ alias: selection.alias?.value,
141
+ mappings: nestedMappings,
142
+ indirectPath: indirectMap?.path ?? [],
143
+ });
144
+
145
+ const { include } = query as { include: Record<string, IncludeMap> };
146
+
147
+ if (selection.selectionSet) {
148
+ includesFromSelectionSet(
149
+ ctx,
150
+ type,
151
+ info,
152
+ includes,
153
+ counts,
154
+ nestedMappings,
155
+ selection.selectionSet,
156
+ );
157
+ }
158
+
159
+ Object.keys(include).forEach((key) => {
160
+ includes[key] = include[key];
161
+ });
162
+
163
+ return;
132
164
  }
133
165
 
134
166
  mappings[relationName].push({