Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
25a28b0
removed unessesary arguments from parseTypes
evanmcneely Jun 30, 2022
c2e8a64
updated function name pareOuery to parseQueryType
evanmcneely Jun 30, 2022
8978a69
added functionality to calculate complexity of lists with variables
evanmcneely Jun 30, 2022
341e2ae
added functionality to appropiatly multiply nested lists
evanmcneely Jun 30, 2022
a2ba5ef
testing new functionality. waiting for updated tests
evanmcneely Jun 30, 2022
e18da20
merged changes from sh/test-suite-updates and fixed confilcts
evanmcneely Jun 30, 2022
f7cd3e2
refactored the complexity analysis to handle nesting properly. Not pa…
evanmcneely Jul 2, 2022
d036acb
Merge branch 'dev' of https://github.com/oslabs-beta/GraphQL-Gate int…
evanmcneely Jul 3, 2022
cb0bc66
test with one level of nesting is passing
evanmcneely Jul 3, 2022
34d834d
activated all the tests that need to pass
evanmcneely Jul 3, 2022
266ccea
updated the way nested queries are adding or subtracting values to pa…
evanmcneely Jul 3, 2022
31bcb99
started to refactor type weights object
evanmcneely Jul 4, 2022
cd7f6c2
refactored typeWeightObject tests to have refernces to their types
evanmcneely Jul 4, 2022
69d1cc6
making progress on the refactoring of buildTypeWeights. a few more ty…
evanmcneely Jul 4, 2022
a5e51c3
got all the tests working and refactoring the code to be more dry
evanmcneely Jul 4, 2022
551f2ae
refactored the typeWeightsObject to include reference to the resolved…
evanmcneely Jul 4, 2022
2e451f9
refactored complexity tests to work with new typeWeightsObject and pa…
evanmcneely Jul 4, 2022
956a7c3
refactored the typeComplexity field node function to be more readable
evanmcneely Jul 4, 2022
908941b
refactored buildTypeWeights parseObjectFields to be mroe readable
evanmcneely Jul 4, 2022
de07e93
refactored lists returning scalar values to only compound if the scal…
evanmcneely Jul 4, 2022
69e31f5
added a few more comments to buildTypeWeights
evanmcneely Jul 4, 2022
367a05f
Refactored the weightFunction calculating list weight to take in the …
evanmcneely Jul 6, 2022
31c1144
small edits after reviewing typeComplexity tests
evanmcneely Jul 6, 2022
66783a7
small edits after reviewing buildTypeWeights tests
evanmcneely Jul 6, 2022
742687f
weightFunction woring with default arguments in the schema
evanmcneely Jul 6, 2022
25e4cde
added one comment to the weightFunction
evanmcneely Jul 6, 2022
a68cfc5
adde a switch block to the parseObject fields function to initialize …
evanmcneely Jul 7, 2022
7610b56
changed the check for scalar lists to use isScalarType and confirmed …
evanmcneely Jul 7, 2022
88cbef8
removed the parseQueryType function and letting parseTypes do that work
evanmcneely Jul 7, 2022
2b34b36
made some notes about what types/edge-cases could be falling through …
evanmcneely Jul 7, 2022
83f4cee
callapsed a query in test suite
evanmcneely Jul 7, 2022
1bf84eb
expanded the tests to include edgecases for custom object and scalar …
evanmcneely Jul 7, 2022
572948e
set the name of the node to lowercase when assigning it to argument p…
evanmcneely Jul 8, 2022
4c36575
Revert "set the name of the node to lowercase when assigning it to ar…
evanmcneely Jul 8, 2022
4602833
discovered bug that calculated query complxity wrong when object weig…
evanmcneely Jul 8, 2022
e984e15
Merge branch 'dev' into em/lists-variables-nesting-refactoring
evanmcneely Jul 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [{
"configurations": [

{
"type": "node",
"request": "launch",
"name": "Jest Tests",
Expand Down
16 changes: 13 additions & 3 deletions src/@types/buildTypeWeights.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export interface Field {
resolveTo?: string;
weight?: FieldWeight;
}
export interface Fields {
[index: string]: FieldWeight;
[index: string]: Field;
}
export type WeightFunction = (args: ArgumentNode[]) => number;
export type WeightFunction = (args: ArgumentNode[], variables, selectionsCost: number) => number;
export type FieldWeight = number | WeightFunction;
export interface Type {
readonly weight: number;
Expand All @@ -17,7 +21,13 @@ export interface TypeWeightConfig {
scalar?: number;
connection?: number;
}

export interface TypeWeightSet {
mutation: number;
query: number;
object: number;
scalar: number;
connection: number;
}
type Variables = {
[index: string]: readonly unknown;
};
69 changes: 29 additions & 40 deletions src/analysis/ASTnodefunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,9 @@ import {
DefinitionNode,
Kind,
SelectionNode,
ArgumentNode,
isConstValueNode,
} from 'graphql';
import { FieldWeight, TypeWeightObject, Variables } from '../@types/buildTypeWeights';

// TODO: handle variables and arguments
// ! this is not functional
const getArgObj = (args: ArgumentNode[]): { [index: string]: any } => {
const argObj: { [index: string]: any } = {};
for (let i = 0; i < args.length; i + 1) {
const node = args[i];
if (args[i].value.kind !== Kind.VARIABLE) {
if (args[i].value.kind === Kind.INT) {
// FIXME: this does not work
argObj[args[i].name.value] = args[i].value;
}
}
}
return argObj;
};
/**
* The AST node functions call each other following the nested structure below
* Each function handles a specific GraphQL AST node type
Expand Down Expand Up @@ -52,34 +36,39 @@ export function fieldNode(
parentName: string
): number {
let complexity = 0;
// console.log('fieldNode', node, parentName);
// check if the field name is in the type weight object.
if (node.name.value.toLocaleLowerCase() in typeWeights) {
// if it is, than the field is an object type, add itss type weight to the total
complexity += typeWeights[node.name.value].weight;
// 'resolvedTypeName' is the name of the Schema Type that this field resolves to
const resolvedTypeName =
node.name.value in typeWeights
? node.name.value
: typeWeights[parentName].fields[node.name.value]?.resolveTo || null;

if (resolvedTypeName) {
// field resolves to an object or a list with possible selections
let selectionsCost = 0;
let calculatedWeight = 0;
const weightFunction = typeWeights[parentName]?.fields[node.name.value]?.weight;

// call the function to handle selection set node with selectionSet property if it is not undefined
if (node.selectionSet) {
complexity += selectionSetNode(
selectionsCost += selectionSetNode(
node.selectionSet,
typeWeights,
variables,
node.name.value
resolvedTypeName
);
}
// if there are arguments and this is a list, call the 'weightFunction' to get the weight of this field. otherwise the weight is static and can be accessed through the typeWeights object
if (node.arguments && typeof weightFunction === 'function') {
calculatedWeight += weightFunction([...node.arguments], variables, selectionsCost);
} else {
calculatedWeight += typeWeights[resolvedTypeName].weight + selectionsCost;
}
complexity += calculatedWeight;
} else {
// otherwise the field is a scalar or a list.
const fieldWeight: FieldWeight = typeWeights[parentName].fields[node.name.value];
if (typeof fieldWeight === 'number') {
// if the feild weight is a number, add the number to the total complexity
complexity += fieldWeight;
} else if (node.arguments) {
// BUG: This code is reached when fieldWeight is undefined, which could result from an invalid query or this type
// missing from the typeWeight object. If left unhandled an error is thrown
// otherwise the the feild weight is a list, invoke the function with variables
// TODO: calculate the complexity for lists with arguments and varibales
// ! this is not functional
// iterate through the arguments to build the object to
complexity += fieldWeight([...node.arguments]);
// field is a scalar and 'weight' is a number
const { weight } = typeWeights[parentName].fields[node.name.value];
if (typeof weight === 'number') {
complexity += weight;
}
}
return complexity;
Expand All @@ -92,7 +81,6 @@ export function selectionNode(
parentName: string
): number {
let complexity = 0;
// console.log('selectionNode', node, parentName);
// check the kind property against the set of selection nodes that are possible
if (node.kind === Kind.FIELD) {
// call the function that handle field nodes
Expand All @@ -101,7 +89,6 @@ export function selectionNode(
// TODO: add checks for Kind.FRAGMENT_SPREAD and Kind.INLINE_FRAGMENT here
return complexity;
}

export function selectionSetNode(
node: SelectionSetNode,
typeWeights: TypeWeightObject,
Expand Down Expand Up @@ -130,14 +117,16 @@ export function definitionNode(
if (node.operation.toLocaleLowerCase() in typeWeights) {
// if it is, it is an object type, add it's type weight to the total
complexity += typeWeights[node.operation].weight;
// console.log(`the weight of ${node.operation} is ${complexity}`);
// call the function to handle selection set node with selectionSet property if it is not undefined
if (node.selectionSet)
if (node.selectionSet) {
complexity += selectionSetNode(
node.selectionSet,
typeWeights,
variables,
node.operation
);
}
}
}
// 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')
Expand Down
Loading