Skip to content

Commit 92a0a6a

Browse files
committed
refactored the type complexity analysis to use several functions, each handling the nuance of a different AST node.
1 parent cb183c0 commit 92a0a6a

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

src/@types/buildTypeWeights.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
interface Fields {
2-
readonly [index: string]: number | ((arg: number, type: Type) => number);
2+
readonly [index: string]: number | ((arg: { [index: string]: any }) => number);
33
}
44

55
interface Type {

src/analysis/ASTnodefunctions.ts

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,70 @@
1+
/* eslint-disable @typescript-eslint/no-use-before-define */
12
import {
23
DocumentNode,
34
FieldNode,
45
SelectionSetNode,
56
DefinitionNode,
67
Kind,
78
SelectionNode,
9+
ArgumentNode,
810
} from 'graphql';
911

12+
// const getArgObj = (args: ArgumentNode[]): { [index: string]: any } => {
13+
// const argObj: { [index: string]: any } = {};
14+
// for (let i = 0; i < args.length; i + 1) {
15+
// if (args[i].kind === Kind.BOOLEAN) {
16+
// argObj[args[i].name.value] = args[i].value.value;
17+
// }
18+
// }
19+
// return argObj;
20+
// };
21+
1022
export function fieldNode(
1123
node: FieldNode,
1224
typeWeights: TypeWeightObject,
1325
variables: any | undefined,
14-
parent: FieldNode | DefinitionNode
26+
parentName: string
1527
): number {
16-
const complexity = 0;
28+
let complexity = 0;
29+
// check if the field name is in the type weight object.
30+
if (node.name.value.toLocaleLowerCase() in typeWeights) {
31+
// if it is, than the field is an object type, add itss type weight to the total
32+
complexity += typeWeights[node.name.value].weight;
33+
// call the function to handle selection set node with selectionSet property if it is not undefined
34+
if (node.selectionSet)
35+
complexity *= selectionSetNode(
36+
node.selectionSet,
37+
typeWeights,
38+
variables,
39+
node.name.value
40+
);
41+
} else {
42+
// otherwise the field is a scalar or a list.
43+
const fieldWeight = typeWeights[parentName].fields[node.name.value];
44+
if (typeof fieldWeight === 'number') {
45+
// if the feild weight is a number, add the number to the total complexity
46+
complexity += fieldWeight;
47+
} else {
48+
// otherwise the the feild weight is a list, invoke the function with variables
49+
// TODO: calculate the complexity for lists with arguments and varibales
50+
// iterate through the arguments to build the object to
51+
// complexity += fieldWeight(getArgObj(node.arguments));
52+
}
53+
}
1754
return complexity;
1855
}
1956

2057
export function selectionNode(
2158
node: SelectionNode,
2259
typeWeights: TypeWeightObject,
2360
variables: any | undefined,
24-
parent: DefinitionNode | FieldNode
61+
parentName: string
2562
): number {
2663
let complexity = 0;
2764
// check the kind property against the set of selection nodes that are possible
2865
if (node.kind === Kind.FIELD) {
29-
// call the function that handle field nodes and multiply the result into complexity to accound for nested fields
30-
complexity *= fieldNode(node, typeWeights, variables, parent);
66+
// call the function that handle field nodes
67+
complexity += fieldNode(node, typeWeights, variables, parentName);
3168
}
3269
// TODO: add checks for Kind.FRAGMENT_SPREAD and Kind.INLINE_FRAGMENT here
3370
return complexity;
@@ -37,14 +74,14 @@ export function selectionSetNode(
3774
node: SelectionSetNode,
3875
typeWeights: TypeWeightObject,
3976
variables: any | undefined,
40-
parent: DefinitionNode | FieldNode
77+
parentName: string
4178
): number {
4279
let complexity = 0;
4380
// iterate shrough the 'selections' array on the seletion set node
4481
for (let i = 0; i < node.selections.length; i + 1) {
4582
// call the function to handle seletion nodes
4683
// pass the current parent through because selection sets act only as intermediaries
47-
complexity += selectionNode(node.selections[i], typeWeights, variables, parent);
84+
complexity += selectionNode(node.selections[i], typeWeights, variables, parentName);
4885
}
4986
return complexity;
5087
}
@@ -63,7 +100,12 @@ export function definitionNode(
63100
complexity += typeWeights[node.operation].weight;
64101
// call the function to handle selection set node with selectionSet property if it is not undefined
65102
if (node.selectionSet)
66-
complexity += selectionSetNode(node.selectionSet, typeWeights, variables, node);
103+
complexity += selectionSetNode(
104+
node.selectionSet,
105+
typeWeights,
106+
variables,
107+
node.operation
108+
);
67109
}
68110
}
69111
// TODO: add checks for Kind.FRAGMENT_DEFINITION here (there are other type definition nodes that i think we can ignore. see ast.d.ts in 'graphql')

src/analysis/typeComplexityAnalysis.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
* @param {any | undefined} varibales
1717
* @param {TypeWeightObject} typeWeights
1818
*/
19-
// TODO add queryVaribables parameter
2019
function getQueryTypeComplexity(
2120
queryAST: DocumentNode,
2221
variables: any | undefined,

0 commit comments

Comments
 (0)