@pothos/plugin-prisma 3.35.8 → 3.37.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 +15 -0
- package/README.md +247 -39
- package/dts/connection-helpers.d.ts +40 -0
- package/dts/connection-helpers.d.ts.map +1 -0
- package/dts/global-types.d.ts +15 -6
- package/dts/global-types.d.ts.map +1 -1
- package/dts/index.d.ts +4 -1
- package/dts/index.d.ts.map +1 -1
- package/dts/node-ref.d.ts +1 -1
- package/dts/node-ref.d.ts.map +1 -1
- package/dts/object-ref.d.ts +2 -0
- package/dts/object-ref.d.ts.map +1 -1
- package/dts/prisma-field-builder.d.ts +7 -4
- package/dts/prisma-field-builder.d.ts.map +1 -1
- package/dts/types.d.ts +35 -33
- package/dts/types.d.ts.map +1 -1
- package/dts/util/cursors.d.ts +11 -5
- package/dts/util/cursors.d.ts.map +1 -1
- package/dts/util/map-query.d.ts.map +1 -1
- package/dts/util/relation-map.d.ts +1 -1
- package/dts/util/relation-map.d.ts.map +1 -1
- package/dts/util/selections.d.ts +1 -1
- package/dts/util/selections.d.ts.map +1 -1
- package/esm/connection-helpers.d.ts +40 -0
- package/esm/connection-helpers.d.ts.map +1 -0
- package/esm/connection-helpers.js +58 -0
- package/esm/connection-helpers.js.map +1 -0
- package/esm/field-builder.js +19 -25
- package/esm/field-builder.js.map +1 -1
- package/esm/generator.js +4 -4
- package/esm/generator.js.map +1 -1
- package/esm/global-types.d.ts +15 -6
- package/esm/global-types.d.ts.map +1 -1
- package/esm/global-types.js.map +1 -1
- package/esm/index.d.ts +4 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +8 -5
- package/esm/index.js.map +1 -1
- package/esm/model-loader.js +9 -9
- package/esm/model-loader.js.map +1 -1
- package/esm/node-ref.d.ts +1 -1
- package/esm/node-ref.d.ts.map +1 -1
- package/esm/node-ref.js +1 -1
- package/esm/node-ref.js.map +1 -1
- package/esm/object-ref.d.ts +2 -0
- package/esm/object-ref.d.ts.map +1 -1
- package/esm/object-ref.js +4 -0
- package/esm/object-ref.js.map +1 -1
- package/esm/prisma-field-builder.d.ts +7 -4
- package/esm/prisma-field-builder.d.ts.map +1 -1
- package/esm/prisma-field-builder.js +14 -14
- package/esm/prisma-field-builder.js.map +1 -1
- package/esm/schema-builder.js +31 -16
- package/esm/schema-builder.js.map +1 -1
- package/esm/types.d.ts +35 -33
- package/esm/types.d.ts.map +1 -1
- package/esm/util/cursors.d.ts +11 -5
- package/esm/util/cursors.d.ts.map +1 -1
- package/esm/util/cursors.js +33 -29
- package/esm/util/cursors.js.map +1 -1
- package/esm/util/datamodel.js +1 -1
- package/esm/util/datamodel.js.map +1 -1
- package/esm/util/get-client.js +2 -2
- package/esm/util/get-client.js.map +1 -1
- package/esm/util/loader-map.js +2 -2
- package/esm/util/loader-map.js.map +1 -1
- package/esm/util/map-query.d.ts.map +1 -1
- package/esm/util/map-query.js +38 -38
- package/esm/util/map-query.js.map +1 -1
- package/esm/util/relation-map.d.ts +1 -1
- package/esm/util/relation-map.d.ts.map +1 -1
- package/esm/util/selections.d.ts +1 -1
- package/esm/util/selections.d.ts.map +1 -1
- package/esm/util/selections.js +2 -2
- package/esm/util/selections.js.map +1 -1
- package/lib/connection-helpers.js +73 -0
- package/lib/connection-helpers.js.map +1 -0
- package/lib/field-builder.js +18 -24
- package/lib/field-builder.js.map +1 -1
- package/lib/generator.js +4 -4
- package/lib/generator.js.map +1 -1
- package/lib/index.js +11 -5
- package/lib/index.js.map +1 -1
- package/lib/model-loader.js +9 -9
- package/lib/model-loader.js.map +1 -1
- package/lib/node-ref.js +1 -1
- package/lib/node-ref.js.map +1 -1
- package/lib/object-ref.js +4 -0
- package/lib/object-ref.js.map +1 -1
- package/lib/prisma-field-builder.js +13 -13
- package/lib/prisma-field-builder.js.map +1 -1
- package/lib/schema-builder.js +31 -21
- package/lib/schema-builder.js.map +1 -1
- package/lib/util/cursors.js +33 -29
- package/lib/util/cursors.js.map +1 -1
- package/lib/util/datamodel.js +1 -1
- package/lib/util/datamodel.js.map +1 -1
- package/lib/util/get-client.js +2 -2
- package/lib/util/get-client.js.map +1 -1
- package/lib/util/loader-map.js +2 -2
- package/lib/util/loader-map.js.map +1 -1
- package/lib/util/map-query.js +38 -37
- package/lib/util/map-query.js.map +1 -1
- package/lib/util/selections.js +2 -2
- package/lib/util/selections.js.map +1 -1
- package/package.json +10 -10
- package/src/connection-helpers.ts +122 -0
- package/src/field-builder.ts +23 -23
- package/src/global-types.ts +50 -14
- package/src/index.ts +3 -0
- package/src/node-ref.ts +1 -4
- package/src/object-ref.ts +7 -0
- package/src/prisma-field-builder.ts +38 -25
- package/src/schema-builder.ts +38 -3
- package/src/types.ts +35 -16
- package/src/util/cursors.ts +8 -1
- package/src/util/datamodel.ts +1 -1
- package/src/util/map-query.ts +32 -17
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ObjectRef, SchemaTypes } from '@pothos/core';
|
|
2
|
+
import { ModelLoader } from './model-loader';
|
|
3
|
+
import { PrismaObjectRef } from './object-ref';
|
|
4
|
+
import type { PrismaModelTypes, ShapeFromSelection } from './types';
|
|
5
|
+
import {
|
|
6
|
+
getCursorFormatter,
|
|
7
|
+
getCursorParser,
|
|
8
|
+
prismaCursorConnectionQuery,
|
|
9
|
+
wrapConnectionResult,
|
|
10
|
+
} from './util/cursors';
|
|
11
|
+
import { getRefFromModel } from './util/datamodel';
|
|
12
|
+
import { getDMMF } from './util/get-client';
|
|
13
|
+
import { getRelationMap } from './util/relation-map';
|
|
14
|
+
import { createState, mergeSelection, selectionToQuery } from './util/selections';
|
|
15
|
+
|
|
16
|
+
export const prismaModelKey = Symbol.for('Pothos.prismaModelKey');
|
|
17
|
+
|
|
18
|
+
export function prismaConnectionHelpers<
|
|
19
|
+
Types extends SchemaTypes,
|
|
20
|
+
RefOrType extends PrismaObjectRef<PrismaModelTypes> | keyof Types['PrismaTypes'],
|
|
21
|
+
Select extends Model['Select'] & {},
|
|
22
|
+
Model extends PrismaModelTypes = RefOrType extends PrismaObjectRef<infer T>
|
|
23
|
+
? T & PrismaModelTypes
|
|
24
|
+
: Types['PrismaTypes'][RefOrType & keyof Types['PrismaTypes']] & PrismaModelTypes,
|
|
25
|
+
Shape = RefOrType extends PrismaObjectRef<PrismaModelTypes, infer T> ? T : Model['Shape'],
|
|
26
|
+
EdgeShape = Model['Include'] extends Select
|
|
27
|
+
? Shape
|
|
28
|
+
: ShapeFromSelection<Model, { select: Select }>,
|
|
29
|
+
NodeShape = EdgeShape,
|
|
30
|
+
>(
|
|
31
|
+
builder: PothosSchemaTypes.SchemaBuilder<Types>,
|
|
32
|
+
refOrType: RefOrType,
|
|
33
|
+
options: {
|
|
34
|
+
cursor: string & keyof Model['WhereUnique'];
|
|
35
|
+
select?: (nestedSelection: <T extends {} | true>(selection?: T) => T) => Select;
|
|
36
|
+
defaultSize?:
|
|
37
|
+
| number
|
|
38
|
+
| ((args: PothosSchemaTypes.DefaultConnectionArguments, ctx: {}) => number);
|
|
39
|
+
maxSize?: number | ((args: PothosSchemaTypes.DefaultConnectionArguments, ctx: {}) => number);
|
|
40
|
+
resolveNode?: (edge: EdgeShape) => NodeShape;
|
|
41
|
+
},
|
|
42
|
+
) {
|
|
43
|
+
const modelName =
|
|
44
|
+
typeof refOrType === 'string' ? refOrType : (refOrType as PrismaObjectRef<Model>).modelName;
|
|
45
|
+
const ref =
|
|
46
|
+
typeof refOrType === 'string'
|
|
47
|
+
? getRefFromModel(modelName, builder)
|
|
48
|
+
: (refOrType as ObjectRef<unknown>);
|
|
49
|
+
const formatCursor = getCursorFormatter(modelName, builder, options.cursor);
|
|
50
|
+
const parseCursor = getCursorParser(modelName, builder, options.cursor);
|
|
51
|
+
const cursorSelection = ModelLoader.getCursorSelection(ref, modelName, options.cursor, builder);
|
|
52
|
+
const fieldMap = getRelationMap(getDMMF(builder)).get(modelName)!;
|
|
53
|
+
|
|
54
|
+
function resolve(
|
|
55
|
+
list: (EdgeShape & {})[],
|
|
56
|
+
args: PothosSchemaTypes.DefaultConnectionArguments,
|
|
57
|
+
ctx: Types['Context'],
|
|
58
|
+
) {
|
|
59
|
+
return wrapConnectionResult(
|
|
60
|
+
list,
|
|
61
|
+
args,
|
|
62
|
+
getQueryArgs(args, ctx).take,
|
|
63
|
+
formatCursor,
|
|
64
|
+
null,
|
|
65
|
+
(options?.resolveNode as never) ?? ((edge: unknown) => edge),
|
|
66
|
+
) as unknown as {
|
|
67
|
+
edges: (Omit<EdgeShape, 'cursor' | 'node'> & { node: NodeShape; cursor: string })[];
|
|
68
|
+
pageInfo: {
|
|
69
|
+
startCursor: string | null;
|
|
70
|
+
endCursor: string | null;
|
|
71
|
+
hasPreviousPage: boolean;
|
|
72
|
+
hasNextPage: boolean;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getQueryArgs(args: PothosSchemaTypes.DefaultConnectionArguments, ctx: Types['Context']) {
|
|
78
|
+
return prismaCursorConnectionQuery({
|
|
79
|
+
args,
|
|
80
|
+
ctx,
|
|
81
|
+
maxSize: typeof options.maxSize === 'function' ? options.maxSize(args, ctx) : options.maxSize,
|
|
82
|
+
defaultSize:
|
|
83
|
+
typeof options.defaultSize === 'function'
|
|
84
|
+
? options.defaultSize(args, ctx)
|
|
85
|
+
: options.defaultSize,
|
|
86
|
+
parseCursor,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getQuery(
|
|
91
|
+
args: PothosSchemaTypes.DefaultConnectionArguments,
|
|
92
|
+
ctx: Types['Context'],
|
|
93
|
+
nestedSelection: <T extends true | {}>(selection?: T, path?: string[]) => T,
|
|
94
|
+
) {
|
|
95
|
+
const nestedSelect: Record<string, unknown> | true = options.select
|
|
96
|
+
? { select: options.select((sel) => nestedSelection(sel, ['edges', 'node'])) }
|
|
97
|
+
: nestedSelection(true, ['edges', 'node']);
|
|
98
|
+
|
|
99
|
+
const selectState = createState(fieldMap, 'select');
|
|
100
|
+
|
|
101
|
+
mergeSelection(selectState, { select: cursorSelection });
|
|
102
|
+
|
|
103
|
+
if (typeof nestedSelect === 'object' && nestedSelect) {
|
|
104
|
+
mergeSelection(selectState, nestedSelect);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
...getQueryArgs(args, ctx),
|
|
109
|
+
...selectionToQuery(selectState),
|
|
110
|
+
} as unknown as ReturnType<typeof getQueryArgs> &
|
|
111
|
+
(Model['Select'] extends Select ? {} : { select: Select });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
ref: (typeof refOrType === 'string'
|
|
116
|
+
? getRefFromModel(refOrType, builder)
|
|
117
|
+
: refOrType) as PrismaObjectRef<Model>,
|
|
118
|
+
resolve,
|
|
119
|
+
select: options.select ?? {},
|
|
120
|
+
getQuery,
|
|
121
|
+
};
|
|
122
|
+
}
|
package/src/field-builder.ts
CHANGED
|
@@ -123,6 +123,8 @@ fieldBuilderProto.prismaConnection = function prismaConnection<
|
|
|
123
123
|
context,
|
|
124
124
|
info,
|
|
125
125
|
select: cursorSelection as {},
|
|
126
|
+
path: ['edges', 'node'],
|
|
127
|
+
typeName,
|
|
126
128
|
}),
|
|
127
129
|
ctx: context,
|
|
128
130
|
parseCursor,
|
|
@@ -135,30 +137,28 @@ fieldBuilderProto.prismaConnection = function prismaConnection<
|
|
|
135
137
|
(query) => resolve(query as never, parent, args as never, context, info) as never,
|
|
136
138
|
),
|
|
137
139
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
140
|
+
connectionOptions instanceof ObjectRef
|
|
141
|
+
? connectionOptions
|
|
142
|
+
: {
|
|
143
|
+
...connectionOptions,
|
|
144
|
+
fields: totalCount
|
|
145
|
+
? (
|
|
146
|
+
t: PothosSchemaTypes.ObjectFieldBuilder<
|
|
147
|
+
SchemaTypes,
|
|
148
|
+
{ totalCount?: () => MaybePromise<number> }
|
|
149
|
+
>,
|
|
150
|
+
) => ({
|
|
151
|
+
totalCount: t.int({
|
|
152
|
+
nullable: false,
|
|
153
|
+
resolve: (parent, args, context) => parent.totalCount?.(),
|
|
154
|
+
}),
|
|
155
|
+
...(connectionOptions as { fields?: (t: unknown) => {} }).fields?.(t),
|
|
156
|
+
})
|
|
157
|
+
: (connectionOptions as { fields: undefined }).fields,
|
|
158
|
+
extensions: {
|
|
159
|
+
...(connectionOptions as Record<string, {}> | undefined)?.extensions,
|
|
160
|
+
},
|
|
159
161
|
},
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
162
|
edgeOptions,
|
|
163
163
|
);
|
|
164
164
|
|
package/src/global-types.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
|
3
3
|
import {
|
|
4
4
|
FieldKind,
|
|
5
|
+
FieldMap,
|
|
5
6
|
FieldNullability,
|
|
6
7
|
FieldRef,
|
|
7
8
|
InputFieldMap,
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
ShapeFromTypeParam,
|
|
15
16
|
TypeParam,
|
|
16
17
|
} from '@pothos/core';
|
|
17
|
-
import PrismaNodeRef from './node-ref';
|
|
18
|
+
import { PrismaNodeRef } from './node-ref';
|
|
18
19
|
import { prismaModelKey, PrismaObjectRef } from './object-ref';
|
|
19
20
|
import { PrismaObjectFieldBuilder as InternalPrismaObjectFieldBuilder } from './prisma-field-builder';
|
|
20
21
|
import {
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
PrismaConnectionFieldOptions,
|
|
23
24
|
PrismaFieldOptions,
|
|
24
25
|
PrismaFieldWithInputOptions,
|
|
26
|
+
prismaModelName,
|
|
25
27
|
PrismaModelTypes,
|
|
26
28
|
PrismaNodeOptions,
|
|
27
29
|
PrismaObjectFieldOptions,
|
|
@@ -116,6 +118,37 @@ declare global {
|
|
|
116
118
|
>,
|
|
117
119
|
) => PrismaObjectRef<Model, ShapeFromSelection<Model, { select: Select; include: Include }>>;
|
|
118
120
|
|
|
121
|
+
prismaObjectField: <
|
|
122
|
+
Type extends PrismaObjectRef<PrismaModelTypes, {}> | keyof Types['PrismaTypes'],
|
|
123
|
+
Model extends PrismaModelTypes = Type extends PrismaObjectRef<infer M, {}>
|
|
124
|
+
? M
|
|
125
|
+
: Types['PrismaTypes'][Type & keyof Types['PrismaTypes']] & PrismaModelTypes,
|
|
126
|
+
Shape extends {} = Type extends PrismaObjectRef<PrismaModelTypes, infer S>
|
|
127
|
+
? S
|
|
128
|
+
: Model['Shape'] & {
|
|
129
|
+
[prismaModelName]?: Type;
|
|
130
|
+
},
|
|
131
|
+
>(
|
|
132
|
+
type: Type,
|
|
133
|
+
fieldName: string,
|
|
134
|
+
field: (t: PrismaObjectFieldBuilder<Types, Model, false, Shape>) => FieldRef,
|
|
135
|
+
) => void;
|
|
136
|
+
|
|
137
|
+
prismaObjectFields: <
|
|
138
|
+
Type extends PrismaObjectRef<PrismaModelTypes, {}> | keyof Types['PrismaTypes'],
|
|
139
|
+
Model extends PrismaModelTypes = Type extends PrismaObjectRef<infer M, {}>
|
|
140
|
+
? M
|
|
141
|
+
: Types['PrismaTypes'][Type & keyof Types['PrismaTypes']] & PrismaModelTypes,
|
|
142
|
+
Shape extends {} = Type extends PrismaObjectRef<PrismaModelTypes, infer S>
|
|
143
|
+
? S
|
|
144
|
+
: Model['Shape'] & {
|
|
145
|
+
[prismaModelName]?: Type;
|
|
146
|
+
},
|
|
147
|
+
>(
|
|
148
|
+
type: Type,
|
|
149
|
+
fields: (t: PrismaObjectFieldBuilder<Types, Model, false, Shape>) => FieldMap,
|
|
150
|
+
) => void;
|
|
151
|
+
|
|
119
152
|
prismaNode: 'relay' extends PluginName
|
|
120
153
|
? <
|
|
121
154
|
Name extends keyof Types['PrismaTypes'],
|
|
@@ -199,6 +232,7 @@ declare global {
|
|
|
199
232
|
Model extends PrismaModelTypes = Type extends PrismaObjectRef<infer T>
|
|
200
233
|
? T
|
|
201
234
|
: PrismaModelTypes & Types['PrismaTypes'][Type & keyof Types['PrismaTypes']],
|
|
235
|
+
Shape = Type extends PrismaObjectRef<PrismaModelTypes, infer S> ? S : Model['Shape'],
|
|
202
236
|
>(
|
|
203
237
|
options: PrismaConnectionFieldOptions<
|
|
204
238
|
Types,
|
|
@@ -213,19 +247,21 @@ declare global {
|
|
|
213
247
|
>,
|
|
214
248
|
...args: NormalizeArgs<
|
|
215
249
|
[
|
|
216
|
-
connectionOptions:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
Types,
|
|
225
|
-
|
|
226
|
-
false,
|
|
227
|
-
|
|
228
|
-
|
|
250
|
+
connectionOptions:
|
|
251
|
+
| ConnectionObjectOptions<
|
|
252
|
+
Types,
|
|
253
|
+
ObjectRef<Shape>,
|
|
254
|
+
false,
|
|
255
|
+
false,
|
|
256
|
+
ResolveReturnShape
|
|
257
|
+
>
|
|
258
|
+
| ObjectRef<ShapeFromConnection<ConnectionShapeHelper<Types, Shape, false>>>,
|
|
259
|
+
edgeOptions:
|
|
260
|
+
| ConnectionEdgeObjectOptions<Types, ObjectRef<Shape>, false, ResolveReturnShape>
|
|
261
|
+
| ObjectRef<{
|
|
262
|
+
cursor: string;
|
|
263
|
+
node?: Shape | null | undefined;
|
|
264
|
+
}>,
|
|
229
265
|
],
|
|
230
266
|
0
|
|
231
267
|
>
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,9 @@ import { PrismaModelTypes } from './types';
|
|
|
13
13
|
import { getLoaderMapping, setLoaderMappings } from './util/loader-map';
|
|
14
14
|
import { queryFromInfo, selectionStateFromInfo } from './util/map-query';
|
|
15
15
|
|
|
16
|
+
export { prismaConnectionHelpers } from './connection-helpers';
|
|
17
|
+
export { PrismaNodeRef } from './node-ref';
|
|
18
|
+
export { PrismaObjectRef } from './object-ref';
|
|
16
19
|
export * from './types';
|
|
17
20
|
|
|
18
21
|
const pluginName = 'prisma' as const;
|
package/src/node-ref.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { PrismaObjectRef } from './object-ref';
|
|
2
2
|
import type { PrismaModelTypes } from './types';
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
Model,
|
|
6
|
-
T
|
|
7
|
-
> {}
|
|
4
|
+
export class PrismaNodeRef<Model extends PrismaModelTypes, T> extends PrismaObjectRef<Model, T> {}
|
package/src/object-ref.ts
CHANGED
|
@@ -6,6 +6,13 @@ export const prismaModelKey = Symbol.for('Pothos.prismaModelKey');
|
|
|
6
6
|
export class PrismaObjectRef<Model extends PrismaModelTypes, T = {}> extends ObjectRef<T> {
|
|
7
7
|
[prismaModelKey]!: Model;
|
|
8
8
|
[abstractReturnShapeKey]!: WithBrand<T>;
|
|
9
|
+
modelName: string;
|
|
10
|
+
|
|
11
|
+
constructor(name: string, modelName: string) {
|
|
12
|
+
super(name);
|
|
13
|
+
|
|
14
|
+
this.modelName = modelName;
|
|
15
|
+
}
|
|
9
16
|
|
|
10
17
|
addBrand<V extends T | T[]>(
|
|
11
18
|
value: V,
|
|
@@ -111,19 +111,28 @@ export class PrismaObjectFieldBuilder<
|
|
|
111
111
|
options: RelatedConnectionOptions<Types, Model, Field, Nullable, Args, NeedsResolve>,
|
|
112
112
|
...args: NormalizeArgs<
|
|
113
113
|
[
|
|
114
|
-
connectionOptions:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
connectionOptions:
|
|
115
|
+
| PothosSchemaTypes.ConnectionObjectOptions<
|
|
116
|
+
Types,
|
|
117
|
+
ObjectRef<Shape>,
|
|
118
|
+
false,
|
|
119
|
+
false,
|
|
120
|
+
ResolveReturnShape
|
|
121
|
+
>
|
|
122
|
+
| ObjectRef<
|
|
123
|
+
ShapeFromConnection<PothosSchemaTypes.ConnectionShapeHelper<Types, Shape, false>>
|
|
124
|
+
>,
|
|
125
|
+
edgeOptions:
|
|
126
|
+
| PothosSchemaTypes.ConnectionEdgeObjectOptions<
|
|
127
|
+
Types,
|
|
128
|
+
ObjectRef<Shape>,
|
|
129
|
+
false,
|
|
130
|
+
ResolveReturnShape
|
|
131
|
+
>
|
|
132
|
+
| ObjectRef<{
|
|
133
|
+
cursor: string;
|
|
134
|
+
node?: ShapeFromTypeParam<Types, Model['Shape'], false>;
|
|
135
|
+
}>,
|
|
127
136
|
],
|
|
128
137
|
0
|
|
129
138
|
>
|
|
@@ -272,18 +281,22 @@ export class PrismaObjectFieldBuilder<
|
|
|
272
281
|
);
|
|
273
282
|
},
|
|
274
283
|
},
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
284
|
+
connectionOptions instanceof ObjectRef
|
|
285
|
+
? connectionOptions
|
|
286
|
+
: {
|
|
287
|
+
...connectionOptions,
|
|
288
|
+
fields: totalCount
|
|
289
|
+
? (
|
|
290
|
+
t: PothosSchemaTypes.ObjectFieldBuilder<SchemaTypes, { totalCount?: number }>,
|
|
291
|
+
) => ({
|
|
292
|
+
totalCount: t.int({
|
|
293
|
+
nullable: false,
|
|
294
|
+
resolve: (parent, args, context) => parent.totalCount,
|
|
295
|
+
}),
|
|
296
|
+
...(connectionOptions as { fields?: (t: unknown) => {} }).fields?.(t),
|
|
297
|
+
})
|
|
298
|
+
: (connectionOptions as { fields: undefined }).fields,
|
|
299
|
+
},
|
|
287
300
|
edgeOptions,
|
|
288
301
|
);
|
|
289
302
|
|
package/src/schema-builder.ts
CHANGED
|
@@ -9,7 +9,8 @@ import SchemaBuilder, {
|
|
|
9
9
|
} from '@pothos/core';
|
|
10
10
|
import { PrismaObjectFieldBuilder } from './field-builder';
|
|
11
11
|
import { ModelLoader } from './model-loader';
|
|
12
|
-
import PrismaNodeRef from './node-ref';
|
|
12
|
+
import { PrismaNodeRef } from './node-ref';
|
|
13
|
+
import { PrismaObjectRef } from './object-ref';
|
|
13
14
|
import { PrismaModelTypes, PrismaNodeOptions } from './types';
|
|
14
15
|
import { getDefaultIDParser, getDefaultIDSerializer } from './util/cursors';
|
|
15
16
|
import { getDelegateFromModel, getRefFromModel } from './util/datamodel';
|
|
@@ -24,7 +25,9 @@ schemaBuilderProto.prismaObject = function prismaObject(
|
|
|
24
25
|
type,
|
|
25
26
|
{ fields, findUnique, select, include, description, ...options },
|
|
26
27
|
) {
|
|
27
|
-
const ref = options.variant
|
|
28
|
+
const ref = options.variant
|
|
29
|
+
? new PrismaObjectRef(options.variant, type)
|
|
30
|
+
: getRefFromModel(type, this);
|
|
28
31
|
const name = options.variant ?? options.name ?? type;
|
|
29
32
|
const fieldMap = getRelationMap(getDMMF(this)).get(type)!;
|
|
30
33
|
const idSelection = ModelLoader.getDefaultIDSelection(ref, type, this);
|
|
@@ -77,7 +80,7 @@ schemaBuilderProto.prismaNode = function prismaNode(
|
|
|
77
80
|
const resolve = rawResolve ?? getDefaultIDSerializer(type, fieldName, this);
|
|
78
81
|
const idParser = fieldName ? getDefaultIDParser(type, fieldName, this) : undefined;
|
|
79
82
|
const typeName = variant ?? name ?? type;
|
|
80
|
-
const nodeRef = new PrismaNodeRef(typeName);
|
|
83
|
+
const nodeRef = new PrismaNodeRef(typeName, type);
|
|
81
84
|
const findUnique = rawFindUnique
|
|
82
85
|
? (parent: unknown, context: {}) =>
|
|
83
86
|
rawFindUnique(resolve(parent as never, context) as string, context)
|
|
@@ -156,3 +159,35 @@ schemaBuilderProto.prismaNode = function prismaNode(
|
|
|
156
159
|
|
|
157
160
|
return nodeRef;
|
|
158
161
|
} as never;
|
|
162
|
+
|
|
163
|
+
schemaBuilderProto.prismaObjectField = function prismaObjectField(type, fieldName, field) {
|
|
164
|
+
const ref = typeof type === 'string' ? getRefFromModel(type, this) : type;
|
|
165
|
+
this.configStore.onTypeConfig(ref, ({ name }) => {
|
|
166
|
+
this.configStore.addFields(ref, () => ({
|
|
167
|
+
[fieldName]: field(
|
|
168
|
+
new PrismaObjectFieldBuilder(
|
|
169
|
+
name,
|
|
170
|
+
this,
|
|
171
|
+
ref.modelName,
|
|
172
|
+
getRelationMap(getDMMF(this)).get(ref.modelName)!,
|
|
173
|
+
),
|
|
174
|
+
),
|
|
175
|
+
}));
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
schemaBuilderProto.prismaObjectFields = function prismaObjectFields(type, fields) {
|
|
180
|
+
const ref = typeof type === 'string' ? getRefFromModel(type, this) : type;
|
|
181
|
+
this.configStore.onTypeConfig(ref, ({ name }) => {
|
|
182
|
+
this.configStore.addFields(ref, () =>
|
|
183
|
+
fields(
|
|
184
|
+
new PrismaObjectFieldBuilder(
|
|
185
|
+
name,
|
|
186
|
+
this,
|
|
187
|
+
ref.modelName,
|
|
188
|
+
getRelationMap(getDMMF(this)).get(ref.modelName)!,
|
|
189
|
+
),
|
|
190
|
+
),
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -151,29 +151,15 @@ type RelationShapeFromInclude<Model extends PrismaModelTypes, Include> = Normali
|
|
|
151
151
|
: unknown;
|
|
152
152
|
}>;
|
|
153
153
|
|
|
154
|
-
export type
|
|
154
|
+
export type PrismaObjectRefOptions<
|
|
155
155
|
Types extends SchemaTypes,
|
|
156
156
|
Model extends PrismaModelTypes,
|
|
157
|
-
Interfaces extends InterfaceParam<Types>[],
|
|
158
157
|
FindUnique,
|
|
159
158
|
Include,
|
|
160
159
|
Select,
|
|
161
160
|
Shape extends object,
|
|
162
161
|
> = NameOrVariant &
|
|
163
|
-
|
|
164
|
-
| PothosSchemaTypes.ObjectTypeOptions<Types, Shape>
|
|
165
|
-
| PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
|
|
166
|
-
'fields' | 'description'
|
|
167
|
-
> & {
|
|
168
|
-
description?: string | false;
|
|
169
|
-
fields?: PrismaObjectFieldsShape<
|
|
170
|
-
Types,
|
|
171
|
-
Model,
|
|
172
|
-
FindUnique extends null ? true : false,
|
|
173
|
-
Shape & (FindUnique extends null ? {} : { [prismaModelName]?: Model['Name'] }),
|
|
174
|
-
Select
|
|
175
|
-
>;
|
|
176
|
-
} & (
|
|
162
|
+
(
|
|
177
163
|
| {
|
|
178
164
|
include?: Include & Model['Include'];
|
|
179
165
|
select?: never;
|
|
@@ -187,6 +173,39 @@ export type PrismaObjectTypeOptions<
|
|
|
187
173
|
}
|
|
188
174
|
);
|
|
189
175
|
|
|
176
|
+
export type PrismaObjectImplementationOptions<
|
|
177
|
+
Types extends SchemaTypes,
|
|
178
|
+
Model extends PrismaModelTypes,
|
|
179
|
+
Interfaces extends InterfaceParam<Types>[],
|
|
180
|
+
FindUnique,
|
|
181
|
+
Select,
|
|
182
|
+
Shape extends object,
|
|
183
|
+
> = Omit<
|
|
184
|
+
| PothosSchemaTypes.ObjectTypeOptions<Types, Shape>
|
|
185
|
+
| PothosSchemaTypes.ObjectTypeWithInterfaceOptions<Types, Shape, Interfaces>,
|
|
186
|
+
'fields' | 'description'
|
|
187
|
+
> & {
|
|
188
|
+
description?: string | false;
|
|
189
|
+
fields?: PrismaObjectFieldsShape<
|
|
190
|
+
Types,
|
|
191
|
+
Model,
|
|
192
|
+
FindUnique extends null ? true : false,
|
|
193
|
+
Shape & (FindUnique extends null ? {} : { [prismaModelName]?: Model['Name'] }),
|
|
194
|
+
Select
|
|
195
|
+
>;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export type PrismaObjectTypeOptions<
|
|
199
|
+
Types extends SchemaTypes,
|
|
200
|
+
Model extends PrismaModelTypes,
|
|
201
|
+
Interfaces extends InterfaceParam<Types>[],
|
|
202
|
+
FindUnique,
|
|
203
|
+
Include,
|
|
204
|
+
Select,
|
|
205
|
+
Shape extends object,
|
|
206
|
+
> = PrismaObjectRefOptions<Types, Model, FindUnique, Include, Select, Shape> &
|
|
207
|
+
PrismaObjectImplementationOptions<Types, Model, Interfaces, FindUnique, Select, Shape>;
|
|
208
|
+
|
|
190
209
|
type NameOrVariant =
|
|
191
210
|
| {
|
|
192
211
|
name?: never;
|
package/src/util/cursors.ts
CHANGED
|
@@ -261,7 +261,8 @@ export function wrapConnectionResult<T extends {}>(
|
|
|
261
261
|
args: PothosSchemaTypes.DefaultConnectionArguments,
|
|
262
262
|
take: number,
|
|
263
263
|
cursor: (node: T) => string,
|
|
264
|
-
totalCount?: number | (() => MaybePromise<number>),
|
|
264
|
+
totalCount?: null | number | (() => MaybePromise<number>),
|
|
265
|
+
resolveNode?: (node: unknown) => unknown,
|
|
265
266
|
) {
|
|
266
267
|
const gotFullResults = results.length === Math.abs(take);
|
|
267
268
|
const hasNextPage = args.before ? true : gotFullResults;
|
|
@@ -273,6 +274,12 @@ export function wrapConnectionResult<T extends {}>(
|
|
|
273
274
|
const edges = nodes.map((value, index) =>
|
|
274
275
|
value == null
|
|
275
276
|
? null
|
|
277
|
+
: resolveNode
|
|
278
|
+
? {
|
|
279
|
+
...value,
|
|
280
|
+
cursor: cursor(value),
|
|
281
|
+
node: resolveNode(value),
|
|
282
|
+
}
|
|
276
283
|
: {
|
|
277
284
|
cursor: cursor(value),
|
|
278
285
|
node: value,
|
package/src/util/datamodel.ts
CHANGED
|
@@ -24,7 +24,7 @@ export function getRefFromModel<Types extends SchemaTypes>(
|
|
|
24
24
|
const cache = refMap.get(builder)!;
|
|
25
25
|
|
|
26
26
|
if (!cache.has(name)) {
|
|
27
|
-
cache.set(name, new PrismaObjectRef(name));
|
|
27
|
+
cache.set(name, new PrismaObjectRef(name, name));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
return cache.get(name)!;
|
package/src/util/map-query.ts
CHANGED
|
@@ -96,6 +96,11 @@ function resolveIndirectInclude(
|
|
|
96
96
|
path: string[],
|
|
97
97
|
resolve: (type: GraphQLNamedType, field: FieldNode, path: string[]) => void,
|
|
98
98
|
) {
|
|
99
|
+
if (includePath.length === 0) {
|
|
100
|
+
resolve(type, selection as FieldNode, path);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
99
104
|
const [include, ...rest] = includePath;
|
|
100
105
|
if (!selection.selectionSet || !include) {
|
|
101
106
|
return;
|
|
@@ -107,18 +112,14 @@ function resolveIndirectInclude(
|
|
|
107
112
|
if (sel.name.value === include.name && isObjectType(type)) {
|
|
108
113
|
const returnType = getNamedType(type.getFields()[sel.name.value].type);
|
|
109
114
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
[...path, sel.alias?.value ?? sel.name.value],
|
|
119
|
-
resolve,
|
|
120
|
-
);
|
|
121
|
-
}
|
|
115
|
+
resolveIndirectInclude(
|
|
116
|
+
returnType,
|
|
117
|
+
info,
|
|
118
|
+
sel,
|
|
119
|
+
rest,
|
|
120
|
+
[...path, sel.alias?.value ?? sel.name.value],
|
|
121
|
+
resolve,
|
|
122
|
+
);
|
|
122
123
|
}
|
|
123
124
|
continue;
|
|
124
125
|
case Kind.FRAGMENT_SPREAD:
|
|
@@ -334,7 +335,8 @@ export function queryFromInfo<T extends SelectionMap['select'] | undefined = und
|
|
|
334
335
|
select?: T;
|
|
335
336
|
path?: string[];
|
|
336
337
|
}): { select: T } | { include?: {} } {
|
|
337
|
-
const
|
|
338
|
+
const returnType = getNamedType(info.returnType);
|
|
339
|
+
const type = typeName ? info.schema.getTypeMap()[typeName] : returnType;
|
|
338
340
|
const state = createStateForType(type, info);
|
|
339
341
|
|
|
340
342
|
if (select) {
|
|
@@ -342,14 +344,27 @@ export function queryFromInfo<T extends SelectionMap['select'] | undefined = und
|
|
|
342
344
|
}
|
|
343
345
|
|
|
344
346
|
if (path.length > 0) {
|
|
347
|
+
const { pothosPrismaIndirectInclude } = (returnType.extensions ?? {}) as {
|
|
348
|
+
pothosPrismaIndirectInclude?: IndirectInclude;
|
|
349
|
+
};
|
|
350
|
+
|
|
345
351
|
resolveIndirectInclude(
|
|
346
|
-
|
|
352
|
+
returnType,
|
|
347
353
|
info,
|
|
348
354
|
info.fieldNodes[0],
|
|
349
|
-
path
|
|
355
|
+
pothosPrismaIndirectInclude?.path ?? [],
|
|
350
356
|
[],
|
|
351
|
-
(
|
|
352
|
-
|
|
357
|
+
(indirectType, indirectField, subPath) => {
|
|
358
|
+
resolveIndirectInclude(
|
|
359
|
+
indirectType,
|
|
360
|
+
info,
|
|
361
|
+
indirectField,
|
|
362
|
+
path.map((n) => (typeof n === 'string' ? { name: n } : n)),
|
|
363
|
+
subPath,
|
|
364
|
+
(resolvedType, resolvedField, nested) => {
|
|
365
|
+
addTypeSelectionsForField(resolvedType, context, info, state, resolvedField, nested);
|
|
366
|
+
},
|
|
367
|
+
);
|
|
353
368
|
},
|
|
354
369
|
);
|
|
355
370
|
} else {
|