diff --git a/packages/wobe-graphql-apollo/package.json b/packages/wobe-graphql-apollo/package.json index 28e44c9..e86bd40 100644 --- a/packages/wobe-graphql-apollo/package.json +++ b/packages/wobe-graphql-apollo/package.json @@ -1,6 +1,6 @@ { "name": "wobe-graphql-apollo", - "version": "1.0.2", + "version": "1.0.3", "description": "Apollo GraphQL server for Wobe (official)", "homepage": "https://wobe.dev", "author": { diff --git a/packages/wobe-graphql-apollo/src/index.test.ts b/packages/wobe-graphql-apollo/src/index.test.ts index 4642f25..148b9d6 100644 --- a/packages/wobe-graphql-apollo/src/index.test.ts +++ b/packages/wobe-graphql-apollo/src/index.test.ts @@ -4,6 +4,62 @@ import getPort from 'get-port' import { WobeGraphqlApolloPlugin } from '.' describe('Wobe GraphQL Apollo plugin', () => { + it('should have WobeResponse in graphql context', async () => { + const port = await getPort() + + const wobe = new Wobe() + + wobe.usePlugin( + await WobeGraphqlApolloPlugin({ + options: { + typeDefs: `#graphql + type Query { + hello: String + } + `, + resolvers: { + Query: { + hello: (_, __, context) => { + context.response.setCookie('before', 'before') + + expect(context.response).toBeDefined() + expect(context.request).toBeDefined() + return 'Hello from Apollo!' + }, + }, + }, + }, + context: async (tutu) => { + return { tata: 'test' } + }, + }), + ) + + wobe.listen(port) + + const res = await fetch(`http://127.0.0.1:${port}/graphql`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query: ` + query { + hello + } + `, + }), + }) + + expect(res.status).toBe(200) + expect(res.headers.get('set-cookie')).toBe('before=before;') + expect(await res.json()).toEqual({ + data: { hello: 'Hello from Apollo!' }, + }) + + wobe.stop() + }) + it("should use the graphql middleware if it's provided", async () => { const port = await getPort() @@ -84,7 +140,7 @@ describe('Wobe GraphQL Apollo plugin', () => { }, }, }, - context: async (request) => { + context: async ({ request }) => { expect(request.method).toBe('POST') return { tata: 'test' } diff --git a/packages/wobe-graphql-apollo/src/index.ts b/packages/wobe-graphql-apollo/src/index.ts index aec3f99..2f218a0 100644 --- a/packages/wobe-graphql-apollo/src/index.ts +++ b/packages/wobe-graphql-apollo/src/index.ts @@ -26,7 +26,10 @@ export const WobeGraphqlApolloPlugin = async ({ }: { options: ApolloServerOptions graphqlEndpoint?: string - context?: (request: Request) => MaybePromise + context?: (options: { + request: Request + response: WobeResponse + }) => MaybePromise } & GraphQLApolloPluginOptions): Promise => { const server = new ApolloServer({ ...options, @@ -45,77 +48,78 @@ export const WobeGraphqlApolloPlugin = async ({ await server.start() return (wobe: Wobe) => { - const fetchEndpoint = async (request: Request) => { - const res = await server.executeHTTPGraphQLRequest({ - httpGraphQLRequest: { - method: request.method, - body: await request.json(), - // @ts-expect-error - headers: request.headers, - search: getQueryString(request.url), - }, - context: context ? () => context(request) as any : () => ({}), - }) - - if (res.body.kind === 'complete') { - const response = new Response(res.body.string, { - status: res.status ?? 200, - // @ts-expect-error - headers: res.headers, + const getResponse = async ( + request: Request, + wobeResponse: WobeResponse, + ) => { + const fetchEndpoint = async (request: Request) => { + const res = await server.executeHTTPGraphQLRequest({ + httpGraphQLRequest: { + method: request.method, + body: await request.json(), + // @ts-expect-error + headers: request.headers, + search: getQueryString(request.url), + }, + context: async () => ({ + request: request, + response: wobeResponse, + ...(context + ? await context({ request, response: wobeResponse }) + : {}), + }), }) - return response - } + if (res.body.kind === 'complete') { + const response = new Response(res.body.string, { + status: res.status ?? 200, + // @ts-expect-error + headers: res.headers, + }) - return new Response() - } + return response + } + + return new Response() + } - wobe.get(graphqlEndpoint, async ({ request, res: wobeResponse }) => { if (!graphqlMiddleware) return fetchEndpoint(request) - const responseAfterMiddleware = await graphqlMiddleware( - async () => { - const response = await fetchEndpoint(request) + return graphqlMiddleware(async () => { + const response = await fetchEndpoint(request) - return response - }, - wobeResponse, - ) + return response + }, wobeResponse) + } + + wobe.get(graphqlEndpoint, async ({ request, res: wobeResponse }) => { + const response = await getResponse(request, wobeResponse) for (const [key, value] of wobeResponse.headers.entries()) { if (key === 'set-cookie') { - responseAfterMiddleware.headers.append('set-cookie', value) + response.headers.append('set-cookie', value) continue } - responseAfterMiddleware.headers.set(key, value) + response.headers.set(key, value) } - return responseAfterMiddleware + return response }) wobe.post(graphqlEndpoint, async ({ request, res: wobeResponse }) => { - if (!graphqlMiddleware) return fetchEndpoint(request) - - const responseAfterMiddleware = await graphqlMiddleware( - async () => { - const response = await fetchEndpoint(request) - - return response - }, - wobeResponse, - ) + const response = await getResponse(request, wobeResponse) for (const [key, value] of wobeResponse.headers.entries()) { if (key === 'set-cookie') { - responseAfterMiddleware.headers.append('set-cookie', value) + response.headers.append('set-cookie', value) continue } - responseAfterMiddleware.headers.set(key, value) + response.headers.set(key, value) } - return responseAfterMiddleware + return response }) } }