44
55import {
66 getArgumentValues ,
7+ getDirectiveValues ,
78} from 'graphql/execution/values' ;
89
910import {
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' ;
2124import {
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