@opennextjs/cloudflare 0.5.4 → 0.5.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.
@@ -0,0 +1,56 @@
1
+ import { OpenNextConfig } from "@opennextjs/aws/types/open-next";
2
+ import type { IncrementalCache, Queue, TagCache } from "@opennextjs/aws/types/overrides";
3
+ export type CloudflareConfigOptions = {
4
+ /**
5
+ * The incremental cache implementation to use, for more details see the [Caching documentation](https://opennext.js.org/cloudflare/caching))
6
+ *
7
+ * `@opennextjs/cloudflare` offers a kv incremental cache implementation ready
8
+ * to use which can be imported from `"@opennextjs/cloudflare/kv-cache"`
9
+ *
10
+ * @example
11
+ * import { defineCloudflareConfig } from "@opennextjs/cloudflare";
12
+ * import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
13
+ *
14
+ * export default defineCloudflareConfig({
15
+ * incrementalCache: kvIncrementalCache,
16
+ * });
17
+ */
18
+ incrementalCache?: "dummy" | IncrementalCache | (() => IncrementalCache | Promise<IncrementalCache>);
19
+ /**
20
+ * The tag cache implementation to use, for more details see the [Caching documentation](https://opennext.js.org/cloudflare/caching))
21
+ *
22
+ * `@opennextjs/cloudflare` offers a d1 tag cache implementation ready
23
+ * to use which can be imported from `"@opennextjs/cloudflare/d1-tag-cache"`
24
+ *
25
+ * @example
26
+ * import { defineCloudflareConfig } from "@opennextjs/cloudflare";
27
+ * import d1TagCache from "@opennextjs/cloudflare/d1-tag-cache";
28
+ *
29
+ * export default defineCloudflareConfig({
30
+ * tagCache: d1TagCache,
31
+ * });
32
+ */
33
+ tagCache?: "dummy" | TagCache | (() => TagCache | Promise<TagCache>);
34
+ /**
35
+ * The revalidation queue implementation to use, for more details see the [Caching documentation](https://opennext.js.org/cloudflare/caching))
36
+ *
37
+ * `@opennextjs/cloudflare` offers an in memory queue implementation ready
38
+ * to use which can be imported from `"@opennextjs/cloudflare/memory-queue"`
39
+ *
40
+ * @example
41
+ * import { defineCloudflareConfig } from "@opennextjs/cloudflare";
42
+ * import memoryQueue from "@opennextjs/cloudflare/memory-queue";
43
+ *
44
+ * export default defineCloudflareConfig({
45
+ * queue: memoryQueue,
46
+ * });
47
+ */
48
+ queue?: "dummy" | "direct" | Queue | (() => Queue | Promise<Queue>);
49
+ };
50
+ /**
51
+ * Defines the OpenNext configuration that targets the Cloudflare adapter
52
+ *
53
+ * @param options options that enabled you to configure the application's behavior
54
+ * @returns the OpenNext configuration object
55
+ */
56
+ export declare function defineCloudflareConfig(options?: CloudflareConfigOptions): OpenNextConfig;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Defines the OpenNext configuration that targets the Cloudflare adapter
3
+ *
4
+ * @param options options that enabled you to configure the application's behavior
5
+ * @returns the OpenNext configuration object
6
+ */
7
+ export function defineCloudflareConfig(options = {}) {
8
+ const { incrementalCache, tagCache, queue } = options;
9
+ return {
10
+ default: {
11
+ override: {
12
+ wrapper: "cloudflare-node",
13
+ converter: "edge",
14
+ incrementalCache: resolveOverride(incrementalCache),
15
+ tagCache: resolveOverride(tagCache),
16
+ queue: resolveOverride(queue),
17
+ },
18
+ },
19
+ middleware: {
20
+ external: true,
21
+ override: {
22
+ wrapper: "cloudflare-edge",
23
+ converter: "edge",
24
+ proxyExternalRequest: "fetch",
25
+ },
26
+ },
27
+ };
28
+ }
29
+ function resolveOverride(value) {
30
+ if (!value || value === "dummy") {
31
+ return "dummy";
32
+ }
33
+ if (value === "direct") {
34
+ return "direct";
35
+ }
36
+ return (typeof value === "function" ? value : () => value);
37
+ }
@@ -1,4 +1,4 @@
1
- import type { TagCache } from "@opennextjs/aws/types/overrides.js";
1
+ import type { OriginalTagCache } from "@opennextjs/aws/types/overrides.js";
2
2
  /**
3
3
  * An instance of the Tag Cache that uses a D1 binding (`NEXT_CACHE_D1`) as it's underlying data store.
4
4
  *
@@ -16,7 +16,7 @@ import type { TagCache } from "@opennextjs/aws/types/overrides.js";
16
16
  * and `revalidatedAt`. The table name can be configured with `NEXT_CACHE_D1_REVALIDATIONS_TABLE`
17
17
  * environment variable.
18
18
  */
