From e2ed33f8b118020cd0e84b4c5266270f4723ee1f Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Fri, 31 May 2019 18:27:27 -0400 Subject: [PATCH] Revert "Revert "Avoid duplicate `cacheControl` directives via `isDirectiveDefined` (#2428)"" This reverts commit c742335a4e745455bc51fbcac7fdab772c20cbc1. --- .../apollo-server-core/src/ApolloServer.ts | 30 +++++++------ .../src/__tests__/isDirectiveDefined.ts | 44 +++++++++++++++++++ .../src/utils/isDirectiveDefined.ts | 13 ++++++ 3 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 packages/apollo-server-core/src/__tests__/isDirectiveDefined.ts create mode 100644 packages/apollo-server-core/src/utils/isDirectiveDefined.ts diff --git a/packages/apollo-server-core/src/ApolloServer.ts b/packages/apollo-server-core/src/ApolloServer.ts index 9d4bfd4dcb1..708bfbc171b 100644 --- a/packages/apollo-server-core/src/ApolloServer.ts +++ b/packages/apollo-server-core/src/ApolloServer.ts @@ -50,8 +50,9 @@ import { PlaygroundRenderPageOptions, } from './playground'; -import createSHA from './utils/createSHA'; import { generateSchemaHash } from './utils/schemaHash'; +import { isDirectiveDefined } from './utils/isDirectiveDefined'; +import createSHA from './utils/createSHA'; import { processGraphQLRequest, GraphQLRequestContext, @@ -270,19 +271,22 @@ export class ApolloServerBase { // We augment the typeDefs with the @cacheControl directive and associated // scope enum, so makeExecutableSchema won't fail SDL validation - augmentedTypeDefs.push( - gql` - enum CacheControlScope { - PUBLIC - PRIVATE - } - directive @cacheControl( - maxAge: Int - scope: CacheControlScope - ) on FIELD_DEFINITION | OBJECT | INTERFACE - `, - ); + if (!isDirectiveDefined(augmentedTypeDefs, 'cacheControl')) { + augmentedTypeDefs.push( + gql` + enum CacheControlScope { + PUBLIC + PRIVATE + } + + directive @cacheControl( + maxAge: Int + scope: CacheControlScope + ) on FIELD_DEFINITION | OBJECT | INTERFACE + `, + ); + } if (this.uploadsConfig) { const { GraphQLUpload } = require('graphql-upload'); diff --git a/packages/apollo-server-core/src/__tests__/isDirectiveDefined.ts b/packages/apollo-server-core/src/__tests__/isDirectiveDefined.ts new file mode 100644 index 00000000000..e3353064f7b --- /dev/null +++ b/packages/apollo-server-core/src/__tests__/isDirectiveDefined.ts @@ -0,0 +1,44 @@ +import { gql } from '../'; +import { isDirectiveDefined } from '../utils/isDirectiveDefined'; + +describe('isDirectiveDefined', () => { + it('returns false when a directive is not defined', () => { + expect( + isDirectiveDefined( + [ + gql` + type Query { + hello: String + } + `, + ], + 'cacheControl', + ), + ).toBe(false); + }); + + it('returns true when a directive is defined', () => { + expect( + isDirectiveDefined( + [ + gql` + type Query { + hello: String + } + + enum CacheControlScope { + PUBLIC + PRIVATE + } + + directive @cacheControl( + maxAge: Int + scope: CacheControlScope + ) on FIELD_DEFINITION | OBJECT | INTERFACE + `, + ], + 'cacheControl', + ), + ).toBe(true); + }); +}); diff --git a/packages/apollo-server-core/src/utils/isDirectiveDefined.ts b/packages/apollo-server-core/src/utils/isDirectiveDefined.ts new file mode 100644 index 00000000000..4523573b851 --- /dev/null +++ b/packages/apollo-server-core/src/utils/isDirectiveDefined.ts @@ -0,0 +1,13 @@ +import { DocumentNode, Kind } from 'graphql/language'; + +export const isDirectiveDefined = ( + typeDefs: DocumentNode[], + directiveName: string, +) => + typeDefs.some(typeDef => + typeDef.definitions.some( + definition => + definition.kind === Kind.DIRECTIVE_DEFINITION && + definition.name.value === directiveName, + ), + );