Skip to content

Commit d2fc8b3

Browse files
authored
Merge pull request slicknode#43 from dimatill/feature/export-complexity-directive
Export complexity directive
2 parents 50c7575 + 210f543 commit d2fc8b3

File tree

5 files changed

+72
-6
lines changed

5 files changed

+72
-6
lines changed

src/estimators/directive/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,19 @@ input Filter {
6363
```
6464

6565
The multipliers can be combined. Configured multipliers that don't have a value or `NULL` are ignored.
66+
67+
Code first approach can use the `createComplexityDirective` function to generate directive definition:
68+
69+
```typescript
70+
import {createComplexityDirective} from 'graphql-query-complexity';
71+
72+
const schema = new GraphQLSchema({
73+
directives: [
74+
createComplexityDirective({
75+
// Optionally change the name of the directive here... Default value is `complexity`
76+
name: 'complexity'
77+
})
78+
]
79+
// ... other config
80+
});
81+
```

src/estimators/directive/__tests__/directiveEstimator-test.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@
33
*/
44

55
import {
6+
GraphQLSchema,
67
parse,
8+
print,
9+
printSchema,
710
TypeInfo,
811
visit,
912
visitWithTypeInfo,
13+
buildSchema
1014
} from 'graphql';
1115

1216
import {expect} from 'chai';
1317

1418
import schema from './fixtures/schema';
1519

1620
import ComplexityVisitor from '../../../QueryComplexity';
17-
import directiveEstimator from '../index';
21+
import directiveEstimator, {createComplexityDirective} from '../index';
1822
import { CompatibleValidationContext } from '../../../__tests__/fixtures/CompatibleValidationContext';
1923

2024
describe('directiveEstimator analysis', () => {
@@ -224,7 +228,7 @@ describe('directiveEstimator analysis', () => {
224228
expect(visitor.complexity).to.equal(10);
225229
});
226230

227-
it('ignores fields without compexity directive', () => {
231+
it('ignores fields without complexity directive', () => {
228232
const ast = parse(`
229233
query {
230234
noDirective
@@ -245,4 +249,38 @@ describe('directiveEstimator analysis', () => {
245249
'No complexity could be calculated for field Query.noDirective',
246250
);
247251
});
252+
253+
it('should create complexity directive that can be used to generate directive definition', () => {
254+
const complexityDirective = createComplexityDirective();
255+
const codeFirstSchema = new GraphQLSchema({
256+
directives: [complexityDirective]
257+
});
258+
259+
// rebuilding code first schema
260+
// graphql-js <= 14 prints descriptions in different ways printSchema(schema) vs print(astNode)
261+
// and directive from code first schema has no astNode
262+
const builtCodeFirstSchema = buildSchema(printSchema(codeFirstSchema));
263+
264+
const printedSchemaFirstDirective = print(schema.getDirective('complexity').astNode);
265+
const printedCodeFirstDirective = print(builtCodeFirstSchema.getDirective('complexity').astNode);
266+
267+
expect(printedSchemaFirstDirective).to.equal(printedCodeFirstDirective);
268+
});
269+
270+
it('should create complexity directive with configured name', () => {
271+
const complexityDirective = createComplexityDirective({name: 'cost'});
272+
const codeFirstSchema = new GraphQLSchema({
273+
directives: [complexityDirective]
274+
});
275+
276+
// rebuilding code first schema
277+
// graphql-js <= 14 prints descriptions in different ways printSchema(schema) vs print(astNode)
278+
// and directive from code first schema has no astNode
279+
const builtCodeFirstSchema = buildSchema(printSchema(codeFirstSchema));
280+
281+
const printedSchemaFirstDirective = print(schema.getDirective('cost').astNode);
282+
const printedCodeFirstDirective = print(builtCodeFirstSchema.getDirective('cost').astNode);
283+
284+
expect(printedSchemaFirstDirective).to.equal(printedCodeFirstDirective);
285+
});
248286
});

src/estimators/directive/__tests__/fixtures/schema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ import {
77
} from 'graphql';
88

99
export default buildSchema(`
10+
"""Define a relation between the field and other nodes"""
1011
directive @cost(
12+
"""The complexity value for the field"""
1113
value: Int!,
1214
multipliers: [String!]
1315
) on FIELD_DEFINITION
1416
17+
"""Define a relation between the field and other nodes"""
1518
directive @complexity(
19+
"""The complexity value for the field"""
1620
value: Int!,
1721
multipliers: [String!]
1822
) on FIELD_DEFINITION

src/estimators/directive/index.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ import { GraphQLDirective } from 'graphql/type/directives';
44
import { DirectiveLocation } from 'graphql/language/directiveLocation';
55
import get from 'lodash.get';
66

7-
export default function (options?: {}): ComplexityEstimator {
7+
export type ComplexityDirectiveOptions = {
8+
name?: string
9+
}
10+
11+
export function createComplexityDirective(options?: ComplexityDirectiveOptions) {
812
const mergedOptions = {
913
name: 'complexity',
1014
...(options || {})
1115
};
1216

13-
const directive = new GraphQLDirective({
17+
return new GraphQLDirective({
1418
name: mergedOptions.name,
1519
description: 'Define a relation between the field and other nodes',
1620
locations: [
17-
DirectiveLocation.FIELD,
21+
DirectiveLocation.FIELD_DEFINITION,
1822
],
1923
args: {
2024
value: {
@@ -26,6 +30,10 @@ export default function (options?: {}): ComplexityEstimator {
2630
}
2731
},
2832
});
33+
}
34+
35+
export default function (options: ComplexityDirectiveOptions = {}): ComplexityEstimator {
36+
const directive = createComplexityDirective(options);
2937

3038
return (args: ComplexityEstimatorArgs) => {
3139
// Ignore if astNode is undefined

src/estimators/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export {default as simpleEstimator} from './simple';
2-
export {default as directiveEstimator} from './directive';
2+
export {default as directiveEstimator, ComplexityDirectiveOptions, createComplexityDirective} from './directive';
33
export {default as fieldExtensionsEstimator} from './fieldExtensions';

0 commit comments

Comments
 (0)