Skip to content

Commit 9787510

Browse files
committed
support @include/@Skip directives
1 parent 47c4e49 commit 9787510

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

src/QueryComplexity.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44

55
import {
66
getArgumentValues,
7+
getDirectiveValues,
78
} from 'graphql/execution/values';
89

910
import {
1011
ValidationContext,
1112
FragmentDefinitionNode,
1213
OperationDefinitionNode,
14+
DirectiveNode,
1315
FieldNode,
1416
FragmentSpreadNode,
1517
InlineFragmentNode,
1618
assertCompositeType,
1719
GraphQLField, isCompositeType, GraphQLCompositeType, GraphQLFieldMap,
1820
GraphQLSchema, DocumentNode, TypeInfo,
19-
visit, visitWithTypeInfo
21+
visit, visitWithTypeInfo,
22+
GraphQLDirective,
2023
} from 'graphql';
2124
import {
2225
GraphQLUnionType,
@@ -102,6 +105,8 @@ export default class QueryComplexity {
102105
options: QueryComplexityOptions;
103106
OperationDefinition: Object;
104107
estimators: Array<ComplexityEstimator>;
108+
includeDirectiveDef: GraphQLDirective;
109+
skipDirectiveDef: GraphQLDirective;
105110

106111
constructor(
107112
context: ValidationContext,
@@ -115,6 +120,9 @@ export default class QueryComplexity {
115120
this.complexity = 0;
116121
this.options = options;
117122

123+
this.includeDirectiveDef = this.context.getSchema().getDirective('include');
124+
this.skipDirectiveDef = this.context.getSchema().getDirective('skip');
125+
118126
if (!options.estimators) {
119127
console.warn(
120128
'DEPRECATION WARNING: Estimators should be configured in the queryComplexity options.'
@@ -183,6 +191,29 @@ export default class QueryComplexity {
183191
(total: number, childNode: FieldNode | FragmentSpreadNode | InlineFragmentNode) => {
184192
let nodeComplexity = 0;
185193

194+
let includeNode = true;
195+
let skipNode = false;
196+
197+
childNode.directives.forEach((directive: DirectiveNode) => {
198+
const directiveName = directive.name.value;
199+
switch (directiveName) {
200+
case 'include': {
201+
const values = getDirectiveValues(this.includeDirectiveDef, childNode, this.options.variables || {});
202+
includeNode = values.if;
203+
break;
204+
}
205+
case 'skip': {
206+
const values = getDirectiveValues(this.skipDirectiveDef, childNode, this.options.variables || {});
207+
skipNode = values.if;
208+
break;
209+
}
210+
}
211+
});
212+
213+
if (!includeNode || skipNode) {
214+
return total;
215+
}
216+
186217
switch (childNode.kind) {
187218
case Kind.FIELD: {
188219
const field = fields[childNode.name.value];

0 commit comments

Comments
 (0)