19
- declare class D1TagCache implements TagCache {
19
+ declare class D1TagCache implements OriginalTagCache {
20
20
  readonly name = "d1-tag-cache";
21
21
  getByPath(rawPath: string): Promise<string[]>;
22
22
  getByTag(rawTag: string): Promise<string[]>;
@@ -1 +1,2 @@
1
1
  export * from "./cloudflare-context.js";
2
+ export { defineCloudflareConfig } from "./config.js";
package/dist/api/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./cloudflare-context.js";
2
+ export { defineCloudflareConfig } from "./config.js";
@@ -1,5 +1,5 @@
1
- import cache from "./kv-cache.js";
1
+ import kvIncrementalCache from "./kv-cache.js";
2
2
  /**
3
3
  * @deprecated Please import from `kv-cache` instead of `kvCache`.
4
4
  */
5
- export default cache;
5
+ export default kvIncrementalCache;
@@ -1,5 +1,5 @@
1
- import cache from "./kv-cache.js";
1
+ import kvIncrementalCache from "./kv-cache.js";
2
2
  /**
3
3
  * @deprecated Please import from `kv-cache` instead of `kvCache`.
4
4
  */
5
- export default cache;
5
+ export default kvIncrementalCache;
@@ -88,6 +88,11 @@ export async function bundleServer(buildOpts) {
88
88
  ],
89
89
  external: ["./middleware/handler.mjs"],
90
90
  alias: {
91
+ // Note: it looks like node-fetch is actually not necessary for us, so we could replace it with an empty shim
92
+ // but just to be safe we replace it with a module that re-exports the native fetch
93
+ // we do this to both save on bundle size (there isn't really any benefit in us shipping the node-fetch code)
94
+ // and also get rid of a warning in the terminal caused by the package (because it performs an === comparison with -0)
95
+ "next/dist/compiled/node-fetch": path.join(buildOpts.outputDir, "cloudflare-templates/shims/fetch.js"),
91
96
  // Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
92
97
  // eval("require")("bufferutil");
93
98
  // eval("require")("utf-8-validate");
@@ -109,7 +114,7 @@ export async function bundleServer(buildOpts) {
109
114
  // Note: we need the __non_webpack_require__ variable declared as it is used by next-server:
110
115
  // https://github.com/vercel/next.js/blob/be0c3283/packages/next/src/server/next-server.ts#L116-L119
111
116
  __non_webpack_require__: "require",
112
- // Ask mhart if he can explain why the `define`s below are necessary
117
+ // We make sure that environment variables that Next.js expects are properly defined
113
118
  "process.env.NEXT_RUNTIME": '"nodejs"',
114
119
  "process.env.NODE_ENV": '"production"',
115
120
  "process.env.NEXT_MINIMAL": "true",
@@ -117,10 +122,11 @@ export async function bundleServer(buildOpts) {
117
122
  platform: "node",
118
123
  banner: {
119
124
  js: `
120
- // __dirname is used by unbundled js files (which don't inherit the __dirname present in the define field)
125
+ // Used by unbundled js files (which don't inherit the __dirname present in the define field)
121
126
  // so we also need to set it on the global scope
122
127
  // Note: this was hit in the next/dist/compiled/@opentelemetry/api module
123
128
  globalThis.__dirname ??= "";
129
+ globalThis.__filename ??= "";
124
130
 
125
131
  // Do not crash on cache not supported
126
132
  // https://github.com/cloudflare/workerd/pull/2434
@@ -11,6 +11,7 @@ import { installDependencies } from "@opennextjs/aws/build/installDeps.js";
11
11
  import logger from "@opennextjs/aws/logger.js";
12
12
  import { minifyAll } from "@opennextjs/aws/minimize-js.js";
13
13
  import { openNextEdgePlugins } from "@opennextjs/aws/plugins/edge.js";
14
+ import { openNextExternalMiddlewarePlugin } from "@opennextjs/aws/plugins/externalMiddleware.js";
14
15
  import { openNextReplacementPlugin } from "@opennextjs/aws/plugins/replacement.js";
15
16
  import { openNextResolvePlugin } from "@opennextjs/aws/plugins/resolve.js";
16
17
  import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
@@ -103,7 +104,13 @@ async function generateBundle(name, options, fnOptions) {
103
104
  // Copy env files
104
105
  buildHelper.copyEnvFile(appBuildOutputPath, packagePath, outputPath);
105
106
  // Copy all necessary traced files
106
- await copyTracedFiles(appBuildOutputPath, packagePath, outputPath, fnOptions.routes ?? ["app/page.tsx"], isBundled);
107
+ await copyTracedFiles({
108
+ buildOutputPath: appBuildOutputPath,
109
+ packagePath,
110
+ outputDir: outputPath,
111
+ routes: fnOptions.routes ?? ["app/page.tsx"],
112
+ bundledNextServer: isBundled,
113
+ });
107
114
  // Build Lambda code
108
115
  // note: bundle in OpenNext package b/c the adapter relies on the
109
116
  // "serverless-http" package which is not a dependency in user's
@@ -136,9 +143,9 @@ async function generateBundle(name, options, fnOptions) {
136
143
  fnName: name,
137
144
  overrides,
138
145
  }),
146
+ openNextExternalMiddlewarePlugin(path.join(options.openNextDistDir, "core/edgeFunctionHandler.js")),
139
147
  openNextEdgePlugins({
140
148
  nextDir: path.join(options.appBuildOutputPath, ".next"),
141
- edgeFunctionHandlerPath: path.join(options.openNextDistDir, "core", "edgeFunctionHandler.js"),
142
149
  isInCloudfare: true,
143
150
  }),
144
151
  ];
@@ -13,7 +13,9 @@ export function patchVercelOgLibrary(buildOpts) {
13
13
  const { appBuildOutputPath, outputDir } = buildOpts;
14
14
  const functionsPath = path.join(outputDir, "server-functions/default");
15
15
  const packagePath = path.join(functionsPath, getPackagePath(buildOpts));
16
- for (const traceInfoPath of globSync(path.join(appBuildOutputPath, ".next/server/**/*.nft.json"))) {
16
+ for (const traceInfoPath of globSync(path.join(appBuildOutputPath, ".next/server/**/*.nft.json"), {
17
+ windowsPathsNoEscape: true,
18
+ })) {
17
19
  const traceInfo = JSON.parse(readFileSync(traceInfoPath, { encoding: "utf8" }));
18
20
  const tracedNodePath = traceInfo.files.find((p) => p.endsWith("@vercel/og/index.node.js"));
19
21
  if (!tracedNodePath)
@@ -18,7 +18,9 @@ async function getRule(buildOpts) {
18
18
  const { outputDir } = buildOpts;
19
19
  const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next");
20
20
  const appDir = join(baseDir, "server/app");
21
- const manifests = await glob(join(baseDir, "**/*_client-reference-manifest.js"));
21
+ const manifests = await glob(join(baseDir, "**/*_client-reference-manifest.js"), {
22
+ windowsPathsNoEscape: true,
23
+ });
22
24
  const returnManifests = manifests
23
25
  .map((manifest) => {
24
26
  const endsWith = normalizePath(relative(baseDir, manifest));
@@ -18,7 +18,7 @@ async function getRule(buildOpts) {
18
18
  const { outputDir } = buildOpts;
19
19
  const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts));
20
20
  const dotNextDir = join(baseDir, ".next");
21
- const manifests = await glob(join(dotNextDir, "**/*-manifest.json"));
21
+ const manifests = await glob(join(dotNextDir, "**/*-manifest.json"), { windowsPathsNoEscape: true });
22
22
  const returnManifests = (await Promise.all(manifests.map(async (manifest) => `
23
23
  if ($PATH.endsWith("${normalizePath("/" + relative(dotNextDir, manifest))}")) {
24
24
  return ${await readFile(manifest, "utf-8")};
@@ -0,0 +1 @@
1
+ export default fetch;
@@ -0,0 +1 @@
1
+ export default fetch;
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.4",
4
+ "version": "0.5.6",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opennextjs-cloudflare": "dist/cli/index.js"
@@ -63,7 +63,7 @@
63
63
  "dependencies": {
64
64
  "@ast-grep/napi": "^0.34.1",
65
65
  "@dotenvx/dotenvx": "1.31.0",
66
- "@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@748",
66
+ "@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@756",
67
67
  "enquirer": "^2.4.1",
68
68
  "glob": "^11.0.0",
69
69
  "yaml": "^2.7.0"
@@ -1,26 +1,7 @@
1
1
  // default open-next.config.ts file created by @opennextjs/cloudflare
2
+ import { defineCloudflareConfig } from "@opennextjs/cloudflare/dist/api/config";
3
+ import kvIncrementalCache from "@opennextjs/cloudflare/dist/api/kv-cache";
2
4
 
3
- import cache from "@opennextjs/cloudflare/kv-cache";
4
-
5
- const config = {
6
- default: {
7
- override: {
8
- wrapper: "cloudflare-node",
9
- converter: "edge",
10
- incrementalCache: async () => cache,
11
- tagCache: "dummy",
12
- queue: "dummy",
13
- },
14
- },
15
-
16
- middleware: {
17
- external: true,
18
- override: {
19
- wrapper: "cloudflare-edge",
20
- converter: "edge",
21
- proxyExternalRequest: "fetch",
22
- },
23
- },
24
- };
25
-
26
- export default config;
5
+ export default defineCloudflareConfig({
6
+ incrementalCache: kvIncrementalCache,
7
+ });