From 68ac5cd579e6ae97aebef0fdae5f74aa30fc5318 Mon Sep 17 00:00:00 2001 From: onmax Date: Tue, 16 Dec 2025 08:33:06 +0100 Subject: [PATCH] feat(cloudflare-durable): add durable.bindingName config --- .../cloudflare/runtime/cloudflare-durable.ts | 2 +- src/presets/cloudflare/types.ts | 12 ++++++++++++ src/presets/cloudflare/utils.ts | 17 +++++++++++++++++ src/rollup/config.ts | 2 ++ src/types/global.ts | 1 + 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/presets/cloudflare/runtime/cloudflare-durable.ts b/src/presets/cloudflare/runtime/cloudflare-durable.ts index 0b0e0b397e..907c2988b3 100644 --- a/src/presets/cloudflare/runtime/cloudflare-durable.ts +++ b/src/presets/cloudflare/runtime/cloudflare-durable.ts @@ -6,7 +6,7 @@ import { useNitroApp } from "nitropack/runtime"; import { isPublicAssetURL } from "#nitro-internal-virtual/public-assets"; import { createHandler, fetchHandler } from "./_module-handler"; -const DURABLE_BINDING = "$DurableObject"; +const DURABLE_BINDING = import.meta._durableBindingName || "$DurableObject"; const DURABLE_INSTANCE = "server"; interface Env { diff --git a/src/presets/cloudflare/types.ts b/src/presets/cloudflare/types.ts index 7f9d7ee451..e06ca29a88 100644 --- a/src/presets/cloudflare/types.ts +++ b/src/presets/cloudflare/types.ts @@ -92,6 +92,18 @@ export interface CloudflareOptions { */ defaultRoutes?: boolean; }; + + /** + * Options for the `cloudflare-durable` preset. + */ + durable?: { + /** + * The binding name for the Durable Object used by `defineWebSocketHandler`. + * + * @default "$DurableObject" + */ + bindingName?: string; + }; } type DurableObjectState = ConstructorParameters[0]; diff --git a/src/presets/cloudflare/utils.ts b/src/presets/cloudflare/utils.ts index b78c89d582..634f2fa0fb 100644 --- a/src/presets/cloudflare/utils.ts +++ b/src/presets/cloudflare/utils.ts @@ -364,6 +364,23 @@ export async function writeWranglerConfig( } wranglerConfig.compatibility_flags = [...compatFlags]; + // Durable Objects config for cloudflare-durable preset + if (nitro.options.preset === "cloudflare-durable") { + const bindingName = + nitro.options.cloudflare?.durable?.bindingName || "$DurableObject"; + wranglerConfig.durable_objects ??= { bindings: [] }; + wranglerConfig.durable_objects.bindings ??= []; + const hasBinding = wranglerConfig.durable_objects.bindings.some( + (b) => b.name === bindingName && b.class_name === "$DurableObject" + ); + if (!hasBinding) { + wranglerConfig.durable_objects.bindings.push({ + name: bindingName, + class_name: "$DurableObject", + }); + } + } + // Write wrangler.json await writeFile( wranglerConfigPath, diff --git a/src/rollup/config.ts b/src/rollup/config.ts index 4e48031048..c49ca5798b 100644 --- a/src/rollup/config.ts +++ b/src/rollup/config.ts @@ -237,6 +237,8 @@ export const getRollupConfig = (nitro: Nitro): RollupConfig => { _asyncContext: nitro.options.experimental.asyncContext, _websocket: nitro.options.experimental.websocket, _tasks: nitro.options.experimental.tasks, + _durableBindingName: + nitro.options.cloudflare?.durable?.bindingName || "$DurableObject", }; // Universal import.meta diff --git a/src/types/global.ts b/src/types/global.ts index 3a384a4c4f..d34972ecc2 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -5,6 +5,7 @@ export interface NitroStaticBuildFlags { _asyncContext?: boolean; _websocket?: boolean; _tasks?: boolean; + _durableBindingName?: string; dev?: boolean; client?: boolean; nitro?: boolean;