@opennextjs/cloudflare 1.6.3 → 1.6.5

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.
@@ -74,11 +74,4 @@ function ensureNextjsVersionSupported(options) {
74
74
  logger.error("Next.js version unsupported, please upgrade to version 14.2 or greater.");
75
75
  process.exit(1);
76
76
  }
77
- // TODO: remove when 15.4 is supported
78
- // Note: `e2e/experimental` is on 15.4.0-canary.14 which works
79
- if (!options.appPath.endsWith("opennextjs-cloudflare/examples/e2e/experimental") &&
80
- buildHelper.compareSemver(options.nextVersion, ">=", "15.4.0")) {
81
- logger.error("Next.js version unsupported, the latest supported version is 15.3");
82
- process.exit(1);
83
- }
84
77
  }
@@ -13,12 +13,14 @@ import { inlineFindDir } from "./patches/plugins/find-dir.js";
13
13
  import { patchInstrumentation } from "./patches/plugins/instrumentation.js";
14
14
  import { inlineLoadManifest } from "./patches/plugins/load-manifest.js";
15
15
  import { patchNextServer } from "./patches/plugins/next-server.js";
16
+ import { patchNodeEnvironment } from "./patches/plugins/node-environment.js";
16
17
  import { patchResolveCache } from "./patches/plugins/open-next.js";
17
18
  import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js";
18
19
  import { patchPagesRouterContext } from "./patches/plugins/pages-router-context.js";
19
20
  import { patchDepdDeprecations } from "./patches/plugins/patch-depd-deprecations.js";
20
21
  import { fixRequire } from "./patches/plugins/require.js";
21
22
  import { shimRequireHook } from "./patches/plugins/require-hook.js";
23
+ import { patchRouteModules } from "./patches/plugins/route-module.js";
22
24
  import { setWranglerExternal } from "./patches/plugins/wrangler-external.js";
23
25
  import { copyPackageCliFiles, needsExperimentalReact, normalizePath } from "./utils/index.js";
24
26
  /** The dist directory of the Cloudflare adapter package */
@@ -86,8 +88,10 @@ export async function bundleServer(buildOpts, projectOpts) {
86
88
  inlineFindDir(updater, buildOpts),
87
89
  inlineLoadManifest(updater, buildOpts),
88
90
  patchNextServer(updater, buildOpts),
91
+ patchRouteModules(updater, buildOpts),
89
92
  patchDepdDeprecations(updater),
90
93
  patchResolveCache(updater, buildOpts),
94
+ patchNodeEnvironment(updater),
91
95
  // Apply updater updates, must be the last plugin
92
96
  updater.plugin,
93
97
  ],
@@ -124,6 +128,8 @@ export async function bundleServer(buildOpts, projectOpts) {
124
128
  "process.env.TURBOPACK": "false",
125
129
  // This define should be safe to use for Next 14.2+, earlier versions (13.5 and less) will cause trouble
126
130
  "process.env.__NEXT_EXPERIMENTAL_REACT": `${needsExperimentalReact(nextConfig)}`,
131
+ // Fix `res.validate` in Next 15.4 (together with the `route-module` patch)
132
+ "process.env.__NEXT_TRUST_HOST_HEADER": "true",
127
133
  },
