@opennextjs/cloudflare 0.5.1 → 0.5.3

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.
@@ -23,7 +23,12 @@ export type CloudflareContext<CfProperties extends Record<string, unknown> = Inc
23
23
  *
24
24
  * @returns the cloudflare context
25
25
  */
26
- export declare function getCloudflareContext<CfProperties extends Record<string, unknown> = IncomingRequestCfProperties, Context = ExecutionContext>(): CloudflareContext<CfProperties, Context>;
26
+ export declare function getCloudflareContext<CfProperties extends Record<string, unknown> = IncomingRequestCfProperties, Context = ExecutionContext>(options: {
27
+ async: true;
28
+ }): Promise<CloudflareContext<CfProperties, Context>>;
29
+ export declare function getCloudflareContext<CfProperties extends Record<string, unknown> = IncomingRequestCfProperties, Context = ExecutionContext>(options?: {
30
+ async: false;
31
+ }): CloudflareContext<CfProperties, Context>;
27
32
  /**
28
33
  * Performs some initial setup to integrate as best as possible the local Next.js dev server (run via `next dev`)
29
34
  * with the open-next Cloudflare adapter
@@ -6,41 +6,65 @@
6
6
  * Note: this symbol needs to be kept in sync with the one used in `src/cli/templates/worker.ts`
7
7
  */
8
8
  const cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
9
+ export function getCloudflareContext(options = { async: false }) {
10
+ return options.async ? getCloudflareContextAsync() : getCloudflareContextSync();
11
+ }
9
12
  /**
10
- * Utility to get the current Cloudflare context
11
- *
12
- * @returns the cloudflare context
13
+ * Get the cloudflare context from the current global scope
14
+ */
15
+ function getCloudflareContextFromGlobalScope() {
16
+ const global = globalThis;
17
+ return global[cloudflareContextSymbol];
18
+ }
19
+ /**
20
+ * Detects whether the current code is being evaluated in a statically generated route
13
21
  */
