1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable @typescript-eslint/no-use-before-define */
1
3
/**
2
4
* Created by Ivo Meißner on 28.07.17.
3
5
*/
@@ -11,11 +13,9 @@ import {
11
13
ValidationContext ,
12
14
FragmentDefinitionNode ,
13
15
OperationDefinitionNode ,
14
- DirectiveNode ,
15
16
FieldNode ,
16
17
FragmentSpreadNode ,
17
18
InlineFragmentNode ,
18
- assertCompositeType ,
19
19
GraphQLField , isCompositeType , GraphQLCompositeType , GraphQLFieldMap ,
20
20
GraphQLSchema , DocumentNode , TypeInfo ,
21
21
visit , visitWithTypeInfo ,
@@ -31,11 +31,11 @@ import {
31
31
} from 'graphql' ;
32
32
33
33
export type ComplexityEstimatorArgs = {
34
- type : GraphQLCompositeType ,
35
- field : GraphQLField < any , any > ,
36
- node : FieldNode ,
37
- args : { [ key : string ] : any } ,
38
- childComplexity : number
34
+ type : GraphQLCompositeType ;
35
+ field : GraphQLField < any , any > ;
36
+ node : FieldNode ;
37
+ args : { [ key : string ] : any } ;
38
+ childComplexity : number ;
39
39
}
40
40
41
41
export type ComplexityEstimator = ( options : ComplexityEstimatorArgs ) => number | void ;
@@ -45,27 +45,27 @@ export type Complexity = any;
45
45
46
46
// Map of complexities for possible types (of Union, Interface types)
47
47
type ComplexityMap = {
48
- [ typeName : string ] : number ,
48
+ [ typeName : string ] : number ;
49
49
}
50
50
51
51
export interface QueryComplexityOptions {
52
52
// The maximum allowed query complexity, queries above this threshold will be rejected
53
- maximumComplexity : number ,
53
+ maximumComplexity : number ;
54
54
55
55
// The query variables. This is needed because the variables are not available
56
56
// in the visitor of the graphql-js library
57
- variables ?: Object ,
57
+ variables ?: Record < string , any > ;
58
58
59
59
// specify operation name only when pass multi-operation documents
60
- operationName ?: string ,
60
+ operationName ?: string ;
61
61
62
62
// Optional callback function to retrieve the determined query complexity
63
63
// Will be invoked whether the query is rejected or not
64
64
// This can be used for logging or to implement rate limiting
65
- onComplete ?: ( complexity : number ) => void ,
65
+ onComplete ?: ( complexity : number ) => void ;
66
66
67
67
// Optional function to create a custom error
68
- createError ?: ( max : number , actual : number ) => GraphQLError ,
68
+ createError ?: ( max : number , actual : number ) => GraphQLError ;
69
69
70
70
// An array of complexity estimators to use for estimating the complexity
71
71
estimators : Array < ComplexityEstimator > ;
@@ -79,11 +79,11 @@ function queryComplexityMessage(max: number, actual: number): string {
79
79
}
80
80
81
81
export function getComplexity ( options : {
82
- estimators : ComplexityEstimator [ ] ,
83
- schema : GraphQLSchema ,
84
- query : DocumentNode ,
85
- variables ?: Object ,
86
- operationName ?: string
82
+ estimators : ComplexityEstimator [ ] ;
83
+ schema : GraphQLSchema ;
84
+ query : DocumentNode ;
85
+ variables ?: Record < string , any > ;
86
+ operationName ?: string ;
87
87
} ) : number {
88
88
const typeInfo = new TypeInfo ( options . schema ) ;
89
89
@@ -104,7 +104,7 @@ export default class QueryComplexity {
104
104
context : ValidationContext ;
105
105
complexity : number ;
106
106
options : QueryComplexityOptions ;
107
- OperationDefinition : Object ;
107
+ OperationDefinition : Record < string , any > ;
108
108
estimators : Array < ComplexityEstimator > ;
109
109
includeDirectiveDef : GraphQLDirective ;
110
110
skipDirectiveDef : GraphQLDirective ;
@@ -123,15 +123,15 @@ export default class QueryComplexity {
123
123
124
124
this . includeDirectiveDef = this . context . getSchema ( ) . getDirective ( 'include' ) ;
125
125
this . skipDirectiveDef = this . context . getSchema ( ) . getDirective ( 'skip' ) ;
126
- this . estimators = options . estimators
126
+ this . estimators = options . estimators ;
127
127
128
128
this . OperationDefinition = {
129
129
enter : this . onOperationDefinitionEnter ,
130
130
leave : this . onOperationDefinitionLeave
131
131
} ;
132
132
}
133
133
134
- onOperationDefinitionEnter ( operation : OperationDefinitionNode ) {
134
+ onOperationDefinitionEnter ( operation : OperationDefinitionNode ) : void {
135
135
if ( typeof this . options . operationName === 'string' && this . options . operationName !== operation . name . value ) {
136
136
return ;
137
137
}
@@ -181,7 +181,7 @@ export default class QueryComplexity {
181
181
typeDef : GraphQLObjectType | GraphQLInterfaceType | GraphQLUnionType ,
182
182
) : number {
183
183
if ( node . selectionSet ) {
184
- let fields :GraphQLFieldMap < any , any > = { } ;
184
+ let fields : GraphQLFieldMap < any , any > = { } ;
185
185
if ( typeDef instanceof GraphQLObjectType || typeDef instanceof GraphQLInterfaceType ) {
186
186
fields = typeDef . getFields ( ) ;
187
187
}
@@ -191,18 +191,19 @@ export default class QueryComplexity {
191
191
if ( isAbstractType ( typeDef ) ) {
192
192
possibleTypeNames = this . context . getSchema ( ) . getPossibleTypes ( typeDef ) . map ( t => t . name ) ;
193
193
} else {
194
- possibleTypeNames = [ typeDef . name ] ;
194
+ possibleTypeNames = [ typeDef . name ] ;
195
195
}
196
196
197
197
// Collect complexities for all possible types individually
198
198
const selectionSetComplexities : ComplexityMap = node . selectionSet . selections . reduce (
199
199
( complexities : ComplexityMap , childNode : FieldNode | FragmentSpreadNode | InlineFragmentNode ) => {
200
200
// let nodeComplexity = 0;
201
+ let innerComplexities = complexities ;
201
202
202
203
let includeNode = true ;
203
204
let skipNode = false ;
204
205
205
- childNode . directives ?. forEach ( ( directive : DirectiveNode ) => {
206
+ for ( const directive of childNode . directives ?? [ ] ) {
206
207
const directiveName = directive . name . value ;
207
208
switch ( directiveName ) {
208
209
case 'include' : {
@@ -216,7 +217,7 @@ export default class QueryComplexity {
216
217
break ;
217
218
}
218
219
}
219
- } ) ;
220
+ }
220
221
221
222
if ( ! includeNode || skipNode ) {
222
223
return complexities ;
@@ -258,7 +259,7 @@ export default class QueryComplexity {
258
259
const tmpComplexity = estimator ( estimatorArgs ) ;
259
260
260
261
if ( typeof tmpComplexity === 'number' && ! isNaN ( tmpComplexity ) ) {
261
- complexities = addComplexities (
262
+ innerComplexities = addComplexities (
262
263
tmpComplexity ,
263
264
complexities ,
264
265
possibleTypeNames ,
@@ -292,17 +293,17 @@ export default class QueryComplexity {
292
293
const nodeComplexity = this . nodeComplexity ( fragment , fragmentType ) ;
293
294
if ( isAbstractType ( fragmentType ) ) {
294
295
// Add fragment complexity for all possible types
295
- complexities = addComplexities (
296
+ innerComplexities = addComplexities (
296
297
nodeComplexity ,
297
298
complexities ,
298
299
this . context . getSchema ( ) . getPossibleTypes ( fragmentType ) . map ( t => t . name ) ,
299
300
) ;
300
301
} else {
301
302
// Add complexity for object type
302
- complexities = addComplexities (
303
+ innerComplexities = addComplexities (
303
304
nodeComplexity ,
304
305
complexities ,
305
- [ fragmentType . name ] ,
306
+ [ fragmentType . name ] ,
306
307
) ;
307
308
}
308
309
break ;
@@ -319,23 +320,23 @@ export default class QueryComplexity {
319
320
const nodeComplexity = this . nodeComplexity ( childNode , inlineFragmentType ) ;
320
321
if ( isAbstractType ( inlineFragmentType ) ) {
321
322
// Add fragment complexity for all possible types
322
- complexities = addComplexities (
323
+ innerComplexities = addComplexities (
323
324
nodeComplexity ,
324
325
complexities ,
325
326
this . context . getSchema ( ) . getPossibleTypes ( inlineFragmentType ) . map ( t => t . name ) ,
326
327
) ;
327
328
} else {
328
329
// Add complexity for object type
329
- complexities = addComplexities (
330
+ innerComplexities = addComplexities (
330
331
nodeComplexity ,
331
332
complexities ,
332
- [ inlineFragmentType . name ] ,
333
+ [ inlineFragmentType . name ] ,
333
334
) ;
334
335
}
335
336
break ;
336
337
}
337
338
default : {
338
- complexities = addComplexities (
339
+ innerComplexities = addComplexities (
339
340
this . nodeComplexity ( childNode , typeDef ) ,
340
341
complexities ,
341
342
possibleTypeNames ,
@@ -344,7 +345,7 @@ export default class QueryComplexity {
344
345
}
345
346
}
346
347
347
- return complexities ;
348
+ return innerComplexities ;
348
349
} , { } ) ;
349
350
// Only return max complexity of all possible types
350
351
if ( ! selectionSetComplexities ) {
@@ -381,8 +382,8 @@ function addComplexities(
381
382
possibleTypes : string [ ] ,
382
383
) : ComplexityMap {
383
384
for ( const type of possibleTypes ) {
384
- if ( complexityMap . hasOwnProperty ( type ) ) {
385
- complexityMap [ type ] = complexityMap [ type ] + complexity ;
385
+ if ( Object . prototype . hasOwnProperty . call ( complexityMap , type ) ) {
386
+ complexityMap [ type ] += complexity ;
386
387
} else {
387
388
complexityMap [ type ] = complexity ;
388
389
}
0 commit comments