From a1fd9d91792b302e2c29977f32f1900a67301028 Mon Sep 17 00:00:00 2001 From: Emre Tinaztepe Date: Tue, 30 Dec 2025 02:33:53 +0200 Subject: [PATCH 1/8] fix: pass cloudflare env & context in websocket context --- src/presets/cloudflare/runtime/cloudflare-durable.ts | 10 ++++++++++ src/presets/cloudflare/runtime/cloudflare-module.ts | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/presets/cloudflare/runtime/cloudflare-durable.ts b/src/presets/cloudflare/runtime/cloudflare-durable.ts index d6f7ad1360..31769fa245 100644 --- a/src/presets/cloudflare/runtime/cloudflare-durable.ts +++ b/src/presets/cloudflare/runtime/cloudflare-durable.ts @@ -52,6 +52,16 @@ export default createHandler({ // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare#durable-objects if (hasWebSocket && request.headers.get("upgrade") === "websocket") { + // Ensure Cloudflare bindings are available on `peer.context` inside WebSocket handlers. + // crossws will forward `request.context` to `peer.context`. + let wsContext = (request as any).context; + if (!wsContext) { + wsContext = {}; + Object.defineProperty(request as any, "context", { enumerable: true, value: wsContext }); + } + wsContext.cloudflare ||= {}; + wsContext.cloudflare.env ||= env; + wsContext.cloudflare.context ||= context; return ws!.handleUpgrade(request, env, context); } }, diff --git a/src/presets/cloudflare/runtime/cloudflare-module.ts b/src/presets/cloudflare/runtime/cloudflare-module.ts index d966dd01f6..fe14ed6e3f 100644 --- a/src/presets/cloudflare/runtime/cloudflare-module.ts +++ b/src/presets/cloudflare/runtime/cloudflare-module.ts @@ -25,6 +25,16 @@ export default createHandler({ // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare if (hasWebSocket && request.headers.get("upgrade") === "websocket") { + // Ensure Cloudflare bindings are available on `peer.context` inside WebSocket handlers. + // crossws will forward `request.context` to `peer.context`. + let wsContext = (request as any).context; + if (!wsContext) { + wsContext = {}; + Object.defineProperty(request as any, "context", { enumerable: true, value: wsContext }); + } + wsContext.cloudflare ||= {}; + wsContext.cloudflare.env ||= env; + wsContext.cloudflare.context ||= context; return ws!.handleUpgrade(request as any, env, context); } }, From 8211f4af76fe40a16b3df0c4d227da7b2156cfc5 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:01:45 +0000 Subject: [PATCH 2/8] chore: apply automated updates --- src/presets/cloudflare/runtime/cloudflare-durable.ts | 5 ++++- src/presets/cloudflare/runtime/cloudflare-module.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/presets/cloudflare/runtime/cloudflare-durable.ts b/src/presets/cloudflare/runtime/cloudflare-durable.ts index 31769fa245..10db13bd30 100644 --- a/src/presets/cloudflare/runtime/cloudflare-durable.ts +++ b/src/presets/cloudflare/runtime/cloudflare-durable.ts @@ -57,7 +57,10 @@ export default createHandler({ let wsContext = (request as any).context; if (!wsContext) { wsContext = {}; - Object.defineProperty(request as any, "context", { enumerable: true, value: wsContext }); + Object.defineProperty(request as any, "context", { + enumerable: true, + value: wsContext, + }); } wsContext.cloudflare ||= {}; wsContext.cloudflare.env ||= env; diff --git a/src/presets/cloudflare/runtime/cloudflare-module.ts b/src/presets/cloudflare/runtime/cloudflare-module.ts index fe14ed6e3f..5dcd31add2 100644 --- a/src/presets/cloudflare/runtime/cloudflare-module.ts +++ b/src/presets/cloudflare/runtime/cloudflare-module.ts @@ -30,7 +30,10 @@ export default createHandler({ let wsContext = (request as any).context; if (!wsContext) { wsContext = {}; - Object.defineProperty(request as any, "context", { enumerable: true, value: wsContext }); + Object.defineProperty(request as any, "context", { + enumerable: true, + value: wsContext, + }); } wsContext.cloudflare ||= {}; wsContext.cloudflare.env ||= env; From f0cef8127cd8decf1fe4626ab3b7d146071b15c0 Mon Sep 17 00:00:00 2001 From: Emre Tinaztepe Date: Fri, 9 Jan 2026 01:18:30 +0100 Subject: [PATCH 3/8] refactor: moved crossws context setting implementation to a shared function --- .../cloudflare/runtime/_module-handler.ts | 45 +++++++++++++++---- .../cloudflare/runtime/cloudflare-durable.ts | 28 +++++------- .../cloudflare/runtime/cloudflare-module.ts | 13 ------ .../cloudflare/runtime/cloudflare-pages.ts | 10 ++--- 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/src/presets/cloudflare/runtime/_module-handler.ts b/src/presets/cloudflare/runtime/_module-handler.ts index 3f397265b0..989058a3bb 100644 --- a/src/presets/cloudflare/runtime/_module-handler.ts +++ b/src/presets/cloudflare/runtime/_module-handler.ts @@ -1,6 +1,5 @@ import "#nitro/virtual/polyfills"; import type * as CF from "@cloudflare/workers-types"; -import type { ExportedHandler } from "@cloudflare/workers-types"; import type { ServerRequest } from "srvx"; import { runCronTasks } from "#nitro/runtime/task"; @@ -8,6 +7,40 @@ import { useNitroApp, useNitroHooks } from "nitro/app"; type MaybePromise = T | Promise; +export function augmentContext( + cfReq: Request | CF.Request, + env: unknown, + context: CF.ExecutionContext | DurableObjectState +) { + // Expose latest env to the global context + (globalThis as any).__env__ = env; + + // srvx compatibility + const req = cfReq as ServerRequest; + req.runtime ??= { name: "cloudflare" }; + (req.runtime as any).cloudflare = { + ...(req.runtime as any).cloudflare, + env, + context, + }; + req.waitUntil = context.waitUntil.bind(context); + + // crossws compatibility: request.context is forwarded to peer.context + let reqContext = (req as any).context; + if (!reqContext || typeof reqContext !== "object") { + reqContext = {}; + Object.defineProperty(req as any, "context", { + enumerable: true, + value: reqContext, + }); + } + reqContext.cloudflare = { + ...reqContext.cloudflare, + env, + context, + }; +} + export function createHandler(hooks: { fetch: ( ...params: [ @@ -25,6 +58,8 @@ export function createHandler(hooks: { const ctxExt = {}; const url = new URL(request.url); + augmentContext(request as any, env, context); + // Preset-specific logic if (hooks.fetch) { const res = await hooks.fetch(request, env, context, url, ctxExt); @@ -123,14 +158,8 @@ export async function fetchHandler( nitroApp = useNitroApp(), ctxExt: any ) { - // Expose latest env to the global context - (globalThis as any).__env__ = env; - - // srvx compatibility + augmentContext(cfReq, env, context); const req = cfReq as ServerRequest; - req.runtime ??= { name: "cloudflare" }; - req.runtime.cloudflare ??= { context, env } as any; - req.waitUntil = context.waitUntil.bind(context); return nitroApp.fetch(req) as unknown as Promise; } diff --git a/src/presets/cloudflare/runtime/cloudflare-durable.ts b/src/presets/cloudflare/runtime/cloudflare-durable.ts index 10db13bd30..ca2cd91efb 100644 --- a/src/presets/cloudflare/runtime/cloudflare-durable.ts +++ b/src/presets/cloudflare/runtime/cloudflare-durable.ts @@ -2,7 +2,11 @@ import "#nitro/virtual/polyfills"; import type * as CF from "@cloudflare/workers-types"; import { DurableObject } from "cloudflare:workers"; import wsAdapter from "crossws/adapters/cloudflare"; -import { createHandler, fetchHandler } from "./_module-handler.ts"; +import { + augmentContext, + createHandler, + fetchHandler, +} from "./_module-handler.ts"; import { useNitroApp, useNitroHooks } from "nitro/app"; import { isPublicAssetURL } from "#nitro/virtual/public-assets"; @@ -33,10 +37,10 @@ const getDurableStub = (env: Env) => { const ws = hasWebSocket ? wsAdapter({ - resolve: resolveWebsocketHooks, - instanceName: DURABLE_INSTANCE, - bindingName: DURABLE_BINDING, - }) + resolve: resolveWebsocketHooks, + instanceName: DURABLE_INSTANCE, + bindingName: DURABLE_BINDING, + }) : undefined; export default createHandler({ @@ -52,19 +56,6 @@ export default createHandler({ // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare#durable-objects if (hasWebSocket && request.headers.get("upgrade") === "websocket") { - // Ensure Cloudflare bindings are available on `peer.context` inside WebSocket handlers. - // crossws will forward `request.context` to `peer.context`. - let wsContext = (request as any).context; - if (!wsContext) { - wsContext = {}; - Object.defineProperty(request as any, "context", { - enumerable: true, - value: wsContext, - }); - } - wsContext.cloudflare ||= {}; - wsContext.cloudflare.env ||= env; - wsContext.cloudflare.context ||= context; return ws!.handleUpgrade(request, env, context); } }, @@ -86,6 +77,7 @@ export class $DurableObject extends DurableObject { override fetch(request: Request) { if (hasWebSocket && request.headers.get("upgrade") === "websocket") { + augmentContext(request, this.env, this.ctx); return ws!.handleDurableUpgrade(this, request); } // Main handler diff --git a/src/presets/cloudflare/runtime/cloudflare-module.ts b/src/presets/cloudflare/runtime/cloudflare-module.ts index 5dcd31add2..d966dd01f6 100644 --- a/src/presets/cloudflare/runtime/cloudflare-module.ts +++ b/src/presets/cloudflare/runtime/cloudflare-module.ts @@ -25,19 +25,6 @@ export default createHandler({ // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare if (hasWebSocket && request.headers.get("upgrade") === "websocket") { - // Ensure Cloudflare bindings are available on `peer.context` inside WebSocket handlers. - // crossws will forward `request.context` to `peer.context`. - let wsContext = (request as any).context; - if (!wsContext) { - wsContext = {}; - Object.defineProperty(request as any, "context", { - enumerable: true, - value: wsContext, - }); - } - wsContext.cloudflare ||= {}; - wsContext.cloudflare.env ||= env; - wsContext.cloudflare.context ||= context; return ws!.handleUpgrade(request as any, env, context); } }, diff --git a/src/presets/cloudflare/runtime/cloudflare-pages.ts b/src/presets/cloudflare/runtime/cloudflare-pages.ts index e4889b3e30..ff756aa5ef 100644 --- a/src/presets/cloudflare/runtime/cloudflare-pages.ts +++ b/src/presets/cloudflare/runtime/cloudflare-pages.ts @@ -12,6 +12,7 @@ import { isPublicAssetURL } from "#nitro/virtual/public-assets"; import { runCronTasks } from "#nitro/runtime/task"; import { resolveWebsocketHooks } from "#nitro/runtime/app"; import { hasWebSocket } from "#nitro/virtual/feature-flags"; +import { augmentContext } from "./_module-handler.ts"; /** * Reference: https://developers.cloudflare.com/workers/runtime-apis/fetch-event/#parameters @@ -38,11 +39,9 @@ export default { env: CFPagesEnv, context: EventContext ) { - // srvx compatibility + // srvx + crossws compatibility (runtime/cloudflare + request.context.cloudflare) const req = cfReq as unknown as ServerRequest; - req.runtime ??= { name: "cloudflare" }; - req.runtime.cloudflare ??= { context, env } as any; - req.waitUntil = context.waitUntil.bind(context); + augmentContext(cfReq, env, context as any); // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare @@ -59,9 +58,6 @@ export default { return env.ASSETS.fetch(cfReq); } - // Expose latest env to the global context - (globalThis as any).__env__ = env; - return nitroApp.fetch(req); }, scheduled(event: any, env: CFPagesEnv, context: ExecutionContext) { From 909ae65c73d5ca058b9d3e61fd28fb2d22901a71 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 9 Jan 2026 10:33:28 +0100 Subject: [PATCH 4/8] update --- .../cloudflare/runtime/_module-handler.ts | 65 ++++--------------- .../cloudflare/runtime/cloudflare-durable.ts | 29 ++++----- .../cloudflare/runtime/cloudflare-module.ts | 8 +-- .../cloudflare/runtime/cloudflare-pages.ts | 11 ++-- 4 files changed, 33 insertions(+), 80 deletions(-) diff --git a/src/presets/cloudflare/runtime/_module-handler.ts b/src/presets/cloudflare/runtime/_module-handler.ts index 989058a3bb..7ae008682d 100644 --- a/src/presets/cloudflare/runtime/_module-handler.ts +++ b/src/presets/cloudflare/runtime/_module-handler.ts @@ -7,40 +7,6 @@ import { useNitroApp, useNitroHooks } from "nitro/app"; type MaybePromise = T | Promise; -export function augmentContext( - cfReq: Request | CF.Request, - env: unknown, - context: CF.ExecutionContext | DurableObjectState -) { - // Expose latest env to the global context - (globalThis as any).__env__ = env; - - // srvx compatibility - const req = cfReq as ServerRequest; - req.runtime ??= { name: "cloudflare" }; - (req.runtime as any).cloudflare = { - ...(req.runtime as any).cloudflare, - env, - context, - }; - req.waitUntil = context.waitUntil.bind(context); - - // crossws compatibility: request.context is forwarded to peer.context - let reqContext = (req as any).context; - if (!reqContext || typeof reqContext !== "object") { - reqContext = {}; - Object.defineProperty(req as any, "context", { - enumerable: true, - value: reqContext, - }); - } - reqContext.cloudflare = { - ...reqContext.cloudflare, - env, - context, - }; -} - export function createHandler(hooks: { fetch: ( ...params: [ @@ -55,11 +21,12 @@ export function createHandler(hooks: { return { async fetch(request, env, context) { + (globalThis as any).__env__ = env; + augmentReq(request as any, env, context); + const ctxExt = {}; const url = new URL(request.url); - augmentContext(request as any, env, context); - // Preset-specific logic if (hooks.fetch) { const res = await hooks.fetch(request, env, context, url, ctxExt); @@ -68,14 +35,7 @@ export function createHandler(hooks: { } } - return fetchHandler( - request, - env, - context, - url, - nitroApp, - ctxExt - ) as Promise; + return (await nitroApp.fetch(request)) as any; }, scheduled(controller, env, context) { @@ -150,16 +110,17 @@ export function createHandler(hooks: { } satisfies ExportedHandler; } -export async function fetchHandler( +export function augmentReq( cfReq: Request | CF.Request, env: unknown, - context: CF.ExecutionContext | DurableObjectState, - url: URL = new URL(cfReq.url), - nitroApp = useNitroApp(), - ctxExt: any + context: CF.ExecutionContext | DurableObjectState ) { - augmentContext(cfReq, env, context); const req = cfReq as ServerRequest; - - return nitroApp.fetch(req) as unknown as Promise; + req.runtime ??= { name: "cloudflare" }; + (req.runtime as any).cloudflare = { + ...(req.runtime as any).cloudflare, + env, + context, + }; + req.waitUntil = context.waitUntil.bind(context); } diff --git a/src/presets/cloudflare/runtime/cloudflare-durable.ts b/src/presets/cloudflare/runtime/cloudflare-durable.ts index ca2cd91efb..800e178180 100644 --- a/src/presets/cloudflare/runtime/cloudflare-durable.ts +++ b/src/presets/cloudflare/runtime/cloudflare-durable.ts @@ -2,11 +2,7 @@ import "#nitro/virtual/polyfills"; import type * as CF from "@cloudflare/workers-types"; import { DurableObject } from "cloudflare:workers"; import wsAdapter from "crossws/adapters/cloudflare"; -import { - augmentContext, - createHandler, - fetchHandler, -} from "./_module-handler.ts"; +import { createHandler, augmentReq } from "./_module-handler.ts"; import { useNitroApp, useNitroHooks } from "nitro/app"; import { isPublicAssetURL } from "#nitro/virtual/public-assets"; @@ -37,21 +33,22 @@ const getDurableStub = (env: Env) => { const ws = hasWebSocket ? wsAdapter({ - resolve: resolveWebsocketHooks, - instanceName: DURABLE_INSTANCE, - bindingName: DURABLE_BINDING, - }) + resolve: resolveWebsocketHooks, + instanceName: DURABLE_INSTANCE, + bindingName: DURABLE_BINDING, + }) : undefined; export default createHandler({ fetch(request, env, context, url, ctxExt) { // Static assets fallback (optional binding) if (env.ASSETS && isPublicAssetURL(url.pathname)) { - return env.ASSETS.fetch(request); + return env.ASSETS.fetch(request as any); } // Expose stub fetch to the context - ctxExt.durableFetch = (req = request) => getDurableStub(env).fetch(req); + ctxExt.durableFetch = (req = request) => + getDurableStub(env).fetch(req as any); // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare#durable-objects @@ -76,15 +73,13 @@ export class $DurableObject extends DurableObject { } override fetch(request: Request) { + augmentReq(request, this.env, this.ctx); + if (hasWebSocket && request.headers.get("upgrade") === "websocket") { - augmentContext(request, this.env, this.ctx); return ws!.handleDurableUpgrade(this, request); } - // Main handler - const url = new URL(request.url); - return fetchHandler(request, this.env, this.ctx, url, nitroApp, { - durable: this, - }); + + return nitroApp.fetch(request); } override alarm(): void | Promise { diff --git a/src/presets/cloudflare/runtime/cloudflare-module.ts b/src/presets/cloudflare/runtime/cloudflare-module.ts index d966dd01f6..798cae3bec 100644 --- a/src/presets/cloudflare/runtime/cloudflare-module.ts +++ b/src/presets/cloudflare/runtime/cloudflare-module.ts @@ -16,16 +16,16 @@ interface Env { } export default createHandler({ - fetch(request, env, context, url) { + fetch(cfRequest, env, context, url) { // Static assets fallback (optional binding) if (env.ASSETS && isPublicAssetURL(url.pathname)) { - return env.ASSETS.fetch(request); + return env.ASSETS.fetch(cfRequest as any); } // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare - if (hasWebSocket && request.headers.get("upgrade") === "websocket") { - return ws!.handleUpgrade(request as any, env, context); + if (hasWebSocket && cfRequest.headers.get("upgrade") === "websocket") { + return ws!.handleUpgrade(cfRequest, env, context); } }, }); diff --git a/src/presets/cloudflare/runtime/cloudflare-pages.ts b/src/presets/cloudflare/runtime/cloudflare-pages.ts index ff756aa5ef..4ad5a08dd2 100644 --- a/src/presets/cloudflare/runtime/cloudflare-pages.ts +++ b/src/presets/cloudflare/runtime/cloudflare-pages.ts @@ -1,5 +1,4 @@ import "#nitro/virtual/polyfills"; -import type { ServerRequest } from "srvx"; import type { Request as CFRequest, EventContext, @@ -12,7 +11,7 @@ import { isPublicAssetURL } from "#nitro/virtual/public-assets"; import { runCronTasks } from "#nitro/runtime/task"; import { resolveWebsocketHooks } from "#nitro/runtime/app"; import { hasWebSocket } from "#nitro/virtual/feature-flags"; -import { augmentContext } from "./_module-handler.ts"; +import { augmentReq } from "./_module-handler.ts"; /** * Reference: https://developers.cloudflare.com/workers/runtime-apis/fetch-event/#parameters @@ -39,15 +38,13 @@ export default { env: CFPagesEnv, context: EventContext ) { - // srvx + crossws compatibility (runtime/cloudflare + request.context.cloudflare) - const req = cfReq as unknown as ServerRequest; - augmentContext(cfReq, env, context as any); + augmentReq(cfReq, env, context as any); // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare if (hasWebSocket && cfReq.headers.get("upgrade") === "websocket") { return ws!.handleUpgrade( - cfReq as any, + cfReq, env, context as unknown as ExecutionContext ); @@ -58,7 +55,7 @@ export default { return env.ASSETS.fetch(cfReq); } - return nitroApp.fetch(req); + return nitroApp.fetch(cfReq as any); }, scheduled(event: any, env: CFPagesEnv, context: ExecutionContext) { if (import.meta._tasks) { From e6970aaa600bfff0b5dc3466f9b37233c9beae8e Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 9 Jan 2026 10:41:47 +0100 Subject: [PATCH 5/8] update types --- src/presets/cloudflare/runtime/_module-handler.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/presets/cloudflare/runtime/_module-handler.ts b/src/presets/cloudflare/runtime/_module-handler.ts index 7ae008682d..afb9b9af78 100644 --- a/src/presets/cloudflare/runtime/_module-handler.ts +++ b/src/presets/cloudflare/runtime/_module-handler.ts @@ -117,10 +117,10 @@ export function augmentReq( ) { const req = cfReq as ServerRequest; req.runtime ??= { name: "cloudflare" }; - (req.runtime as any).cloudflare = { - ...(req.runtime as any).cloudflare, - env, - context, + req.runtime.cloudflare = { + ...req.runtime.cloudflare, + env: env as any, + context: context as any, }; req.waitUntil = context.waitUntil.bind(context); } From 72d9d851512cc51067e542c75fe3f4d9751e73dd Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 9 Jan 2026 10:48:01 +0100 Subject: [PATCH 6/8] fix type ref --- src/presets/cloudflare/runtime/_module-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/presets/cloudflare/runtime/_module-handler.ts b/src/presets/cloudflare/runtime/_module-handler.ts index afb9b9af78..545860f3a9 100644 --- a/src/presets/cloudflare/runtime/_module-handler.ts +++ b/src/presets/cloudflare/runtime/_module-handler.ts @@ -113,7 +113,7 @@ export function createHandler(hooks: { export function augmentReq( cfReq: Request | CF.Request, env: unknown, - context: CF.ExecutionContext | DurableObjectState + context: CF.ExecutionContext | CF.DurableObjectState ) { const req = cfReq as ServerRequest; req.runtime ??= { name: "cloudflare" }; From 0d295c380ce3e7b147162932e92aba5293d8154c Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 9 Jan 2026 10:55:25 +0100 Subject: [PATCH 7/8] fix types --- .../cloudflare/runtime/_module-handler.ts | 16 +++++++--------- .../cloudflare/runtime/cloudflare-durable.ts | 5 ++++- .../cloudflare/runtime/cloudflare-pages.ts | 5 ++++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/presets/cloudflare/runtime/_module-handler.ts b/src/presets/cloudflare/runtime/_module-handler.ts index 545860f3a9..ee98e0b600 100644 --- a/src/presets/cloudflare/runtime/_module-handler.ts +++ b/src/presets/cloudflare/runtime/_module-handler.ts @@ -1,6 +1,6 @@ import "#nitro/virtual/polyfills"; import type * as CF from "@cloudflare/workers-types"; -import type { ServerRequest } from "srvx"; +import type { ServerRequest, ServerRuntimeContext } from "srvx"; import { runCronTasks } from "#nitro/runtime/task"; import { useNitroApp, useNitroHooks } from "nitro/app"; @@ -22,7 +22,7 @@ export function createHandler(hooks: { return { async fetch(request, env, context) { (globalThis as any).__env__ = env; - augmentReq(request as any, env, context); + augmentReq(request as any, { env: env as any, context }); const ctxExt = {}; const url = new URL(request.url); @@ -66,8 +66,8 @@ export function createHandler(hooks: { (globalThis as any).__env__ = env; context.waitUntil( nitroHooks.callHook("cloudflare:email", { - message, - event: message, // backward compat + message: message as any, + event: message as any, // backward compat env, context, }) || Promise.resolve() @@ -112,15 +112,13 @@ export function createHandler(hooks: { export function augmentReq( cfReq: Request | CF.Request, - env: unknown, - context: CF.ExecutionContext | CF.DurableObjectState + ctx: NonNullable ) { const req = cfReq as ServerRequest; + req.waitUntil = ctx.context?.waitUntil.bind(ctx.context); req.runtime ??= { name: "cloudflare" }; req.runtime.cloudflare = { ...req.runtime.cloudflare, - env: env as any, - context: context as any, + ...ctx, }; - req.waitUntil = context.waitUntil.bind(context); } diff --git a/src/presets/cloudflare/runtime/cloudflare-durable.ts b/src/presets/cloudflare/runtime/cloudflare-durable.ts index 800e178180..54b214b2ea 100644 --- a/src/presets/cloudflare/runtime/cloudflare-durable.ts +++ b/src/presets/cloudflare/runtime/cloudflare-durable.ts @@ -73,7 +73,10 @@ export class $DurableObject extends DurableObject { } override fetch(request: Request) { - augmentReq(request, this.env, this.ctx); + augmentReq(request, { + env: this.env, + context: this.ctx as any, + }); if (hasWebSocket && request.headers.get("upgrade") === "websocket") { return ws!.handleDurableUpgrade(this, request); diff --git a/src/presets/cloudflare/runtime/cloudflare-pages.ts b/src/presets/cloudflare/runtime/cloudflare-pages.ts index 4ad5a08dd2..d1c176a873 100644 --- a/src/presets/cloudflare/runtime/cloudflare-pages.ts +++ b/src/presets/cloudflare/runtime/cloudflare-pages.ts @@ -38,7 +38,10 @@ export default { env: CFPagesEnv, context: EventContext ) { - augmentReq(cfReq, env, context as any); + augmentReq(cfReq, { + env, + context: context as any, + }); // Websocket upgrade // https://crossws.unjs.io/adapters/cloudflare From 772948a3e9c18fc3ecf7fa71f4ab37a8abaf80d2 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 9 Jan 2026 10:55:52 +0100 Subject: [PATCH 8/8] refactor --- src/presets/cloudflare/runtime/_module-handler.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/presets/cloudflare/runtime/_module-handler.ts b/src/presets/cloudflare/runtime/_module-handler.ts index ee98e0b600..d9d479318b 100644 --- a/src/presets/cloudflare/runtime/_module-handler.ts +++ b/src/presets/cloudflare/runtime/_module-handler.ts @@ -115,10 +115,7 @@ export function augmentReq( ctx: NonNullable ) { const req = cfReq as ServerRequest; - req.waitUntil = ctx.context?.waitUntil.bind(ctx.context); req.runtime ??= { name: "cloudflare" }; - req.runtime.cloudflare = { - ...req.runtime.cloudflare, - ...ctx, - }; + req.runtime.cloudflare = { ...req.runtime.cloudflare, ...ctx }; + req.waitUntil = ctx.context?.waitUntil.bind(ctx.context); }