diff --git a/CHANGELOG.md b/CHANGELOG.md index 999e1308415..d82ba35e11c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ ### vNEXT -- FIXME(@abernix): Allow context to be passed to all GraphQLExtension methods. - Allow an optional function to resolve the `rootValue`, passing the `DocumentNode` AST to determine the value. [PR #1555](https://github.com/apollographql/apollo-server/pull/1555) - Follow-up on the work in [PR #1516](https://github.com/apollographql/apollo-server/pull/1516) to also fix missing insertion cursor/caret when a custom GraphQL configuration is specified which doesn't specify its own `cursorShape` property. [PR #1607](https://github.com/apollographql/apollo-server/pull/1607) diff --git a/packages/apollo-engine-reporting/src/extension.ts b/packages/apollo-engine-reporting/src/extension.ts index a986de83246..7f870ad1a6d 100644 --- a/packages/apollo-engine-reporting/src/extension.ts +++ b/packages/apollo-engine-reporting/src/extension.ts @@ -68,7 +68,7 @@ export class EngineReportingExtension request: Request; queryString?: string; parsedQuery?: DocumentNode; - variables: Record; + variables?: Record; persistedQueryHit?: boolean; persistedQueryRegister?: boolean; context: any; @@ -153,7 +153,7 @@ export class EngineReportingExtension } else { try { this.trace.details!.variablesJson![name] = JSON.stringify( - o.variables[name], + o.variables![name], ); } catch (e) { // This probably means that the value contains a circular reference, diff --git a/packages/apollo-server-core/src/__tests__/runQuery.test.ts b/packages/apollo-server-core/src/__tests__/runQuery.test.ts index 43064cb4c1a..2a3d25fdb30 100644 --- a/packages/apollo-server-core/src/__tests__/runQuery.test.ts +++ b/packages/apollo-server-core/src/__tests__/runQuery.test.ts @@ -435,6 +435,28 @@ describe('runQuery', () => { }); }); }); + + it('runs willSendResponse with extensions context', async () => { + class CustomExtension implements GraphQLExtension { + willSendResponse(o: any) { + expect(o).toHaveProperty('context.baz', 'always here'); + return o; + } + } + + const queryString = `{ testString }`; + const expected = { testString: 'it works' }; + const extensions = [() => new CustomExtension()]; + return runQuery({ + schema, + queryString, + context: { baz: 'always here' }, + extensions, + request: new MockReq(), + }).then(res => { + expect(res.data).toEqual(expected); + }); + }); }); describe('async_hooks', () => { diff --git a/packages/apollo-server-core/src/formatters.ts b/packages/apollo-server-core/src/formatters.ts index c509d07f0c9..2410f74aee2 100644 --- a/packages/apollo-server-core/src/formatters.ts +++ b/packages/apollo-server-core/src/formatters.ts @@ -1,7 +1,7 @@ import { GraphQLExtension, GraphQLResponse } from 'graphql-extensions'; import { formatApolloErrors } from 'apollo-server-errors'; -export class FormatErrorExtension extends GraphQLExtension { +export class FormatErrorExtension extends GraphQLExtension { private formatError?: Function; private debug: boolean; @@ -13,9 +13,11 @@ export class FormatErrorExtension extends GraphQLExtension { public willSendResponse(o: { graphqlResponse: GraphQLResponse; - }): void | { graphqlResponse: GraphQLResponse } { + context: TContext; + }): void | { graphqlResponse: GraphQLResponse; context: TContext } { if (o.graphqlResponse.errors) { return { + ...o, graphqlResponse: { ...o.graphqlResponse, errors: formatApolloErrors(o.graphqlResponse.errors, { diff --git a/packages/apollo-server-integration-testsuite/src/ApolloServer.ts b/packages/apollo-server-integration-testsuite/src/ApolloServer.ts index d35f37eac7b..380c130f97c 100644 --- a/packages/apollo-server-integration-testsuite/src/ApolloServer.ts +++ b/packages/apollo-server-integration-testsuite/src/ApolloServer.ts @@ -547,8 +547,11 @@ export function testApolloServer( } }); - class Extension extends GraphQLExtension { - willSendResponse(o: { graphqlResponse: GraphQLResponse }) { + class Extension extends GraphQLExtension { + willSendResponse(o: { + graphqlResponse: GraphQLResponse; + context: TContext; + }) { expect(o.graphqlResponse.errors.length).toEqual(1); // formatError should be called after extensions expect(formatError).not.toBeCalled(); @@ -636,8 +639,11 @@ export function testApolloServer( return error; }); - class Extension extends GraphQLExtension { - willSendResponse(_o: { graphqlResponse: GraphQLResponse }) { + class Extension extends GraphQLExtension { + willSendResponse(_o: { + graphqlResponse: GraphQLResponse; + context: TContext; + }) { // formatError should be called after extensions expect(formatError).not.toBeCalled(); extension(); diff --git a/packages/graphql-extensions/src/index.ts b/packages/graphql-extensions/src/index.ts index aae80b7a1a9..7a706c599b3 100644 --- a/packages/graphql-extensions/src/index.ts +++ b/packages/graphql-extensions/src/index.ts @@ -33,6 +33,7 @@ export class GraphQLExtension { variables?: { [key: string]: any }; persistedQueryHit?: boolean; persistedQueryRegister?: boolean; + context: TContext; }): EndHandler | void; public parsingDidStart?(o: { queryString: string }): EndHandler | void; public validationDidStart?(): EndHandler | void; @@ -42,7 +43,8 @@ export class GraphQLExtension { public willSendResponse?(o: { graphqlResponse: GraphQLResponse; - }): void | { graphqlResponse: GraphQLResponse }; + context: TContext; + }): void | { graphqlResponse: GraphQLResponse; context: TContext }; public willResolveField?( source: any, @@ -71,7 +73,7 @@ export class GraphQLExtensionStack { variables?: { [key: string]: any }; persistedQueryHit?: boolean; persistedQueryRegister?: boolean; - extensions?: Record; + context: TContext; }): EndHandler { return this.handleDidStart( ext => ext.requestDidStart && ext.requestDidStart(o), @@ -98,7 +100,8 @@ export class GraphQLExtensionStack { public willSendResponse(o: { graphqlResponse: GraphQLResponse; - }): { graphqlResponse: GraphQLResponse } { + context: TContext; + }): { graphqlResponse: GraphQLResponse; context: TContext } { let reference = o; // Reverse the array, since this is functions as an end handler [...this.extensions].reverse().forEach(extension => {