Skip to content

Commit 99691fc

Browse files
feat(cloudflare): always augment request with cf context (#3904)
1 parent 0874039 commit 99691fc

4 files changed

Lines changed: 33 additions & 49 deletions

File tree

src/presets/cloudflare/runtime/_module-handler.ts

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import "#nitro/virtual/polyfills";
22
import type * as CF from "@cloudflare/workers-types";
3-
import type { ExportedHandler } from "@cloudflare/workers-types";
4-
import type { ServerRequest } from "srvx";
3+
import type { ServerRequest, ServerRuntimeContext } from "srvx";
54

65
import { runCronTasks } from "#nitro/runtime/task";
76
import { useNitroApp, useNitroHooks } from "nitro/app";
@@ -22,6 +21,9 @@ export function createHandler<Env>(hooks: {
2221

2322
return {
2423
async fetch(request, env, context) {
24+
(globalThis as any).__env__ = env;
25+
augmentReq(request as any, { env: env as any, context });
26+
2527
const ctxExt = {};
2628
const url = new URL(request.url);
2729

@@ -33,14 +35,7 @@ export function createHandler<Env>(hooks: {
3335
}
3436
}
3537

36-
return fetchHandler(
37-
request,
38-
env,
39-
context,
40-
url,
41-
nitroApp,
42-
ctxExt
43-
) as Promise<any /* CF response! */>;
38+
return (await nitroApp.fetch(request)) as any;
4439
},
4540

4641
scheduled(controller, env, context) {
@@ -71,8 +66,8 @@ export function createHandler<Env>(hooks: {
7166
(globalThis as any).__env__ = env;
7267
context.waitUntil(
7368
nitroHooks.callHook("cloudflare:email", {
74-
message,
75-
event: message, // backward compat
69+
message: message as any,
70+
event: message as any, // backward compat
7671
env,
7772
context,
7873
}) || Promise.resolve()
@@ -115,22 +110,12 @@ export function createHandler<Env>(hooks: {
115110
} satisfies ExportedHandler<Env>;
116111
}
117112

118-
export async function fetchHandler(
113+
export function augmentReq(
119114
cfReq: Request | CF.Request,
120-
env: unknown,
121-
context: CF.ExecutionContext | DurableObjectState,
122-
url: URL = new URL(cfReq.url),
123-
nitroApp = useNitroApp(),
124-
ctxExt: any
115+
ctx: NonNullable<ServerRuntimeContext["cloudflare"]>
125116
) {
126-
// Expose latest env to the global context
127-
(globalThis as any).__env__ = env;
128-
129-
// srvx compatibility
130117
const req = cfReq as ServerRequest;
131118
req.runtime ??= { name: "cloudflare" };
132-
req.runtime.cloudflare ??= { context, env } as any;
133-
req.waitUntil = context.waitUntil.bind(context);
134-
135-
return nitroApp.fetch(req) as unknown as Promise<Response>;
119+
req.runtime.cloudflare = { ...req.runtime.cloudflare, ...ctx };
120+
req.waitUntil = ctx.context?.waitUntil.bind(ctx.context);
136121
}

src/presets/cloudflare/runtime/cloudflare-durable.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import "#nitro/virtual/polyfills";
22
import type * as CF from "@cloudflare/workers-types";
33
import { DurableObject } from "cloudflare:workers";
44
import wsAdapter from "crossws/adapters/cloudflare";
5-
import { createHandler, fetchHandler } from "./_module-handler.ts";
5+
import { createHandler, augmentReq } from "./_module-handler.ts";
66

77
import { useNitroApp, useNitroHooks } from "nitro/app";
88
import { isPublicAssetURL } from "#nitro/virtual/public-assets";
@@ -43,11 +43,12 @@ export default createHandler<Env>({
4343
fetch(request, env, context, url, ctxExt) {
4444
// Static assets fallback (optional binding)
4545
if (env.ASSETS && isPublicAssetURL(url.pathname)) {
46-
return env.ASSETS.fetch(request);
46+
return env.ASSETS.fetch(request as any);
4747
}
4848

4949
// Expose stub fetch to the context
50-
ctxExt.durableFetch = (req = request) => getDurableStub(env).fetch(req);
50+
ctxExt.durableFetch = (req = request) =>
51+
getDurableStub(env).fetch(req as any);
5152

5253
// Websocket upgrade
5354
// https://crossws.unjs.io/adapters/cloudflare#durable-objects
@@ -72,14 +73,16 @@ export class $DurableObject extends DurableObject {
7273
}
7374

7475
override fetch(request: Request) {
76+
augmentReq(request, {
77+
env: this.env,
78+
context: this.ctx as any,
79+
});
80+
7581
if (hasWebSocket && request.headers.get("upgrade") === "websocket") {
7682
return ws!.handleDurableUpgrade(this, request);
7783
}
78-
// Main handler
79-
const url = new URL(request.url);
80-
return fetchHandler(request, this.env, this.ctx, url, nitroApp, {
81-
durable: this,
82-
});
84+
85+
return nitroApp.fetch(request);
8386
}
8487

8588
override alarm(): void | Promise<void> {

src/presets/cloudflare/runtime/cloudflare-module.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ interface Env {
1616
}
1717

1818
export default createHandler<Env>({
19-
fetch(request, env, context, url) {
19+
fetch(cfRequest, env, context, url) {
2020
// Static assets fallback (optional binding)
2121
if (env.ASSETS && isPublicAssetURL(url.pathname)) {
22-
return env.ASSETS.fetch(request);
22+
return env.ASSETS.fetch(cfRequest as any);
2323
}
2424

2525
// Websocket upgrade
2626
// https://crossws.unjs.io/adapters/cloudflare
27-
if (hasWebSocket && request.headers.get("upgrade") === "websocket") {
28-
return ws!.handleUpgrade(request as any, env, context);
27+
if (hasWebSocket && cfRequest.headers.get("upgrade") === "websocket") {
28+
return ws!.handleUpgrade(cfRequest, env, context);
2929
}
3030
},
3131
});

src/presets/cloudflare/runtime/cloudflare-pages.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import "#nitro/virtual/polyfills";
2-
import type { ServerRequest } from "srvx";
32
import type {
43
Request as CFRequest,
54
EventContext,
@@ -12,6 +11,7 @@ import { isPublicAssetURL } from "#nitro/virtual/public-assets";
1211
import { runCronTasks } from "#nitro/runtime/task";
1312
import { resolveWebsocketHooks } from "#nitro/runtime/app";
1413
import { hasWebSocket } from "#nitro/virtual/feature-flags";
14+
import { augmentReq } from "./_module-handler.ts";
1515

1616
/**
1717
* Reference: https://developers.cloudflare.com/workers/runtime-apis/fetch-event/#parameters
@@ -38,17 +38,16 @@ export default {
3838
env: CFPagesEnv,
3939
context: EventContext<CFPagesEnv, string, any>
4040
) {
41-
// srvx compatibility
42-
const req = cfReq as unknown as ServerRequest;
43-
req.runtime ??= { name: "cloudflare" };
44-
req.runtime.cloudflare ??= { context, env } as any;
45-
req.waitUntil = context.waitUntil.bind(context);
41+
augmentReq(cfReq, {
42+
env,
43+
context: context as any,
44+
});
4645

4746
// Websocket upgrade
4847
// https://crossws.unjs.io/adapters/cloudflare
4948
if (hasWebSocket && cfReq.headers.get("upgrade") === "websocket") {
5049
return ws!.handleUpgrade(
51-
cfReq as any,
50+
cfReq,
5251
env,
5352
context as unknown as ExecutionContext
5453
);
@@ -59,10 +58,7 @@ export default {
5958
return env.ASSETS.fetch(cfReq);
6059
}
6160

62-
// Expose latest env to the global context
63-
(globalThis as any).__env__ = env;
64-
65-
return nitroApp.fetch(req);
61+
return nitroApp.fetch(cfReq as any);
6662
},
6763
scheduled(event: any, env: CFPagesEnv, context: ExecutionContext) {
6864
if (import.meta._tasks) {

0 commit comments

Comments
 (0)