@opennextjs/cloudflare 0.6.5 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import type { GetPlatformProxyOptions } from "wrangler";
1
2
  import type { DurableObjectQueueHandler } from "./durable-objects/queue";
2
3
  import { DOShardedTagCache } from "./durable-objects/sharded-tag-cache";
3
4
  declare global {
@@ -49,5 +50,6 @@ export declare function getCloudflareContext<CfProperties extends Record<string,
49
50
  * with the open-next Cloudflare adapter
50
51
  *
51
52
  * Note: this function should only be called inside the Next.js config file, and although async it doesn't need to be `await`ed
53
+ * @param options options on how the function should operate and if/where to persist the platform data
52
54
  */
53
- export declare function initOpenNextCloudflareForDev(): Promise<void>;
55
+ export declare function initOpenNextCloudflareForDev(options?: GetPlatformProxyOptions): Promise<void>;
@@ -71,12 +71,17 @@ async function getCloudflareContextAsync() {
71
71
  * with the open-next Cloudflare adapter
72
72
  *
73
73
  * Note: this function should only be called inside the Next.js config file, and although async it doesn't need to be `await`ed
74
+ * @param options options on how the function should operate and if/where to persist the platform data
74
75
  */
75
- export async function initOpenNextCloudflareForDev() {
76
+ export async function initOpenNextCloudflareForDev(options) {
76
77
  const shouldInitializationRun = shouldContextInitializationRun();
77
78
  if (!shouldInitializationRun)
78
79
  return;
79
- const context = await getCloudflareContextFromWrangler();
80
+ if (options?.environment && process.env.NEXT_DEV_WRANGLER_ENV) {
81
+ console.warn(`'initOpenNextCloudflareForDev' has been called with an environment option while NEXT_DEV_WRANGLER_ENV is set.` +
82
+ ` NEXT_DEV_WRANGLER_ENV will be ignored and the environment will be set to: '${options.environment}'`);
83
+ }
84
+ const context = await getCloudflareContextFromWrangler(options);
80
85
  addCloudflareContextToNodejsGlobal(context);
81
86
  await monkeyPatchVmModuleEdgeContext(context);
82
87
  }
@@ -131,12 +136,14 @@ async function monkeyPatchVmModuleEdgeContext(cloudflareContext) {
131
136
  *
132
137
  * @returns the cloudflare context ready for use
133
138
  */
134
- async function getCloudflareContextFromWrangler() {
139
+ async function getCloudflareContextFromWrangler(options) {
135
140
  // Note: we never want wrangler to be bundled in the Next.js app, that's why the import below looks like it does
136
141
  const { getPlatformProxy } = await import(/* webpackIgnore: true */ `${"__wrangler".replaceAll("_", "")}`);
142
+ // This allows the selection of a wrangler environment while running in next dev mode
143
+ const environment = options?.environment ?? process.env.NEXT_DEV_WRANGLER_ENV;
137
144
  const { env, cf, ctx } = await getPlatformProxy({
138
- // This allows the selection of a wrangler environment while running in next dev mode
139
- environment: process.env.NEXT_DEV_WRANGLER_ENV,
145
+ ...options,
146
+ environment,
140
147
  });
141
148
  return {
142
149
  env,
@@ -82,7 +82,14 @@ rule:
82
82
  regex: ^NodeModuleLoader$
83
83
  fix: |
84
84
  async load($ID) {
85
- ${getRequires("$ID", files, serverDir)}
85
+ ${buildOpts.debug
86
+ ? ` try {
87
+ ${getRequires("$ID", files, serverDir)}
88
+ } catch (e) {
89
+ console.error('Exception in NodeModuleLoader', e);
90
+ throw e;
91
+ }`
92
+ : getRequires("$ID", files, serverDir)}
86
93
  }`;
87
94
  }
88
95
  async function getRequirePageRule(buildOpts) {
@@ -112,7 +119,14 @@ function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
112
119
  process.env.__NEXT_PRIVATE_RUNTIME_TYPE = $IS_APP_PATH ? 'app' : 'pages';
113
120
  try {
114
121
  ${getRequires("pagePath", jsFiles, serverDir)}
115
- } finally {
122
+ } ${buildOpts.debug
123
+ ? `
124
+ catch (e) {
125
+ console.error("Exception in requirePage", e);
126
+ throw e;
127
+ }`
128
+ : ``}
129
+ finally {
116
130
  process.env.__NEXT_PRIVATE_RUNTIME_TYPE = '';
117
131
  }
118
132
  }`,
@@ -1,8 +1,15 @@
1
1
  import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
2
+ // Remove an instantiation of `AbortController` from the runtime.
3
+ //
4
+ // Solves https://github.com/cloudflare/workerd/issues/3657:
5
+ // - The `AbortController` is meant for the client side, but ends in the server code somehow.
6
+ // That's why we can get ride of it. See https://github.com/vercel/next.js/pull/73975/files.
7
+ // - Top level instantiation of `AbortController` are not supported by workerd as of March, 2025.
8
+ // See https://github.com/cloudflare/workerd/issues/3657
9
+ // - As Next code is not more executed at top level, we do not need to apply this patch
10
+ // See https://github.com/opennextjs/opennextjs-cloudflare/pull/497
11
+ //
2
12
  // We try to be as specific as possible to avoid patching the wrong thing here
3
- // It seems that there is a bug in the worker runtime. When the AbortController is created outside of the request context it throws an error (not sure if it's expected or not) except in this case. https://github.com/cloudflare/workerd/issues/3657
4
- // It fails while requiring the `app-page.runtime.prod.js` file, but instead of throwing an error, it just return an empty object for the `require('app-page.runtime.prod.js')` call which makes every request to an app router page fail.
5
- // If it's a bug in workerd and it's not expected to throw an error, we can remove this patch.
6
13
  export const abortControllerRule = `
7
14
  rule:
8
15
  all:
@@ -65,18 +72,7 @@ fix:
65
72
  'true'
66
73
  `;
67
74
  export function patchNextMinimal(updater) {
68
- updater.updateContent("patch-abortController-next15.2", [
69
- {
70
- field: {
71
- filter: /app-page(-experimental)?\.runtime\.prod\.js$/,
72
- contentFilter: /new AbortController/,
73
- callback: ({ contents }) => {
74
- return patchCode(contents, abortControllerRule);
75
- },
76
- },
77
- },
78
- ]);
79
- updater.updateContent("patch-next-minimal", [
75
+ return updater.updateContent("patch-next-minimal", [
80
76
  {
81
77
  field: {
82
78
  filter: /next-server\.(js)$/,
@@ -87,8 +83,4 @@ export function patchNextMinimal(updater) {
87
83
  },
88
84
  },
89
85
  ]);
90
- return {
91
- name: "patch-abortController",
92
- setup() { },
93
- };
94
86
  }
@@ -1,4 +1,5 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
+ import process from "node:process";
2
3
  // @ts-expect-error: resolved by wrangler build
3
4
  import * as nextEnvVars from "./env/next-env.mjs";
4
5
  const cloudflareContextALS = new AsyncLocalStorage();
@@ -54,6 +55,11 @@ function populateProcessEnv(url, env) {
54
55
  if (processEnvPopulated) {
55
56
  return;
56
57
  }
58
+ // Some packages rely on `process.version` and `process.versions.node` (i.e. Jose@4)
59
+ // TODO: Remove when https://github.com/unjs/unenv/pull/493 is merged
60
+ Object.assign(process, { version: process.version || "v22.14.0" });
61
+ // @ts-expect-error Node type does not match workerd
62
+ Object.assign(process.versions, { node: "22.14.0", ...process.versions });
57
63
  processEnvPopulated = true;
58
64
  for (const [key, value] of Object.entries(env)) {
59
65
  if (typeof value === "string") {
@@ -63,7 +69,7 @@ function populateProcessEnv(url, env) {
63
69
  const mode = env.NEXTJS_ENV ?? "production";
64
70
  if (nextEnvVars[mode]) {
65
71
  for (const key in nextEnvVars[mode]) {
66
- process.env[key] = nextEnvVars[mode][key];
72
+ process.env[key] ??= nextEnvVars[mode][key];
67
73
  }
68
74
  }
69
75
  // Set the default Origin for the origin resolver.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@opennextjs/cloudflare",
3
3
  "description": "Cloudflare builder for next apps",
4
- "version": "0.6.5",
4
+ "version": "0.6.6",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"