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