14
- export function getCloudflareContext() {
22
+ function inSSG() {
15
23
  const global = globalThis;
16
- const cloudflareContext = global[cloudflareContextSymbol];
17
- if (!cloudflareContext) {
18
- // For SSG Next.js creates (jest) workers that run in parallel, those don't get the current global
19
- // state so they can't get access to the cloudflare context, unfortunately there isn't anything we
20
- // can do about this, so the only solution is to error asking the developer to opt-out of SSG
21
- // Next.js sets globalThis.__NEXT_DATA__.nextExport to true for the worker, so we can use that to detect
22
- // that the route is being SSG'd (source: https://github.com/vercel/next.js/blob/4e394608423/packages/next/src/export/worker.ts#L55-L57)
23
- if (global.__NEXT_DATA__?.nextExport === true) {
24
- throw new Error(`\n\nERROR: \`getCloudflareContext\` has been called in a static route` +
25
- ` that is not allowed, please either avoid calling \`getCloudflareContext\`` +
26
- ` in the route or make the route non static (for example by exporting the` +
27
- ` \`dynamic\` route segment config set to \`'force-dynamic'\`.\n`);
28
- }
29
- // the cloudflare context is initialized by the worker and is always present in production/preview
30
- // during local development (`next dev`) it might be missing only if the developers hasn't called
31
- // the `initOpenNextCloudflareForDev` function in their Next.js config file
32
- throw new Error(`\n\nERROR: \`getCloudflareContext\` has been called without having called` +
33
- ` \`initOpenNextCloudflareForDev\` from the Next.js config file.\n` +
34
- `You should update your Next.js config file as shown below:\n\n` +
35
- " ```\n // next.config.mjs\n\n" +
36
- ` import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";\n\n` +
37
- ` initOpenNextCloudflareForDev();\n\n` +
38
- " const nextConfig = { ... };\n" +
39
- " export default nextConfig;\n" +
40
- " ```\n" +
41
- "\n");
24
+ // Note: Next.js sets globalThis.__NEXT_DATA__.nextExport to true for SSG routes
25
+ // source: https://github.com/vercel/next.js/blob/4e394608423/packages/next/src/export/worker.ts#L55-L57)
26
+ return global.__NEXT_DATA__?.nextExport === true;
27
+ }
28
+ /**
29
+ * Utility to get the current Cloudflare context in sync mode
30
+ */
31
+ function getCloudflareContextSync() {
32
+ const cloudflareContext = getCloudflareContextFromGlobalScope();
33
+ if (cloudflareContext) {
34
+ return cloudflareContext;
35
+ }
36
+ // The sync mode of `getCloudflareContext`, relies on the context being set on the global state
37
+ // by either the worker entrypoint (in prod) or by `initOpenNextCloudflareForDev` (in dev), neither
38
+ // can work during SSG since for SSG Next.js creates (jest) workers that don't get access to the
39
+ // normal global state so we throw with a helpful error message.
40
+ if (inSSG()) {
41
+ throw new Error(`\n\nERROR: \`getCloudflareContext\` has been called in a static route,` +
42
+ ` that is not allowed, this can be solved in different ways:\n\n` +
43
+ ` - call \`getCloudflareContext({async: true})\` to use the \`async\` mode\n` +
44
+ ` - avoid calling \`getCloudflareContext\` in the route\n` +
45
+ ` - make the route non static\n`);
46
+ }
47
+ throw new Error(initOpenNextCloudflareForDevErrorMsg);
48
+ }
49
+ /**
50
+ * Utility to get the current Cloudflare context in async mode
51
+ */
52
+ async function getCloudflareContextAsync() {
53
+ const cloudflareContext = getCloudflareContextFromGlobalScope();
54
+ if (cloudflareContext) {
55
+ return cloudflareContext;
56
+ }
57
+ // Note: Next.js sets process.env.NEXT_RUNTIME to 'nodejs' when the runtime in use is the node.js one
58
+ // We want to detect when the runtime is the node.js one so that during development (`next dev`) we know wether
59
+ // we are or not in a node.js process and that access to wrangler's node.js apis
60
+ const inNodejsRuntime = process.env.NEXT_RUNTIME === "nodejs";
61
+ if (inNodejsRuntime || inSSG()) {
62
+ // we're in a node.js process and also in "async mode" so we can use wrangler to asynchronously get the context
63
+ const cloudflareContext = await getCloudflareContextFromWrangler();
64
+ addCloudflareContextToNodejsGlobal(cloudflareContext);
65
+ return cloudflareContext;
42
66
  }
43
- return cloudflareContext;
67
+ throw new Error(initOpenNextCloudflareForDevErrorMsg);
44
68
  }
45
69
  /**
46
70
  * Performs some initial setup to integrate as best as possible the local Next.js dev server (run via `next dev`)
@@ -72,7 +96,7 @@ function shouldContextInitializationRun() {
72
96
  return !!AsyncLocalStorage;
73
97
  }
74
98
  /**
75
- * Adds the cloudflare context to the global scope in which the Next.js dev node.js process runs in, enabling
99
+ * Adds the cloudflare context to the global scope of the current node.js process, enabling
76
100
  * future calls to `getCloudflareContext` to retrieve and return such context
77
101
  *
78
102
  * @param cloudflareContext the cloudflare context to add to the node.sj global scope
@@ -120,3 +144,16 @@ async function getCloudflareContextFromWrangler() {
120
144
  ctx: ctx,
121
145
  };
122
146
  }
147
+ // In production the cloudflare context is initialized by the worker so it is always available.
148
+ // During local development (`next dev`) it might be missing only if the developers hasn't called
149
+ // the `initOpenNextCloudflareForDev` function in their Next.js config file
150
+ const initOpenNextCloudflareForDevErrorMsg = `\n\nERROR: \`getCloudflareContext\` has been called without having called` +
151
+ ` \`initOpenNextCloudflareForDev\` from the Next.js config file.\n` +
152
+ `You should update your Next.js config file as shown below:\n\n` +
153
+ " ```\n // next.config.mjs\n\n" +
154
+ ` import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";\n\n` +
155
+ ` initOpenNextCloudflareForDev();\n\n` +
156
+ " const nextConfig = { ... };\n" +
157
+ " export default nextConfig;\n" +
158
+ " ```\n" +
159
+ "\n";
@@ -8,12 +8,15 @@ import { patchVercelOgLibrary } from "./patches/ast/patch-vercel-og-library.js";
8
8
  import { patchWebpackRuntime } from "./patches/ast/webpack-runtime.js";
9
9
  import * as patches from "./patches/index.js";
10
10
  import { ContentUpdater } from "./patches/plugins/content-updater.js";
11
+ import { inlineEvalManifest } from "./patches/plugins/eval-manifest.js";
11
12
  import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cache-wait-until.js";
13
+ import { inlineFindDir } from "./patches/plugins/find-dir.js";
12
14
  import { patchLoadInstrumentation } from "./patches/plugins/load-instrumentation.js";
15
+ import { inlineLoadManifest } from "./patches/plugins/load-manifest.js";
13
16
  import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js";
14
17
  import { fixRequire } from "./patches/plugins/require.js";
15
18
  import { shimRequireHook } from "./patches/plugins/require-hook.js";
16
- import { inlineRequirePagePlugin } from "./patches/plugins/require-page.js";
19
+ import { inlineRequirePage } from "./patches/plugins/require-page.js";
17
20
  import { setWranglerExternal } from "./patches/plugins/wrangler-external.js";
18
21
  import { normalizePath, patchCodeWithValidations } from "./utils/index.js";
19
22
  /** The dist directory of the Cloudflare adapter package */
@@ -67,12 +70,15 @@ export async function bundleServer(buildOpts) {
67
70
  conditions: [],
68
71
  plugins: [
69
72
  shimRequireHook(buildOpts),
70
- inlineRequirePagePlugin(updater, buildOpts),
73
+ inlineRequirePage(updater, buildOpts),
71
74
  setWranglerExternal(),
72
75
  fixRequire(updater),
73
76
  handleOptionalDependencies(optionalDependencies),
74
77
  patchLoadInstrumentation(updater),
75
78
  patchFetchCacheSetMissingWaitUntil(updater),
79
+ inlineEvalManifest(updater, buildOpts),
80
+ inlineFindDir(updater, buildOpts),
81
+ inlineLoadManifest(updater, buildOpts),
76
82
  // Apply updater updaters, must be the last plugin
77
83
  updater.plugin,
78
84
  ],
@@ -161,9 +167,6 @@ export async function updateWorkerBundledCode(workerOutputFile, buildOpts) {
161
167
  const patchedCode = await patchCodeWithValidations(code, [
162
168
  ["require", patches.patchRequire],
163
169
  ["`buildId` function", (code) => patches.patchBuildId(code, buildOpts)],
164
- ["`loadManifest` function", (code) => patches.patchLoadManifest(code, buildOpts)],
165
- ["`findDir` function", (code) => patches.patchFindDir(code, buildOpts)],
166
- ["`evalManifest` function", (code) => patches.inlineEvalManifest(code, buildOpts)],
167
170
  ["cacheHandler", (code) => patches.patchCache(code, buildOpts)],
168
171
  [
169
172
  "'require(this.middlewareManifestPath)'",
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext`
3
+ * that are not supported by workerd.
4
+ */
5
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
6
+ import type { ContentUpdater } from "./content-updater.js";
7
+ export declare function inlineEvalManifest(updater: ContentUpdater, buildOpts: BuildOptions): import("esbuild").Plugin;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext`
3
+ * that are not supported by workerd.
4
+ */
5
+ import { join, relative } from "node:path";
6
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
7
+ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
8
+ import { glob } from "glob";
9
+ import { normalizePath } from "../../utils/normalize-path.js";
10
+ import { patchCode } from "../ast/util.js";
11
+ export function inlineEvalManifest(updater, buildOpts) {
12
+ return updater.updateContent("inline-eval-manifest", {
13
+ filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/load-manifest\.js$`, { escape: false }),
14
+ contentFilter: /function evalManifest\(/,
15
+ }, async ({ contents }) => patchCode(contents, await getRule(buildOpts)));
16
+ }
17
+ async function getRule(buildOpts) {
18
+ const { outputDir } = buildOpts;
19
+ const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next");
20
+ const appDir = join(baseDir, "server/app");
21
+ const manifests = await glob(join(baseDir, "**/*_client-reference-manifest.js"));
22
+ const returnManifests = manifests
23
+ .map((manifest) => {
24
+ const endsWith = normalizePath(relative(baseDir, manifest));
25
+ const key = normalizePath("/" + relative(appDir, manifest)).replace("_client-reference-manifest.js", "");
26
+ return `
27
+ if ($PATH.endsWith("${endsWith}")) {
28
+ require(${JSON.stringify(manifest)});
29
+ return {
30
+ __RSC_MANIFEST: {
31
+ "${key}": globalThis.__RSC_MANIFEST["${key}"],
32
+ },
33
+ };
34
+ }
35
+ `;
36
+ })
37
+ .join("\n");
38
+ return {
39
+ rule: {
40
+ pattern: `
41
+ function evalManifest($PATH, $$$ARGS) {
42
+ $$$_
43
+ }`,
44
+ },
45
+ fix: `
46
+ function evalManifest($PATH, $$$ARGS) {
47
+ const { platform } = require('process');
48
+ $PATH = platform === 'win32' ? $PATH.replaceAll('\\\\', '/') : $PATH;
49
+ ${returnManifests}
50
+ throw new Error(\`Unexpected evalManifest(\${$PATH}) call!\`);
51
+ }`,
52
+ };
53
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext`
3
+ * that are not supported by workerd.
4
+ */
5
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
6
+ import type { ContentUpdater } from "./content-updater.js";
7
+ export declare function inlineFindDir(updater: ContentUpdater, buildOpts: BuildOptions): import("esbuild").Plugin;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext`
3
+ * that are not supported by workerd.
4
+ */
5
+ import { existsSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
8
+ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
9
+ import { patchCode } from "../ast/util.js";
10
+ export function inlineFindDir(updater, buildOpts) {
11
+ return updater.updateContent("inline-find-dir", {
12
+ filter: getCrossPlatformPathRegex(String.raw `/next/dist/lib/find-pages-dir\.js$`, { escape: false }),
13
+ contentFilter: /function findDir\(/,
14
+ }, async ({ contents }) => patchCode(contents, await getRule(buildOpts)));
15
+ }
16
+ async function getRule(buildOpts) {
17
+ const { outputDir } = buildOpts;
18
+ const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
19
+ const appExists = existsSync(join(baseDir, "app"));
20
+ const pagesExists = existsSync(join(baseDir, "pages"));
21
+ return `
22
+ rule:
23
+ pattern: function findDir($DIR, $NAME) { $$$_ }
24
+ fix: |-
25
+ function findDir($DIR, $NAME) {
26
+ const { platform } = require('process');
27
+ $DIR = platform === 'win32' ? $DIR.replaceAll('\\\\', '/') : $DIR;
28
+ if ($DIR.endsWith(".next/server")) {
29
+ if ($NAME === "app") {
30
+ return ${appExists};
31
+ }
32
+ if ($NAME === "pages") {
33
+ return ${pagesExists};
34
+ }
35
+ }
36
+ throw new Error(\`Unexpected findDir(\${$DIR}, \${$NAME}) call!\`);
37
+ }
38
+ `;
39
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Inline `loadManifest` as it relies on `readFileSync`that is not supported by workerd.
3
+ */
4
+ import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
5
+ import type { ContentUpdater } from "./content-updater.js";
6
+ export declare function inlineLoadManifest(updater: ContentUpdater, buildOpts: BuildOptions): import("esbuild").Plugin;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Inline `loadManifest` as it relies on `readFileSync`that is not supported by workerd.
3
+ */
4
+ import { readFile } from "node:fs/promises";
5
+ import { join, relative } from "node:path";
6
+ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
7
+ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
8
+ import { glob } from "glob";
9
+ import { normalizePath } from "../../utils/normalize-path.js";
10
+ import { patchCode } from "../ast/util.js";
11
+ export function inlineLoadManifest(updater, buildOpts) {
12
+ return updater.updateContent("inline-load-manifest", {
13
+ filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/load-manifest\.js$`, { escape: false }),
14
+ contentFilter: /function loadManifest\(/,
15
+ }, async ({ contents }) => patchCode(contents, await getRule(buildOpts)));
16
+ }
17
+ async function getRule(buildOpts) {
18
+ const { outputDir } = buildOpts;
19
+ const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts));
20
+ const dotNextDir = join(baseDir, ".next");
21
+ const manifests = await glob(join(dotNextDir, "**/*-manifest.json"));
22
+ const returnManifests = (await Promise.all(manifests.map(async (manifest) => `
23
+ if ($PATH.endsWith("${normalizePath("/" + relative(dotNextDir, manifest))}")) {
24
+ return ${await readFile(manifest, "utf-8")};
25
+ }
26
+ `))).join("\n");
27
+ return {
28
+ rule: {
29
+ pattern: `
30
+ function loadManifest($PATH, $$$ARGS) {
31
+ $$$_
32
+ }`,
33
+ },
34
+ fix: `
35
+ function loadManifest($PATH, $$$ARGS) {
36
+ const { platform } = require('process');
37
+ $PATH = platform === 'win32' ? $PATH.replaceAll('\\\\', '/') : $PATH;
38
+ ${returnManifests}
39
+ throw new Error(\`Unexpected loadManifest(\${$PATH}) call!\`);
40
+ }`,
41
+ };
42
+ }
@@ -1,3 +1,3 @@
1
1
  import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
2
  import type { ContentUpdater } from "./content-updater.js";
3
- export declare function inlineRequirePagePlugin(updater: ContentUpdater, buildOpts: BuildOptions): import("esbuild").Plugin;
3
+ export declare function inlineRequirePage(updater: ContentUpdater, buildOpts: BuildOptions): import("esbuild").Plugin;
@@ -2,8 +2,9 @@ import { readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { getPackagePath } from "@opennextjs/aws/build/helper.js";
4
4
  import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
5
+ import { normalizePath } from "../../utils/normalize-path.js";
5
6
  import { patchCode } from "../ast/util.js";
6
- export function inlineRequirePagePlugin(updater, buildOpts) {
7
+ export function inlineRequirePage(updater, buildOpts) {
7
8
  return updater.updateContent("inline-require-page", {
8
9
  filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/require\.js$`, { escape: false }),
9
10
  contentFilter: /function requirePage\(/,
@@ -30,7 +31,7 @@ async function getRule(buildOpts) {
30
31
  // The file does not exists
31
32
  appPathsManifests = [];
32
33
  }
33
- const manifests = pagesManifests.concat(appPathsManifests);
34
+ const manifests = pagesManifests.concat(appPathsManifests).map((path) => normalizePath(path));
34
35
  const htmlFiles = manifests.filter((file) => file.endsWith(".html"));
35
36
  const jsFiles = manifests.filter((file) => file.endsWith(".js"));
36
37
  // Inline fs access and dynamic require that are not supported by workerd.
@@ -61,7 +62,8 @@ function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
61
62
  },
62
63
  fix: `
63
64
  function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
64
- const pagePath = getPagePath($$$ARGS);
65
+ const { platform } = require('process');
66
+ const pagePath = platform === 'win32' ? getPagePath($$$ARGS).replaceAll('\\\\', '/') : getPagePath($$$ARGS);
65
67
  ${fnBody}
66
68
  }`,
67
69
  };
@@ -1,5 +1,3 @@
1
- export * from "./inline-eval-manifest.js";
2
1
  export * from "./inline-middleware-manifest-require.js";
3
2
  export * from "./patch-exception-bubbling.js";
4
- export * from "./patch-find-dir.js";
5
3
  export * from "./patch-read-file.js";
@@ -1,5 +1,3 @@
1
- export * from "./inline-eval-manifest.js";
2
1
  export * from "./inline-middleware-manifest-require.js";
3
2
  export * from "./patch-exception-bubbling.js";
4
- export * from "./patch-find-dir.js";
5
3
  export * from "./patch-read-file.js";
@@ -1,3 +1,2 @@
1
1
  import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
2
  export declare function patchBuildId(code: string, buildOpts: BuildOptions): string;
3
- export declare function patchLoadManifest(code: string, buildOpts: BuildOptions): string;
@@ -1,28 +1,7 @@
1
- import { readFileSync } from "node:fs";
2
- import { join, relative } from "node:path";
3
- import { getBuildId, getPackagePath } from "@opennextjs/aws/build/helper.js";
4
- import { globSync } from "glob";
5
- import { normalizePath } from "../../utils/index.js";
1
+ import { getBuildId } from "@opennextjs/aws/build/helper.js";
6
2
  export function patchBuildId(code, buildOpts) {
7
3
  // The Next code gets the buildId from the filesystem so we hardcode the value at build time.
8
4
  return code.replace("getBuildId() {", `getBuildId() {
9
5
  return ${JSON.stringify(getBuildId(buildOpts))};
10
6
  `);
11
7
  }
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"));
18
- return code.replace(/function loadManifest\((.+?), .+?\) {/, `$&
19
- ${manifests
20
- .map((manifest) => `
21
- if ($1.endsWith("${normalizePath("/" + relative(dotNextDir, manifest))}")) {
22
- return ${readFileSync(manifest, "utf-8")};
23
- }
24
- `)
25
- .join("\n")}
26
- throw new Error("Unknown loadManifest: " + $1);
27
- `);
28
- }
@@ -6,13 +6,11 @@ import { handler as middlewareHandler } from "./middleware/handler.mjs";
6
6
  // @ts-expect-error: resolved by wrangler build
7
7
  import { handler as serverHandler } from "./server-functions/default/handler.mjs";
8
8
  const cloudflareContextALS = new AsyncLocalStorage();
9
- // Note: this symbol needs to be kept in sync with the one defined in `src/api/get-cloudflare-context.ts`
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
- globalThis[Symbol.for("__cloudflare-context__")] = new Proxy({}, {
12
- ownKeys: () => Reflect.ownKeys(cloudflareContextALS.getStore()),
13
- getOwnPropertyDescriptor: (_, ...args) => Reflect.getOwnPropertyDescriptor(cloudflareContextALS.getStore(), ...args),
14
- get: (_, property) => Reflect.get(cloudflareContextALS.getStore(), property),
15
- set: (_, property, value) => Reflect.set(cloudflareContextALS.getStore(), property, value),
9
+ // Note: this symbol needs to be kept in sync with `src/api/get-cloudflare-context.ts`
10
+ Object.defineProperty(globalThis, Symbol.for("__cloudflare-context__"), {
11
+ get() {
12
+ return cloudflareContextALS.getStore();
13
+ },
16
14
  });
17
15
  // Populate process.env on the first request
18
16
  let processEnvPopulated = false;
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.5.1",
4
+ "version": "0.5.3",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"
@@ -1,9 +0,0 @@
1
- import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
- /**
3
- * `evalManifest` relies on readFileSync so we need to patch the function so that it instead returns the content of the manifest files
4
- * which are known at build time
5
- * (source: https://github.com/vercel/next.js/blob/b1e32c5d1f/packages/next/src/server/load-manifest.ts#L72)
6
- * Note: we could/should probably just patch readFileSync here or something, but here the issue is that after the readFileSync call
7
- * 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)
8
- */
9
- export declare function inlineEvalManifest(code: string, buildOpts: BuildOptions): string;
@@ -1,36 +0,0 @@
1
- import { join, relative } from "node:path";
2
- import { getPackagePath } from "@opennextjs/aws/build/helper.js";
3
- import { globSync } from "glob";
4
- import { normalizePath } from "../../utils/index.js";
5
- /**
6
- * `evalManifest` relies on readFileSync so we need to patch the function so that it instead returns the content of the manifest files
7
- * which are known at build time
8
- * (source: https://github.com/vercel/next.js/blob/b1e32c5d1f/packages/next/src/server/load-manifest.ts#L72)
9
- * Note: we could/should probably just patch readFileSync here or something, but here the issue is that after the readFileSync call
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)
11
- */
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"));
17
- return code.replace(/function evalManifest\((.+?), .+?\) {/, `$&
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
- };
30
- }
31
- `;
32
- })
33
- .join("\n")}
34
- throw new Error("Unknown evalManifest: " + $1);
35
- `);
36
- }
@@ -1,5 +0,0 @@
1
- import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
2
- /**
3
- * Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists
4
- */
5
- export declare function patchFindDir(code: string, buildOpts: BuildOptions): string;
@@ -1,21 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { join } from "node:path";
3
- import { getPackagePath } from "@opennextjs/aws/build/helper.js";
4
- /**
5
- * Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists
6
- */
7
- export function patchFindDir(code, buildOpts) {
8
- const { outputDir } = buildOpts;
9
- const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
10
- return code.replace(/function findDir\((?<dir>dir\d*), (?<name>name\d*)\) {/, `function findDir($dir, $name) {
11
- if ($dir.endsWith(".next/server")) {
12
- if ($name === "app") {
13
- return ${existsSync(`${join(baseDir, "app")}`)};
14
- }
15
- if ($name === "pages") {
16
- return ${existsSync(`${join(baseDir, "pages")}`)};
17
- }
18
- }
19
- throw new Error("Unknown findDir call: " + $dir + " " + $name);
20
- `);
21
- }