Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0da8e4a

Browse files
committed
feat: support fetchable object for dynamic handlers
1 parent b2ce1af commit 0da8e4a

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

src/handler.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
EventHandlerResponse,
1111
DynamicEventHandler,
1212
EventHandlerWithFetch,
13+
FetchableObject,
1314
} from "./types/handler.ts";
1415
import type {
1516
InferOutput,
@@ -130,14 +131,14 @@ function handlerWithFetch<
130131
// --- dynamic event handler ---
131132

132133
export function dynamicEventHandler(
133-
initial?: EventHandler,
134+
initial?: EventHandler | FetchableObject,
134135
): DynamicEventHandler {
135-
let current: EventHandler | undefined = initial;
136+
let current: EventHandler | undefined = _toEventHandler(initial);
136137
return Object.assign(
137138
defineHandler((event: H3Event) => current?.(event)),
138139
{
139-
set: (handler: EventHandler) => {
140-
current = handler;
140+
set: (handler: EventHandler | FetchableObject) => {
141+
current = _toEventHandler(handler);
141142
},
142143
},
143144
);
@@ -146,7 +147,10 @@ export function dynamicEventHandler(
146147
// --- lazy event handler ---
147148

148149
export function defineLazyEventHandler(
149-
load: () => Promise<EventHandler> | EventHandler,
150+
load: () =>
151+
| Promise<EventHandler | FetchableObject>
152+
| EventHandler
153+
| FetchableObject,
150154
): EventHandlerWithFetch {
151155
let _promise: Promise<typeof _resolved>;
152156
let _resolved: { handler: EventHandler };
@@ -157,14 +161,16 @@ export function defineLazyEventHandler(
157161
}
158162
if (!_promise) {
159163
_promise = Promise.resolve(load()).then((r: any) => {
160-
const handler = r.default || r;
164+
let handler = r.default || r;
161165
if (typeof handler !== "function") {
162-
throw new (TypeError as any)(
163-
"Invalid lazy handler result. It should be a function:",
164-
handler,
165-
);
166+
const _fetchHandler = (handler as FetchableObject).fetch;
167+
if (typeof _fetchHandler === "function") {
168+
handler = (event: H3Event) => _fetchHandler(event.req);
169+
} else {
170+
throw new TypeError("Invalid lazy handler: " + r);
171+
}
166172
}
167-
_resolved = { handler: r.default || r };
173+
_resolved = { handler };
168174
return _resolved;
169175
});
170176
}
@@ -178,3 +184,16 @@ export function defineLazyEventHandler(
178184
return resolveHandler().then((r) => r.handler(event));
179185
});
180186
}
187+
188+
// --- normalize ---
189+
190+
function _toEventHandler(
191+
handler: undefined | EventHandler | FetchableObject,
192+
): EventHandler | undefined {
193+
if (typeof handler === "function") {
194+
return handler;
195+
}
196+
if (typeof handler?.fetch === "function") {
197+
return (event: H3Event) => handler.fetch!(event.req);
198+
}
199+
}

src/types/handler.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,13 @@ export type Middleware = (
6868

6969
// --- lazy event handler ---
7070

71-
export type LazyEventHandler = () => EventHandler | Promise<EventHandler>;
71+
export type LazyEventHandler = () =>
72+
| EventHandler
73+
| FetchableObject
74+
| Promise<EventHandler | FetchableObject>;
7275

7376
export interface DynamicEventHandler extends EventHandlerWithFetch {
74-
set: (handler: EventHandler) => void;
77+
set: (handler: EventHandler | FetchableObject) => void;
7578
}
7679

7780
// --- utils ---

test/handler.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ describe("handler.ts", () => {
5050
expect(result).toBe("initial");
5151
});
5252

53+
it("should call the initial handler if set (fetchable)", async () => {
54+
const initialHandler = vi.fn(() => new Response("initial"));
55+
const dynamicHandler = dynamicEventHandler(initialHandler);
56+
57+
const mockEvent = {} as H3Event;
58+
const result = await dynamicHandler(mockEvent);
59+
60+
expect(initialHandler).toHaveBeenCalledWith(mockEvent);
61+
expect(result).toBeInstanceOf(Response);
62+
});
63+
5364
it("should allow setting a new handler", async () => {
5465
const initialHandler = vi.fn(async (_: H3Event) => "initial");
5566
const newHandler = vi.fn(async (_: H3Event) => "new");
@@ -79,14 +90,27 @@ describe("handler.ts", () => {
7990
expect(result).toBe("lazy");
8091
});
8192

93+
it("should resolve and call the lazy-loaded handler (fetchable)", async () => {
94+
const lazyHandler = vi.fn(async (_req: Request) => new Response("lazy"));
95+
const load = vi.fn(() => Promise.resolve({ fetch: lazyHandler }));
96+
const lazyEventHandler = defineLazyEventHandler(load);
97+
98+
const mockEvent = {} as H3Event;
99+
const result = await lazyEventHandler(mockEvent);
100+
101+
expect(load).toHaveBeenCalled();
102+
expect(lazyHandler).toHaveBeenCalled();
103+
expect(result).toBeInstanceOf(Response);
104+
});
105+
82106
it("should throw an error if the lazy-loaded handler is invalid", async () => {
83107
const load = vi.fn(() => Promise.resolve({}));
84108
const lazyEventHandler = defineLazyEventHandler(load as any);
85109

86110
const mockEvent = {} as H3Event;
87111

88112
await expect(lazyEventHandler(mockEvent)).rejects.toThrow(
89-
"Invalid lazy handler result. It should be a function:",
113+
"Invalid lazy handler:",
90114
);
91115
});
92116
});

0 commit comments

Comments
 (0)