From dc491756c0225130b81f2d044eccf1a0e81408ae Mon Sep 17 00:00:00 2001 From: Stefan Maric Date: Mon, 11 May 2026 12:19:23 +0200 Subject: [PATCH 1/2] fix: accept async/sync middleware on `onOriginRequest` / `onOriginResponse` `onOriginRequest`'s old `Promise | Promise` signature doesn't accept `async` callbacks returning a mix of the two: TS infers `Promise` for them, which is a supertype the narrower union won't accept. Flagged in #63 and partially fixed in #64 (which only touched the ambient declaration). Widen both hooks, with sync returns too: * `onOriginRequest`: `(ctx) => Request | Response | Promise` * `onOriginResponse`: `(ctx) => Response | Promise` Same shape as `ServerHandler`, strictly wider, nothing breaks. Internal middleware arrays and the ambient `Bunny.v1.registerMiddlewares` get the same widening; runtime is unchanged since both call sites already `await mid(...)`. `src/net/serve.test.ts` covers sync, async, and mixed at the type level. --- .../fix-onoriginrequest-async-signature.md | 16 ++++++ libs/bunny-sdk/src/net/serve.test.ts | 51 +++++++++++++++++++ libs/bunny-sdk/src/net/serve.ts | 8 +-- libs/bunny-sdk/types/bunny.d.ts | 4 +- 4 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 .changeset/fix-onoriginrequest-async-signature.md create mode 100644 libs/bunny-sdk/src/net/serve.test.ts diff --git a/.changeset/fix-onoriginrequest-async-signature.md b/.changeset/fix-onoriginrequest-async-signature.md new file mode 100644 index 0000000..7307112 --- /dev/null +++ b/.changeset/fix-onoriginrequest-async-signature.md @@ -0,0 +1,16 @@ +--- +"@bunny.net/edgescript-sdk": minor +--- + +`onOriginRequest`'s old `Promise | Promise` signature +doesn't accept `async` callbacks returning a mix of the two: TS infers +`Promise` for them, which is a supertype the narrower +union won't accept. Flagged in #63 and partially fixed in #64 (which only +touched the ambient declaration). + +Widen both hooks, with sync returns too: + +* `onOriginRequest`: `(ctx) => Request | Response | Promise` +* `onOriginResponse`: `(ctx) => Response | Promise` + +Same shape as `ServerHandler`, strictly wider, nothing breaks. diff --git a/libs/bunny-sdk/src/net/serve.test.ts b/libs/bunny-sdk/src/net/serve.test.ts new file mode 100644 index 0000000..170bc08 --- /dev/null +++ b/libs/bunny-sdk/src/net/serve.test.ts @@ -0,0 +1,51 @@ +// Type-level tests for the middleware signatures on `servePullZone`. +// The callbacks below are typechecked but never invoked — these +// exist purely to ensure the public signatures accept all the shapes +// documented in the JSDoc. If any stop typechecking, it's a regression. + +import type * as Http from "./serve.ts"; + +type OnRequest = Parameters[0]; +type OnResponse = Parameters[0]; + +// Async arrow with mixed Request / Response returns — async-flattening +// produces `Promise`. Used to fail under the previous +// `Promise | Promise` signature. +const _asyncMixed: OnRequest = async (ctx) => { + if (ctx.request.headers.get("upgrade") === "websocket") { + return new Response(null, { status: 426 }); + } + return new Request(ctx.request); +}; + +// Plain function returning `Promise.resolve(...)` — the classic workaround. +const _promiseResolve: OnRequest = (ctx) => { + if (ctx.request.headers.get("x-block") === "1") { + return Promise.resolve(new Response(null, { status: 403 })); + } + return Promise.resolve(new Request(ctx.request)); +}; + +// Sync returns — mirrors the `ServerHandler` pattern. +const _sync: OnRequest = (ctx) => { + if (ctx.request.headers.get("x-fast-path") === "1") { + return new Response("ok"); + } + return new Request(ctx.request); +}; + +// `onOriginResponse` accepts sync and async too. +const _resSync: OnResponse = (ctx) => ctx.response; +const _resAsync: OnResponse = async (ctx) => { + ctx.response.headers.set("Via", "Custom"); + return ctx.response; +}; + +test("middleware type signatures accept sync, async, and mixed returns", () => { + // Silence unused-var warnings; the real check is at compile time. + expect(typeof _asyncMixed).toBe("function"); + expect(typeof _promiseResolve).toBe("function"); + expect(typeof _sync).toBe("function"); + expect(typeof _resSync).toBe("function"); + expect(typeof _resAsync).toBe("function"); +}); diff --git a/libs/bunny-sdk/src/net/serve.ts b/libs/bunny-sdk/src/net/serve.ts index bdb594d..2aa7d54 100644 --- a/libs/bunny-sdk/src/net/serve.ts +++ b/libs/bunny-sdk/src/net/serve.ts @@ -136,7 +136,7 @@ export type PullZoneHandler = { onOriginRequest: ( middleware: ( ctx: OriginRequestContext, - ) => Promise | Promise, + ) => Request | Response | Promise, ) => PullZoneHandler; /** @@ -145,7 +145,7 @@ export type PullZoneHandler = { onOriginResponse: ( middleware: ( ctx: OriginResponseContext, - ) => Promise, + ) => Response | Promise, ) => PullZoneHandler; }; @@ -234,12 +234,12 @@ function servePullZone( const onOriginRequestMiddleware: Array< ( ctx: OriginRequestContext, - ) => Promise | Promise | undefined + ) => Request | Response | Promise | undefined > = []; const onOriginResponseMiddleware: Array< ( ctx: OriginResponseContext, - ) => Promise | undefined + ) => Response | Promise | undefined > = []; const platform = internal_getPlatform(); diff --git a/libs/bunny-sdk/types/bunny.d.ts b/libs/bunny-sdk/types/bunny.d.ts index 18314fa..323985f 100644 --- a/libs/bunny-sdk/types/bunny.d.ts +++ b/libs/bunny-sdk/types/bunny.d.ts @@ -14,10 +14,10 @@ declare namespace Bunny { registerMiddlewares: (middlewares: { onOriginRequest: Array<( ctx: { request: Request }, - ) => Promise | Promise | undefined> + ) => Request | Response | Promise | undefined> onOriginResponse: Array<( ctx: { request: Request, response: Response }, - ) => Promise | Promise | undefined> + ) => Response | Promise | undefined> }) => void, }; From fc252dae4fbffae6bdb08e16183c24bc17634e98 Mon Sep 17 00:00:00 2001 From: Jamie Barton Date: Thu, 18 Jun 2026 12:23:19 +0100 Subject: [PATCH 2/2] Apply suggestion from @jamie-at-bunny --- .changeset/fix-onoriginrequest-async-signature.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fix-onoriginrequest-async-signature.md b/.changeset/fix-onoriginrequest-async-signature.md index 7307112..bc8c991 100644 --- a/.changeset/fix-onoriginrequest-async-signature.md +++ b/.changeset/fix-onoriginrequest-async-signature.md @@ -1,5 +1,5 @@ --- -"@bunny.net/edgescript-sdk": minor +"@bunny.net/edgescript-sdk": patch --- `onOriginRequest`'s old `Promise | Promise` signature