Skip to content

Commit 521bc76

Browse files
authored
feat(adapters): pass app to middleware (#2114)
#2095 (reply in thread)
1 parent 551c3ca commit 521bc76

10 files changed

Lines changed: 92 additions & 54 deletions

File tree

packages/waku/src/adapters/aws-lambda.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default createServerEntryAdapter(
2222
options?: {
2323
streaming?: boolean;
2424
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
25-
middlewareFns?: (() => MiddlewareHandler)[];
25+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
2626
middlewareModules?: Record<string, () => Promise<unknown>>;
2727
},
2828
) => {
@@ -48,9 +48,9 @@ export default createServerEntryAdapter(
4848
}
4949
app.use(contextMiddleware());
5050
for (const middlewareFn of middlewareFns) {
51-
app.use(middlewareFn());
51+
app.use(middlewareFn({ app }));
5252
}
53-
app.use(middlewareRunner(middlewareModules as never));
53+
app.use(middlewareRunner(middlewareModules as never, { app }));
5454
app.use(rscMiddleware({ processRequest }));
5555
const buildOptions: BuildOptions = {
5656
distDir: config.distDir,

packages/waku/src/adapters/bun.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default createServerEntryAdapter(
2020
{ processRequest, processBuild, config, isBuild, notFoundHtml },
2121
options?: {
2222
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
23-
middlewareFns?: (() => MiddlewareHandler)[];
23+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
2424
middlewareModules?: Record<string, () => Promise<unknown>>;
2525
},
2626
) => {
@@ -52,9 +52,9 @@ export default createServerEntryAdapter(
5252
}
5353
app.use(contextMiddleware());
5454
for (const middlewareFn of middlewareFns) {
55-
app.use(middlewareFn());
55+
app.use(middlewareFn({ app }));
5656
}
57-
app.use(middlewareRunner(middlewareModules as never));
57+
app.use(middlewareRunner(middlewareModules as never, { app }));
5858
app.use(rscMiddleware({ processRequest }));
5959
const buildOptions: BuildOptions = {
6060
distDir: config.distDir,

packages/waku/src/adapters/cloudflare.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default createServerEntryAdapter(
6060
handlers?: Record<string, unknown>;
6161
assetsDir?: string;
6262
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
63-
middlewareFns?: (() => MiddlewareHandler)[];
63+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
6464
middlewareModules?: Record<string, () => Promise<unknown>>;
6565
internalPathToBuildStaticFiles?: string;
6666
},
@@ -85,9 +85,9 @@ export default createServerEntryAdapter(
8585
}
8686
app.use(contextMiddleware());
8787
for (const middlewareFn of middlewareFns) {
88-
app.use(middlewareFn());
88+
app.use(middlewareFn({ app }));
8989
}
90-
app.use(middlewareRunner(middlewareModules as never));
90+
app.use(middlewareRunner(middlewareModules as never, { app }));
9191
app.use(rscMiddleware({ processRequest }));
9292
const buildOptions: BuildOptions = {
9393
srcDir: config.srcDir,

packages/waku/src/adapters/deno.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ export default createServerEntryAdapter(
2020
{ processRequest, processBuild, config, notFoundHtml },
2121
options?: {
2222
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
23-
middlewareFns?: (() => MiddlewareHandler)[];
23+
middlewareFns?: ((opts: {
24+
app: HonoForDevAndBuild;
25+
}) => MiddlewareHandler)[];
2426
middlewareModules?: Record<string, () => Promise<unknown>>;
2527
},
2628
) => {
@@ -50,9 +52,9 @@ export default createServerEntryAdapter(
5052
}
5153
app.use(contextMiddleware());
5254
for (const middlewareFn of middlewareFns) {
53-
app.use(middlewareFn());
55+
app.use(middlewareFn({ app }));
5456
}
55-
app.use(middlewareRunner(middlewareModules as never));
57+
app.use(middlewareRunner(middlewareModules as never, { app }));
5658
app.use(rscMiddleware({ processRequest }));
5759
const buildOptions: BuildOptions = {
5860
distDir: config.distDir,

packages/waku/src/adapters/edge.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default createServerEntryAdapter(
2020
{ processRequest, processBuild, notFoundHtml },
2121
options?: {
2222
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
23-
middlewareFns?: (() => MiddlewareHandler)[];
23+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
2424
middlewareModules?: Record<string, () => Promise<unknown>>;
2525
},
2626
) => {
@@ -43,9 +43,9 @@ export default createServerEntryAdapter(
4343
}
4444
app.use(contextMiddleware());
4545
for (const middlewareFn of middlewareFns) {
46-
app.use(middlewareFn());
46+
app.use(middlewareFn({ app }));
4747
}
48-
app.use(middlewareRunner(middlewareModules as never));
48+
app.use(middlewareRunner(middlewareModules as never, { app }));
4949
app.use(rscMiddleware({ processRequest }));
5050
return {
5151
fetch: app.fetch,

packages/waku/src/adapters/netlify.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default createServerEntryAdapter(
1919
options?: {
2020
static?: boolean;
2121
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
22-
middlewareFns?: (() => MiddlewareHandler)[];
22+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
2323
middlewareModules?: Record<string, () => Promise<unknown>>;
2424
},
2525
) => {
@@ -42,9 +42,9 @@ export default createServerEntryAdapter(
4242
}
4343
app.use(contextMiddleware());
4444
for (const middlewareFn of middlewareFns) {
45-
app.use(middlewareFn());
45+
app.use(middlewareFn({ app }));
4646
}
47-
app.use(middlewareRunner(middlewareModules as never));
47+
app.use(middlewareRunner(middlewareModules as never, { app }));
4848
app.use(rscMiddleware({ processRequest }));
4949
const buildOptions: BuildOptions = {
5050
distDir: config.distDir,

packages/waku/src/adapters/node.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default createServerEntryAdapter(
2121
{ processRequest, processBuild, config, isBuild, notFoundHtml },
2222
options?: {
2323
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
24-
middlewareFns?: (() => MiddlewareHandler)[];
24+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
2525
middlewareModules?: Record<string, () => Promise<unknown>>;
2626
},
2727
) => {
@@ -53,9 +53,9 @@ export default createServerEntryAdapter(
5353
}
5454
app.use(contextMiddleware());
5555
for (const middlewareFn of middlewareFns) {
56-
app.use(middlewareFn());
56+
app.use(middlewareFn({ app }));
5757
}
58-
app.use(middlewareRunner(middlewareModules as never));
58+
app.use(middlewareRunner(middlewareModules as never, { app }));
5959
app.use(rscMiddleware({ processRequest }));
6060
const buildOptions: BuildOptions = {
6161
distDir: config.distDir,

packages/waku/src/adapters/vercel.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default createServerEntryAdapter(
2323
static?: boolean;
2424
assetsDir?: string;
2525
bodyLimit?: Parameters<typeof bodyLimit>[0] | false;
26-
middlewareFns?: (() => MiddlewareHandler)[];
26+
middlewareFns?: ((opts: { app: Hono }) => MiddlewareHandler)[];
2727
middlewareModules?: Record<string, () => Promise<unknown>>;
2828
},
2929
) => {
@@ -46,9 +46,9 @@ export default createServerEntryAdapter(
4646
}
4747
app.use(contextMiddleware());
4848
for (const middlewareFn of middlewareFns) {
49-
app.use(middlewareFn());
49+
app.use(middlewareFn({ app }));
5050
}
51-
app.use(middlewareRunner(middlewareModules as never));
51+
app.use(middlewareRunner(middlewareModules as never, { app }));
5252
app.use(rscMiddleware({ processRequest }));
5353
const buildOptions: BuildOptions = {
5454
assetsDir: options?.assetsDir || 'assets',

packages/waku/src/lib/hono/middleware.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { MiddlewareHandler } from 'hono';
2+
import type { Hono } from 'hono/tiny';
23
import { INTERNAL_runWithContext } from '../context.js';
34
import type { Unstable_ProcessRequest as ProcessRequest } from '../types.js';
45

@@ -29,16 +30,17 @@ export function middlewareRunner(
2930
middlewareModules: Record<
3031
string,
3132
() => Promise<{
32-
default: () => MiddlewareHandler;
33+
default: (opts: { app: Hono }) => MiddlewareHandler;
3334
}>
3435
>,
36+
opts: { app: Hono },
3537
): MiddlewareHandler {
3638
let handlersPromise: Promise<MiddlewareHandler[]> | undefined;
3739
return async (c, next) => {
3840
if (!handlersPromise) {
3941
handlersPromise = Promise.all(
4042
Object.values(middlewareModules).map((m) =>
41-
m().then((mod) => mod.default()),
43+
m().then((mod) => mod.default(opts)),
4244
),
4345
);
4446
}

packages/waku/tests/hono-middleware.test.ts

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ describe('middlewareRunner', () => {
66
test('preserves response returned by a middleware module', async () => {
77
const app = new Hono();
88
app.use(
9-
middlewareRunner({
10-
'/src/middleware/no-trailing-slash.ts': async () => ({
11-
default: () => async (c) =>
12-
c.redirect(new URL('/about', c.req.url).toString(), 301),
13-
}),
14-
}),
9+
middlewareRunner(
10+
{
11+
'/src/middleware/no-trailing-slash.ts': async () => ({
12+
default: () => async (c) =>
13+
c.redirect(new URL('/about', c.req.url).toString(), 301),
14+
}),
15+
},
16+
{ app },
17+
),
1518
);
1619
app.get('*', (c) => c.text('ok'));
1720

@@ -24,17 +27,20 @@ describe('middlewareRunner', () => {
2427
test('preserves response returned by an inner middleware module', async () => {
2528
const app = new Hono();
2629
app.use(
27-
middlewareRunner({
28-
'/src/middleware/outer.ts': async () => ({
29-
default: () => async (_c, next) => {
30-
await next();
31-
},
32-
}),
33-
'/src/middleware/no-trailing-slash.ts': async () => ({
34-
default: () => async (c) =>
35-
c.redirect(new URL('/about', c.req.url).toString(), 301),
36-
}),
37-
}),
30+
middlewareRunner(
31+
{
32+
'/src/middleware/outer.ts': async () => ({
33+
default: () => async (_c, next) => {
34+
await next();
35+
},
36+
}),
37+
'/src/middleware/no-trailing-slash.ts': async () => ({
38+
default: () => async (c) =>
39+
c.redirect(new URL('/about', c.req.url).toString(), 301),
40+
}),
41+
},
42+
{ app },
43+
),
3844
);
3945
app.get('*', (c) => c.text('ok'));
4046

@@ -47,17 +53,20 @@ describe('middlewareRunner', () => {
4753
test('keeps inner response even if outer middleware returns after next', async () => {
4854
const app = new Hono();
4955
app.use(
50-
middlewareRunner({
51-
'/src/middleware/outer.ts': async () => ({
52-
default: () => async (_c, next) => {
53-
await next();
54-
return new Response('outer', { status: 202 });
55-
},
56-
}),
57-
'/src/middleware/inner.ts': async () => ({
58-
default: () => async () => new Response('inner', { status: 201 }),
59-
}),
60-
}),
56+
middlewareRunner(
57+
{
58+
'/src/middleware/outer.ts': async () => ({
59+
default: () => async (_c, next) => {
60+
await next();
61+
return new Response('outer', { status: 202 });
62+
},
63+
}),
64+
'/src/middleware/inner.ts': async () => ({
65+
default: () => async () => new Response('inner', { status: 201 }),
66+
}),
67+
},
68+
{ app },
69+
),
6170
);
6271
app.get('*', (c) => c.text('ok'));
6372

@@ -66,4 +75,29 @@ describe('middlewareRunner', () => {
6675
expect(res.status).toBe(201);
6776
expect(await res.text()).toBe('inner');
6877
});
78+
79+
test('passes { app } to each middleware module factory', async () => {
80+
const app = new Hono();
81+
let receivedApp: unknown;
82+
app.use(
83+
middlewareRunner(
84+
{
85+
'/src/middleware/probe.ts': async () => ({
86+
default: ({ app }) => {
87+
receivedApp = app;
88+
return async (_c, next) => {
89+
await next();
90+
};
91+
},
92+
}),
93+
},
94+
{ app },
95+
),
96+
);
97+
app.get('*', (c) => c.text('ok'));
98+
99+
await app.request('http://example.com/');
100+
101+
expect(receivedApp).toBe(app);
102+
});
69103
});

0 commit comments

Comments
 (0)