Skip to content

Commit

Permalink
Avoid duplicate cacheControl directives via `isDirectiveDefin… (#2762)
Browse files Browse the repository at this point in the history
* Revert "Revert "Avoid duplicate `cacheControl` directives via `isDirectiveDefined` (#2428)""

This reverts commit c742335.

* Account for typeDefs possibly being a string

* Add tests to ensure isDirectiveDefiend works for strings

* rename test file to add ".test"

* update changelog
  • Loading branch information
cheapsteak authored and abernix committed Jun 25, 2019
1 parent a2b2a0d commit 65ca915
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The version headers in this history reflect the versions of Apollo Server itself

> The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. When a release is being prepared, a new header will be (manually) created below and the the appropriate changes within that release will be moved into the new section.
- `apollo-server-core`: Avoid duplicate `cacheControl` directives being added via `isDirectiveDefined`. [PR #2762](https://github.com/apollographql/apollo-server/pull/2762) (was reverted in 2.6.1 because previous implementation released in 2.6.0 broke passing in typedefs as a string)

### v2.6.5

- `apollo-engine-reporting`: Simplify the technique for capturing `operationName`. [PR #2899](https://github.com/apollographql/apollo-server/pull/2899)
Expand Down
30 changes: 17 additions & 13 deletions packages/apollo-server-core/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -272,19 +273,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');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { gql } from '../';
import { isDirectiveDefined } from '../utils/isDirectiveDefined';

describe('isDirectiveDefined', () => {
const noCacheControl = `
type Query {
hello: String
}
`;
const hasCacheControl = `
type Query {
hello: String
}
enum CacheControlScope {
PUBLIC
PRIVATE
}
directive @cacheControl(
maxAge: Int
scope: CacheControlScope
) on FIELD_DEFINITION | OBJECT | INTERFACE
`;

describe('When passed an array of DocumentNode', () => {
it('returns false when a directive is not defined', () => {
expect(isDirectiveDefined([gql(noCacheControl)], 'cacheControl')).toBe(
false,
);
});
it('returns true when a directive is defined', () => {
expect(isDirectiveDefined([gql(hasCacheControl)], 'cacheControl')).toBe(
true,
);
});
});

describe('When passed a string', () => {
it('returns false when a directive is not defined', () => {
expect(isDirectiveDefined(noCacheControl, 'cacheControl')).toBe(false);
});
it('returns true when a directive is defined', () => {
expect(isDirectiveDefined(hasCacheControl, 'cacheControl')).toBe(true);
});
});
});
18 changes: 18 additions & 0 deletions packages/apollo-server-core/src/utils/isDirectiveDefined.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DocumentNode, Kind } from 'graphql/language';
import { gql } from '../';

export const isDirectiveDefined = (
typeDefs: DocumentNode[] | string,
directiveName: string,
): boolean => {
if (typeof typeDefs === 'string') {
return isDirectiveDefined([gql(typeDefs)], directiveName);
}
return typeDefs.some(typeDef =>
typeDef.definitions.some(
definition =>
definition.kind === Kind.DIRECTIVE_DEFINITION &&
definition.name.value === directiveName,
),
);
};

0 comments on commit 65ca915

Please sign in to comment.