@opennextjs/cloudflare 0.3.9 → 0.4.0

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.
Files changed (61) hide show
  1. package/README.md +1 -64
  2. package/dist/api/{get-cloudflare-context.d.ts → cloudflare-context.d.ts} +8 -1
  3. package/dist/api/cloudflare-context.js +96 -0
  4. package/dist/api/index.d.ts +1 -1
  5. package/dist/api/index.js +1 -1
  6. package/dist/api/kvCache.d.ts +0 -5
  7. package/dist/api/kvCache.js +15 -28
  8. package/dist/cli/build/build.d.ts +1 -1
  9. package/dist/cli/build/build.js +2 -12
  10. package/dist/cli/build/bundle-server.d.ts +4 -5
  11. package/dist/cli/build/bundle-server.js +39 -38
  12. package/dist/cli/build/open-next/compile-env-files.d.ts +1 -1
  13. package/dist/cli/build/open-next/compile-env-files.js +2 -2
  14. package/dist/cli/build/open-next/createServerBundle.js +3 -2
  15. package/dist/cli/build/patches/ast/optional-deps.d.ts +13 -0
  16. package/dist/cli/build/patches/ast/optional-deps.js +31 -0
  17. package/dist/cli/build/patches/ast/optional-deps.spec.d.ts +1 -0
  18. package/dist/cli/build/patches/ast/optional-deps.spec.js +89 -0
  19. package/dist/cli/build/patches/ast/util.d.ts +50 -0
  20. package/dist/cli/build/patches/ast/util.js +65 -0
  21. package/dist/cli/build/patches/ast/util.spec.d.ts +1 -0
  22. package/dist/cli/build/patches/ast/util.spec.js +43 -0
  23. package/dist/cli/build/patches/ast/vercel-og.d.ts +23 -0
  24. package/dist/cli/build/patches/ast/vercel-og.js +58 -0
  25. package/dist/cli/build/patches/ast/vercel-og.spec.d.ts +1 -0
  26. package/dist/cli/build/patches/ast/vercel-og.spec.js +22 -0
  27. package/dist/cli/build/patches/investigated/copy-package-cli-files.d.ts +4 -3
  28. package/dist/cli/build/patches/investigated/copy-package-cli-files.js +8 -5
  29. package/dist/cli/build/patches/investigated/index.d.ts +1 -0
  30. package/dist/cli/build/patches/investigated/index.js +1 -0
  31. package/dist/cli/build/patches/investigated/patch-cache.d.ts +2 -2
  32. package/dist/cli/build/patches/investigated/patch-cache.js +7 -6
  33. package/dist/cli/build/patches/investigated/patch-require.d.ts +1 -4
  34. package/dist/cli/build/patches/investigated/patch-require.js +1 -4
  35. package/dist/cli/build/patches/investigated/patch-vercel-og-library.d.ts +7 -0
  36. package/dist/cli/build/patches/investigated/patch-vercel-og-library.js +39 -0
  37. package/dist/cli/build/patches/investigated/patch-vercel-og-library.spec.d.ts +1 -0
  38. package/dist/cli/build/patches/investigated/patch-vercel-og-library.spec.js +50 -0
  39. package/dist/cli/build/patches/investigated/update-webpack-chunks-file/index.d.ts +2 -5
  40. package/dist/cli/build/patches/investigated/update-webpack-chunks-file/index.js +6 -6
  41. package/dist/cli/build/patches/to-investigate/inline-eval-manifest.d.ts +2 -2
  42. package/dist/cli/build/patches/to-investigate/inline-eval-manifest.js +21 -17
  43. package/dist/cli/build/patches/to-investigate/inline-middleware-manifest-require.d.ts +2 -2
  44. package/dist/cli/build/patches/to-investigate/inline-middleware-manifest-require.js +4 -2
  45. package/dist/cli/build/patches/to-investigate/inline-next-require.d.ts +2 -2
  46. package/dist/cli/build/patches/to-investigate/inline-next-require.js +16 -12
  47. package/dist/cli/build/patches/to-investigate/patch-find-dir.d.ts +3 -6
  48. package/dist/cli/build/patches/to-investigate/patch-find-dir.js +11 -11
  49. package/dist/cli/build/patches/to-investigate/patch-read-file.d.ts +3 -3
  50. package/dist/cli/build/patches/to-investigate/patch-read-file.js +15 -16
  51. package/dist/cli/build/patches/to-investigate/wrangler-deps.d.ts +2 -2
  52. package/dist/cli/build/patches/to-investigate/wrangler-deps.js +36 -67
  53. package/dist/cli/build/utils/create-config-files.d.ts +1 -1
  54. package/dist/cli/build/utils/create-config-files.js +2 -2
  55. package/dist/cli/project-options.d.ts +7 -0
  56. package/dist/cli/project-options.js +1 -0
  57. package/package.json +8 -6
  58. package/templates/defaults/wrangler.json +1 -0
  59. package/dist/api/get-cloudflare-context.js +0 -42
  60. package/dist/cli/config.d.ts +0 -42
  61. package/dist/cli/config.js +0 -92
