Skip to content

Commit

Permalink
Avoid duplicate cacheControl directives via isDirectiveDefined (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
cheapsteak authored and abernix committed May 22, 2019
1 parent ecc9880 commit 4e84def
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
- `apollo-datasource-rest`: Correctly allow a TTL value of `0` to represent "not-cacheable". [PR #2588](https://github.com/apollographql/apollo-server/pull/2588)
- `apollo-datasource-rest`: Fix `Invalid argument` in IE11, when `this.headers` is `undefined`. [PR #2607](https://github.com/apollographql/apollo-server/pull/2607)

- Don't add `cacheControl` directive if one has already been defined. [PR #2428](https://github.com/apollographql/apollo-server/pull/2428)

### v2.4.8

- No functional changes in this version. The patch version has been bumped to fix the `README.md` displayed on the [npm package for `apollo-server`](https://npm.im/apollo-server) as a result of a broken publish. Apologies for the additional noise!
Expand Down
28 changes: 16 additions & 12 deletions packages/apollo-server-core/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
} from './playground';

import { generateSchemaHash } from './utils/schemaHash';
import { isDirectiveDefined } from './utils/isDirectiveDefined';
import {
processGraphQLRequest,
GraphQLRequestContext,
Expand Down Expand Up @@ -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');
Expand Down
44 changes: 44 additions & 0 deletions packages/apollo-server-core/src/__tests__/isDirectiveDefined.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
13 changes: 13 additions & 0 deletions packages/apollo-server-core/src/utils/isDirectiveDefined.ts
Original file line number Diff line number Diff line change
@@ -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,
),
);

0 comments on commit 4e84def

Please sign in to comment.