@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.
- package/CHANGELOG.md +18 -0
- package/README.md +420 -315
- package/esm/field-builder.d.ts.map +1 -1
- package/esm/field-builder.js +19 -6
- package/esm/field-builder.js.map +1 -1
- package/esm/generator.js +4 -0
- package/esm/generator.js.map +1 -1
- package/esm/global-types.d.ts +23 -5
- package/esm/global-types.d.ts.map +1 -1
- package/esm/index.d.ts +4 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +46 -1
- package/esm/index.js.map +1 -1
- package/esm/model-loader.d.ts +5 -6
- package/esm/model-loader.d.ts.map +1 -1
- package/esm/model-loader.js +18 -78
- package/esm/model-loader.js.map +1 -1
- package/esm/prisma-field-builder.d.ts +25 -6
- package/esm/prisma-field-builder.d.ts.map +1 -1
- package/esm/prisma-field-builder.js +86 -118
- package/esm/prisma-field-builder.js.map +1 -1
- package/esm/schema-builder.js +14 -4
- package/esm/schema-builder.js.map +1 -1
- package/esm/types.d.ts +74 -77
- package/esm/types.d.ts.map +1 -1
- package/esm/types.js +1 -0
- package/esm/types.js.map +1 -1
- package/esm/{cursors.d.ts → util/cursors.d.ts} +5 -5
- package/esm/util/cursors.d.ts.map +1 -0
- package/esm/{cursors.js → util/cursors.js} +0 -0
- package/esm/util/cursors.js.map +1 -0
- package/{lib/refs.d.ts → esm/util/datamodel.d.ts} +4 -8
- package/esm/util/datamodel.d.ts.map +1 -0
- package/esm/{refs.js → util/datamodel.js} +2 -25
- package/esm/util/datamodel.js.map +1 -0
- package/esm/util/deep-equal.d.ts +2 -0
- package/esm/util/deep-equal.d.ts.map +1 -0
- package/esm/util/deep-equal.js +39 -0
- package/esm/util/deep-equal.js.map +1 -0
- package/esm/util/loader-map.d.ts +6 -0
- package/esm/util/loader-map.d.ts.map +1 -0
- package/esm/{loader-map.js → util/loader-map.js} +10 -12
- package/esm/util/loader-map.js.map +1 -0
- package/esm/util/map-query.d.ts +6 -0
- package/esm/util/map-query.d.ts.map +1 -0
- package/esm/util/map-query.js +169 -0
- package/esm/util/map-query.js.map +1 -0
- package/esm/util/relation-map.d.ts +9 -0
- package/esm/util/relation-map.d.ts.map +1 -0
- package/esm/util/relation-map.js +20 -0
- package/esm/util/relation-map.js.map +1 -0
- package/esm/util/selections.d.ts +20 -0
- package/esm/util/selections.d.ts.map +1 -0
- package/esm/util/selections.js +139 -0
- package/esm/util/selections.js.map +1 -0
- package/lib/field-builder.d.ts.map +1 -1
- package/lib/field-builder.js +30 -13
- package/lib/field-builder.js.map +1 -1
- package/lib/generator.js +9 -1
- package/lib/generator.js.map +1 -1
- package/lib/global-types.d.ts +23 -5
- package/lib/global-types.d.ts.map +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +50 -1
- package/lib/index.js.map +1 -1
- package/lib/model-loader.d.ts +5 -6
- package/lib/model-loader.d.ts.map +1 -1
- package/lib/model-loader.js +19 -79
- package/lib/model-loader.js.map +1 -1
- package/lib/prisma-field-builder.d.ts +25 -6
- package/lib/prisma-field-builder.d.ts.map +1 -1
- package/lib/prisma-field-builder.js +92 -124
- package/lib/prisma-field-builder.js.map +1 -1
- package/lib/schema-builder.js +22 -8
- package/lib/schema-builder.js.map +1 -1
- package/lib/types.d.ts +74 -77
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -1
- package/lib/{cursors.d.ts → util/cursors.d.ts} +5 -5
- package/lib/util/cursors.d.ts.map +1 -0
- package/lib/{cursors.js → util/cursors.js} +0 -0
- package/lib/util/cursors.js.map +1 -0
- package/{esm/refs.d.ts → lib/util/datamodel.d.ts} +4 -8
- package/lib/util/datamodel.d.ts.map +1 -0
- package/lib/{refs.js → util/datamodel.js} +3 -29
- package/lib/util/datamodel.js.map +1 -0
- package/lib/util/deep-equal.d.ts +2 -0
- package/lib/util/deep-equal.d.ts.map +1 -0
- package/lib/util/deep-equal.js +43 -0
- package/lib/util/deep-equal.js.map +1 -0
- package/lib/util/loader-map.d.ts +6 -0
- package/lib/util/loader-map.d.ts.map +1 -0
- package/lib/{loader-map.js → util/loader-map.js} +10 -12
- package/lib/util/loader-map.js.map +1 -0
- package/lib/util/map-query.d.ts +6 -0
- package/lib/util/map-query.d.ts.map +1 -0
- package/lib/util/map-query.js +175 -0
- package/lib/util/map-query.js.map +1 -0
- package/lib/util/relation-map.d.ts +9 -0
- package/lib/util/relation-map.d.ts.map +1 -0
- package/lib/util/relation-map.js +24 -0
- package/lib/util/relation-map.js.map +1 -0
- package/lib/util/selections.d.ts +20 -0
- package/lib/util/selections.d.ts.map +1 -0
- package/lib/util/selections.js +148 -0
- package/lib/util/selections.js.map +1 -0
- package/package.json +8 -8
- package/src/field-builder.ts +22 -5
- package/src/generator.ts +18 -0
- package/src/global-types.ts +59 -12
- package/src/index.ts +75 -1
- package/src/model-loader.ts +27 -106
- package/src/prisma-field-builder.ts +195 -152
- package/src/schema-builder.ts +28 -7
- package/src/types.ts +155 -102
- package/src/{cursors.ts → util/cursors.ts} +3 -3
- package/src/{refs.ts → util/datamodel.ts} +3 -44
- package/src/util/deep-equal.ts +51 -0
- package/src/{loader-map.ts → util/loader-map.ts} +13 -13
- package/src/util/map-query.ts +327 -0
- package/src/util/relation-map.ts +36 -0
- package/src/util/selections.ts +192 -0
- package/esm/cursors.d.ts.map +0 -1
- package/esm/cursors.js.map +0 -1
- package/esm/loader-map.d.ts +0 -6
- package/esm/loader-map.d.ts.map +0 -1
- package/esm/loader-map.js.map +0 -1
- package/esm/refs.d.ts.map +0 -1
- package/esm/refs.js.map +0 -1
- package/esm/util/index.d.ts +0 -5
- package/esm/util/index.d.ts.map +0 -1
- package/esm/util/index.js +0 -16
- package/esm/util/index.js.map +0 -1
- package/esm/util/map-includes.d.ts +0 -6
- package/esm/util/map-includes.d.ts.map +0 -1
- package/esm/util/map-includes.js +0 -184
- package/esm/util/map-includes.js.map +0 -1
- package/esm/util/merge-includes.d.ts +0 -3
- package/esm/util/merge-includes.d.ts.map +0 -1
- package/esm/util/merge-includes.js +0 -91
- package/esm/util/merge-includes.js.map +0 -1
- package/lib/cursors.d.ts.map +0 -1
- package/lib/cursors.js.map +0 -1
- package/lib/loader-map.d.ts +0 -6
- package/lib/loader-map.d.ts.map +0 -1
- package/lib/loader-map.js.map +0 -1
- package/lib/refs.d.ts.map +0 -1
- package/lib/refs.js.map +0 -1
- package/lib/util/index.d.ts +0 -5
- package/lib/util/index.d.ts.map +0 -1
- package/lib/util/index.js +0 -30
- package/lib/util/index.js.map +0 -1
- package/lib/util/map-includes.d.ts +0 -6
- package/lib/util/map-includes.d.ts.map +0 -1
- package/lib/util/map-includes.js +0 -189
- package/lib/util/map-includes.js.map +0 -1
- package/lib/util/merge-includes.d.ts +0 -3
- package/lib/util/merge-includes.d.ts.map +0 -1
- package/lib/util/merge-includes.js +0 -96
- package/lib/util/merge-includes.js.map +0 -1
- package/src/util/index.ts +0 -26
- package/src/util/map-includes.ts +0 -328
- package/src/util/merge-includes.ts +0 -121
|
@@ -1,46 +1,66 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
2
|
import { GraphQLResolveInfo } from 'graphql';
|
|
3
3
|
import {
|
|
4
|
+
CompatibleTypes,
|
|
5
|
+
FieldKind,
|
|
4
6
|
FieldRef,
|
|
5
7
|
InputFieldMap,
|
|
6
8
|
MaybePromise,
|
|
7
9
|
NormalizeArgs,
|
|
8
|
-
ObjectFieldBuilder,
|
|
9
10
|
ObjectRef,
|
|
10
11
|
PluginName,
|
|
12
|
+
RootFieldBuilder,
|
|
11
13
|
SchemaTypes,
|
|
14
|
+
TypeParam,
|
|
12
15
|
} from '@pothos/core';
|
|
13
|
-
import { prismaCursorConnectionQuery, wrapConnectionResult } from './cursors';
|
|
14
|
-
import { getLoaderMapping, setLoaderMappings } from './loader-map';
|
|
15
|
-
import { ModelLoader } from './model-loader';
|
|
16
16
|
import { PrismaObjectRef } from './object-ref';
|
|
17
17
|
import {
|
|
18
|
-
getCursorFormatter,
|
|
19
|
-
getCursorParser,
|
|
20
|
-
getDelegateFromModel,
|
|
21
|
-
getFindUniqueForRef,
|
|
22
|
-
getRefFromModel,
|
|
23
|
-
getRelation,
|
|
24
|
-
} from './refs';
|
|
25
|
-
import {
|
|
26
|
-
PrismaDelegate,
|
|
27
18
|
PrismaModelTypes,
|
|
28
19
|
RelatedConnectionOptions,
|
|
29
20
|
RelatedFieldOptions,
|
|
30
21
|
RelationCountOptions,
|
|
31
22
|
ShapeFromConnection,
|
|
23
|
+
VariantFieldOptions,
|
|
32
24
|
} from './types';
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
25
|
+
import { prismaCursorConnectionQuery, wrapConnectionResult } from './util/cursors';
|
|
26
|
+
import {
|
|
27
|
+
getCursorFormatter,
|
|
28
|
+
getCursorParser,
|
|
29
|
+
getRefFromModel,
|
|
30
|
+
getRelation,
|
|
31
|
+
} from './util/datamodel';
|
|
32
|
+
import { FieldMap } from './util/relation-map';
|
|
33
|
+
|
|
34
|
+
// Workaround for FieldKind not being extended on Builder classes
|
|
35
|
+
const RootBuilder: {
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/prefer-function-type
|
|
37
|
+
new <Types extends SchemaTypes, Shape, Kind extends FieldKind>(
|
|
38
|
+
name: string,
|
|
39
|
+
builder: PothosSchemaTypes.SchemaBuilder<Types>,
|
|
40
|
+
kind: FieldKind,
|
|
41
|
+
graphqlKind: PothosSchemaTypes.PothosKindToGraphQLType[FieldKind],
|
|
42
|
+
): PothosSchemaTypes.RootFieldBuilder<Types, Shape, Kind>;
|
|
43
|
+
} = RootFieldBuilder as never;
|
|
35
44
|
|
|
36
45
|
export class PrismaObjectFieldBuilder<
|
|
37
46
|
Types extends SchemaTypes,
|
|
38
47
|
Model extends PrismaModelTypes,
|
|
39
48
|
NeedsResolve extends boolean,
|
|
40
49
|
Shape extends object = Model['Shape'],
|
|
41
|
-
> extends
|
|
42
|
-
delegate: PrismaDelegate;
|
|
50
|
+
> extends RootBuilder<Types, Shape, 'PrismaObject'> {
|
|
43
51
|
model: string;
|
|
52
|
+
prismaFieldMap: FieldMap;
|
|
53
|
+
|
|
54
|
+
exposeBoolean = this.createExpose('Boolean');
|
|
55
|
+
exposeFloat = this.createExpose('Float');
|
|
56
|
+
exposeInt = this.createExpose('Int');
|
|
57
|
+
exposeID = this.createExpose('ID');
|
|
58
|
+
exposeString = this.createExpose('String');
|
|
59
|
+
exposeBooleanList = this.createExpose(['Boolean']);
|
|
60
|
+
exposeFloatList = this.createExpose(['Float']);
|
|
61
|
+
exposeIntList = this.createExpose(['Int']);
|
|
62
|
+
exposeIDList = this.createExpose(['ID']);
|
|
63
|
+
exposeStringList = this.createExpose(['String']);
|
|
44
64
|
|
|
45
65
|
relatedConnection: 'relay' extends PluginName
|
|
46
66
|
? <
|
|
@@ -97,10 +117,7 @@ export class PrismaObjectFieldBuilder<
|
|
|
97
117
|
edgeOptions = {},
|
|
98
118
|
) {
|
|
99
119
|
const relationField = getRelation(this.model, this.builder, name);
|
|
100
|
-
const parentRef = getRefFromModel(this.model, this.builder);
|
|
101
120
|
const ref = options.type ?? getRefFromModel(relationField.type, this.builder);
|
|
102
|
-
const findUnique = getFindUniqueForRef(parentRef, this.builder);
|
|
103
|
-
const loaderCache = ModelLoader.forModel(this.model, this.builder);
|
|
104
121
|
let typeName: string | undefined;
|
|
105
122
|
|
|
106
123
|
const formatCursor = getCursorFormatter(relationField.type, this.builder, cursor);
|
|
@@ -116,6 +133,24 @@ export class PrismaObjectFieldBuilder<
|
|
|
116
133
|
}),
|
|
117
134
|
});
|
|
118
135
|
|
|
136
|
+
const relationSelect = (
|
|
137
|
+
args: object,
|
|
138
|
+
context: object,
|
|
139
|
+
nestedQuery: (query: unknown) => unknown,
|
|
140
|
+
) => ({
|
|
141
|
+
select: {
|
|
142
|
+
[name]: nestedQuery({
|
|
143
|
+
...((typeof query === 'function' ? query(args, context) : query) as {}),
|
|
144
|
+
...prismaCursorConnectionQuery({
|
|
145
|
+
parseCursor,
|
|
146
|
+
maxSize,
|
|
147
|
+
defaultSize,
|
|
148
|
+
args,
|
|
149
|
+
}),
|
|
150
|
+
}),
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
119
154
|
const fieldRef = (
|
|
120
155
|
this as unknown as {
|
|
121
156
|
connection: (...args: unknown[]) => FieldRef<unknown>;
|
|
@@ -125,49 +160,40 @@ export class PrismaObjectFieldBuilder<
|
|
|
125
160
|
...options,
|
|
126
161
|
extensions: {
|
|
127
162
|
...extensions,
|
|
128
|
-
|
|
129
|
-
|
|
163
|
+
pothosPrismaSelect: relationSelect,
|
|
164
|
+
pothosPrismaLoaded: (value: Record<string, unknown>) => value[name] !== undefined,
|
|
165
|
+
pothosPrismaFallback:
|
|
166
|
+
resolve &&
|
|
167
|
+
((
|
|
168
|
+
q: { take: number },
|
|
169
|
+
parent: unknown,
|
|
170
|
+
args: PothosSchemaTypes.DefaultConnectionArguments,
|
|
171
|
+
context: {},
|
|
172
|
+
info: GraphQLResolveInfo,
|
|
173
|
+
) =>
|
|
174
|
+
Promise.resolve(
|
|
175
|
+
resolve(
|
|
176
|
+
{
|
|
177
|
+
...q,
|
|
178
|
+
...(typeof query === 'function' ? query(args, context) : query),
|
|
179
|
+
} as never,
|
|
180
|
+
parent,
|
|
181
|
+
args,
|
|
182
|
+
context,
|
|
183
|
+
info,
|
|
184
|
+
),
|
|
185
|
+
).then((result) => wrapConnectionResult(result, args, q.take, formatCursor))),
|
|
130
186
|
},
|
|
131
187
|
type: ref,
|
|
132
|
-
resolve:
|
|
133
|
-
parent:
|
|
188
|
+
resolve: (
|
|
189
|
+
parent: unknown,
|
|
134
190
|
args: PothosSchemaTypes.DefaultConnectionArguments,
|
|
135
191
|
context: {},
|
|
136
|
-
info: GraphQLResolveInfo,
|
|
137
192
|
) => {
|
|
138
193
|
const connectionQuery = getQuery(args, context);
|
|
139
|
-
const getResult = () => {
|
|
140
|
-
const mapping = getLoaderMapping(context, info.path);
|
|
141
|
-
const loadedValue = (parent as Record<string, unknown>)[name];
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
// if we attempted to load the relation, and its missing it will be null
|
|
145
|
-
// undefined means that the query was not constructed in a way that requested the relation
|
|
146
|
-
loadedValue !== undefined &&
|
|
147
|
-
mapping
|
|
148
|
-
) {
|
|
149
|
-
if (loadedValue !== null && loadedValue !== undefined) {
|
|
150
|
-
setLoaderMappings(context, info.path, mapping);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return loadedValue as {}[];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (!resolve && !findUnique) {
|
|
157
|
-
throw new Error(`Missing findUnique for Prisma type ${this.model}`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const mergedQuery = { ...queryFromInfo(context, info), ...connectionQuery };
|
|
161
|
-
|
|
162
|
-
if (resolve) {
|
|
163
|
-
return resolve(mergedQuery, parent, args, context, info);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return loaderCache(parent).loadRelation(name, mergedQuery, context) as Promise<{}[]>;
|
|
167
|
-
};
|
|
168
194
|
|
|
169
195
|
return wrapConnectionResult(
|
|
170
|
-
|
|
196
|
+
(parent as Record<string, never>)[name],
|
|
171
197
|
args,
|
|
172
198
|
connectionQuery.take,
|
|
173
199
|
formatCursor,
|
|
@@ -180,18 +206,11 @@ export class PrismaObjectFieldBuilder<
|
|
|
180
206
|
fields: totalCount
|
|
181
207
|
? (t: PothosSchemaTypes.ObjectFieldBuilder<SchemaTypes, { totalCount?: number }>) => ({
|
|
182
208
|
totalCount: t.int({
|
|
209
|
+
nullable: false,
|
|
183
210
|
extensions: {
|
|
184
|
-
|
|
185
|
-
},
|
|
186
|
-
resolve: (parent, args, context) => {
|
|
187
|
-
const loadedValue = parent.totalCount;
|
|
188
|
-
|
|
189
|
-
if (loadedValue !== undefined) {
|
|
190
|
-
return loadedValue;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return loaderCache(parent).loadCount(name, context);
|
|
211
|
+
pothosPrismaParentSelect: { _count: { select: { [name]: true } } },
|
|
194
212
|
},
|
|
213
|
+
resolve: (parent, args, context) => parent.totalCount,
|
|
195
214
|
}),
|
|
196
215
|
...(connectionOptions as { fields?: (t: unknown) => {} }).fields?.(t),
|
|
197
216
|
})
|
|
@@ -215,11 +234,16 @@ export class PrismaObjectFieldBuilder<
|
|
|
215
234
|
return fieldRef;
|
|
216
235
|
} as never;
|
|
217
236
|
|
|
218
|
-
constructor(
|
|
219
|
-
|
|
237
|
+
constructor(
|
|
238
|
+
name: string,
|
|
239
|
+
builder: PothosSchemaTypes.SchemaBuilder<Types>,
|
|
240
|
+
model: string,
|
|
241
|
+
fieldMap: FieldMap,
|
|
242
|
+
) {
|
|
243
|
+
super(name, builder, 'PrismaObject', 'Object');
|
|
220
244
|
|
|
221
245
|
this.model = model;
|
|
222
|
-
this.
|
|
246
|
+
this.prismaFieldMap = fieldMap;
|
|
223
247
|
}
|
|
224
248
|
|
|
225
249
|
relation<
|
|
@@ -246,54 +270,35 @@ export class PrismaObjectFieldBuilder<
|
|
|
246
270
|
): FieldRef<Model['Relations'][Field]['Shape'], 'Object'> {
|
|
247
271
|
const [name, options = {} as never] = allArgs;
|
|
248
272
|
const relationField = getRelation(this.model, this.builder, name);
|
|
249
|
-
const parentRef = getRefFromModel(this.model, this.builder);
|
|
250
273
|
const ref = options.type ?? getRefFromModel(relationField.type, this.builder);
|
|
251
|
-
const findUnique = getFindUniqueForRef(parentRef, this.builder);
|
|
252
|
-
const loaderCache = ModelLoader.forModel(this.model, this.builder);
|
|
253
274
|
|
|
254
|
-
const { query = {}, resolve, ...rest } = options;
|
|
275
|
+
const { query = {}, resolve, extensions, ...rest } = options;
|
|
276
|
+
|
|
277
|
+
const relationSelect = (
|
|
278
|
+
args: object,
|
|
279
|
+
context: object,
|
|
280
|
+
nestedQuery: (query: unknown) => unknown,
|
|
281
|
+
) => ({ select: { [name]: nestedQuery(query) } });
|
|
255
282
|
|
|
256
283
|
return this.field({
|
|
257
284
|
...rest,
|
|
258
285
|
type: relationField.isList ? [ref] : ref,
|
|
259
286
|
extensions: {
|
|
260
|
-
...
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
mapping
|
|
274
|
-
) {
|
|
275
|
-
if (loadedValue !== null && loadedValue !== undefined) {
|
|
276
|
-
setLoaderMappings(context, info.path, mapping);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return loadedValue as never;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const queryOptions = {
|
|
283
|
-
...((typeof query === 'function' ? query(args, context) : query) as {}),
|
|
284
|
-
...queryFromInfo(context, info),
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
if (resolve) {
|
|
288
|
-
return resolve(queryOptions, parent, args as never, context, info) as never;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (!findUnique) {
|
|
292
|
-
throw new Error(`Missing findUnique for Prisma type ${this.model}`);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return loaderCache(parent).loadRelation(name, queryOptions, context) as never;
|
|
287
|
+
...extensions,
|
|
288
|
+
pothosPrismaSelect: relationSelect as never,
|
|
289
|
+
pothosPrismaLoaded: (value: Record<string, unknown>) => value[name] !== undefined,
|
|
290
|
+
pothosPrismaFallback:
|
|
291
|
+
resolve &&
|
|
292
|
+
((q: {}, parent: Shape, args: {}, context: {}, info: GraphQLResolveInfo) =>
|
|
293
|
+
resolve(
|
|
294
|
+
{ ...q, ...(typeof query === 'function' ? query(args, context) : query) } as never,
|
|
295
|
+
parent,
|
|
296
|
+
args as never,
|
|
297
|
+
context,
|
|
298
|
+
info,
|
|
299
|
+
)),
|
|
296
300
|
},
|
|
301
|
+
resolve: (parent) => (parent as Record<string, never>)[name],
|
|
297
302
|
}) as FieldRef<Model['Relations'][Field]['Shape'], 'Object'>;
|
|
298
303
|
}
|
|
299
304
|
|
|
@@ -303,37 +308,22 @@ export class PrismaObjectFieldBuilder<
|
|
|
303
308
|
>
|
|
304
309
|
): FieldRef<number, 'Object'> {
|
|
305
310
|
const [name, options = {} as never] = allArgs;
|
|
306
|
-
const parentRef = getRefFromModel(this.model, this.builder);
|
|
307
|
-
const findUnique = getFindUniqueForRef(parentRef, this.builder);
|
|
308
|
-
const loaderCache = ModelLoader.forModel(this.model, this.builder);
|
|
309
311
|
|
|
310
312
|
const { resolve, ...rest } = options;
|
|
311
313
|
|
|
314
|
+
const countSelect = {
|
|
315
|
+
_count: {
|
|
316
|
+
select: { [name]: true },
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
|
|
312
320
|
return this.field({
|
|
313
321
|
...rest,
|
|
314
322
|
type: 'Int',
|
|
315
323
|
nullable: false,
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
},
|
|
320
|
-
resolve: (parent, args, context, info) => {
|
|
321
|
-
const loadedValue = (parent as { _count: Record<string, unknown> })._count?.[name];
|
|
322
|
-
|
|
323
|
-
if (loadedValue !== undefined) {
|
|
324
|
-
return loadedValue as never;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (resolve) {
|
|
328
|
-
return resolve(parent, args, context, info) as never;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (!findUnique) {
|
|
332
|
-
throw new Error(`Missing findUnique for Prisma type ${this.model}`);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
return loaderCache(parent).loadCount(name, context) as never;
|
|
336
|
-
},
|
|
324
|
+
select: countSelect as never,
|
|
325
|
+
resolve: (parent, args, context, info) =>
|
|
326
|
+
(parent as unknown as { _count: Record<string, never> })._count?.[name],
|
|
337
327
|
}) as FieldRef<number, 'Object'>;
|
|
338
328
|
}
|
|
339
329
|
|
|
@@ -352,34 +342,87 @@ export class PrismaObjectFieldBuilder<
|
|
|
352
342
|
const [variant, options = {} as never] = allArgs;
|
|
353
343
|
const ref: PrismaObjectRef<PrismaModelTypes> =
|
|
354
344
|
typeof variant === 'string' ? getRefFromModel(variant, this.builder) : variant;
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
|
|
345
|
+
|
|
346
|
+
const selfSelect = (args: object, context: object, nestedQuery: (query: unknown) => unknown) =>
|
|
347
|
+
nestedQuery({});
|
|
358
348
|
|
|
359
349
|
return this.field({
|
|
360
350
|
...options,
|
|
361
351
|
type: ref,
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
resolve: (parent, args, context, info) => {
|
|
367
|
-
const mapping = getLoaderMapping(context, info.path);
|
|
352
|
+
select: selfSelect as never,
|
|
353
|
+
resolve: (parent, args, context, info) => parent,
|
|
354
|
+
}) as FieldRef<Model['Shape'], 'Object'>;
|
|
355
|
+
}
|
|
368
356
|
|
|
369
|
-
|
|
370
|
-
|
|
357
|
+
expose<
|
|
358
|
+
Type extends TypeParam<Types>,
|
|
359
|
+
Nullable extends boolean,
|
|
360
|
+
ResolveReturnShape,
|
|
361
|
+
Name extends CompatibleTypes<Types, Model['Shape'], Type, Nullable>,
|
|
362
|
+
>(
|
|
363
|
+
...args: NormalizeArgs<
|
|
364
|
+
[
|
|
365
|
+
name: Name,
|
|
366
|
+
options?: Omit<
|
|
367
|
+
PothosSchemaTypes.ObjectFieldOptions<
|
|
368
|
+
Types,
|
|
369
|
+
Shape,
|
|
370
|
+
Type,
|
|
371
|
+
Nullable,
|
|
372
|
+
{},
|
|
373
|
+
ResolveReturnShape
|
|
374
|
+
>,
|
|
375
|
+
'resolve' | 'select'
|
|
376
|
+
>,
|
|
377
|
+
]
|
|
378
|
+
>
|
|
379
|
+
) {
|
|
380
|
+
const [name, options = {} as never] = args;
|
|
371
381
|
|
|
372
|
-
|
|
373
|
-
|
|
382
|
+
const typeConfig = this.builder.configStore.getTypeConfig(this.typename, 'Object');
|
|
383
|
+
const usingSelect = !!typeConfig.extensions?.pothosPrismaSelect;
|
|
374
384
|
|
|
375
|
-
|
|
385
|
+
return this.exposeField(name as never, {
|
|
386
|
+
...options,
|
|
387
|
+
extensions: {
|
|
388
|
+
...options.extensions,
|
|
389
|
+
pothosPrismaVariant: name,
|
|
390
|
+
pothosPrismaSelect: usingSelect && {
|
|
391
|
+
[name]: true,
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
}
|
|
376
396
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
397
|
+
private createExpose<Type extends TypeParam<Types>>(type: Type) {
|
|
398
|
+
return <
|
|
399
|
+
Nullable extends boolean,
|
|
400
|
+
ResolveReturnShape,
|
|
401
|
+
Name extends CompatibleTypes<Types, Model['Shape'], Type, Nullable>,
|
|
402
|
+
>(
|
|
403
|
+
...args: NormalizeArgs<
|
|
404
|
+
[
|
|
405
|
+
name: Name,
|
|
406
|
+
options?: Omit<
|
|
407
|
+
PothosSchemaTypes.ObjectFieldOptions<
|
|
408
|
+
Types,
|
|
409
|
+
Shape,
|
|
410
|
+
Type,
|
|
411
|
+
Nullable,
|
|
412
|
+
{},
|
|
413
|
+
ResolveReturnShape
|
|
414
|
+
>,
|
|
415
|
+
'resolve' | 'type' | 'select'
|
|
416
|
+
>,
|
|
417
|
+
]
|
|
418
|
+
>
|
|
419
|
+
) => {
|
|
420
|
+
const [name, options = {} as never] = args;
|
|
380
421
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
422
|
+
return this.expose(name as never, {
|
|
423
|
+
...options,
|
|
424
|
+
type,
|
|
425
|
+
});
|
|
426
|
+
};
|
|
384
427
|
}
|
|
385
428
|
}
|
package/src/schema-builder.ts
CHANGED
|
@@ -10,21 +10,22 @@ import SchemaBuilder, {
|
|
|
10
10
|
TypeParam,
|
|
11
11
|
} from '@pothos/core';
|
|
12
12
|
import { PrismaObjectFieldBuilder } from './field-builder';
|
|
13
|
+
import { ModelLoader } from './model-loader';
|
|
13
14
|
import PrismaNodeRef from './node-ref';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { queryFromInfo } from './util';
|
|
15
|
+
import { PrismaModelTypes, PrismaNodeOptions } from './types';
|
|
16
|
+
import { getDelegateFromModel, getRefFromModel } from './util/datamodel';
|
|
17
|
+
import { queryFromInfo } from './util/map-query';
|
|
18
|
+
import { getRelationMap } from './util/relation-map';
|
|
17
19
|
|
|
18
20
|
const schemaBuilderProto = SchemaBuilder.prototype as PothosSchemaTypes.SchemaBuilder<SchemaTypes>;
|
|
19
21
|
|
|
20
22
|
schemaBuilderProto.prismaObject = function prismaObject(type, { fields, findUnique, ...options }) {
|
|
21
23
|
const ref = options.variant ? this.objectRef(options.variant) : getRefFromModel(type, this);
|
|
22
24
|
const name = options.variant ?? options.name ?? type;
|
|
25
|
+
const fieldMap = getRelationMap(this.options.prisma.client).get(type)!;
|
|
23
26
|
|
|
24
27
|
ref.name = name;
|
|
25
28
|
|
|
26
|
-
setFindUniqueForRef(ref, this, findUnique);
|
|
27
|
-
|
|
28
29
|
this.objectType(ref, {
|
|
29
30
|
...(options as {} as PothosSchemaTypes.ObjectFieldOptions<
|
|
30
31
|
SchemaTypes,
|
|
@@ -38,9 +39,29 @@ schemaBuilderProto.prismaObject = function prismaObject(type, { fields, findUniq
|
|
|
38
39
|
...options.extensions,
|
|
39
40
|
pothosPrismaInclude: options.include,
|
|
40
41
|
pothosPrismaModel: type,
|
|
42
|
+
pothosPrismaFieldMap: fieldMap,
|
|
43
|
+
pothosPrismaSelect: options.select,
|
|
44
|
+
pothosPrismaLoader: ModelLoader.forRef(
|
|
45
|
+
type,
|
|
46
|
+
(findUnique as never) ||
|
|
47
|
+
(() => {
|
|
48
|
+
throw new Error(`Missing findUnique for ${ref.name}`);
|
|
49
|
+
}),
|
|
50
|
+
this,
|
|
51
|
+
),
|
|
41
52
|
},
|
|
42
53
|
name,
|
|
43
|
-
fields: fields
|
|
54
|
+
fields: fields
|
|
55
|
+
? () =>
|
|
56
|
+
fields(
|
|
57
|
+
new PrismaObjectFieldBuilder(
|
|
58
|
+
name,
|
|
59
|
+
this,
|
|
60
|
+
type,
|
|
61
|
+
getRelationMap(this.options.prisma.client).get(type)!,
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
: undefined,
|
|
44
65
|
});
|
|
45
66
|
|
|
46
67
|
return ref as never;
|
|
@@ -56,7 +77,7 @@ schemaBuilderProto.prismaNode = function prismaNode(
|
|
|
56
77
|
name,
|
|
57
78
|
variant,
|
|
58
79
|
...options
|
|
59
|
-
}: PrismaNodeOptions<SchemaTypes,
|
|
80
|
+
}: PrismaNodeOptions<SchemaTypes, PrismaModelTypes, [], never, {}, {}>,
|
|
60
81
|
) {
|
|
61
82
|
const interfaceRef = this.nodeInterfaceRef?.();
|
|
62
83
|
|