Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/fix-onoriginrequest-async-signature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@bunny.net/edgescript-sdk": patch
---

`onOriginRequest`'s old `Promise<Request> | Promise<Response>` signature
doesn't accept `async` callbacks returning a mix of the two: TS infers
`Promise<Request | Response>` 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<Request | Response>`
* `onOriginResponse`: `(ctx) => Response | Promise<Response>`

Same shape as `ServerHandler`, strictly wider, nothing breaks.
51 changes: 51 additions & 0 deletions libs/bunny-sdk/src/net/serve.test.ts
Original file line number Diff line number Diff line change
@@ -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<Http.PullZoneHandler["onOriginRequest"]>[0];
type OnResponse = Parameters<Http.PullZoneHandler["onOriginResponse"]>[0];

// Async arrow with mixed Request / Response returns — async-flattening
// produces `Promise<Request | Response>`. Used to fail under the previous
// `Promise<Request> | Promise<Response>` 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) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick, but we could probably drop this. The inferred type ends up being the same.

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");
});
8 changes: 4 additions & 4 deletions libs/bunny-sdk/src/net/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export type PullZoneHandler = {
onOriginRequest: (
middleware: (
ctx: OriginRequestContext,
) => Promise<Request> | Promise<Response>,
) => Request | Response | Promise<Request | Response>,
) => PullZoneHandler;

/**
Expand All @@ -145,7 +145,7 @@ export type PullZoneHandler = {
onOriginResponse: (
middleware: (
ctx: OriginResponseContext,
) => Promise<Response>,
) => Response | Promise<Response>,
) => PullZoneHandler;
};

Expand Down Expand Up @@ -234,12 +234,12 @@ function servePullZone(
const onOriginRequestMiddleware: Array<
(
ctx: OriginRequestContext,
) => Promise<Request> | Promise<Response> | undefined
) => Request | Response | Promise<Request | Response> | undefined
> = [];
const onOriginResponseMiddleware: Array<
(
ctx: OriginResponseContext,
) => Promise<Response> | undefined
) => Response | Promise<Response> | undefined
> = [];

const platform = internal_getPlatform();
Expand Down
4 changes: 2 additions & 2 deletions libs/bunny-sdk/types/bunny.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ declare namespace Bunny {
registerMiddlewares: (middlewares: {
onOriginRequest: Array<(
ctx: { request: Request },
) => Promise<Request> | Promise<Response> | undefined>
) => Request | Response | Promise<Request | Response> | undefined>
onOriginResponse: Array<(
ctx: { request: Request, response: Response },
) => Promise<Request> | Promise<Response> | undefined>
) => Response | Promise<Response> | undefined>
}) => void,
};

Expand Down
Loading