diff --git a/.circleci/config.yml b/.circleci/config.yml index 129f531..2dbb463 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,7 @@ workflows: # definitions for field extensions in older @types/graphql versions matrix: parameters: - graphql-version: ["~0.13", "~14.0", "~14.5", "~14.6"] + graphql-version: ["~0.13", "~14.0", "~14.5", "~14.6", "~15.0"] - test-and-build: # Leave graphql-version unspecified to respect the lockfile and also run tsc name: test-and-build-with-typecheck diff --git a/README.md b/README.md index 49d5b3d..487661e 100644 --- a/README.md +++ b/README.md @@ -83,10 +83,6 @@ or write your own: schema definition (for example via GraphQL SDL) * **[`fieldExtensionsEstimator`](src/estimators/fieldExtensions/README.md):** The field extensions estimator lets you set a numeric value or a custom estimator function in the field config extensions of your schema. -* **[`fieldConfigEstimator`](src/estimators/fieldConfig/README.md):** (DEPRECATED) The field config estimator lets you set a numeric value or a custom estimator - function in the field config of your schema. -* **[`legacyEstimator`](src/estimators/legacy/README.md):** (DEPRECATED) The legacy estimator implements the logic of previous versions. Can be used - to gradually migrate your codebase to new estimators. * PRs welcome... Consult the documentation of each estimator for information about how to use them. diff --git a/package.json b/package.json index f835299..032f488 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "lodash.get": "^4.4.2" }, "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0" + "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" }, "files": [ "dist", @@ -41,14 +41,13 @@ "devDependencies": { "@types/assert": "^1.4.6", "@types/chai": "^4.2.11", - "@types/graphql": "^0.13.0 || ^14.0.0", "@types/lodash.get": "^4.4.6", "@types/mocha": "^7.0.2", "@typescript-eslint/eslint-plugin": "^2.27.0", "@typescript-eslint/parser": "^2.27.0", "chai": "^4.2.0", "eslint": "^6.8.0", - "graphql": "^0.13.0 || ^14.0.0", + "graphql": "^14.5.0 || ^15.0.0", "mocha": "^7.1.1", "rimraf": "^3.0.2", "ts-node": "^8.8.2", diff --git a/src/QueryComplexity.ts b/src/QueryComplexity.ts index 4245358..845340f 100644 --- a/src/QueryComplexity.ts +++ b/src/QueryComplexity.ts @@ -29,10 +29,6 @@ import { getNamedType, GraphQLError } from 'graphql'; -import { - simpleEstimator, - legacyEstimator -} from './estimators'; declare module 'graphql/type/definition' { export interface GraphQLField { @@ -72,7 +68,7 @@ export interface QueryComplexityOptions { createError?: (max: number, actual: number) => GraphQLError, // An array of complexity estimators to use for estimating the complexity - estimators?: Array; + estimators: Array; } function queryComplexityMessage(max: number, actual: number): string { @@ -91,7 +87,7 @@ export function getComplexity(options: { }): number { const typeInfo = new TypeInfo(options.schema); - const context = new ValidationContext(options.schema, options.query, typeInfo); + const context = new ValidationContext(options.schema, options.query, typeInfo, () => null); const visitor = new QueryComplexity(context, { // Maximum complexity does not matter since we're only interested in the calculated complexity. maximumComplexity: Infinity, @@ -127,17 +123,7 @@ export default class QueryComplexity { this.includeDirectiveDef = this.context.getSchema().getDirective('include'); this.skipDirectiveDef = this.context.getSchema().getDirective('skip'); - - if (!options.estimators) { - console.warn( - 'DEPRECATION WARNING: Estimators should be configured in the queryComplexity options.' - ); - } - - this.estimators = options.estimators || [ - legacyEstimator(), - simpleEstimator() - ]; + this.estimators = options.estimators this.OperationDefinition = { enter: this.onOperationDefinitionEnter, @@ -178,7 +164,7 @@ export default class QueryComplexity { if (typeof this.options.operationName === 'string' && this.options.operationName !== operation.name.value) { return; } - + if (this.options.onComplete) { this.options.onComplete(this.complexity); } diff --git a/src/__tests__/QueryComplexity-test.ts b/src/__tests__/QueryComplexity-test.ts index 3d0b491..b2bb133 100644 --- a/src/__tests__/QueryComplexity-test.ts +++ b/src/__tests__/QueryComplexity-test.ts @@ -5,7 +5,6 @@ import { parse, TypeInfo, - ValidationContext, visit, visitWithTypeInfo, } from 'graphql'; @@ -18,8 +17,9 @@ import ComplexityVisitor, {getComplexity} from '../QueryComplexity'; import { simpleEstimator, directiveEstimator, - fieldConfigEstimator, + fieldExtensionsEstimator, } from '../index'; +import { CompatibleValidationContext } from './fixtures/CompatibleValidationContext'; describe('QueryComplexity analysis', () => { const typeInfo = new TypeInfo(schema); @@ -135,7 +135,7 @@ describe('QueryComplexity analysis', () => { const complexity = getComplexity({ estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({defaultComplexity: 1}) ], schema, @@ -154,7 +154,7 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -173,11 +173,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -203,11 +203,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -230,11 +230,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -257,11 +257,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -284,11 +284,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -310,11 +310,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -332,11 +332,11 @@ describe('QueryComplexity analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -353,11 +353,11 @@ describe('QueryComplexity analysis', () => { requiredArgs } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({ defaultComplexity: 1 }) @@ -374,7 +374,7 @@ describe('QueryComplexity analysis', () => { scalar } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [] @@ -393,11 +393,11 @@ describe('QueryComplexity analysis', () => { scalar } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ - fieldConfigEstimator() + fieldExtensionsEstimator() ] }); visit(ast, visitWithTypeInfo(typeInfo, visitor)); @@ -463,7 +463,7 @@ describe('QueryComplexity analysis', () => { const complexity1 = getComplexity({ estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({defaultComplexity: 1}) ], schema, @@ -473,7 +473,7 @@ describe('QueryComplexity analysis', () => { const complexity2 = getComplexity({ estimators: [ - fieldConfigEstimator(), + fieldExtensionsEstimator(), simpleEstimator({defaultComplexity: 1}) ], schema, diff --git a/src/__tests__/fixtures/CompatibleValidationContext.ts b/src/__tests__/fixtures/CompatibleValidationContext.ts new file mode 100644 index 0000000..655578c --- /dev/null +++ b/src/__tests__/fixtures/CompatibleValidationContext.ts @@ -0,0 +1,28 @@ +import { GraphQLError, TypeInfo, ValidationContext } from "graphql"; +import { GraphQLSchema } from "graphql/type/schema"; +import { DocumentNode } from "graphql/language/ast"; + +/** + * This class is used to test that validation errors are raised correctly + * + * A compatibility layer is necessary to support graphql versions since 15.0.0 + * *as well as* versions prior to 14.5.0 with the same test, because older + * versions of `ValidationContext` only expose a `getErrors` API and newer + * versions only expose the `onError` API via a fourth constructor argument. + * + * Once we drop support for versions older than 14.5.0 this layer will no + * longer be necessary and tests may use `ValidationContext` directly using the + * `onError` API. + */ +export class CompatibleValidationContext extends ValidationContext { + private errors: GraphQLError[] = [] + + constructor(schema: GraphQLSchema, ast: DocumentNode, typeInfo: TypeInfo) { + super(schema, ast, typeInfo, err => this.errors.push(err)); + } + + getErrors(): ReadonlyArray { + // @ts-ignore + return super.getErrors ? super.getErrors() : this.errors + } +} diff --git a/src/__tests__/fixtures/schema.ts b/src/__tests__/fixtures/schema.ts index 9d9e982..ef7fa96 100644 --- a/src/__tests__/fixtures/schema.ts +++ b/src/__tests__/fixtures/schema.ts @@ -21,7 +21,9 @@ const Item: GraphQLObjectType = new GraphQLObjectType({ fields: () => ({ variableList: { type: Item, - complexity: (args: ComplexityEstimatorArgs) => args.childComplexity * (args.args.count || 10), + extensions: { + complexity: (args: ComplexityEstimatorArgs) => args.childComplexity * (args.args.count || 10) + }, args: { count: { type: GraphQLInt @@ -29,10 +31,12 @@ const Item: GraphQLObjectType = new GraphQLObjectType({ } }, scalar: { type: GraphQLString }, - complexScalar: { type: GraphQLString, complexity: 20 }, + complexScalar: { type: GraphQLString, extensions: { complexity: 20 } }, variableScalar: { type: Item, - complexity: (args: ComplexityEstimatorArgs) => 10 * (args.args.count || 10), + extensions: { + complexity: (args: ComplexityEstimatorArgs) => 10 * (args.args.count || 10) + }, args: { count: { type: GraphQLInt @@ -97,7 +101,9 @@ const Query = new GraphQLObjectType({ name: { type: GraphQLString }, variableList: { type: Item, - complexity: (args: ComplexityEstimatorArgs) => args.childComplexity * (args.args.count || 10), + extensions: { + complexity: (args: ComplexityEstimatorArgs) => args.childComplexity * (args.args.count || 10) + }, args: { count: { type: GraphQLInt @@ -107,11 +113,13 @@ const Query = new GraphQLObjectType({ interface: {type: NameInterface}, enum: {type: EnumType}, scalar: { type: GraphQLString }, - complexScalar: { type: GraphQLString, complexity: 20 }, + complexScalar: { type: GraphQLString, extensions: { complexity: 20 } }, union: { type: Union }, variableScalar: { type: Item, - complexity: (args: ComplexityEstimatorArgs) => 10 * (args.args.count || 10), + extensions: { + complexity: (args: ComplexityEstimatorArgs) => 10 * (args.args.count || 10) + }, args: { count: { type: GraphQLInt diff --git a/src/estimators/directive/__tests__/directiveEstimator-test.ts b/src/estimators/directive/__tests__/directiveEstimator-test.ts index 3dec3d1..b303b9d 100644 --- a/src/estimators/directive/__tests__/directiveEstimator-test.ts +++ b/src/estimators/directive/__tests__/directiveEstimator-test.ts @@ -5,7 +5,6 @@ import { parse, TypeInfo, - ValidationContext, visit, visitWithTypeInfo, } from 'graphql'; @@ -16,6 +15,7 @@ import schema from './fixtures/schema'; import ComplexityVisitor from '../../../QueryComplexity'; import directiveEstimator from '../index'; +import { CompatibleValidationContext } from '../../../__tests__/fixtures/CompatibleValidationContext'; describe('directiveEstimator analysis', () => { const typeInfo = new TypeInfo(schema); @@ -27,7 +27,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -46,7 +46,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -65,7 +65,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -84,7 +84,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -107,7 +107,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -128,7 +128,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -149,7 +149,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -170,7 +170,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -191,7 +191,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -212,7 +212,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -231,7 +231,7 @@ describe('directiveEstimator analysis', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -240,8 +240,8 @@ describe('directiveEstimator analysis', () => { }); visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.context.getErrors().length).to.equal(1); - expect(visitor.context.getErrors()[0].message).to.include( + expect(context.getErrors().length).to.equal(1); + expect(context.getErrors()[0].message).to.include( 'No complexity could be calculated for field Query.noDirective', ); }); diff --git a/src/estimators/fieldConfig/README.md b/src/estimators/fieldConfig/README.md deleted file mode 100644 index 16b3caf..0000000 --- a/src/estimators/fieldConfig/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# Field Config Estimator - -The `fieldConfigEstimator` lets you define a numeric value or a custom estimator -in the field config of your GraphQL schema. If no complexity is set in the field config, -the estimator does not return any value and the next estimator in the chain is executed. - -## Usage - -```typescript -import queryComplexity, { - fieldConfigEstimator, - simpleEstimator -} from 'graphql-query-complexity'; - -const rule = queryComplexity({ - estimators: [ - fieldConfigEstimator(), - - // We use the simpleEstimator as fallback so we only need to - // define the complexity for non 1 values (this is not required...) - simpleEstimator({defaultComplexity: 1}) - ] - // ... other config -}); -``` - -You can set a custom complexity as a numeric value in the field config: - -```javascript -const Post = new GraphQLObjectType({ - name: 'Post', - fields: () => ({ - title: { type: GraphQLString }, - text: { type: GraphQLString, complexity: 5 }, - }), -}); -``` - -**Example Query:** - -```graphql -query { - posts(count: 10) { - title - text - } -} -``` - -This query would result in a complexity of 7. -5 for the `text` field and 1 for each of the other fields. - -You can also pass an estimator in the field config to determine a custom complexity. -This function will provide the complexity of the child nodes as well as the field input arguments. - -The function signature is the same as for the main estimator which lets you reuse estimators: - -```typescript -type ComplexityEstimatorArgs = { - type: GraphQLCompositeType, - field: GraphQLField, - args: {[key: string]: any}, - childComplexity: number -} - -type ComplexityEstimator = (options: ComplexityEstimatorArgs) => number | void; -``` - -That way you can make a more realistic estimation of individual field complexity values: - -```javascript -const Query = new GraphQLObjectType({ - name: 'Query', - fields: () => ({ - posts: { - type: new GraphQLList(Post), - complexity: ({args, childComplexity}) => childComplexity * args.count, - args: { - count: { - type: GraphQLInt, - defaultValue: 10 - } - } - }, - }), -}); -``` - -This would result in a complexity of 60 since the `childComplexity` of posts (`text` 5, `title` 1) is multiplied by the -number of posts (`args.count`). diff --git a/src/estimators/fieldConfig/__tests__/fieldConfigEstimator-test.ts b/src/estimators/fieldConfig/__tests__/fieldConfigEstimator-test.ts deleted file mode 100644 index 791555d..0000000 --- a/src/estimators/fieldConfig/__tests__/fieldConfigEstimator-test.ts +++ /dev/null @@ -1,313 +0,0 @@ -/** - * Created by Ivo Meißner on 28.07.17. - */ - -import { - parse, - TypeInfo, - ValidationContext, - visit, - visitWithTypeInfo, -} from 'graphql'; - -import {expect} from 'chai'; - -import schema from './fixtures/schema'; - -import ComplexityVisitor from '../../../QueryComplexity'; -import simpleEstimator from '../../simple'; -import fieldConfigEstimator from '../index'; - -describe('fieldConfig estimator', () => { - const typeInfo = new TypeInfo(schema); - - it('should consider default scalar cost', () => { - const ast = parse(` - query { - scalar - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1); - }); - - it('should consider custom scalar cost', () => { - const ast = parse(` - query { - complexScalar - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(20); - }); - - it('should consider variable scalar cost', () => { - const ast = parse(` - query { - variableScalar(count: 100) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1000); - }); - - it('should not allow negative cost', () => { - const ast = parse(` - query { - variableScalar(count: -100) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(0); - }); - - it('should report error above threshold', () => { - const ast = parse(` - query { - variableScalar(count: 100) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1000); - expect(context.getErrors().length).to.equal(1); - expect(context.getErrors()[0].message).to.equal( - 'The query exceeds the maximum complexity of 100. Actual complexity is 1000' - ); - }); - - it('should add inline fragments', () => { - const ast = parse(` - query { - variableScalar(count: 5) - ...on Query { - scalar - alias: scalar - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(52); - }); - - it('should add fragments', () => { - const ast = parse(` - query { - scalar - ...QueryFragment - } - - fragment QueryFragment on Query { - variableScalar(count: 2) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(21); - }); - - it('should add complexity for union types', () => { - const ast = parse(` - query { - union { - ...on Item { - scalar - complexScalar - } - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(22); - }); - - it('should add complexity for interface types', () => { - const ast = parse(` - query { - interface { - name - ...on NameInterface { - name - } - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(3); - }); - - it('should add complexity for inline fragments without type condition', () => { - const ast = parse(` - query { - interface { - ... { - name - } - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(2); - }); - - it('should add complexity for enum types', () => { - const ast = parse(` - query { - enum - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1); - }); - - it('should error on a missing non-null argument', () => { - const ast = parse(` - query { - requiredArgs - } - `); - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - fieldConfigEstimator(), - simpleEstimator({ - defaultComplexity: 1 - }) - ] - }); - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(context.getErrors().length).to.equal(1); - expect(context.getErrors()[0].message).to.equal('Argument "count" of required type "Int!" was not provided.'); - }); -}); diff --git a/src/estimators/fieldConfig/__tests__/fixtures/schema.ts b/src/estimators/fieldConfig/__tests__/fixtures/schema.ts deleted file mode 100644 index 8ff1a3b..0000000 --- a/src/estimators/fieldConfig/__tests__/fixtures/schema.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Created by Ivo Meißner on 28.07.17. - */ - -import { - GraphQLList, - GraphQLObjectType, - GraphQLNonNull, - GraphQLSchema, - GraphQLString, - GraphQLInt, - GraphQLEnumType, - GraphQLUnionType, - GraphQLInterfaceType, -} from 'graphql'; - -import {ComplexityEstimatorArgs} from '../../../../QueryComplexity'; - -const Item: GraphQLObjectType = new GraphQLObjectType({ - name: 'Item', - fields: () => ({ - variableList: { - type: Item, - complexity: (args: ComplexityEstimatorArgs) => args.childComplexity * (args.args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - scalar: { type: GraphQLString }, - complexScalar: { type: GraphQLString, complexity: 20 }, - variableScalar: { - type: Item, - complexity: (args: ComplexityEstimatorArgs) => 10 * (args.args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - list: { type: new GraphQLList(Item) }, - nonNullItem: { - type: new GraphQLNonNull(Item), - resolve: () => ({}), - }, - nonNullList: { - type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(Item))), - resolve: () => [], - }, - }), -}); - -const NameInterface = new GraphQLInterfaceType({ - name: 'NameInterface', - fields: { - name: { type: GraphQLString } - }, - resolveType: () => Item -}); - -const SecondItem = new GraphQLObjectType({ - name: 'SecondItem', - fields: () => ({ - name: {type: GraphQLString}, - scalar: {type: GraphQLString} - }), - interfaces: [ NameInterface ] -}); - -const EnumType = new GraphQLEnumType({ - name: 'RGB', - values: { - RED: { value: 0 }, - GREEN: { value: 1 }, - BLUE: { value: 2 } - } -}); - -const Union = new GraphQLUnionType({ - name: 'Union', - types: [ Item, SecondItem ], - resolveType: () => Item -}); - -const Query = new GraphQLObjectType({ - name: 'Query', - fields: () => ({ - name: { type: GraphQLString }, - variableList: { - type: Item, - complexity: (args: ComplexityEstimatorArgs) => args.childComplexity * (args.args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - interface: {type: NameInterface}, - enum: {type: EnumType}, - scalar: { type: GraphQLString }, - complexScalar: { type: GraphQLString, complexity: 20 }, - union: { type: Union }, - variableScalar: { - type: Item, - complexity: (args: ComplexityEstimatorArgs) => 10 * (args.args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - list: { type: new GraphQLList(Item) }, - nonNullItem: { - type: new GraphQLNonNull(Item), - resolve: () => ({}), - }, - nonNullList: { - type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(Item))), - resolve: () => [], - }, - requiredArgs: { - type: Item, - args: { - count: { - type: new GraphQLNonNull(GraphQLInt) - } - } - } - }), -}); - -export default new GraphQLSchema({ query: Query }); diff --git a/src/estimators/fieldConfig/index.ts b/src/estimators/fieldConfig/index.ts deleted file mode 100644 index 407b9b8..0000000 --- a/src/estimators/fieldConfig/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {ComplexityEstimator, ComplexityEstimatorArgs} from '../../QueryComplexity'; - -/** - * @deprecated Use fieldExtensionsEstimator instead - */ -export default function (): ComplexityEstimator { - console.warn( - 'DEPRECATION WARNING: fieldConfigEstimator is deprecated. Use fieldExtensionsEstimator instead' - ); - - return (args: ComplexityEstimatorArgs) => { - // Calculate complexity score - if (typeof args.field.complexity === 'number') { - return args.childComplexity + args.field.complexity; - } else if (typeof args.field.complexity === 'function') { - return args.field.complexity(args); - } - }; -} diff --git a/src/estimators/fieldExtensions/__tests__/fieldExtensionsEstimator-test.ts b/src/estimators/fieldExtensions/__tests__/fieldExtensionsEstimator-test.ts index 7130bb9..6f7bb28 100644 --- a/src/estimators/fieldExtensions/__tests__/fieldExtensionsEstimator-test.ts +++ b/src/estimators/fieldExtensions/__tests__/fieldExtensionsEstimator-test.ts @@ -5,7 +5,6 @@ import { parse, TypeInfo, - ValidationContext, visit, visitWithTypeInfo, } from 'graphql'; @@ -17,6 +16,7 @@ import schema from './fixtures/schema'; import ComplexityVisitor from '../../../QueryComplexity'; import simpleEstimator from '../../simple'; import fieldExtensionsEstimator from '../index'; +import { CompatibleValidationContext } from '../../../__tests__/fixtures/CompatibleValidationContext'; describe('fieldExtensions estimator', () => { const typeInfo = new TypeInfo(schema); @@ -28,7 +28,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -50,7 +50,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -72,7 +72,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -94,7 +94,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -116,7 +116,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -146,7 +146,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -173,7 +173,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -200,7 +200,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -227,7 +227,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -253,7 +253,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -275,7 +275,7 @@ describe('fieldExtensions estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -296,7 +296,7 @@ describe('fieldExtensions estimator', () => { requiredArgs } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ diff --git a/src/estimators/index.ts b/src/estimators/index.ts index bdd1c08..2efd4b2 100644 --- a/src/estimators/index.ts +++ b/src/estimators/index.ts @@ -1,5 +1,3 @@ export {default as simpleEstimator} from './simple'; -export {default as legacyEstimator} from './legacy'; -export {default as fieldConfigEstimator} from './fieldConfig'; export {default as directiveEstimator} from './directive'; export {default as fieldExtensionsEstimator} from './fieldExtensions'; diff --git a/src/estimators/legacy/README.md b/src/estimators/legacy/README.md deleted file mode 100644 index 5bc34ff..0000000 --- a/src/estimators/legacy/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Legacy Estimator - -WARNING: The legacy estimator is only part of the library to provide the functionality of previous versions. -You should use the fieldConfig estimator for new projects and migrate old implementations. - -## Usage - -````typescript -import queryComplexity, {legacyEstimator} from 'graphql-query-complexity'; - -const rule = queryComplexity({ - estimators: [ - legacyEstimator() - ] - // ... other config -}); -```` - -You can set a custom complexity in the field config: - -```javascript -const Post = new GraphQLObjectType({ - name: 'Post', - fields: () => ({ - title: { type: GraphQLString }, - text: { type: GraphQLString, complexity: 5 }, - }), -}); -``` -The same query would now result in a complexity of 7. -5 for the `text` field and 1 for each of the other fields. - -You can also pass a calculation function in the field config to determine a custom complexity. -This function will provide the complexity of the child nodes as well as the field input arguments. - -That way you can make a more realistic estimation of individual field complexity values: - -```javascript -const Query = new GraphQLObjectType({ - name: 'Query', - fields: () => ({ - posts: { - type: new GraphQLList(Post), - complexity: (args, childComplexity) => childComplexity * args.count, - args: { - count: { - type: GraphQLInt, - defaultValue: 10 - } - } - }, - }), -}); -``` - -This would result in a complexity of 60 since the `childComplexity` of posts (`text` 5, `title` 1) is multiplied by the -number of posts (`args.count`). \ No newline at end of file diff --git a/src/estimators/legacy/__tests__/fixtures/schema.ts b/src/estimators/legacy/__tests__/fixtures/schema.ts deleted file mode 100644 index 02b977f..0000000 --- a/src/estimators/legacy/__tests__/fixtures/schema.ts +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Created by Ivo Meißner on 28.07.17. - */ - -import { - GraphQLList, - GraphQLObjectType, - GraphQLNonNull, - GraphQLSchema, - GraphQLString, - GraphQLInt, - GraphQLEnumType, - GraphQLUnionType, - GraphQLInterfaceType, -} from 'graphql'; - -const Item: GraphQLObjectType = new GraphQLObjectType({ - name: 'Item', - fields: () => ({ - variableList: { - type: Item, - complexity: (args: any, childComplexity: number) => childComplexity * (args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - scalar: { type: GraphQLString }, - complexScalar: { type: GraphQLString, complexity: 20 }, - variableScalar: { - type: Item, - complexity: (args: {[key: string]: any}) => 10 * (args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - list: { type: new GraphQLList(Item) }, - nonNullItem: { - type: new GraphQLNonNull(Item), - resolve: () => ({}), - }, - nonNullList: { - type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(Item))), - resolve: () => [], - }, - }), -}); - -const NameInterface = new GraphQLInterfaceType({ - name: 'NameInterface', - fields: { - name: { type: GraphQLString } - }, - resolveType: () => Item -}); - -const SecondItem = new GraphQLObjectType({ - name: 'SecondItem', - fields: () => ({ - name: {type: GraphQLString}, - scalar: {type: GraphQLString} - }), - interfaces: [ NameInterface ] -}); - -const EnumType = new GraphQLEnumType({ - name: 'RGB', - values: { - RED: { value: 0 }, - GREEN: { value: 1 }, - BLUE: { value: 2 } - } -}); - -const Union = new GraphQLUnionType({ - name: 'Union', - types: [ Item, SecondItem ], - resolveType: () => Item -}); - -const Query = new GraphQLObjectType({ - name: 'Query', - fields: () => ({ - name: { type: GraphQLString }, - variableList: { - type: Item, - complexity: (args: {[key: string]: any}, childComplexity: number) => childComplexity * (args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - interface: {type: NameInterface}, - enum: {type: EnumType}, - scalar: { type: GraphQLString }, - complexScalar: { type: GraphQLString, complexity: 20 }, - union: { type: Union }, - variableScalar: { - type: Item, - complexity: (args: {[key: string]: any}) => 10 * (args.count || 10), - args: { - count: { - type: GraphQLInt - } - } - }, - list: { type: new GraphQLList(Item) }, - nonNullItem: { - type: new GraphQLNonNull(Item), - resolve: () => ({}), - }, - nonNullList: { - type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(Item))), - resolve: () => [], - }, - requiredArgs: { - type: Item, - args: { - count: { - type: new GraphQLNonNull(GraphQLInt) - } - } - } - }), -}); - -export default new GraphQLSchema({ query: Query }); diff --git a/src/estimators/legacy/__tests__/legacyEstimator-test.ts b/src/estimators/legacy/__tests__/legacyEstimator-test.ts deleted file mode 100644 index 6a75644..0000000 --- a/src/estimators/legacy/__tests__/legacyEstimator-test.ts +++ /dev/null @@ -1,289 +0,0 @@ -/** - * Created by Ivo Meißner on 28.07.17. - */ - -import { - parse, - TypeInfo, - ValidationContext, - visit, - visitWithTypeInfo, -} from 'graphql'; - -import {expect} from 'chai'; - -import schema from './fixtures/schema'; - -import ComplexityVisitor from '../../../QueryComplexity'; -import legacyEstimator from '../index'; -import simpleEstimator from '../../simple'; - -describe('legacy estimator', () => { - const typeInfo = new TypeInfo(schema); - - it('should consider default scalar cost', () => { - const ast = parse(` - query { - scalar - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1); - }); - - it('should consider custom scalar cost', () => { - const ast = parse(` - query { - complexScalar - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(20); - }); - - it('should consider variable scalar cost', () => { - const ast = parse(` - query { - variableScalar(count: 100) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1000); - }); - - it('should not allow negative cost', () => { - const ast = parse(` - query { - variableScalar(count: -100) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(0); - }); - - it('should report error above threshold', () => { - const ast = parse(` - query { - variableScalar(count: 100) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1000); - expect(context.getErrors().length).to.equal(1); - expect(context.getErrors()[0].message).to.equal( - 'The query exceeds the maximum complexity of 100. Actual complexity is 1000' - ); - }); - - it('should add inline fragments', () => { - const ast = parse(` - query { - variableScalar(count: 5) - ...on Query { - scalar - alias: scalar - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(52); - }); - - it('should add fragments', () => { - const ast = parse(` - query { - scalar - ...QueryFragment - } - - fragment QueryFragment on Query { - variableScalar(count: 2) - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(21); - }); - - it('should add complexity for union types', () => { - const ast = parse(` - query { - union { - ...on Item { - scalar - complexScalar - } - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(22); - }); - - it('should add complexity for interface types', () => { - const ast = parse(` - query { - interface { - name - ...on NameInterface { - name - } - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(3); - }); - - it('should add complexity for inline fragments without type condition', () => { - const ast = parse(` - query { - interface { - ... { - name - } - } - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(2); - }); - - it('should add complexity for enum types', () => { - const ast = parse(` - query { - enum - } - `); - - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(visitor.complexity).to.equal(1); - }); - - it('should error on a missing non-null argument', () => { - const ast = parse(` - query { - requiredArgs - } - `); - const context = new ValidationContext(schema, ast, typeInfo); - const visitor = new ComplexityVisitor(context, { - maximumComplexity: 100, - estimators: [ - legacyEstimator(), - simpleEstimator() - ] - }); - visit(ast, visitWithTypeInfo(typeInfo, visitor)); - expect(context.getErrors().length).to.equal(1); - expect(context.getErrors()[0].message).to.equal('Argument "count" of required type "Int!" was not provided.'); - }); -}); diff --git a/src/estimators/legacy/index.ts b/src/estimators/legacy/index.ts deleted file mode 100644 index a3c3746..0000000 --- a/src/estimators/legacy/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {ComplexityEstimator, ComplexityEstimatorArgs} from '../../QueryComplexity'; - -export default function (): ComplexityEstimator { - return (args: ComplexityEstimatorArgs) => { - // Calculate complexity score - if (typeof args.field.complexity === 'number') { - return args.childComplexity + args.field.complexity; - } else if (typeof args.field.complexity === 'function') { - return args.field.complexity(args.args, args.childComplexity); - } - }; -} diff --git a/src/estimators/simple/__tests__/simpleEstimator-test.ts b/src/estimators/simple/__tests__/simpleEstimator-test.ts index 10d47a9..620a8dd 100644 --- a/src/estimators/simple/__tests__/simpleEstimator-test.ts +++ b/src/estimators/simple/__tests__/simpleEstimator-test.ts @@ -5,7 +5,6 @@ import { parse, TypeInfo, - ValidationContext, visit, visitWithTypeInfo, } from 'graphql'; @@ -16,6 +15,7 @@ import schema from './fixtures/schema'; import simpleEstimator from '../index'; import ComplexityVisitor from '../../../QueryComplexity'; +import { CompatibleValidationContext } from '../../../__tests__/fixtures/CompatibleValidationContext'; describe('simple estimator', () => { const typeInfo = new TypeInfo(schema); @@ -27,7 +27,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -46,7 +46,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -65,7 +65,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -84,7 +84,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -111,7 +111,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -135,7 +135,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -158,7 +158,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -182,7 +182,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -205,7 +205,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ @@ -224,7 +224,7 @@ describe('simple estimator', () => { } `); - const context = new ValidationContext(schema, ast, typeInfo); + const context = new CompatibleValidationContext(schema, ast, typeInfo); const visitor = new ComplexityVisitor(context, { maximumComplexity: 100, estimators: [ diff --git a/yarn.lock b/yarn.lock index 014afdb..c344d36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36,12 +36,6 @@ version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" -"@types/graphql@^0.13.0 || ^14.0.0": - version "14.5.0" - resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.5.0.tgz#a545fb3bc8013a3547cf2f07f5e13a33642b75d6" - dependencies: - graphql "*" - "@types/json-schema@^7.0.3": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -616,15 +610,10 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -graphql@*: +"graphql@^14.5.0 || ^15.0.0": version "15.0.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.0.0.tgz#042a5eb5e2506a2e2111ce41eb446a8e570b8be9" - -"graphql@^0.13.0 || ^14.0.0": - version "14.6.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.6.0.tgz#57822297111e874ea12f5cd4419616930cd83e49" - dependencies: - iterall "^1.2.2" + integrity sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ== growl@1.10.5: version "1.10.5" @@ -762,10 +751,6 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" -iterall@^1.2.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" - js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"