128
134
  banner: {
129
135
  // We need to import them here, assigning them to `globalThis` does not work because node:timers use `globalThis` and thus create an infinite loop
@@ -46,8 +46,8 @@ function loadManifest($PATH, $$$ARGS) {
46
46
  fix: `
47
47
  function loadManifest($PATH, $$$ARGS) {
48
48
  $PATH = $PATH.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)});
49
- if ($PATH === "/.next/BUILD_ID") {
50
- return process.env.NEXT_BUILD_ID;
49
+ if ($PATH.endsWith(".next/BUILD_ID")) {
50
+ return process.env.NEXT_BUILD_ID;
51
51
  }
52
52
  ${returnManifests}
53
53
  throw new Error(\`Unexpected loadManifest(\${$PATH}) call!\`);
@@ -9,6 +9,7 @@
9
9
  import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
10
10
  import type { ContentUpdater, Plugin } from "@opennextjs/aws/plugins/content-updater.js";
11
11
  export declare function patchNextServer(updater: ContentUpdater, buildOpts: BuildOptions): Plugin;
12
+ export declare const disableNodeMiddlewareRule = "\nrule:\n pattern:\n selector: method_definition\n context: \"class { async loadNodeMiddleware($$$PARAMS) { $$$_ } }\"\nfix: |-\n async loadNodeMiddleware($$$PARAMS) {\n // patched by open next\n }\n";
12
13
  export declare const buildIdRule = "\nrule:\n pattern:\n selector: method_definition\n context: \"class { getBuildId($$$PARAMS) { $$$_ } }\"\nfix: |-\n getBuildId($$$PARAMS) {\n return process.env.NEXT_BUILD_ID;\n }\n";
13
14
  /**
14
15
  * The cache handler used by Next.js is normally defined in the config file as a path. At runtime,
@@ -26,11 +26,24 @@ export function patchNextServer(updater, buildOpts) {
26
26
  contents = patchCode(contents, createCacheHandlerRule(cacheHandler));
27
27
  const composableCacheHandler = path.join(outputPath, getPackagePath(buildOpts), "composable-cache.cjs");
28
28
  contents = patchCode(contents, createComposableCacheHandlersRule(composableCacheHandler));
29
+ // Node middleware are not supported on Cloudflare yet
30
+ contents = patchCode(contents, disableNodeMiddlewareRule);
29
31
  return contents;
30
32
  },
31
33
  },
32
34
  ]);
33
35
  }
36
+ // Do not try to load Node middlewares
37
+ export const disableNodeMiddlewareRule = `
38
+ rule:
39
+ pattern:
40
+ selector: method_definition
41
+ context: "class { async loadNodeMiddleware($$$PARAMS) { $$$_ } }"
42
+ fix: |-
43
+ async loadNodeMiddleware($$$PARAMS) {
44
+ // patched by open next
45
+ }
46
+ `;
34
47
  export const buildIdRule = `
35
48
  rule:
36
49
  pattern:
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Remove a dependency on Babel by dropping the require of error-inspect
3
+ */
4
+ import type { ContentUpdater, Plugin } from "@opennextjs/aws/plugins/content-updater.js";
5
+ export declare function patchNodeEnvironment(updater: ContentUpdater): Plugin;
6
+ /**
7
+ * Drops `require("./node-environment-extensions/error-inspect");`
8
+ */
9
+ export declare const errorInspectRule = "\nrule:\n pattern: require(\"./node-environment-extensions/error-inspect\");\nfix: |-\n // Removed by OpenNext\n // require(\"./node-environment-extensions/error-inspect\");\n";
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Remove a dependency on Babel by dropping the require of error-inspect
3
+ */
4
+ import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
5
+ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
6
+ export function patchNodeEnvironment(updater) {
7
+ return updater.updateContent("node-environment", [
8
+ {
9
+ filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/node-environment\.js$`, {
10
+ escape: false,
11
+ }),
12
+ contentFilter: /error-inspect/,
13
+ callback: async ({ contents }) => patchCode(contents, errorInspectRule),
14
+ },
15
+ ]);
16
+ }
17
+ /**
18
+ * Drops `require("./node-environment-extensions/error-inspect");`
19
+ */
20
+ export const errorInspectRule = `
21
+ rule:
22
+ pattern: require("./node-environment-extensions/error-inspect");
23
+ fix: |-
24
+ // Removed by OpenNext
25
+ // require("./node-environment-extensions/error-inspect");
26
+ `;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Patch for `next/src/server/route-modules/route-module.ts`
3
+ * https://github.com/vercel/next.js/blob/c8c9bef/packages/next/src/server/route-modules/route-module.ts#L389-L437
4
+ *
5
+ * Patch getIncrementalCache to use a string literal for the cache handler path
6
+ *
7
+ */
8
+ import { BuildOptions } from "@opennextjs/aws/build/helper.js";
9
+ import type { ContentUpdater, Plugin } from "@opennextjs/aws/plugins/content-updater.js";
10
+ export declare function patchRouteModules(updater: ContentUpdater, buildOpts: BuildOptions): Plugin;
11
+ /**
12
+ * The cache handler used by Next.js is normally defined in the config file as a path. At runtime,
13
+ * Next.js would then do a dynamic require on a transformed version of the path to retrieve the
14
+ * cache handler and create a new instance of it.
15
+ *
16
+ * This is problematic in workerd due to the dynamic import of the file that is not known from
17
+ * build-time. Therefore, we have to manually override the default way that the cache handler is
18
+ * instantiated with a dynamic require that uses a string literal for the path.
19
+ */
20
+ export declare function getIncrementalCacheRule(handlerPath: string): string;
21
+ /**
22
+ * Force trustHostHeader to be true for revalidation
23
+ */
24
+ export declare const forceTrustHostHeader = "\nrule:\n pattern: async function $FN($$$ARGS) { $$$BODY }\n all:\n - has:\n pattern: if ($CONTEXT.trustHostHeader) { $$$_ }\n stopBy: end\n - has:\n regex: \"^x-vercel-protection-bypass$\"\n stopBy: end\n - has:\n regex: \"Invariant: missing internal\"\n stopBy: end\nfix: |-\n async function $FN($$$ARGS) {\n $CONTEXT.trustHostHeader = true;\n $$$BODY\n }\n";
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Patch for `next/src/server/route-modules/route-module.ts`
3
+ * https://github.com/vercel/next.js/blob/c8c9bef/packages/next/src/server/route-modules/route-module.ts#L389-L437
4
+ *
5
+ * Patch getIncrementalCache to use a string literal for the cache handler path
6
+ *
7
+ */
8
+ import path from "node:path";
9
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
10
+ import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
11
+ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
12
+ import { normalizePath } from "../../utils/index.js";
13
+ export function patchRouteModules(updater, buildOpts) {
14
+ return updater.updateContent("route-module", [
15
+ {
16
+ filter: getCrossPlatformPathRegex(String.raw `/next/dist/compiled/next-server/.*?\.runtime\.prod\.js$`, {
17
+ escape: false,
18
+ }),
19
+ versions: ">=15.4.0",
20
+ contentFilter: /getIncrementalCache\(/,
21
+ callback: async ({ contents }) => {
22
+ const { outputDir } = buildOpts;
23
+ const outputPath = path.join(outputDir, "server-functions/default");
24
+ const cacheHandler = path.join(outputPath, getPackagePath(buildOpts), "cache.cjs");
25
+ contents = patchCode(contents, getIncrementalCacheRule(cacheHandler));
26
+ contents = patchCode(contents, forceTrustHostHeader);
27
+ return contents;
28
+ },
29
+ },
30
+ ]);
31
+ }
32
+ /**
33
+ * The cache handler used by Next.js is normally defined in the config file as a path. At runtime,
34
+ * Next.js would then do a dynamic require on a transformed version of the path to retrieve the
35
+ * cache handler and create a new instance of it.
36
+ *
37
+ * This is problematic in workerd due to the dynamic import of the file that is not known from
38
+ * build-time. Therefore, we have to manually override the default way that the cache handler is
39
+ * instantiated with a dynamic require that uses a string literal for the path.
40
+ */
41
+ export function getIncrementalCacheRule(handlerPath) {
42
+ return `
43
+ rule:
44
+ pattern: "let $CACHE_HANDLER, { cacheHandler: $HANDLER_PATH } = $C"
45
+ inside:
46
+ kind: method_definition
47
+ has:
48
+ field: name
49
+ regex: ^getIncrementalCache$
50
+ stopBy: end
51
+ fix: |-
52
+ const $HANDLER_PATH = null;
53
+ let $CACHE_HANDLER = require('${normalizePath(handlerPath)}').default;
54
+ `;
55
+ }
56
+ /**
57
+ * Force trustHostHeader to be true for revalidation
58
+ */
59
+ export const forceTrustHostHeader = `
60
+ rule:
61
+ pattern: async function $FN($$$ARGS) { $$$BODY }
62
+ all:
63
+ - has:
64
+ pattern: if ($CONTEXT.trustHostHeader) { $$$_ }
65
+ stopBy: end
66
+ - has:
67
+ regex: "^x-vercel-protection-bypass$"
68
+ stopBy: end
69
+ - has:
70
+ regex: "Invariant: missing internal"
71
+ stopBy: end
72
+ fix: |-
73
+ async function $FN($$$ARGS) {
74
+ $CONTEXT.trustHostHeader = true;
75
+ $$$BODY
76
+ }
77
+ `;
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": "1.6.3",
4
+ "version": "1.6.5",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"
@@ -43,7 +43,7 @@
43
43
  "homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
44
44
  "dependencies": {
45
45
  "@dotenvx/dotenvx": "1.31.0",
46
- "@opennextjs/aws": "3.7.2",
46
+ "@opennextjs/aws": "3.7.4",
47
47
  "cloudflare": "^4.4.1",
48
48
  "enquirer": "^2.4.1",
49
49
  "glob": "^11.0.0",