diff --git a/packages/hono/README.md b/packages/hono/README.md index 669209ef..a2330c26 100644 --- a/packages/hono/README.md +++ b/packages/hono/README.md @@ -25,3 +25,18 @@ import api from "./api"; const app = new Hono(); app.use("*", stlApi(api)); ``` + +Individual handlers can also use Hono responses: + +```ts +const retrieve = stl.endpoint({ + endpoint: "GET /api/posts", + response: z.any() as z.ZodType, + handler: (_, context) => { + const [c] = context.server.args; + + // c is a Hono context + return c.redirect("/"); + }, +}); +``` diff --git a/packages/hono/src/honoPlugin.test.ts b/packages/hono/src/honoPlugin.test.ts index bfcda194..ac9023a3 100644 --- a/packages/hono/src/honoPlugin.test.ts +++ b/packages/hono/src/honoPlugin.test.ts @@ -182,6 +182,19 @@ describe("hono passthrough", () => { }), }, }), + redirect: stl.resource({ + summary: "redirect", + actions: { + retrieve: stl.endpoint({ + endpoint: "GET /api/redirect", + response: z.any() as z.ZodType, + handler: (_, context) => { + const [c] = context.server.args; + return c.redirect("/"); + }, + }), + }, + }), }, }); @@ -197,6 +210,12 @@ describe("hono passthrough", () => { return c.text(`custom error: ${err.message}`, 500); }); + test("hono response", async () => { + const response = await app.request("/api/redirect"); + expect(response).toHaveProperty("status", 302); + expect(response.headers.get("location")).toMatchInlineSnapshot(`"/"`); + }); + test("public passthrough", async () => { const response = await app.request("/public/foo/bar"); expect(response).toHaveProperty("status", 200); diff --git a/packages/hono/src/honoPlugin.ts b/packages/hono/src/honoPlugin.ts index dff8ff10..f31a14d1 100644 --- a/packages/hono/src/honoPlugin.ts +++ b/packages/hono/src/honoPlugin.ts @@ -83,6 +83,10 @@ function makeHandler(endpoints: AnyEndpoint[], options?: StlAppOptions) { const result = await stl.execute(params, context); + if (result instanceof Response) { + return result; + } + return c.json(result); } catch (error) { if (options?.handleErrors === false) {