Skip to content

Commit

Permalink
Merge branch 'main' of github.com:coratgerl/wobe
Browse files Browse the repository at this point in the history
  • Loading branch information
coratgerl committed Jul 23, 2024
2 parents 20a298b + d5dc858 commit 2774bec
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 58 deletions.
63 changes: 61 additions & 2 deletions packages/wobe-graphql-apollo/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,65 @@ import getPort from 'get-port'
import { WobeGraphqlApolloPlugin } from '.'

describe('Wobe GraphQL Apollo plugin', () => {
it('should have custom wobe context in graphql context', async () => {
const port = await getPort()

const wobe = new Wobe<{ customType: string }>().beforeHandler((ctx) => {
ctx.customType = 'test'
})

wobe.usePlugin(
await WobeGraphqlApolloPlugin({
options: {
typeDefs: `#graphql
type Query {
hello: String
}
`,
resolvers: {
Query: {
hello: (_, __, context) => {
context.res.setCookie('before', 'before')

expect(context.res).toBeDefined()
expect(context.request).toBeDefined()
expect(context.customType).toEqual('test')
return 'Hello from Apollo!'
},
},
},
},
context: async () => {
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 have WobeResponse in graphql context', async () => {
const port = await getPort()

Expand All @@ -20,9 +79,9 @@ describe('Wobe GraphQL Apollo plugin', () => {
resolvers: {
Query: {
hello: (_, __, context) => {
context.response.setCookie('before', 'before')
context.res.setCookie('before', 'before')

expect(context.response).toBeDefined()
expect(context.res).toBeDefined()
expect(context.request).toBeDefined()
return 'Hello from Apollo!'
},
Expand Down
47 changes: 22 additions & 25 deletions packages/wobe-graphql-apollo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import {
ApolloServerPluginLandingPageLocalDefault,
ApolloServerPluginLandingPageProductionDefault,
} from '@apollo/server/plugin/landingPage/default'
import type { Wobe, MaybePromise, WobePlugin, WobeResponse } from 'wobe'
import type {
Wobe,
MaybePromise,
WobePlugin,
WobeResponse,
Context,
} from 'wobe'

const getQueryString = (url: string) => url.slice(url.indexOf('?', 11) + 1)

Expand All @@ -22,14 +28,11 @@ export const WobeGraphqlApolloPlugin = async ({
options,
graphqlEndpoint = '/graphql',
graphqlMiddleware,
context,
context: apolloContext,
}: {
options: ApolloServerOptions<any>
graphqlEndpoint?: string
context?: (options: {
request: Request
response: WobeResponse
}) => MaybePromise<BaseContext>
context?: (options: Context) => MaybePromise<BaseContext>
} & GraphQLApolloPluginOptions): Promise<WobePlugin> => {
const server = new ApolloServer({
...options,
Expand All @@ -47,11 +50,8 @@ export const WobeGraphqlApolloPlugin = async ({

await server.start()

return (wobe: Wobe) => {
const getResponse = async (
request: Request,
wobeResponse: WobeResponse,
) => {
return (wobe: Wobe<unknown>) => {
const getResponse = async (context: Context) => {
const fetchEndpoint = async (request: Request) => {
const res = await server.executeHTTPGraphQLRequest({
httpGraphQLRequest: {
Expand All @@ -65,11 +65,8 @@ export const WobeGraphqlApolloPlugin = async ({
search: getQueryString(request.url),
},
context: async () => ({
request: request,
response: wobeResponse,
...(context
? await context({ request, response: wobeResponse })
: {}),
...context,
...(apolloContext ? await apolloContext(context) : {}),
}),
})

Expand All @@ -86,19 +83,19 @@ export const WobeGraphqlApolloPlugin = async ({
return new Response()
}

if (!graphqlMiddleware) return fetchEndpoint(request)
if (!graphqlMiddleware) return fetchEndpoint(context.request)

return graphqlMiddleware(async () => {
const response = await fetchEndpoint(request)
const response = await fetchEndpoint(context.request)

return response
}, wobeResponse)
}, context.res)
}

wobe.get(graphqlEndpoint, async ({ request, res: wobeResponse }) => {
const response = await getResponse(request, wobeResponse)
wobe.get(graphqlEndpoint, async (context) => {
const response = await getResponse(context)

for (const [key, value] of wobeResponse.headers.entries()) {
for (const [key, value] of context.res.headers.entries()) {
if (key === 'set-cookie') {
response.headers.append('set-cookie', value)
continue
Expand All @@ -110,10 +107,10 @@ export const WobeGraphqlApolloPlugin = async ({
return response
})

wobe.post(graphqlEndpoint, async ({ request, res: wobeResponse }) => {
const response = await getResponse(request, wobeResponse)
wobe.post(graphqlEndpoint, async (context) => {
const response = await getResponse(context)

for (const [key, value] of wobeResponse.headers.entries()) {
for (const [key, value] of context.res.headers.entries()) {
if (key === 'set-cookie') {
response.headers.append('set-cookie', value)
continue
Expand Down
62 changes: 59 additions & 3 deletions packages/wobe-graphql-yoga/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,62 @@ import getPort from 'get-port'
import { WobeGraphqlYogaPlugin } from '.'

describe('Wobe GraphQL Yoga plugin', () => {
it('should set the wobe response in the graphql context', async () => {
const port = await getPort()
const wobe = new Wobe<{ customType: string }>().beforeHandler((ctx) => {
ctx.customType = 'test'
})

wobe.usePlugin(
WobeGraphqlYogaPlugin({
typeDefs: `
type Query {
hello: String
}
`,
resolvers: {
Query: {
hello: (_, __, context: any) => {
context.res.setCookie('tata', 'tata')
expect(context.test).toBeDefined()
expect(context.res).toBeDefined()
expect(context.request.headers).toBeDefined()
expect(context.customType).toEqual('test')
return 'Hello from Yoga!'
},
},
},
context: () => {
return { test: '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.headers.get('set-cookie')).toBe('tata=tata;')
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
data: { hello: 'Hello from Yoga!' },
})

wobe.stop()
})

it('should set the wobe response in the graphql context', async () => {
const port = await getPort()
const wobe = new Wobe()
Expand All @@ -18,10 +74,10 @@ describe('Wobe GraphQL Yoga plugin', () => {
`,
resolvers: {
Query: {
hello: (_, __, context) => {
context.response.setCookie('tata', 'tata')
hello: (_, __, context: any) => {
context.res.setCookie('tata', 'tata')
expect(context.test).toBeDefined()
expect(context.response).toBeDefined()
expect(context.res).toBeDefined()
expect(context.request.headers).toBeDefined()
return 'Hello from Yoga!'
},
Expand Down
46 changes: 18 additions & 28 deletions packages/wobe-graphql-yoga/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import {
type GraphQLSchemaWithContext,
type YogaServerOptions,
} from 'graphql-yoga'
import type { MaybePromise, Wobe, WobePlugin, WobeResponse } from 'wobe'
import type {
Context,
MaybePromise,
Wobe,
WobePlugin,
WobeResponse,
} from 'wobe'

export type GraphqlYogaContext =
| MaybePromise<Record<string, unknown>>
| ((context: {
request: Request
response: WobeResponse
}) => MaybePromise<unknown>)
| ((context: any) => MaybePromise<unknown>)

export interface GraphqlYogaPluginOptions {
graphqlMiddleware?: (
Expand Down Expand Up @@ -43,30 +46,19 @@ export const WobeGraphqlYogaPlugin = ({
}),
})

const handleGraphQLRequest = async (
request: Request,
res: WobeResponse,
) => {
const handleGraphQLRequest = async (context: Context) => {
const getResponse = async () => {
if (!graphqlMiddleware)
return yoga.handle(request, {
response: res,
request,
})
if (!graphqlMiddleware) return yoga.handle(context.request, context)

return graphqlMiddleware(
async () =>
yoga.handle(request, {
response: res,
request,
}),
res,
async () => yoga.handle(context.request, context),
context.res,
)
}

const response = await getResponse()

for (const [key, value] of res.headers.entries()) {
for (const [key, value] of context.res.headers.entries()) {
if (key === 'set-cookie') {
response.headers.append('set-cookie', value)
continue
Expand All @@ -78,14 +70,12 @@ export const WobeGraphqlYogaPlugin = ({
return response
}

return (wobe: Wobe) => {
wobe.get(
options?.graphqlEndpoint || '/graphql',
async ({ request, res }) => handleGraphQLRequest(request, res),
return (wobe: Wobe<unknown>) => {
wobe.get(options?.graphqlEndpoint || '/graphql', async (context) =>
handleGraphQLRequest(context),
)
wobe.post(
options?.graphqlEndpoint || '/graphql',
async ({ request, res }) => handleGraphQLRequest(request, res),
wobe.post(options?.graphqlEndpoint || '/graphql', async (context) =>
handleGraphQLRequest(context),
)
}
}

0 comments on commit 2774bec

Please sign in to comment.