@pothos/plugin-prisma 3.28.0 → 3.31.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 +9 -1
- package/dts/global-types.d.ts +2 -0
- package/dts/global-types.d.ts.map +1 -1
- package/dts/model-loader.d.ts +3 -3
- package/dts/model-loader.d.ts.map +1 -1
- package/dts/prisma-field-builder.d.ts +1 -1
- package/dts/prisma-field-builder.d.ts.map +1 -1
- package/dts/types.d.ts +5 -3
- package/dts/types.d.ts.map +1 -1
- package/dts/util/map-query.d.ts.map +1 -1
- package/dts/util/selections.d.ts +1 -1
- package/dts/util/selections.d.ts.map +1 -1
- package/esm/field-builder.js.map +1 -1
- package/esm/generator.js +4 -3
- package/esm/generator.js.map +1 -1
- package/esm/global-types.js.map +1 -1
- package/esm/index.js.map +1 -1
- package/esm/model-loader.js.map +1 -1
- package/esm/object-ref.js.map +1 -1
- package/esm/prisma-field-builder.js +28 -14
- package/esm/prisma-field-builder.js.map +1 -1
- package/esm/schema-builder.js.map +1 -1
- package/esm/util/cursors.js.map +1 -1
- package/esm/util/datamodel.js.map +1 -1
- package/esm/util/deep-equal.js.map +1 -1
- package/esm/util/description.js.map +1 -1
- package/esm/util/get-client.js.map +1 -1
- package/esm/util/loader-map.js.map +1 -1
- package/esm/util/map-query.js +14 -22
- package/esm/util/map-query.js.map +1 -1
- package/esm/util/relation-map.js.map +1 -1
- package/esm/util/selections.js +12 -4
- package/esm/util/selections.js.map +1 -1
- package/lib/field-builder.js.map +1 -1
- package/lib/generator.js +3 -2
- package/lib/generator.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/model-loader.js.map +1 -1
- package/lib/object-ref.js.map +1 -1
- package/lib/prisma-field-builder.js +28 -14
- package/lib/prisma-field-builder.js.map +1 -1
- package/lib/schema-builder.js.map +1 -1
- package/lib/util/cursors.js.map +1 -1
- package/lib/util/datamodel.js.map +1 -1
- package/lib/util/deep-equal.js.map +1 -1
- package/lib/util/description.js.map +1 -1
- package/lib/util/get-client.js.map +1 -1
- package/lib/util/loader-map.js.map +1 -1
- package/lib/util/map-query.js +14 -21
- package/lib/util/map-query.js.map +1 -1
- package/lib/util/relation-map.js.map +1 -1
- package/lib/util/selections.js +12 -4
- package/lib/util/selections.js.map +1 -1
- package/package.json +7 -7
- package/src/generator.ts +4 -2
- package/src/global-types.ts +2 -0
- package/src/model-loader.ts +5 -5
- package/src/prisma-field-builder.ts +37 -12
- package/src/types.ts +5 -1
- package/src/util/map-query.ts +65 -50
- package/src/util/selections.ts +21 -8
- package/tsconfig.type.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pothos/plugin-prisma",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.31.0",
|
|
4
4
|
"description": "A Pothos plugin for more efficient integration with prisma",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./dts/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@prisma/generator-helper": "^4.
|
|
39
|
+
"@prisma/generator-helper": "^4.3.1"
|
|
40
40
|
},
|
|
41
41
|
"prisma": {
|
|
42
42
|
"seed": "node prisma/seed.mjs"
|
|
@@ -48,16 +48,16 @@
|
|
|
48
48
|
"typescript": ">=4.7.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@pothos/core": "3.
|
|
52
|
-
"@pothos/plugin-complexity": "3.
|
|
51
|
+
"@pothos/core": "3.19.1",
|
|
52
|
+
"@pothos/plugin-complexity": "3.9.1",
|
|
53
53
|
"@pothos/plugin-errors": "3.6.0",
|
|
54
|
-
"@pothos/plugin-relay": "3.
|
|
54
|
+
"@pothos/plugin-relay": "3.24.0",
|
|
55
55
|
"@pothos/plugin-simple-objects": "3.4.0",
|
|
56
56
|
"@pothos/test-utils": "1.3.0",
|
|
57
|
-
"@prisma/client": "^4.
|
|
57
|
+
"@prisma/client": "^4.3.1",
|
|
58
58
|
"graphql": "16.6.0",
|
|
59
59
|
"graphql-tag": "^2.12.6",
|
|
60
|
-
"prisma": "^4.
|
|
60
|
+
"prisma": "^4.3.1"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"generate": "prisma generate",
|
package/src/generator.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-magic-numbers */
|
|
2
2
|
/* eslint-disable no-nested-ternary */
|
|
3
3
|
import { mkdir, writeFile } from 'fs';
|
|
4
|
-
import { dirname } from 'path';
|
|
4
|
+
import { dirname, resolve as resolvePath } from 'path';
|
|
5
5
|
import ts, { ListFormat, ScriptKind, ScriptTarget, SyntaxKind, version } from 'typescript';
|
|
6
6
|
import { generatorHandler } from '@prisma/generator-helper';
|
|
7
7
|
|
|
@@ -24,11 +24,13 @@ function checkTSVersion() {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
const defaultOutput = resolvePath(__dirname, '../generated');
|
|
28
|
+
|
|
27
29
|
generatorHandler({
|
|
28
30
|
onManifest: () => ({
|
|
29
31
|
prettyName: 'Pothos integration',
|
|
30
|
-
defaultOutput: 'node_modules/@pothos/plugin-prisma/generated.ts',
|
|
31
32
|
requiresGenerators: ['prisma-client-js'],
|
|
33
|
+
defaultOutput,
|
|
32
34
|
}),
|
|
33
35
|
onGenerate: async (options) => {
|
|
34
36
|
checkTSVersion();
|
package/src/global-types.ts
CHANGED
|
@@ -39,6 +39,7 @@ declare global {
|
|
|
39
39
|
export interface SchemaBuilderOptions<Types extends SchemaTypes> {
|
|
40
40
|
prisma:
|
|
41
41
|
| {
|
|
42
|
+
filterConnectionTotalCount?: boolean;
|
|
42
43
|
client: PrismaClient;
|
|
43
44
|
exposeDescriptions?:
|
|
44
45
|
| boolean
|
|
@@ -48,6 +49,7 @@ declare global {
|
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
51
|
| {
|
|
52
|
+
filterConnectionTotalCount?: boolean;
|
|
51
53
|
client: (ctx: Types['Context']) => PrismaClient;
|
|
52
54
|
dmmf: { datamodel: unknown };
|
|
53
55
|
exposeDescriptions?:
|
package/src/model-loader.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
export class ModelLoader {
|
|
12
12
|
model: object;
|
|
13
13
|
builder: PothosSchemaTypes.SchemaBuilder<never>;
|
|
14
|
-
findUnique: (
|
|
14
|
+
findUnique: (model: Record<string, unknown>, ctx: {}) => unknown;
|
|
15
15
|
modelName: string;
|
|
16
16
|
|
|
17
17
|
staged = new Set<{
|
|
@@ -23,7 +23,7 @@ export class ModelLoader {
|
|
|
23
23
|
model: object,
|
|
24
24
|
builder: PothosSchemaTypes.SchemaBuilder<never>,
|
|
25
25
|
modelName: string,
|
|
26
|
-
findUnique: (
|
|
26
|
+
findUnique: (model: Record<string, unknown>, ctx: {}) => unknown,
|
|
27
27
|
) {
|
|
28
28
|
this.model = model;
|
|
29
29
|
this.builder = builder;
|
|
@@ -34,7 +34,7 @@ export class ModelLoader {
|
|
|
34
34
|
static forRef<Types extends SchemaTypes>(
|
|
35
35
|
ref: ObjectRef<unknown>,
|
|
36
36
|
modelName: string,
|
|
37
|
-
findUnique: (
|
|
37
|
+
findUnique: ((model: Record<string, unknown>, ctx: {}) => unknown) | undefined,
|
|
38
38
|
builder: PothosSchemaTypes.SchemaBuilder<Types>,
|
|
39
39
|
) {
|
|
40
40
|
return createContextCache(
|
|
@@ -238,14 +238,14 @@ export class ModelLoader {
|
|
|
238
238
|
if (delegate.findUniqueOrThrow) {
|
|
239
239
|
return delegate.findUniqueOrThrow({
|
|
240
240
|
...selectionToQuery(state),
|
|
241
|
-
where: { ...(this.findUnique(this.model, context) as {}) },
|
|
241
|
+
where: { ...(this.findUnique(this.model as Record<string, unknown>, context) as {}) },
|
|
242
242
|
} as never) as Promise<Record<string, unknown>>;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
return delegate.findUnique({
|
|
246
246
|
rejectOnNotFound: true,
|
|
247
247
|
...selectionToQuery(state),
|
|
248
|
-
where: { ...(this.findUnique(this.model, context) as {}) },
|
|
248
|
+
where: { ...(this.findUnique(this.model as Record<string, unknown>, context) as {}) },
|
|
249
249
|
} as never) as Promise<Record<string, unknown>>;
|
|
250
250
|
}),
|
|
251
251
|
state,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
1
2
|
/* eslint-disable no-underscore-dangle */
|
|
2
|
-
import { GraphQLResolveInfo } from 'graphql';
|
|
3
|
+
import { FieldNode, GraphQLResolveInfo } from 'graphql';
|
|
3
4
|
import {
|
|
4
5
|
CompatibleTypes,
|
|
5
6
|
FieldKind,
|
|
@@ -172,6 +173,7 @@ export class PrismaObjectFieldBuilder<
|
|
|
172
173
|
args,
|
|
173
174
|
}),
|
|
174
175
|
});
|
|
176
|
+
|
|
175
177
|
const cursorSelection = ModelLoader.getCursorSelection(
|
|
176
178
|
ref,
|
|
177
179
|
relationField.type,
|
|
@@ -182,7 +184,8 @@ export class PrismaObjectFieldBuilder<
|
|
|
182
184
|
const relationSelect = (
|
|
183
185
|
args: object,
|
|
184
186
|
context: object,
|
|
185
|
-
nestedQuery: (query: unknown, path
|
|
187
|
+
nestedQuery: (query: unknown, path?: unknown) => { select?: {} },
|
|
188
|
+
getSelection: (path: string[]) => FieldNode | null,
|
|
186
189
|
) => {
|
|
187
190
|
const nested = nestedQuery(getQuery(args, context), {
|
|
188
191
|
getType: () => {
|
|
@@ -194,8 +197,16 @@ export class PrismaObjectFieldBuilder<
|
|
|
194
197
|
path: [{ name: 'edges' }, { name: 'node' }],
|
|
195
198
|
}) as SelectionMap;
|
|
196
199
|
|
|
200
|
+
const hasTotalCount = totalCount && !!getSelection(['totalCount']);
|
|
201
|
+
const countSelect = this.builder.options.prisma.filterConnectionTotalCount
|
|
202
|
+
? nested.where
|
|
203
|
+
? { where: nested.where }
|
|
204
|
+
: true
|
|
205
|
+
: true;
|
|
206
|
+
|
|
197
207
|
return {
|
|
198
208
|
select: {
|
|
209
|
+
...(hasTotalCount ? { _count: { select: { [name]: countSelect } } } : {}),
|
|
199
210
|
[name]: nested?.select
|
|
200
211
|
? {
|
|
201
212
|
...nested,
|
|
@@ -266,9 +277,6 @@ export class PrismaObjectFieldBuilder<
|
|
|
266
277
|
? (t: PothosSchemaTypes.ObjectFieldBuilder<SchemaTypes, { totalCount?: number }>) => ({
|
|
267
278
|
totalCount: t.int({
|
|
268
279
|
nullable: false,
|
|
269
|
-
extensions: {
|
|
270
|
-
pothosPrismaParentSelect: { _count: { select: { [name]: true } } },
|
|
271
|
-
},
|
|
272
280
|
resolve: (parent, args, context) => parent.totalCount,
|
|
273
281
|
}),
|
|
274
282
|
...(connectionOptions as { fields?: (t: unknown) => {} }).fields?.(t),
|
|
@@ -352,18 +360,35 @@ export class PrismaObjectFieldBuilder<
|
|
|
352
360
|
|
|
353
361
|
relationCount<Field extends Model['RelationName']>(
|
|
354
362
|
...allArgs: NormalizeArgs<
|
|
355
|
-
[
|
|
363
|
+
[
|
|
364
|
+
name: Field,
|
|
365
|
+
options?: RelationCountOptions<
|
|
366
|
+
Types,
|
|
367
|
+
Shape,
|
|
368
|
+
NeedsResolve,
|
|
369
|
+
Model['Relations'][Field]['Types']['Where']
|
|
370
|
+
>,
|
|
371
|
+
]
|
|
356
372
|
>
|
|
357
373
|
): FieldRef<number, 'Object'> {
|
|
358
|
-
const [name, options = {} as never] = allArgs;
|
|
374
|
+
const [name, { where, ...options } = {} as never] = allArgs;
|
|
359
375
|
|
|
360
376
|
const { resolve, ...rest } = options;
|
|
361
377
|
|
|
362
|
-
const countSelect =
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
378
|
+
const countSelect =
|
|
379
|
+
typeof where === 'function'
|
|
380
|
+
? (args: {}, context: {}) => ({
|
|
381
|
+
_count: {
|
|
382
|
+
select: {
|
|
383
|
+
[name]: { where: (where as (args: unknown, ctx: unknown) => {})(args, context) },
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
})
|
|
387
|
+
: {
|
|
388
|
+
_count: {
|
|
389
|
+
select: { [name]: where ? { where } : true },
|
|
390
|
+
},
|
|
391
|
+
};
|
|
367
392
|
|
|
368
393
|
return this.field({
|
|
369
394
|
...(rest as {}),
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GraphQLResolveInfo } from 'graphql';
|
|
1
|
+
import { FieldNode, GraphQLResolveInfo } from 'graphql';
|
|
2
2
|
import {
|
|
3
3
|
FieldKind,
|
|
4
4
|
FieldMap,
|
|
@@ -385,12 +385,14 @@ export type RelationCountOptions<
|
|
|
385
385
|
Types extends SchemaTypes,
|
|
386
386
|
Shape,
|
|
387
387
|
NeedsResolve extends boolean,
|
|
388
|
+
Where,
|
|
388
389
|
> = Omit<
|
|
389
390
|
PothosSchemaTypes.ObjectFieldOptions<Types, Shape, 'Int', false, {}, number>,
|
|
390
391
|
'resolve' | 'type'
|
|
391
392
|
> &
|
|
392
393
|
(NeedsResolve extends false
|
|
393
394
|
? {
|
|
395
|
+
where?: Where | ((args: {}, context: Types['Context']) => Where);
|
|
394
396
|
resolve?: (
|
|
395
397
|
parent: Shape,
|
|
396
398
|
args: {},
|
|
@@ -399,6 +401,7 @@ export type RelationCountOptions<
|
|
|
399
401
|
) => MaybePromise<number>;
|
|
400
402
|
}
|
|
401
403
|
: {
|
|
404
|
+
where?: Where | ((args: {}, context: Types['Context']) => Where);
|
|
402
405
|
resolve: (
|
|
403
406
|
parent: Shape,
|
|
404
407
|
args: {},
|
|
@@ -620,6 +623,7 @@ export type FieldSelection =
|
|
|
620
623
|
selection: SelectionMap | boolean | ((args: object, context: object) => SelectionMap),
|
|
621
624
|
path?: string[] | IndirectInclude,
|
|
622
625
|
) => SelectionMap | boolean,
|
|
626
|
+
resolveSelection: (path: string[]) => FieldNode | null,
|
|
623
627
|
) => SelectionMap);
|
|
624
628
|
|
|
625
629
|
export type LoaderMappings = Record<
|
package/src/util/map-query.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
FieldNode,
|
|
5
5
|
FragmentDefinitionNode,
|
|
6
|
+
getArgumentValues,
|
|
6
7
|
getNamedType,
|
|
7
8
|
GraphQLField,
|
|
8
9
|
GraphQLNamedType,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
Kind,
|
|
14
15
|
SelectionSetNode,
|
|
15
16
|
} from 'graphql';
|
|
16
|
-
import { getArgumentValues } from 'graphql/execution/values';
|
|
17
17
|
import {
|
|
18
18
|
FieldSelection,
|
|
19
19
|
IncludeMap,
|
|
@@ -222,9 +222,6 @@ function addFieldSelection(
|
|
|
222
222
|
|
|
223
223
|
let fieldSelectionMap: SelectionMap;
|
|
224
224
|
|
|
225
|
-
const fieldParentSelect = field.extensions?.pothosPrismaParentSelect as
|
|
226
|
-
| Record<string, SelectionMap | boolean>
|
|
227
|
-
| undefined;
|
|
228
225
|
let mappings: LoaderMappings = {};
|
|
229
226
|
|
|
230
227
|
if (typeof fieldSelect === 'function') {
|
|
@@ -233,52 +230,82 @@ function addFieldSelection(
|
|
|
233
230
|
unknown
|
|
234
231
|
>;
|
|
235
232
|
|
|
236
|
-
fieldSelectionMap = fieldSelect(
|
|
237
|
-
|
|
238
|
-
|
|
233
|
+
fieldSelectionMap = fieldSelect(
|
|
234
|
+
args,
|
|
235
|
+
context,
|
|
236
|
+
(rawQuery, indirectInclude) => {
|
|
237
|
+
const returnType = getNamedType(field.type);
|
|
238
|
+
const query = typeof rawQuery === 'function' ? rawQuery(args, context) : rawQuery;
|
|
239
|
+
|
|
240
|
+
const normalizedIndirectInclude = Array.isArray(indirectInclude)
|
|
241
|
+
? normalizeInclude(indirectInclude, getIndirectType(returnType, info))
|
|
242
|
+
: indirectInclude;
|
|
243
|
+
|
|
244
|
+
const fieldState = createStateForType(
|
|
245
|
+
getIndirectType(
|
|
246
|
+
normalizedIndirectInclude
|
|
247
|
+
? info.schema.getType(normalizedIndirectInclude.getType())!
|
|
248
|
+
: returnType,
|
|
249
|
+
info,
|
|
250
|
+
),
|
|
251
|
+
info,
|
|
252
|
+
state,
|
|
253
|
+
);
|
|
239
254
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
255
|
+
if (typeof query === 'object' && Object.keys(query).length > 0) {
|
|
256
|
+
mergeSelection(fieldState, { select: {}, ...query });
|
|
257
|
+
}
|
|
243
258
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
259
|
+
if (normalizedIndirectInclude && normalizedIndirectInclude.path.length > 0) {
|
|
260
|
+
resolveIndirectInclude(
|
|
261
|
+
returnType,
|
|
262
|
+
info,
|
|
263
|
+
selection,
|
|
264
|
+
[
|
|
265
|
+
...((returnType.extensions?.pothosPrismaIndirectInclude as { path: [] })?.path ?? []),
|
|
266
|
+
...normalizedIndirectInclude.path,
|
|
267
|
+
],
|
|
268
|
+
[],
|
|
269
|
+
(resolvedType, resolvedField, path) => {
|
|
270
|
+
addTypeSelectionsForField(
|
|
271
|
+
resolvedType,
|
|
272
|
+
context,
|
|
273
|
+
info,
|
|
274
|
+
fieldState,
|
|
275
|
+
resolvedField,
|
|
276
|
+
path,
|
|
277
|
+
);
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
addTypeSelectionsForField(returnType, context, info, fieldState, selection, []);
|
|
283
|
+
|
|
284
|
+
// eslint-disable-next-line prefer-destructuring
|
|
285
|
+
mappings = fieldState.mappings;
|
|
254
286
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
287
|
+
return selectionToQuery(fieldState);
|
|
288
|
+
},
|
|
289
|
+
(path) => {
|
|
290
|
+
const returnType = getNamedType(field.type);
|
|
291
|
+
let node: FieldNode | null = null;
|
|
258
292
|
|
|
259
|
-
if (normalizedIndirectInclude && normalizedIndirectInclude.path.length > 0) {
|
|
260
293
|
resolveIndirectInclude(
|
|
261
294
|
returnType,
|
|
262
295
|
info,
|
|
263
296
|
selection,
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
],
|
|
297
|
+
path.map((name) => ({
|
|
298
|
+
name,
|
|
299
|
+
})),
|
|
268
300
|
[],
|
|
269
|
-
(
|
|
270
|
-
|
|
301
|
+
(_, resolvedField) => {
|
|
302
|
+
node = resolvedField;
|
|
271
303
|
},
|
|
272
304
|
);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
addTypeSelectionsForField(returnType, context, info, fieldState, selection, []);
|
|
276
|
-
|
|
277
|
-
// eslint-disable-next-line prefer-destructuring
|
|
278
|
-
mappings = fieldState.mappings;
|
|
279
305
|
|
|
280
|
-
|
|
281
|
-
|
|
306
|
+
return node;
|
|
307
|
+
},
|
|
308
|
+
);
|
|
282
309
|
} else {
|
|
283
310
|
fieldSelectionMap = { select: fieldSelect };
|
|
284
311
|
}
|
|
@@ -291,18 +318,6 @@ function addFieldSelection(
|
|
|
291
318
|
mappings,
|
|
292
319
|
indirectPath,
|
|
293
320
|
};
|
|
294
|
-
} else if (
|
|
295
|
-
fieldParentSelect &&
|
|
296
|
-
state.parent &&
|
|
297
|
-
selectionCompatible(state.parent, { select: fieldParentSelect }, true)
|
|
298
|
-
) {
|
|
299
|
-
mergeSelection(state.parent, { select: fieldParentSelect });
|
|
300
|
-
state.mappings[selection.alias?.value ?? selection.name.value] = {
|
|
301
|
-
field: selection.name.value,
|
|
302
|
-
type: type.name,
|
|
303
|
-
mappings,
|
|
304
|
-
indirectPath,
|
|
305
|
-
};
|
|
306
321
|
}
|
|
307
322
|
}
|
|
308
323
|
|
package/src/util/selections.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface SelectionState {
|
|
|
11
11
|
query: object;
|
|
12
12
|
mode: SelectionMode;
|
|
13
13
|
fields: Set<string>;
|
|
14
|
-
counts:
|
|
14
|
+
counts: Map<string, boolean | Record<string, unknown>>;
|
|
15
15
|
relations: Map<string, SelectionState>;
|
|
16
16
|
mappings: LoaderMappings;
|
|
17
17
|
parent?: SelectionState;
|
|
@@ -39,6 +39,19 @@ export function selectionCompatible(
|
|
|
39
39
|
return ignoreQuery || deepEqual(state.query, query);
|
|
40
40
|
|
|
41
41
|
function compare(key: string, value: SelectionMap | boolean) {
|
|
42
|
+
if (key === '_count') {
|
|
43
|
+
const selections = value && (value as { select?: Record<string, unknown> }).select;
|
|
44
|
+
const keys = selections && Object.keys(selections);
|
|
45
|
+
|
|
46
|
+
if (!keys || keys.length === 0) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return keys.some(
|
|
51
|
+
(k) => state.counts.has(k) && !deepEqual(state.counts.get(k), selections[k]),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
return (
|
|
43
56
|
value &&
|
|
44
57
|
state.fieldMap.relations.has(key) &&
|
|
@@ -89,7 +102,7 @@ export function createState(
|
|
|
89
102
|
fieldMap,
|
|
90
103
|
query: {},
|
|
91
104
|
fields: new Set(),
|
|
92
|
-
counts: new
|
|
105
|
+
counts: new Map(),
|
|
93
106
|
relations: new Map(),
|
|
94
107
|
mappings: {},
|
|
95
108
|
};
|
|
@@ -122,9 +135,9 @@ export function mergeSelection(state: SelectionState, { select, include, ...quer
|
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
if (key === '_count') {
|
|
125
|
-
const counts = (value as { select?:
|
|
138
|
+
const counts = (value as { select?: Record<string, boolean> }).select ?? {};
|
|
126
139
|
Object.keys(counts).forEach((count) => {
|
|
127
|
-
state.counts.
|
|
140
|
+
state.counts.set(count, counts[count]);
|
|
128
141
|
});
|
|
129
142
|
|
|
130
143
|
return;
|
|
@@ -149,7 +162,7 @@ export function mergeSelection(state: SelectionState, { select, include, ...quer
|
|
|
149
162
|
|
|
150
163
|
export function selectionToQuery(state: SelectionState): SelectionMap {
|
|
151
164
|
const nestedIncludes: Record<string, SelectionMap | boolean> = {};
|
|
152
|
-
const counts: Record<string,
|
|
165
|
+
const counts: Record<string, unknown> = {};
|
|
153
166
|
|
|
154
167
|
let hasSelection = false;
|
|
155
168
|
|
|
@@ -161,12 +174,12 @@ export function selectionToQuery(state: SelectionState): SelectionMap {
|
|
|
161
174
|
|
|
162
175
|
if (state.counts.size > 0) {
|
|
163
176
|
hasSelection = true;
|
|
164
|
-
for (const count of state.counts) {
|
|
165
|
-
counts[count] =
|
|
177
|
+
for (const [count, selection] of state.counts) {
|
|
178
|
+
counts[count] = selection;
|
|
166
179
|
}
|
|
167
180
|
|
|
168
181
|
nestedIncludes._count = {
|
|
169
|
-
select: counts,
|
|
182
|
+
select: counts as {},
|
|
170
183
|
};
|
|
171
184
|
}
|
|
172
185
|
|