@k0lyan/nestjs-prisma-graphql-generator 0.5.0 → 0.5.2
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/README.md +5 -0
- package/dist/cli/options-parser.d.ts +6 -0
- package/dist/cli/options-parser.d.ts.map +1 -1
- package/dist/cli/options-parser.js +4 -0
- package/dist/cli/options-parser.js.map +1 -1
- package/dist/generator/generate-grouped-fast.js +25 -7
- package/dist/generator/generate-grouped-fast.js.map +1 -1
- package/dist/generator/helpers-generator.js +91 -204
- package/dist/generator/helpers-generator.js.map +1 -1
- package/dist/generator/templates/enum.js +28 -14
- package/dist/generator/templates/enum.js.map +1 -1
- package/dist/generator/templates/resolver.js +15 -6
- package/dist/generator/templates/resolver.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/runtime/helpers.d.ts +42 -68
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +93 -201
- package/dist/runtime/helpers.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* These helpers are used at runtime to transform GraphQL queries
|
|
5
5
|
* into optimized Prisma select/include objects.
|
|
6
6
|
*/
|
|
7
|
-
import { ResolveTree } from 'graphql-parse-resolve-info';
|
|
8
7
|
import type { GraphQLResolveInfo } from 'graphql';
|
|
9
8
|
/**
|
|
10
9
|
* Prisma select/include object type
|
|
@@ -14,7 +13,28 @@ export interface PrismaSelect {
|
|
|
14
13
|
include?: Record<string, boolean | PrismaSelect>;
|
|
15
14
|
}
|
|
16
15
|
/**
|
|
17
|
-
*
|
|
16
|
+
* Prisma aggregate arguments type
|
|
17
|
+
*
|
|
18
|
+
* For aggregate operations, Prisma expects _count, _avg, etc. at the top level,
|
|
19
|
+
* NOT wrapped in a select object.
|
|
20
|
+
*/
|
|
21
|
+
export interface PrismaAggregateArgs {
|
|
22
|
+
_count?: boolean | Record<string, boolean>;
|
|
23
|
+
_avg?: Record<string, boolean>;
|
|
24
|
+
_sum?: Record<string, boolean>;
|
|
25
|
+
_min?: Record<string, boolean>;
|
|
26
|
+
_max?: Record<string, boolean>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Context type that should contain the Prisma client.
|
|
30
|
+
* Extend this interface in your app to add custom properties.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // In your app
|
|
34
|
+
* interface AppContext extends GraphQLContext {
|
|
35
|
+
* req: Request;
|
|
36
|
+
* user?: User;
|
|
37
|
+
* }
|
|
18
38
|
*/
|
|
19
39
|
export interface GraphQLContext<PrismaClient = unknown> {
|
|
20
40
|
prisma: PrismaClient;
|
|
@@ -41,6 +61,26 @@ export interface GraphQLContext<PrismaClient = unknown> {
|
|
|
41
61
|
* ```
|
|
42
62
|
*/
|
|
43
63
|
export declare function transformInfoIntoPrismaArgs(info: GraphQLResolveInfo): PrismaSelect;
|
|
64
|
+
/**
|
|
65
|
+
* Transform GraphQL resolve info into Prisma aggregate arguments
|
|
66
|
+
*
|
|
67
|
+
* Unlike transformInfoIntoPrismaArgs, this function returns aggregate fields
|
|
68
|
+
* directly at the top level (e.g., { _count: true, _avg: { field: true } })
|
|
69
|
+
* rather than wrapped in a select object.
|
|
70
|
+
*
|
|
71
|
+
* @param info - GraphQL resolve info from the resolver
|
|
72
|
+
* @returns Prisma aggregate arguments
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* @Query(() => AggregateUser)
|
|
77
|
+
* async aggregateUser(@Info() info: GraphQLResolveInfo, @Args() args: AggregateUserArgs) {
|
|
78
|
+
* const aggregateArgs = transformInfoIntoPrismaAggregateArgs(info);
|
|
79
|
+
* return prisma.user.aggregate({ ...args, ...aggregateArgs });
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function transformInfoIntoPrismaAggregateArgs(info: GraphQLResolveInfo): PrismaAggregateArgs;
|
|
44
84
|
/**
|
|
45
85
|
* Get Prisma client from GraphQL context
|
|
46
86
|
*
|
|
@@ -58,19 +98,6 @@ export declare function transformInfoIntoPrismaArgs(info: GraphQLResolveInfo): P
|
|
|
58
98
|
* ```
|
|
59
99
|
*/
|
|
60
100
|
export declare function getPrismaFromContext<PrismaClient = unknown>(context: GraphQLContext<PrismaClient>): PrismaClient;
|
|
61
|
-
/**
|
|
62
|
-
* Transform count fields into Prisma _count select
|
|
63
|
-
*
|
|
64
|
-
* Handles the special _count field that aggregates relation counts
|
|
65
|
-
*
|
|
66
|
-
* @param fields - Parsed fields containing _count
|
|
67
|
-
* @returns Prisma _count select object
|
|
68
|
-
*/
|
|
69
|
-
export declare function transformCountFieldIntoSelectRelationsCount(fields: Record<string, ResolveTree>): {
|
|
70
|
-
_count?: {
|
|
71
|
-
select: Record<string, boolean>;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
101
|
/**
|
|
75
102
|
* Merge multiple Prisma select objects
|
|
76
103
|
*
|
|
@@ -78,57 +105,4 @@ export declare function transformCountFieldIntoSelectRelationsCount(fields: Reco
|
|
|
78
105
|
* @returns Merged PrismaSelect object
|
|
79
106
|
*/
|
|
80
107
|
export declare function mergePrismaSelects(...selects: PrismaSelect[]): PrismaSelect;
|
|
81
|
-
/**
|
|
82
|
-
* Check if a field is a relation based on Prisma schema info
|
|
83
|
-
*
|
|
84
|
-
* This is a simple heuristic - in generated code, we have full schema info
|
|
85
|
-
*
|
|
86
|
-
* @param fieldName - Name of the field
|
|
87
|
-
* @param modelFields - Map of field names to their types
|
|
88
|
-
* @returns true if the field is a relation
|
|
89
|
-
*/
|
|
90
|
-
export declare function isRelationField(fieldName: string, modelFields: Map<string, {
|
|
91
|
-
isRelation: boolean;
|
|
92
|
-
}>): boolean;
|
|
93
|
-
/**
|
|
94
|
-
* Apply pagination to Prisma args
|
|
95
|
-
*
|
|
96
|
-
* @param args - Existing Prisma args
|
|
97
|
-
* @param pagination - Pagination options
|
|
98
|
-
* @returns Prisma args with pagination
|
|
99
|
-
*/
|
|
100
|
-
export declare function applyPagination<T extends object>(args: T, pagination?: {
|
|
101
|
-
skip?: number;
|
|
102
|
-
take?: number;
|
|
103
|
-
cursor?: any;
|
|
104
|
-
}): T;
|
|
105
|
-
/**
|
|
106
|
-
* Prisma aggregate arguments type
|
|
107
|
-
*/
|
|
108
|
-
export interface PrismaAggregateArgs {
|
|
109
|
-
_count?: boolean | Record<string, boolean>;
|
|
110
|
-
_avg?: Record<string, boolean>;
|
|
111
|
-
_sum?: Record<string, boolean>;
|
|
112
|
-
_min?: Record<string, boolean>;
|
|
113
|
-
_max?: Record<string, boolean>;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Transform GraphQL resolve info into Prisma aggregate arguments
|
|
117
|
-
*
|
|
118
|
-
* Unlike regular queries, Prisma's aggregate() expects _count, _avg, etc.
|
|
119
|
-
* directly at the top level, not wrapped in a `select` object.
|
|
120
|
-
*
|
|
121
|
-
* @param info - GraphQL resolve info from the resolver
|
|
122
|
-
* @returns Prisma aggregate arguments
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* ```typescript
|
|
126
|
-
* @Query(() => AggregateUser)
|
|
127
|
-
* async aggregateUser(@Info() info: GraphQLResolveInfo, @Args() args: AggregateUserArgs) {
|
|
128
|
-
* const aggregateArgs = transformInfoIntoPrismaAggregateArgs(info);
|
|
129
|
-
* return prisma.user.aggregate({ ...args, ...aggregateArgs });
|
|
130
|
-
* }
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
133
|
-
export declare function transformInfoIntoPrismaAggregateArgs(info: GraphQLResolveInfo): PrismaAggregateArgs;
|
|
134
108
|
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/runtime/helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/runtime/helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC;CAClD;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc,CAAC,YAAY,GAAG,OAAO;IACpD,MAAM,EAAE,YAAY,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,kBAAkB,GAAG,YAAY,CAMlF;AAsCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,kBAAkB,GACvB,mBAAmB,CAKrB;AA8CD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,GAAG,OAAO,EACzD,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,GACpC,YAAY,CASd;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,CAO3E"}
|
package/dist/runtime/helpers.js
CHANGED
|
@@ -7,18 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.transformInfoIntoPrismaArgs = transformInfoIntoPrismaArgs;
|
|
10
|
+
exports.transformInfoIntoPrismaAggregateArgs = transformInfoIntoPrismaAggregateArgs;
|
|
10
11
|
exports.getPrismaFromContext = getPrismaFromContext;
|
|
11
|
-
exports.transformCountFieldIntoSelectRelationsCount = transformCountFieldIntoSelectRelationsCount;
|
|
12
12
|
exports.mergePrismaSelects = mergePrismaSelects;
|
|
13
|
-
exports.isRelationField = isRelationField;
|
|
14
|
-
exports.applyPagination = applyPagination;
|
|
15
|
-
exports.transformInfoIntoPrismaAggregateArgs = transformInfoIntoPrismaAggregateArgs;
|
|
16
13
|
const graphql_parse_resolve_info_1 = require("graphql-parse-resolve-info");
|
|
17
|
-
/**
|
|
18
|
-
* Fields that should be excluded from selection
|
|
19
|
-
* These are GraphQL internal fields or aggregation fields
|
|
20
|
-
*/
|
|
21
|
-
const EXCLUDED_FIELDS = new Set(['__typename', '_count', '_avg', '_sum', '_min', '_max']);
|
|
22
14
|
/**
|
|
23
15
|
* Transform GraphQL resolve info into Prisma select/include arguments
|
|
24
16
|
*
|
|
@@ -41,53 +33,104 @@ const EXCLUDED_FIELDS = new Set(['__typename', '_count', '_avg', '_sum', '_min',
|
|
|
41
33
|
*/
|
|
42
34
|
function transformInfoIntoPrismaArgs(info) {
|
|
43
35
|
const parsedInfo = (0, graphql_parse_resolve_info_1.parseResolveInfo)(info);
|
|
44
|
-
if (!parsedInfo)
|
|
36
|
+
if (!parsedInfo)
|
|
45
37
|
return {};
|
|
38
|
+
const select = buildPrismaSelect(parsedInfo.fieldsByTypeName);
|
|
39
|
+
return Object.keys(select).length > 0 ? { select } : {};
|
|
40
|
+
}
|
|
41
|
+
function buildPrismaSelect(fieldsByTypeName) {
|
|
42
|
+
const result = {};
|
|
43
|
+
for (const typeName in fieldsByTypeName) {
|
|
44
|
+
const fields = fieldsByTypeName[typeName];
|
|
45
|
+
for (const fieldName in fields) {
|
|
46
|
+
if (fieldName.startsWith('__') ||
|
|
47
|
+
fieldName.startsWith('_count') ||
|
|
48
|
+
fieldName.startsWith('_avg') ||
|
|
49
|
+
fieldName.startsWith('_sum') ||
|
|
50
|
+
fieldName.startsWith('_min') ||
|
|
51
|
+
fieldName.startsWith('_max'))
|
|
52
|
+
continue;
|
|
53
|
+
const field = fields[fieldName];
|
|
54
|
+
const nestedFields = field.fieldsByTypeName;
|
|
55
|
+
if (Object.keys(nestedFields).length > 0) {
|
|
56
|
+
const nestedSelect = buildPrismaSelect(nestedFields);
|
|
57
|
+
result[fieldName] = Object.keys(nestedSelect).length > 0 ? { select: nestedSelect } : true;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
result[fieldName] = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
46
63
|
}
|
|
47
|
-
|
|
48
|
-
return buildPrismaSelect(simplifiedInfo.fields);
|
|
64
|
+
return result;
|
|
49
65
|
}
|
|
50
66
|
/**
|
|
51
|
-
*
|
|
67
|
+
* Aggregate field names that Prisma expects
|
|
68
|
+
*/
|
|
69
|
+
const AGGREGATE_FIELDS = ['_count', '_avg', '_sum', '_min', '_max'];
|
|
70
|
+
/**
|
|
71
|
+
* Transform GraphQL resolve info into Prisma aggregate arguments
|
|
52
72
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
73
|
+
* Unlike transformInfoIntoPrismaArgs, this function returns aggregate fields
|
|
74
|
+
* directly at the top level (e.g., { _count: true, _avg: { field: true } })
|
|
75
|
+
* rather than wrapped in a select object.
|
|
76
|
+
*
|
|
77
|
+
* @param info - GraphQL resolve info from the resolver
|
|
78
|
+
* @returns Prisma aggregate arguments
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* @Query(() => AggregateUser)
|
|
83
|
+
* async aggregateUser(@Info() info: GraphQLResolveInfo, @Args() args: AggregateUserArgs) {
|
|
84
|
+
* const aggregateArgs = transformInfoIntoPrismaAggregateArgs(info);
|
|
85
|
+
* return prisma.user.aggregate({ ...args, ...aggregateArgs });
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
55
88
|
*/
|
|
56
|
-
function
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
89
|
+
function transformInfoIntoPrismaAggregateArgs(info) {
|
|
90
|
+
const parsedInfo = (0, graphql_parse_resolve_info_1.parseResolveInfo)(info);
|
|
91
|
+
if (!parsedInfo)
|
|
92
|
+
return {};
|
|
93
|
+
return buildPrismaAggregateArgs(parsedInfo.fieldsByTypeName);
|
|
94
|
+
}
|
|
95
|
+
function buildPrismaAggregateArgs(fieldsByTypeName) {
|
|
96
|
+
const result = {};
|
|
97
|
+
for (const typeName in fieldsByTypeName) {
|
|
98
|
+
const fields = fieldsByTypeName[typeName];
|
|
99
|
+
for (const aggregateField of AGGREGATE_FIELDS) {
|
|
100
|
+
const fieldInfo = fields?.[aggregateField];
|
|
101
|
+
if (!fieldInfo)
|
|
102
|
+
continue;
|
|
103
|
+
const nestedFields = fieldInfo.fieldsByTypeName;
|
|
104
|
+
const nestedTypes = Object.keys(nestedFields);
|
|
105
|
+
if (nestedTypes.length === 0) {
|
|
106
|
+
if (aggregateField === '_count')
|
|
107
|
+
result._count = true;
|
|
108
|
+
continue;
|
|
72
109
|
}
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
110
|
+
const selectedFields = {};
|
|
111
|
+
for (const nestedTypeName of nestedTypes) {
|
|
112
|
+
const typeFields = nestedFields[nestedTypeName];
|
|
113
|
+
for (const nestedFieldName in typeFields) {
|
|
114
|
+
if (nestedFieldName === '_all') {
|
|
115
|
+
if (aggregateField === '_count') {
|
|
116
|
+
result._count = true;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
selectedFields[nestedFieldName] = true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
77
124
|
}
|
|
78
|
-
|
|
79
|
-
|
|
125
|
+
if (Object.keys(selectedFields).length > 0) {
|
|
126
|
+
result[aggregateField] = selectedFields;
|
|
127
|
+
}
|
|
128
|
+
else if (aggregateField === '_count') {
|
|
129
|
+
result._count = true;
|
|
80
130
|
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
// Scalar field
|
|
84
|
-
select[fieldName] = true;
|
|
85
131
|
}
|
|
86
132
|
}
|
|
87
|
-
|
|
88
|
-
return {};
|
|
89
|
-
}
|
|
90
|
-
return { select };
|
|
133
|
+
return result;
|
|
91
134
|
}
|
|
92
135
|
/**
|
|
93
136
|
* Get Prisma client from GraphQL context
|
|
@@ -113,42 +156,6 @@ function getPrismaFromContext(context) {
|
|
|
113
156
|
}
|
|
114
157
|
return prismaClient;
|
|
115
158
|
}
|
|
116
|
-
/**
|
|
117
|
-
* Transform count fields into Prisma _count select
|
|
118
|
-
*
|
|
119
|
-
* Handles the special _count field that aggregates relation counts
|
|
120
|
-
*
|
|
121
|
-
* @param fields - Parsed fields containing _count
|
|
122
|
-
* @returns Prisma _count select object
|
|
123
|
-
*/
|
|
124
|
-
function transformCountFieldIntoSelectRelationsCount(fields) {
|
|
125
|
-
const countField = fields['_count'];
|
|
126
|
-
if (!countField) {
|
|
127
|
-
return {};
|
|
128
|
-
}
|
|
129
|
-
const countNestedFields = countField.fieldsByTypeName;
|
|
130
|
-
const countTypes = Object.keys(countNestedFields);
|
|
131
|
-
if (countTypes.length === 0) {
|
|
132
|
-
return {};
|
|
133
|
-
}
|
|
134
|
-
const countSelect = {};
|
|
135
|
-
for (const typeName of countTypes) {
|
|
136
|
-
const typeFields = countNestedFields[typeName];
|
|
137
|
-
if (typeFields) {
|
|
138
|
-
for (const fieldName of Object.keys(typeFields)) {
|
|
139
|
-
countSelect[fieldName] = true;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (Object.keys(countSelect).length === 0) {
|
|
144
|
-
return {};
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
_count: {
|
|
148
|
-
select: countSelect,
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
159
|
/**
|
|
153
160
|
* Merge multiple Prisma select objects
|
|
154
161
|
*
|
|
@@ -157,126 +164,11 @@ function transformCountFieldIntoSelectRelationsCount(fields) {
|
|
|
157
164
|
*/
|
|
158
165
|
function mergePrismaSelects(...selects) {
|
|
159
166
|
const result = {};
|
|
160
|
-
for (const
|
|
161
|
-
if (
|
|
162
|
-
result.select = {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
if (select.include) {
|
|
168
|
-
result.include = {
|
|
169
|
-
...result.include,
|
|
170
|
-
...select.include,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Check if a field is a relation based on Prisma schema info
|
|
178
|
-
*
|
|
179
|
-
* This is a simple heuristic - in generated code, we have full schema info
|
|
180
|
-
*
|
|
181
|
-
* @param fieldName - Name of the field
|
|
182
|
-
* @param modelFields - Map of field names to their types
|
|
183
|
-
* @returns true if the field is a relation
|
|
184
|
-
*/
|
|
185
|
-
function isRelationField(fieldName, modelFields) {
|
|
186
|
-
const field = modelFields.get(fieldName);
|
|
187
|
-
return field?.isRelation ?? false;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Apply pagination to Prisma args
|
|
191
|
-
*
|
|
192
|
-
* @param args - Existing Prisma args
|
|
193
|
-
* @param pagination - Pagination options
|
|
194
|
-
* @returns Prisma args with pagination
|
|
195
|
-
*/
|
|
196
|
-
function applyPagination(args, pagination) {
|
|
197
|
-
if (!pagination) {
|
|
198
|
-
return args;
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
201
|
-
...args,
|
|
202
|
-
...(pagination.skip !== undefined && { skip: pagination.skip }),
|
|
203
|
-
...(pagination.take !== undefined && { take: pagination.take }),
|
|
204
|
-
...(pagination.cursor !== undefined && { cursor: pagination.cursor }),
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Transform GraphQL resolve info into Prisma aggregate arguments
|
|
209
|
-
*
|
|
210
|
-
* Unlike regular queries, Prisma's aggregate() expects _count, _avg, etc.
|
|
211
|
-
* directly at the top level, not wrapped in a `select` object.
|
|
212
|
-
*
|
|
213
|
-
* @param info - GraphQL resolve info from the resolver
|
|
214
|
-
* @returns Prisma aggregate arguments
|
|
215
|
-
*
|
|
216
|
-
* @example
|
|
217
|
-
* ```typescript
|
|
218
|
-
* @Query(() => AggregateUser)
|
|
219
|
-
* async aggregateUser(@Info() info: GraphQLResolveInfo, @Args() args: AggregateUserArgs) {
|
|
220
|
-
* const aggregateArgs = transformInfoIntoPrismaAggregateArgs(info);
|
|
221
|
-
* return prisma.user.aggregate({ ...args, ...aggregateArgs });
|
|
222
|
-
* }
|
|
223
|
-
* ```
|
|
224
|
-
*/
|
|
225
|
-
function transformInfoIntoPrismaAggregateArgs(info) {
|
|
226
|
-
const parsedInfo = (0, graphql_parse_resolve_info_1.parseResolveInfo)(info);
|
|
227
|
-
if (!parsedInfo) {
|
|
228
|
-
return {};
|
|
229
|
-
}
|
|
230
|
-
const simplifiedInfo = (0, graphql_parse_resolve_info_1.simplifyParsedResolveInfoFragmentWithType)(parsedInfo, info.returnType);
|
|
231
|
-
return buildPrismaAggregateArgs(simplifiedInfo.fields);
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Build Prisma aggregate arguments from parsed GraphQL fields
|
|
235
|
-
*
|
|
236
|
-
* @param fields - Parsed fields from graphql-parse-resolve-info
|
|
237
|
-
* @returns Prisma aggregate arguments
|
|
238
|
-
*/
|
|
239
|
-
function buildPrismaAggregateArgs(fields) {
|
|
240
|
-
const result = {};
|
|
241
|
-
for (const [fieldName, fieldInfo] of Object.entries(fields)) {
|
|
242
|
-
// Only process aggregate fields
|
|
243
|
-
if (!['_count', '_avg', '_sum', '_min', '_max'].includes(fieldName)) {
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
const nestedFields = fieldInfo.fieldsByTypeName;
|
|
247
|
-
const nestedTypes = Object.keys(nestedFields);
|
|
248
|
-
if (nestedTypes.length === 0) {
|
|
249
|
-
// No nested fields specified - select all
|
|
250
|
-
if (fieldName === '_count') {
|
|
251
|
-
result._count = true;
|
|
252
|
-
}
|
|
253
|
-
continue;
|
|
254
|
-
}
|
|
255
|
-
// Merge fields from all possible types
|
|
256
|
-
const fieldSelect = {};
|
|
257
|
-
for (const typeName of nestedTypes) {
|
|
258
|
-
const typeFields = nestedFields[typeName];
|
|
259
|
-
if (typeFields) {
|
|
260
|
-
for (const nestedFieldName of Object.keys(typeFields)) {
|
|
261
|
-
if (nestedFieldName === '_all') {
|
|
262
|
-
// Special _all field for _count
|
|
263
|
-
if (fieldName === '_count') {
|
|
264
|
-
result._count = true;
|
|
265
|
-
break;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
fieldSelect[nestedFieldName] = true;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (Object.keys(fieldSelect).length > 0) {
|
|
275
|
-
result[fieldName] = fieldSelect;
|
|
276
|
-
}
|
|
277
|
-
else if (fieldName === '_count' && result._count !== true) {
|
|
278
|
-
result._count = true;
|
|
279
|
-
}
|
|
167
|
+
for (const s of selects) {
|
|
168
|
+
if (s.select)
|
|
169
|
+
result.select = { ...(result.select ?? {}), ...s.select };
|
|
170
|
+
if (s.include)
|
|
171
|
+
result.include = { ...(result.include ?? {}), ...s.include };
|
|
280
172
|
}
|
|
281
173
|
return result;
|
|
282
174
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/runtime/helpers.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/runtime/helpers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@k0lyan/nestjs-prisma-graphql-generator",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Prisma generator for NestJS 11 GraphQL with optimized query building from GraphQL selections",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|