|
5 | 5 | DefinitionNode, |
6 | 6 | Kind, |
7 | 7 | SelectionNode, |
8 | | - NamedTypeNode, |
9 | 8 | } from 'graphql'; |
10 | 9 | import { FieldWeight, TypeWeightObject, Variables } from '../@types/buildTypeWeights'; |
11 | 10 | /** |
@@ -160,13 +159,30 @@ class ASTParser { |
160 | 159 |
|
161 | 160 | selectionSetNode(node: SelectionSetNode, parentName: string): number { |
162 | 161 | let complexity = 0; |
| 162 | + let maxFragmentComplexity = 0; |
163 | 163 | // iterate shrough the 'selections' array on the seletion set node |
164 | 164 | for (let i = 0; i < node.selections.length; i += 1) { |
165 | 165 | // call the function to handle seletion nodes |
166 | 166 | // pass the current parent through because selection sets act only as intermediaries |
167 | | - complexity += this.selectionNode(node.selections[i], parentName); |
| 167 | + const selectionNode = node.selections[i]; |
| 168 | + const selectionCost = this.selectionNode(node.selections[i], parentName); |
| 169 | + |
| 170 | + // we need to get the largest possible complexity so we save the largest inline fragment |
| 171 | + // FIXME: Consider the case where 2 typed fragments are applicable |
| 172 | + // e.g. ...UnionType and ...PartofTheUnion |
| 173 | + // this case these complexities should be summed in order to be accurate |
| 174 | + // However an estimation suffice |
| 175 | + if (selectionNode.kind === Kind.INLINE_FRAGMENT) { |
| 176 | + if (!selectionNode.typeCondition) { |
| 177 | + // complexity is always applicable |
| 178 | + complexity += selectionCost; |
| 179 | + } else if (selectionCost > maxFragmentComplexity) |
| 180 | + maxFragmentComplexity = selectionCost; |
| 181 | + } else { |
| 182 | + complexity += selectionCost; |
| 183 | + } |
168 | 184 | } |
169 | | - return complexity; |
| 185 | + return complexity + maxFragmentComplexity; |
170 | 186 | } |
171 | 187 |
|
172 | 188 | definitionNode(node: DefinitionNode): number { |
|
0 commit comments