fix(trpc-server): Support asynchronous context creation (#482)
* Support asynchronous context generation * Added changesetpull/484/head
parent
9c98a73405
commit
4446eeeb9f
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/trpc-server': minor
|
||||
---
|
||||
|
||||
Support asynchronous context creation for trpc server middleware
|
|
@ -5,14 +5,14 @@ import type { Context, MiddlewareHandler } from 'hono'
|
|||
|
||||
type tRPCOptions = Omit<FetchHandlerRequestOptions<AnyRouter>, 'req' | 'endpoint' | 'createContext'> &
|
||||
Partial<Pick<FetchHandlerRequestOptions<AnyRouter>, 'endpoint'>> &
|
||||
{ createContext? (opts: FetchCreateContextFnOptions, c: Context): Record<string, unknown> }
|
||||
{ createContext? (opts: FetchCreateContextFnOptions, c: Context): Record<string, unknown> | Promise<Record<string, unknown>> }
|
||||
|
||||
export const trpcServer = ({ endpoint = '/trpc', createContext, ...rest }: tRPCOptions): MiddlewareHandler => {
|
||||
return async (c) => {
|
||||
const res = fetchRequestHandler({
|
||||
...rest,
|
||||
createContext: (opts) => ({
|
||||
...createContext ? createContext(opts, c) : {},
|
||||
createContext: async (opts) => ({
|
||||
...createContext ? await createContext(opts, c) : {},
|
||||
// propagate env by default
|
||||
env: c.env,
|
||||
}),
|
||||
|
|
|
@ -2,7 +2,7 @@ import { initTRPC } from '@trpc/server'
|
|||
import { Hono } from 'hono'
|
||||
import { trpcServer } from '../src'
|
||||
|
||||
describe('tRPC Adapter Middleware passing Context', () => {
|
||||
describe('tRPC Adapter Middleware passing synchronous Context', () => {
|
||||
type Env = {
|
||||
NAME: string;
|
||||
}
|
||||
|
@ -65,3 +65,68 @@ describe('tRPC Adapter Middleware passing Context', () => {
|
|||
])
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('tRPC Adapter Middleware passing asynchronous Context', () => {
|
||||
type Env = {
|
||||
NAME: string;
|
||||
}
|
||||
type HonoContext = {
|
||||
env: Env,
|
||||
batch: string;
|
||||
};
|
||||
|
||||
const t = initTRPC.context<HonoContext>().create()
|
||||
|
||||
const publicProcedure = t.procedure.use(
|
||||
t.middleware((opts) => {
|
||||
return opts.next({
|
||||
ctx: {
|
||||
// add .env into context, simulating a middleware as cloudflare pages
|
||||
env: {
|
||||
DB: {
|
||||
getName: () => 'World'
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
const router = t.router
|
||||
|
||||
const appRouter = router({
|
||||
hello: publicProcedure.query(({ ctx }) => {
|
||||
return `Hello ${ctx.env.DB.getName()}, batch is ${ctx.batch}`
|
||||
}),
|
||||
})
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use(
|
||||
'/trpc/*',
|
||||
trpcServer({
|
||||
router: appRouter,
|
||||
// optional createContext, additional `c` arg with the hono context
|
||||
createContext: async (_opts, c) => ({
|
||||
batch: c.req.query('batch'),
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
it.only('Should return 200 response', async () => {
|
||||
const searchParams = new URLSearchParams({
|
||||
input: JSON.stringify({ '0': 'Hono' }),
|
||||
batch: '2',
|
||||
})
|
||||
const req = new Request(`http://localhost/trpc/hello?${searchParams.toString()}`)
|
||||
const res = await app.request(req)
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual([
|
||||
{
|
||||
result: {
|
||||
data: 'Hello World, batch is 2',
|
||||
},
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue