Skip to content

Commit 0d340b2

Browse files
authored
Add support default values for query variables, fixes #50 (#52)
1 parent 8e19e3f commit 0d340b2

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

src/QueryComplexity.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import {
88
getArgumentValues,
99
getDirectiveValues,
10+
getVariableValues,
1011
} from 'graphql/execution/values';
1112

1213
import {
@@ -121,6 +122,7 @@ export default class QueryComplexity {
121122
estimators: Array<ComplexityEstimator>;
122123
includeDirectiveDef: GraphQLDirective;
123124
skipDirectiveDef: GraphQLDirective;
125+
variableValues: Record<string, any>;
124126

125127
constructor(context: ValidationContext, options: QueryComplexityOptions) {
126128
if (
@@ -139,6 +141,7 @@ export default class QueryComplexity {
139141
this.includeDirectiveDef = this.context.getSchema().getDirective('include');
140142
this.skipDirectiveDef = this.context.getSchema().getDirective('skip');
141143
this.estimators = options.estimators;
144+
this.variableValues = {};
142145

143146
this.OperationDefinition = {
144147
enter: this.onOperationDefinitionEnter,
@@ -154,6 +157,14 @@ export default class QueryComplexity {
154157
return;
155158
}
156159

160+
// Get variable values from variables that are passed from options, merged
161+
// with default values defined in the operation
162+
this.variableValues = getVariableValues(
163+
this.context.getSchema(),
164+
operation.variableDefinitions ?? [],
165+
this.options.variables ?? {}
166+
).coerced;
167+
157168
switch (operation.operation) {
158169
case 'query':
159170
this.complexity += this.nodeComplexity(
@@ -246,7 +257,7 @@ export default class QueryComplexity {
246257
const values = getDirectiveValues(
247258
this.includeDirectiveDef,
248259
childNode,
249-
this.options.variables || {}
260+
this.variableValues || {}
250261
);
251262
includeNode = values.if;
252263
break;
@@ -255,7 +266,7 @@ export default class QueryComplexity {
255266
const values = getDirectiveValues(
256267
this.skipDirectiveDef,
257268
childNode,
258-
this.options.variables || {}
269+
this.variableValues || {}
259270
);
260271
skipNode = values.if;
261272
break;
@@ -282,7 +293,7 @@ export default class QueryComplexity {
282293
args = getArgumentValues(
283294
field,
284295
childNode,
285-
this.options.variables || {}
296+
this.variableValues || {}
286297
);
287298
} catch (e) {
288299
return this.context.reportError(e);

src/__tests__/QueryComplexity-test.ts

+34
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ describe('QueryComplexity analysis', () => {
3737
expect(complexity).to.equal(1);
3838
});
3939

40+
it('should respect @include(if: false) via default variable value', () => {
41+
const ast = parse(`
42+
query Foo ($shouldSkip: Boolean = false) {
43+
variableScalar(count: 10) @include(if: $shouldSkip)
44+
}
45+
`);
46+
47+
const complexity = getComplexity({
48+
estimators: [simpleEstimator({ defaultComplexity: 1 })],
49+
schema,
50+
query: ast,
51+
});
52+
expect(complexity).to.equal(0);
53+
});
54+
4055
it('should respect @include(if: false)', () => {
4156
const ast = parse(`
4257
query {
@@ -133,6 +148,25 @@ describe('QueryComplexity analysis', () => {
133148
expect(complexity).to.equal(50);
134149
});
135150

151+
it('should calculate complexity with variables and default value', () => {
152+
const ast = parse(`
153+
query Q($count: Int = 5) {
154+
variableScalar(count: $count)
155+
}
156+
`);
157+
158+
const complexity = getComplexity({
159+
estimators: [
160+
fieldExtensionsEstimator(),
161+
simpleEstimator({ defaultComplexity: 1 }),
162+
],
163+
schema,
164+
query: ast,
165+
variables: {},
166+
});
167+
expect(complexity).to.equal(50);
168+
});
169+
136170
it('should not allow negative cost', () => {
137171
const ast = parse(`
138172
query {

0 commit comments

Comments
 (0)