From ee83665c5e01acbcfaaddcd552f2f6d2d3e8006c Mon Sep 17 00:00:00 2001 From: Gaubee Date: Mon, 2 Dec 2024 09:08:18 +0800 Subject: [PATCH] feat: Use honoReq's bodyCache to provide a body function for trpc's req (#850) Some middleware (in createContext) may need to read the body. If the raw request instance is provided directly, the body will be consumed prematurely, blocking the development of middleware. --- .changeset/chilly-experts-sneeze.md | 5 +++++ packages/trpc-server/src/index.ts | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .changeset/chilly-experts-sneeze.md diff --git a/.changeset/chilly-experts-sneeze.md b/.changeset/chilly-experts-sneeze.md new file mode 100644 index 00000000..df53a008 --- /dev/null +++ b/.changeset/chilly-experts-sneeze.md @@ -0,0 +1,5 @@ +--- +'@hono/trpc-server': patch +--- + +Use honoReq's bodyCache to provide a body function for trpc's req diff --git a/packages/trpc-server/src/index.ts b/packages/trpc-server/src/index.ts index 5b8fd34d..b2b572b4 100644 --- a/packages/trpc-server/src/index.ts +++ b/packages/trpc-server/src/index.ts @@ -22,7 +22,10 @@ export const trpcServer = ({ createContext, ...rest }: tRPCOptions): MiddlewareHandler => { + const bodyProps = new Set(['arrayBuffer', 'blob', 'formData', 'json', 'text'] as const) + type BodyProp = typeof bodyProps extends Set ? T : never return async (c) => { + const canWithBody = c.req.method === 'GET' || c.req.method === 'HEAD' const res = fetchRequestHandler({ ...rest, createContext: async (opts) => ({ @@ -31,7 +34,16 @@ export const trpcServer = ({ env: c.env, }), endpoint, - req: c.req.raw, + req: canWithBody + ? c.req.raw + : new Proxy(c.req.raw, { + get(t, p, r) { + if (bodyProps.has(p as BodyProp)) { + return () => c.req[p as BodyProp]() + } + return Reflect.get(t, p, r) + }, + }), }).then((res) => c.body(res.body, res)) return res }