@@ -1,4 +1,5 @@
1
- import { join, posix } from "node:path";
1
+ import { join, relative } from "node:path";
2
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
2
3
  import { globSync } from "glob";
3
4
  import { normalizePath } from "../../utils/index.js";
4
5
  /**
@@ -8,24 +9,27 @@ import { normalizePath } from "../../utils/index.js";
8
9
  * Note: we could/should probably just patch readFileSync here or something, but here the issue is that after the readFileSync call
9
10
  * there is a vm `runInNewContext` call which we also don't support (source: https://github.com/vercel/next.js/blob/b1e32c5d1f/packages/next/src/server/load-manifest.ts#L88)
10
11
  */
11
- export function inlineEvalManifest(code, config) {
12
- const manifestJss = globSync(normalizePath(join(config.paths.output.standaloneAppDotNext, "**", "*_client-reference-manifest.js"))).map((file) => normalizePath(file).replace(normalizePath(config.paths.output.standaloneApp) + posix.sep, ""));
12
+ export function inlineEvalManifest(code, buildOpts) {
13
+ const { outputDir } = buildOpts;
14
+ const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next");
15
+ const appDir = join(baseDir, "server/app");
16
+ const manifests = globSync(join(baseDir, "**/*_client-reference-manifest.js"));
13
17
  return code.replace(/function evalManifest\((.+?), .+?\) {/, `$&
14
- ${manifestJss
15
- .map((manifestJs) => `
16
- if ($1.endsWith("${manifestJs}")) {
17
- require(${JSON.stringify(join(config.paths.output.standaloneApp, manifestJs))});
18
- return {
19
- __RSC_MANIFEST: {
20
- "${manifestJs
21
- .replace(".next/server/app", "")
22
- .replace("_client-reference-manifest.js", "")}": globalThis.__RSC_MANIFEST["${manifestJs
23
- .replace(".next/server/app", "")
24
- .replace("_client-reference-manifest.js", "")}"],
25
- },
26
- };
18
+ ${manifests
19
+ .map((manifest) => {
20
+ const endsWith = normalizePath(relative(baseDir, manifest));
21
+ const key = normalizePath("/" + relative(appDir, manifest)).replace("_client-reference-manifest.js", "");
22
+ return `
23
+ if ($1.endsWith("${endsWith}")) {
24
+ require(${JSON.stringify(manifest)});
25
+ return {
26
+ __RSC_MANIFEST: {
27
+ "${key}": globalThis.__RSC_MANIFEST["${key}"],
28
+ },
29
+ };
27
30
  }
28
- `)
31
+ `;
32
+ })
29
33
  .join("\n")}
30
34
  throw new Error("Unknown evalManifest: " + $1);
31
35
  `);
@@ -1,6 +1,6 @@
1
- import { Config } from "../../../config.js";
1
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
2
  /**
3
3
  * Inlines the middleware manifest from the build output to prevent a dynamic require statement
4
4
  * as they result in runtime failures.
5
5
  */
6
- export declare function inlineMiddlewareManifestRequire(code: string, config: Config): string;
6
+ export declare function inlineMiddlewareManifestRequire(code: string, buildOpts: BuildOptions): string;
@@ -1,11 +1,13 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
3
4
  /**
4
5
  * Inlines the middleware manifest from the build output to prevent a dynamic require statement
5
6
  * as they result in runtime failures.
6
7
  */
7
- export function inlineMiddlewareManifestRequire(code, config) {
8
- const middlewareManifestPath = join(config.paths.output.standaloneAppServer, "middleware-manifest.json");
8
+ export function inlineMiddlewareManifestRequire(code, buildOpts) {
9
+ const { outputDir } = buildOpts;
10
+ const middlewareManifestPath = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server/middleware-manifest.json");
9
11
  const middlewareManifest = existsSync(middlewareManifestPath)
10
12
  ? JSON.parse(readFileSync(middlewareManifestPath, "utf-8"))
11
13
  : {};
@@ -1,6 +1,6 @@
1
- import { Config } from "../../../config.js";
1
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
2
  /**
3
3
  * The following avoid various Next.js specific files `require`d at runtime since we can just read
4
4
  * and inline their content during build time
5
5
  */
6
- export declare function inlineNextRequire(code: string, config: Config): string;
6
+ export declare function inlineNextRequire(code: string, buildOpts: BuildOptions): string;
@@ -1,33 +1,37 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
3
4
  /**
4
5
  * The following avoid various Next.js specific files `require`d at runtime since we can just read
5
6
  * and inline their content during build time
6
7
  */
7
- export function inlineNextRequire(code, config) {
8
- const pagesManifestFile = join(config.paths.output.standaloneAppServer, "pages-manifest.json");
9
- const appPathsManifestFile = join(config.paths.output.standaloneAppServer, "app-paths-manifest.json");
10
- const pagesManifestFiles = existsSync(pagesManifestFile)
11
- ? Object.values(JSON.parse(readFileSync(pagesManifestFile, "utf-8"))).map((file) => ".next/server/" + file)
8
+ // TODO(vicb): __NEXT_PRIVATE_RUNTIME_TYPE is not handled by this patch
9
+ export function inlineNextRequire(code, buildOpts) {
10
+ const { outputDir } = buildOpts;
11
+ const serverDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
12
+ const pagesManifestFile = join(serverDir, "pages-manifest.json");
13
+ const appPathsManifestFile = join(serverDir, "app-paths-manifest.json");
14
+ const pagesManifests = existsSync(pagesManifestFile)
15
+ ? Object.values(JSON.parse(readFileSync(pagesManifestFile, "utf-8")))
12
16
  : [];
13
- const appPathsManifestFiles = existsSync(appPathsManifestFile)
14
- ? Object.values(JSON.parse(readFileSync(appPathsManifestFile, "utf-8"))).map((file) => ".next/server/" + file)
17
+ const appPathsManifests = existsSync(appPathsManifestFile)
18
+ ? Object.values(JSON.parse(readFileSync(appPathsManifestFile, "utf-8")))
15
19
  : [];
16
- const allManifestFiles = pagesManifestFiles.concat(appPathsManifestFiles);
17
- const htmlPages = allManifestFiles.filter((file) => file.endsWith(".html"));
18
- const pageModules = allManifestFiles.filter((file) => file.endsWith(".js"));
20
+ const manifests = pagesManifests.concat(appPathsManifests);
21
+ const htmlPages = manifests.filter((file) => file.endsWith(".html"));
22
+ const pageModules = manifests.filter((file) => file.endsWith(".js"));
19
23
  return code.replace(/const pagePath = getPagePath\(.+?\);/, `$&
20
24
  ${htmlPages
21
25
  .map((htmlPage) => `
22
26
  if (pagePath.endsWith("${htmlPage}")) {
23
- return ${JSON.stringify(readFileSync(join(config.paths.output.standaloneApp, htmlPage), "utf-8"))};
27
+ return ${JSON.stringify(readFileSync(join(serverDir, htmlPage), "utf-8"))};
24
28
  }
25
29
  `)
26
30
  .join("\n")}
27
31
  ${pageModules
28
32
  .map((module) => `
29
33
  if (pagePath.endsWith("${module}")) {
30
- return require(${JSON.stringify(join(config.paths.output.standaloneApp, module))});
34
+ return require(${JSON.stringify(join(serverDir, module))});
31
35
  }
32
36
  `)
33
37
  .join("\n")}
@@ -1,8 +1,5 @@
1
- import { Config } from "../../../config.js";
1
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
2
  /**
3
- * Here we patch `findDir` so that the next server can detect whether the `app` or `pages` directory exists
4
- * (source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/lib/find-pages-dir.ts#L4-L13)
5
- * (usage source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/server/next-server.ts#L450-L451)
6
- * Note: `findDir` uses `fs.existsSync` under the hood, so patching that should be enough to make this work
3
+ * Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists
7
4
  */
8
- export declare function patchFindDir(code: string, config: Config): string;
5
+ export declare function patchFindDir(code: string, buildOpts: BuildOptions): string;
@@ -1,20 +1,20 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
3
4
  /**
4
- * Here we patch `findDir` so that the next server can detect whether the `app` or `pages` directory exists
5
- * (source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/lib/find-pages-dir.ts#L4-L13)
6
- * (usage source: https://github.com/vercel/next.js/blob/ba995993/packages/next/src/server/next-server.ts#L450-L451)
7
- * Note: `findDir` uses `fs.existsSync` under the hood, so patching that should be enough to make this work
5
+ * Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists
8
6
  */
9
- export function patchFindDir(code, config) {
7
+ export function patchFindDir(code, buildOpts) {
8
+ const { outputDir } = buildOpts;
9
+ const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
10
10
  return code.replace(/function findDir\((?<dir>dir\d*), (?<name>name\d*)\) {/, `function findDir($dir, $name) {
11
11
  if ($dir.endsWith(".next/server")) {
12
- if ($name === "app") {
13
- return ${existsSync(`${join(config.paths.output.standaloneAppServer, "app")}`)};
14
- }
15
- if ($name === "pages") {
16
- return ${existsSync(`${join(config.paths.output.standaloneAppServer, "pages")}`)};
17
- }
12
+ if ($name === "app") {
13
+ return ${existsSync(`${join(baseDir, "app")}`)};
14
+ }
15
+ if ($name === "pages") {
16
+ return ${existsSync(`${join(baseDir, "pages")}`)};
17
+ }
18
18
  }
19
19
  throw new Error("Unknown findDir call: " + $dir + " " + $name);
20
20
  `);
@@ -1,3 +1,3 @@
1
- import { Config } from "../../../config.js";
2
- export declare function patchBuildId(code: string, config: Config): string;
3
- export declare function patchLoadManifest(code: string, config: Config): string;
1
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
+ export declare function patchBuildId(code: string, buildOpts: BuildOptions): string;
3
+ export declare function patchLoadManifest(code: string, buildOpts: BuildOptions): string;
@@ -1,26 +1,25 @@
1
1
  import { readFileSync } from "node:fs";
2
- import { join, posix } from "node:path";
2
+ import { join, relative } from "node:path";
3
+ import { getBuildId, getPackagePath } from "@opennextjs/aws/build/helper.js";
3
4
  import { globSync } from "glob";
4
5
  import { normalizePath } from "../../utils/index.js";
5
- export function patchBuildId(code, config) {
6
- // The next-server code gets the buildId from the filesystem, resulting in a `[unenv] fs.readFileSync is not implemented yet!` error
7
- // so we add an early return to the `getBuildId` function so that the `readyFileSync` is never encountered
8
- // (source: https://github.com/vercel/next.js/blob/15aeb92efb34c09a36/packages/next/src/server/next-server.ts#L438-L451)
9
- // Note: we could/should probably just patch readFileSync here or something!
6
+ export function patchBuildId(code, buildOpts) {
7
+ // The Next code gets the buildId from the filesystem so we hardcode the value at build time.
10
8
  return code.replace("getBuildId() {", `getBuildId() {
11
- return ${JSON.stringify(readFileSync(join(config.paths.output.standaloneAppDotNext, "BUILD_ID"), "utf-8"))};
9
+ return ${JSON.stringify(getBuildId(buildOpts))};
12
10
  `);
13
11
  }
14
- export function patchLoadManifest(code, config) {
15
- // Same as patchBuildId, the next-server code loads the manifests with `readFileSync` and we want to avoid that
16
- // (source: https://github.com/vercel/next.js/blob/15aeb92e/packages/next/src/server/load-manifest.ts#L34-L56)
17
- // Note: we could/should probably just patch readFileSync here or something!
18
- const manifestJsons = globSync(normalizePath(join(config.paths.output.standaloneAppDotNext, "**", "*-manifest.json"))).map((file) => normalizePath(file).replace(normalizePath(config.paths.output.standaloneApp) + posix.sep, ""));
12
+ export function patchLoadManifest(code, buildOpts) {
13
+ // Inline manifest that Next would otherwise retrieve from the file system.
14
+ const { outputDir } = buildOpts;
15
+ const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts));
16
+ const dotNextDir = join(baseDir, ".next");
17
+ const manifests = globSync(join(dotNextDir, "**/*-manifest.json"));
19
18
  return code.replace(/function loadManifest\((.+?), .+?\) {/, `$&
20
- ${manifestJsons
21
- .map((manifestJson) => `
22
- if ($1.endsWith("${manifestJson}")) {
23
- return ${readFileSync(join(config.paths.output.standaloneApp, manifestJson), "utf-8")};
19
+ ${manifests
20
+ .map((manifest) => `
21
+ if ($1.endsWith("${normalizePath("/" + relative(dotNextDir, manifest))}")) {
22
+ return ${readFileSync(manifest, "utf-8")};
24
23
  }
25
24
  `)
26
25
  .join("\n")}
@@ -1,2 +1,2 @@
1
- import { Config } from "../../../config.js";
2
- export declare function patchWranglerDeps(config: Config): void;
1
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
+ export declare function patchWranglerDeps(buildOpts: BuildOptions): void;
@@ -1,60 +1,30 @@
1
- import { readFileSync, statSync, writeFileSync } from "node:fs";
1
+ import { readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
3
4
  import * as ts from "ts-morph";
4
5
  import { tsParseFile } from "../../utils/index.js";
5
- export function patchWranglerDeps(config) {
6
+ export function patchWranglerDeps(buildOpts) {
6
7
  console.log("# patchWranglerDeps");
7
- const distPath = getDistPath(config);
8
- // Patch .next/standalone/node_modules/next/dist/compiled/next-server/pages.runtime.prod.js
9
- //
10
- // Remove the need for an alias in wrangler.toml:
11
- //
12
- // [alias]
13
- // # critters is `require`d from `pages.runtime.prod.js` when running wrangler dev, so we need to stub it out
14
- // "critters" = "./.next/standalone/node_modules/cf/templates/shims/empty.ts"
15
- const pagesRuntimeFile = join(distPath, "compiled", "next-server", "pages.runtime.prod.js");
16
- const patchedPagesRuntime = readFileSync(pagesRuntimeFile, "utf-8").replace(`e.exports=require("critters")`, `e.exports={}`);
8
+ const { outputDir } = buildOpts;
9
+ const nextDistDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), "node_modules/next/dist");
10
+ const pagesRuntimeFile = join(nextDistDir, "compiled/next-server/pages.runtime.prod.js");
11
+ const patchedPagesRuntime = readFileSync(pagesRuntimeFile, "utf-8").replace(`e.exports=require("critters")`, `
12
+ try {
13
+ e.exports=require("critters");
14
+ }
15
+ catch {
16
+ console.error('critters is not installed');
17
+ }
18
+ `);
17
19
  writeFileSync(pagesRuntimeFile, patchedPagesRuntime);
18
- patchRequireReactDomServerEdge(config);
19
- // Patch .next/standalone/node_modules/next/dist/server/lib/trace/tracer.js
20
- //
21
- // Remove the need for an alias in wrangler.toml:
22
- //
23
- // [alias]
24
- // # @opentelemetry/api is `require`d when running wrangler dev, so we need to stub it out
25
- // # IMPORTANT: we shim @opentelemetry/api to the throwing shim so that it will throw right away, this is so that we throw inside the
26
- // # try block here: https://github.com/vercel/next.js/blob/9e8266a7/packages/next/src/server/lib/trace/tracer.ts#L27-L31
27
- // # causing the code to require the 'next/dist/compiled/@opentelemetry/api' module instead (which properly works)
28
- // #"@opentelemetry/api" = "./.next/standalone/node_modules/cf/templates/shims/throw.ts"
29
- const tracerFile = join(distPath, "server", "lib", "trace", "tracer.js");
20
+ patchRequireReactDomServerEdge(nextDistDir);
21
+ // we shim @opentelemetry/api to the throwing shim so that it will throw right away, this is so that we throw inside the
22
+ // try block here: https://github.com/vercel/next.js/blob/9e8266a7/packages/next/src/server/lib/trace/tracer.ts#L27-L31
23
+ // causing the code to require the 'next/dist/compiled/@opentelemetry/api' module instead (which properly works)
24
+ const tracerFile = join(nextDistDir, "server/lib/trace/tracer.js");
30
25
  const patchedTracer = readFileSync(tracerFile, "utf-8").replaceAll(/\w+\s*=\s*require\([^/]*opentelemetry.*\)/g, `throw new Error("@opentelemetry/api")`);
31
26
  writeFileSync(tracerFile, patchedTracer);
32
27
  }
33
- /**
34
- * Next.js saves the node_modules/next/dist directory in either the standaloneApp path or in the
35
- * standaloneRoot path, this depends on where the next dependency is actually saved (
36
- * https://github.com/vercel/next.js/blob/39e06c75/packages/next/src/build/webpack-config.ts#L103-L104
37
- * ) and can depend on the package manager used, if it is using workspaces, etc...
38
- *
39
- * This function checks the two potential paths for the dist directory and returns the first that it finds,
40
- * it throws an error if it can't find either
41
- *
42
- * @param config
43
- * @returns the node_modules/next/dist directory path
44
- */
45
- function getDistPath(config) {
46
- for (const root of [config.paths.output.standaloneApp, config.paths.output.standaloneRoot]) {
47
- try {
48
- const distPath = join(root, "node_modules", "next", "dist");
49
- if (statSync(distPath).isDirectory())
50
- return distPath;
51
- }
52
- catch {
53
- /* empty */
54
- }
55
- }
56
- throw new Error("Unexpected error: unable to detect the node_modules/next/dist directory");
57
- }
58
28
  /**
59
29
  * `react-dom` v>=19 has a `server.edge` export: https://github.com/facebook/react/blob/a160102f3/packages/react-dom/package.json#L79
60
30
  * but version of `react-dom` <= 18 do not have this export but have a `server.browser` export instead: https://github.com/facebook/react/blob/8a015b68/packages/react-dom/package.json#L49
@@ -70,10 +40,9 @@ function getDistPath(config) {
70
40
  * it's not clear what code and how might be rely on this require call)
71
41
  *
72
42
  */
73
- function patchRequireReactDomServerEdge(config) {
74
- const distPath = getDistPath(config);
43
+ function patchRequireReactDomServerEdge(nextDistDir) {
75
44
  // Patch .next/standalone/node_modules/next/dist/compiled/next-server/pages.runtime.prod.js
76
- const pagesRuntimeFile = join(distPath, "compiled", "next-server", "pages.runtime.prod.js");
45
+ const pagesRuntimeFile = join(nextDistDir, "compiled/next-server/pages.runtime.prod.js");
77
46
  const code = readFileSync(pagesRuntimeFile, "utf-8");
78
47
  const file = tsParseFile(code);
79
48
  // we need to update this function: `e=>{"use strict";e.exports=require("react-dom/server.edge")}`
@@ -125,21 +94,21 @@ function patchRequireReactDomServerEdge(config) {
125
94
  return;
126
95
  }
127
96
  arrowFunction.setBodyText(`
128
- "use strict";
129
- let ReactDOMServer;
130
- try {
131
- ReactDOMServer = require('react-dom/server.edge');
132
- } catch (error) {
133
- if (
134
- error.code !== 'MODULE_NOT_FOUND' &&
135
- error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED'
136
- ) {
137
- throw error;
138
- }
139
- ReactDOMServer = require('react-dom/server.browser');
140
- }
141
- ${parameterName}.exports = ReactDOMServer;
142
- `.replace(/\ns*/g, " "));
97
+ // OpenNext patch
98
+ let ReactDOMServer;
99
+ try {
100
+ ReactDOMServer = require('react-dom/server.edge');
101
+ } catch (error) {
102
+ if (
103
+ error.code !== 'MODULE_NOT_FOUND' &&
104
+ error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED'
105
+ ) {
106
+ throw error;
107
+ }
108
+ ReactDOMServer = require('react-dom/server.browser');
109
+ }
110
+ ${parameterName}.exports = ReactDOMServer;
111
+ `);
143
112
  });
144
113
  const updatedCode = file.print();
145
114
  writeFileSync(pagesRuntimeFile, updatedCode);
@@ -1,4 +1,4 @@
1
- import type { ProjectOptions } from "../../config.js";
1
+ import type { ProjectOptions } from "../../project-options.js";
2
2
  /**
3
3
  * Creates a `wrangler.json` file for the user if a wrangler config file doesn't already exist,
4
4
  * but only after asking for the user's confirmation.
@@ -28,7 +28,7 @@ export async function createWranglerConfigIfNotExistent(projectOpts) {
28
28
  "(to avoid this check use the `--skipWranglerConfigCheck` flag or set a `SKIP_WRANGLER_CONFIG_CHECK` environment variable to `yes`)");
29
29
  return;
30
30
  }
31
- let wranglerConfig = readFileSync(join(getPackageTemplatesDirPath(), "defaults", "wrangler.json"), "utf8");
31
+ let wranglerConfig = readFileSync(join(getPackageTemplatesDirPath(), "defaults/wrangler.json"), "utf8");
32
32
  const appName = getAppNameFromPackageJson(projectOpts.sourceDir) ?? "app-name";
33
33
  if (appName) {
34
34
  wranglerConfig = wranglerConfig.replace('"app-name"', JSON.stringify(appName.replaceAll("_", "-")));
@@ -80,6 +80,6 @@ export async function createOpenNextConfigIfNotExistent(projectOpts) {
80
80
  if (!answer) {
81
81
  throw new Error("The `open-next.config.ts` file is required, aborting!");
82
82
  }
83
- cpSync(join(getPackageTemplatesDirPath(), "defaults", "open-next.config.ts"), openNextConfigPath);
83
+ cpSync(join(getPackageTemplatesDirPath(), "defaults/open-next.config.ts"), openNextConfigPath);
84
84
  }
85
85
  }
@@ -0,0 +1,7 @@
1
+ export type ProjectOptions = {
2
+ sourceDir: string;
3
+ outputDir: string;
4
+ skipNextBuild: boolean;
5
+ skipWranglerConfigCheck: boolean;
6
+ minify: boolean;
7
+ };
@@ -0,0 +1 @@
1
+ export {};
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.3.9",
4
+ "version": "0.4.0",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"
@@ -48,27 +48,29 @@
48
48
  "@types/mock-fs": "^4.13.4",
49
49
  "@types/node": "^22.2.0",
50
50
  "esbuild": "^0.23.0",
51
+ "eslint": "^9.11.1",
51
52
  "eslint-plugin-import": "^2.31.0",
52
53
  "eslint-plugin-simple-import-sort": "^12.1.1",
53
54
  "eslint-plugin-unicorn": "^55.0.0",
54
- "eslint": "^9.11.1",
55
55
  "globals": "^15.9.0",
56
56
  "mock-fs": "^5.4.1",
57
57
  "next": "14.2.11",
58
58
  "rimraf": "^6.0.1",
59
+ "typescript": "^5.7.3",
59
60
  "typescript-eslint": "^8.7.0",
60
- "typescript": "^5.5.4",
61
61
  "vitest": "^2.1.1"
62
62
  },
63
63
  "dependencies": {
64
+ "@ast-grep/napi": "^0.34.1",
64
65
  "@dotenvx/dotenvx": "1.31.0",
65
- "@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@704",
66
+ "@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@712",
67
+ "enquirer": "^2.4.1",
66
68
  "glob": "^11.0.0",
67
69
  "ts-morph": "^23.0.0",
68
- "enquirer": "^2.4.1"
70
+ "yaml": "^2.7.0"
69
71
  },
70
72
  "peerDependencies": {
71
- "wrangler": "^3.101.0"
73
+ "wrangler": "^3.105.0"
72
74
  },
73
75
  "scripts": {
74
76
  "clean": "rimraf dist",
@@ -1,4 +1,5 @@
1
1
  {
2
+ "$schema": "node_modules/wrangler/config-schema.json",
2
3
  "main": ".open-next/worker.js",
3
4
  "name": "app-name",
4
5
  "compatibility_date": "2024-12-30",
@@ -1,42 +0,0 @@
1
- // Note: this symbol needs to be kept in sync with the one used in `src/cli/templates/worker.ts`
2
- const cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
3
- /**
4
- * Utility to get the current Cloudflare context
5
- *
6
- * @returns the cloudflare context
7
- */
8
- export async function getCloudflareContext() {
9
- const global = globalThis;
10
- const cloudflareContext = global[cloudflareContextSymbol];
11
- if (!cloudflareContext) {
12
- // the cloudflare context is initialized by the worker and is always present in production/preview,
13
- // so, it not being present means that the application is running under `next dev`
14
- return getCloudflareContextInNextDev();
15
- }
16
- return cloudflareContext;
17
- }
18
- const cloudflareContextInNextDevSymbol = Symbol.for("__next-dev/cloudflare-context__");
19
- /**
20
- * Gets a local proxy version of the cloudflare context (created using `getPlatformProxy`) when
21
- * running in the standard next dev server (via `next dev`)
22
- *
23
- * @returns the local proxy version of the cloudflare context
24
- */
25
- async function getCloudflareContextInNextDev() {
26
- const global = globalThis;
27
- if (!global[cloudflareContextInNextDevSymbol]) {
28
- // Note: we never want wrangler to be bundled in the Next.js app, that's why the import below looks like it does
29
- const { getPlatformProxy } = await import(
30
- /* webpackIgnore: true */ `${"__wrangler".replaceAll("_", "")}`);
31
- const { env, cf, ctx } = await getPlatformProxy({
32
- // This allows the selection of a wrangler environment while running in next dev mode
33
- environment: process.env.NEXT_DEV_WRANGLER_ENV,
34
- });
35
- global[cloudflareContextInNextDevSymbol] = {
36
- env,
37
- cf: cf,
38
- ctx: ctx,
39
- };
40
- }
41
- return global[cloudflareContextInNextDevSymbol];
42
- }
@@ -1,42 +0,0 @@
1
- export type Config = {
2
- build: {
3
- skipNextBuild: boolean;
4
- shouldMinify: boolean;
5
- };
6
- paths: {
7
- source: {
8
- root: string;
9
- dotNext: string;
10
- standaloneRoot: string;
11
- };
12
- output: {
13
- root: string;
14
- assets: string;
15
- dotNext: string;
16
- standaloneRoot: string;
17
- standaloneApp: string;
18
- standaloneAppDotNext: string;
19
- standaloneAppServer: string;
20
- };
21
- internal: {
22
- package: string;
23
- templates: string;
24
- };
25
- };
26
- internalPackageName: string;
27
- };
28
- /**
29
- * Computes the configuration.
30
- *
31
- * @param projectOpts The options for the project
32
- * @returns The configuration, see `Config`
33
- */
34
- export declare function getConfig(projectOpts: ProjectOptions): Config;
35
- export declare function containsDotNextDir(folder: string): boolean;
36
- export type ProjectOptions = {
37
- sourceDir: string;
38
- outputDir: string;
39
- skipNextBuild: boolean;
40
- skipWranglerConfigCheck: boolean;
41
- minify: boolean;
42
- };