diff --git a/CHANGELOG.md b/CHANGELOG.md index d08dca380a8..abe87e7f253 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All of the packages in the `apollo-server` repo are released with the same versi ### vNEXT +- Core: Allow context to be passed to all GraphQLExtension methods. [PR #1547](https://github.com/apollographql/apollo-server/pull/1547) + ### v2.0.7 - Fix [#1581](https://github.com/apollographql/apollo-server/issues/1581) `apollo-server-micro` top level error response [#1619](https://github.com/apollographql/apollo-server/pull/1619) diff --git a/packages/apollo-engine-reporting/src/extension.ts b/packages/apollo-engine-reporting/src/extension.ts index 74a58efbfe2..fe3b66ae5d0 100644 --- a/packages/apollo-engine-reporting/src/extension.ts +++ b/packages/apollo-engine-reporting/src/extension.ts @@ -57,7 +57,7 @@ export class EngineReportingExtension request: Request; queryString?: string; parsedQuery?: DocumentNode; - variables: Record; + variables?: Record; persistedQueryHit?: boolean; persistedQueryRegister?: boolean; }): EndHandler { @@ -139,7 +139,7 @@ export class EngineReportingExtension this.trace.details!.variablesJson![name] = ''; } else { this.trace.details!.variablesJson![name] = JSON.stringify( - o.variables[name], + o.variables![name], ); } }); diff --git a/packages/apollo-server-core/src/__tests__/runQuery.test.ts b/packages/apollo-server-core/src/__tests__/runQuery.test.ts index cc3ea0e98ab..f2b6729eda4 100644 --- a/packages/apollo-server-core/src/__tests__/runQuery.test.ts +++ b/packages/apollo-server-core/src/__tests__/runQuery.test.ts @@ -353,6 +353,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 8e708b41393..8cedf112d20 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-core/src/runQuery.ts b/packages/apollo-server-core/src/runQuery.ts index 12c33fbbaa1..516750dfd78 100644 --- a/packages/apollo-server-core/src/runQuery.ts +++ b/packages/apollo-server-core/src/runQuery.ts @@ -135,6 +135,7 @@ function doRunQuery(options: QueryOptions): Promise { variables: options.variables, persistedQueryHit: options.persistedQueryHit, persistedQueryRegister: options.persistedQueryRegister, + context, }); return Promise.resolve() .then( @@ -278,7 +279,10 @@ function doRunQuery(options: QueryOptions): Promise { throw err; }) .then((graphqlResponse: GraphQLResponse) => { - const response = extensionStack.willSendResponse({ graphqlResponse }); + const response = extensionStack.willSendResponse({ + graphqlResponse, + context, + }); requestDidEnd(); return response.graphqlResponse; }); diff --git a/packages/apollo-server-integration-testsuite/src/ApolloServer.ts b/packages/apollo-server-integration-testsuite/src/ApolloServer.ts index 22981425598..fbe88bbe8ed 100644 --- a/packages/apollo-server-integration-testsuite/src/ApolloServer.ts +++ b/packages/apollo-server-integration-testsuite/src/ApolloServer.ts @@ -526,8 +526,11 @@ export function testApolloServer( return error; }); - 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(); @@ -609,8 +612,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 e09457768db..b7f358f6da8 100644 --- a/packages/graphql-extensions/src/index.ts +++ b/packages/graphql-extensions/src/index.ts @@ -40,6 +40,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; @@ -49,7 +50,8 @@ export class GraphQLExtension { public willSendResponse?(o: { graphqlResponse: GraphQLResponse; - }): void | { graphqlResponse: GraphQLResponse }; + context: TContext; + }): void | { graphqlResponse: GraphQLResponse; context: TContext }; public willResolveField?( source: any, @@ -78,6 +80,7 @@ export class GraphQLExtensionStack { variables?: { [key: string]: any }; persistedQueryHit?: boolean; persistedQueryRegister?: boolean; + context: TContext; }): EndHandler { return this.handleDidStart( ext => ext.requestDidStart && ext.requestDidStart(o), @@ -104,7 +107,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 => {