@opennextjs/cloudflare 0.0.0-698638 → 0.0.0-9758666

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.
package/README.md CHANGED
@@ -1,39 +1,65 @@
1
- # Next.js builder for Cloudflare
1
+ # OpenNext for Cloudflare
2
2
 
3
- How to update a Next.js application to run on Cloudflare.
3
+ Deploy Next.js apps to Cloudflare!
4
4
 
5
- ## Configure your app
5
+ OpenNext for Cloudflare is Cloudflare specific adapter that enables deployment of Next.js applications to Cloudflare.
6
6
 
7
- - add the following `devDependencies` to the `package.json`:
7
+ ## Getting started
8
8
 
9
- ```bash
10
- pnpm add -D wrangler@latest @opennextjs/cloudflare
11
- ```
9
+ You can use [`create-next-app`](https://nextjs.org/docs/pages/api-reference/cli/create-next-app) to start a new application or take an existing Next.js application and deploy it to Cloudflare using the following few steps:
12
10
 
13
- ## Serve your app
11
+ ## Configure your app
14
12
 
15
- - build the app and adapt it for Cloudflare
13
+ - add the following `devDependencies` to the `package.json`:
16
14
 
17
15
  ```bash
18
- pnpx cloudflare
16
+ pnpm add -D wrangler@latest @opennextjs/cloudflare
19
17
  ```
20
18
 
21
19
  - add a `wrangler.toml` at the root of your project
22
20
 
23
21
  ```toml
24
22
  #:schema node_modules/wrangler/config-schema.json
25
- name = "<app-name>"
23
+ name = "<your-app-name>"
26
24
  main = ".worker-next/index.mjs"
27
25
 
28
- compatibility_date = "2024-08-29"
29
- compatibility_flags = ["nodejs_compat_v2"]
26
+ compatibility_date = "2024-09-23"
27
+ compatibility_flags = ["nodejs_compat"]
30
28
 
31
29
  # Use the new Workers + Assets to host the static frontend files
32
30
  experimental_assets = { directory = ".worker-next/assets", binding = "ASSETS" }
33
31
  ```
34
32
 
33
+ ## Local development
34
+
35
+ - you can use the regular `next` CLI to start the Next.js dev server:
36
+
37
+ ## Local preview
38
+
39
+ Run the following commands to preview the production build of your application locally:
40
+
41
+ - build the app and adapt it for Cloudflare
42
+
43
+ ```bash
44
+ pnpx cloudflare
45
+ ```
46
+
35
47
  - Preview the app in Wrangler
36
48
 
37
49
  ```bash
38
50
  pnpm wrangler dev
39
51
  ```
52
+
53
+ ## Deploy your app
54
+
55
+ Deploy your application to production with the following:
56
+
57
+ - build the app and adapt it for Cloudflare
58
+
59
+ ```bash
60
+ pnpx cloudflare
61
+ ```
62
+
63
+ ```bash
64
+ pnpm wrangler deploy
65
+ ```
@@ -0,0 +1,48 @@
1
+ import "./chunk-UJCSKKID.mjs";
2
+
3
+ // src/cache-handler.ts
4
+ var CfWorkersKvCacheHandler = class _CfWorkersKvCacheHandler {
5
+ constructor(ctx) {
6
+ this.ctx = ctx;
7
+ }
8
+ static maybeKVNamespace = void 0;
9
+ async get(key) {
10
+ if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
11
+ return null;
12
+ }
13
+ console.log(`[Cf] Getting cache[${key}]`);
14
+ try {
15
+ return await _CfWorkersKvCacheHandler.maybeKVNamespace.get(key, "json") ?? null;
16
+ } catch (e) {
17
+ console.error(`Failed to get value for key = ${key}: ${e}`);
18
+ return null;
19
+ }
20
+ }
21
+ async set(key, entry, ctx) {
22
+ if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
23
+ return;
24
+ }
25
+ console.log(`[Cf] Setting cache[${key}]`);
26
+ try {
27
+ const data = {
28
+ lastModified: Date.now(),
29
+ value: entry
30
+ };
31
+ await _CfWorkersKvCacheHandler.maybeKVNamespace.put(key, JSON.stringify(data));
32
+ } catch (e) {
33
+ console.error(`Failed to set value for key = ${key}: ${e}`);
34
+ }
35
+ }
36
+ async revalidateTag(tags) {
37
+ if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
38
+ return;
39
+ }
40
+ tags = [tags].flat();
41
+ console.log(`[Cf] revalidateTag ${JSON.stringify(tags)}}`);
42
+ }
43
+ resetRequestCache() {
44
+ }
45
+ };
46
+ export {
47
+ CfWorkersKvCacheHandler as default
48
+ };
@@ -0,0 +1,30 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ export {
28
+ __commonJS,
29
+ __toESM
30
+ };
package/dist/index.mjs CHANGED
@@ -1,29 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJS = (cb, mod) => function __require() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
2
+ import {
3
+ __commonJS,
4
+ __toESM
5
+ } from "./chunk-UJCSKKID.mjs";
27
6
 
28
7
  // ../../node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js
29
8
  var require_balanced_match = __commonJS({
@@ -267,15 +246,15 @@ function getArgs() {
267
246
  skipBuild: skipBuild2 || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD))
268
247
  };
269
248
  }
270
- function assertDirArg(path6, argName, make) {
249
+ function assertDirArg(path12, argName, make) {
271
250
  let dirStats;
272
251
  try {
273
- dirStats = statSync(path6);
252
+ dirStats = statSync(path12);
274
253
  } catch {
275
254
  if (!make) {
276
255
  throw new Error(`Error: the provided${argName ? ` "${argName}"` : ""} input is not a valid path`);
277
256
  }
278
- mkdirSync(path6);
257
+ mkdirSync(path12);
279
258
  return;
280
259
  }
281
260
  if (!dirStats.isDirectory()) {
@@ -312,6 +291,8 @@ function runNextBuildCommand(packager, nextAppDir2) {
312
291
  import { build } from "esbuild";
313
292
  import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
314
293
  import { cp, readFile, writeFile } from "node:fs/promises";
294
+ import path9 from "node:path";
295
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
315
296
 
316
297
  // src/build/patches/investigated/patch-require.ts
317
298
  function patchRequire(code) {
@@ -319,14 +300,11 @@ function patchRequire(code) {
319
300
  return code.replace(/__require\d?\(/g, "require(").replace(/__require\d?\./g, "require.");
320
301
  }
321
302
 
322
- // src/build/patches/investigated/copy-templates.ts
323
- import path from "node:path";
303
+ // src/build/patches/investigated/copy-package.ts
324
304
  import { cpSync } from "node:fs";
325
- function copyTemplates(srcDir, nextjsAppPaths) {
326
- console.log("# copyTemplates");
327
- const destDir = path.join(nextjsAppPaths.standaloneAppDir, "node_modules/cf/templates");
328
- cpSync(srcDir, destDir, { recursive: true });
329
- return destDir;
305
+ function copyPackage(srcDir, config) {
306
+ console.log("# copyPackage");
307
+ cpSync(srcDir, config.paths.internalPackage, { recursive: true });
330
308
  }
331
309
 
332
310
  // src/build/patches/to-investigate/patch-read-file.ts
@@ -1003,11 +981,11 @@ var qmarksTestNoExtDot = ([$0]) => {
1003
981
  return (f) => f.length === len && f !== "." && f !== "..";
1004
982
  };
1005
983
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
1006
- var path2 = {
984
+ var path = {
1007
985
  win32: { sep: "\\" },
1008
986
  posix: { sep: "/" }
1009
987
  };
1010
- var sep = defaultPlatform === "win32" ? path2.win32.sep : path2.posix.sep;
988
+ var sep = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
1011
989
  minimatch.sep = sep;
1012
990
  var GLOBSTAR = Symbol("globstar **");
1013
991
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -4184,12 +4162,12 @@ var PathBase = class {
4184
4162
  /**
4185
4163
  * Get the Path object referenced by the string path, resolved from this Path
4186
4164
  */
4187
- resolve(path6) {
4188
- if (!path6) {
4165
+ resolve(path12) {
4166
+ if (!path12) {
4189
4167
  return this;
4190
4168
  }
4191
- const rootPath = this.getRootString(path6);
4192
- const dir = path6.substring(rootPath.length);
4169
+ const rootPath = this.getRootString(path12);
4170
+ const dir = path12.substring(rootPath.length);
4193
4171
  const dirParts = dir.split(this.splitSep);
4194
4172
  const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
4195
4173
  return result;
@@ -4941,8 +4919,8 @@ var PathWin32 = class _PathWin32 extends PathBase {
4941
4919
  /**
4942
4920
  * @internal
4943
4921
  */
4944
- getRootString(path6) {
4945
- return win32.parse(path6).root;
4922
+ getRootString(path12) {
4923
+ return win32.parse(path12).root;
4946
4924
  }
4947
4925
  /**
4948
4926
  * @internal
@@ -4988,8 +4966,8 @@ var PathPosix = class _PathPosix extends PathBase {
4988
4966
  /**
4989
4967
  * @internal
4990
4968
  */
4991
- getRootString(path6) {
4992
- return path6.startsWith("/") ? "/" : "";
4969
+ getRootString(path12) {
4970
+ return path12.startsWith("/") ? "/" : "";
4993
4971
  }
4994
4972
  /**
4995
4973
  * @internal
@@ -5078,11 +5056,11 @@ var PathScurryBase = class {
5078
5056
  /**
5079
5057
  * Get the depth of a provided path, string, or the cwd
5080
5058
  */
5081
- depth(path6 = this.cwd) {
5082
- if (typeof path6 === "string") {
5083
- path6 = this.cwd.resolve(path6);
5059
+ depth(path12 = this.cwd) {
5060
+ if (typeof path12 === "string") {
5061
+ path12 = this.cwd.resolve(path12);
5084
5062
  }
5085
- return path6.depth();
5063
+ return path12.depth();
5086
5064
  }
5087
5065
  /**
5088
5066
  * Return the cache of child entries. Exposed so subclasses can create
@@ -5569,9 +5547,9 @@ var PathScurryBase = class {
5569
5547
  process2();
5570
5548
  return results;
5571
5549
  }
5572
- chdir(path6 = this.cwd) {
5550
+ chdir(path12 = this.cwd) {
5573
5551
  const oldCwd = this.cwd;
5574
- this.cwd = typeof path6 === "string" ? this.cwd.resolve(path6) : path6;
5552
+ this.cwd = typeof path12 === "string" ? this.cwd.resolve(path12) : path12;
5575
5553
  this.cwd[setAsCwd](oldCwd);
5576
5554
  }
5577
5555
  };
@@ -5927,8 +5905,8 @@ var MatchRecord = class {
5927
5905
  }
5928
5906
  // match, absolute, ifdir
5929
5907
  entries() {
5930
- return [...this.store.entries()].map(([path6, n]) => [
5931
- path6,
5908
+ return [...this.store.entries()].map(([path12, n]) => [
5909
+ path12,
5932
5910
  !!(n & 2),
5933
5911
  !!(n & 1)
5934
5912
  ]);
@@ -6133,9 +6111,9 @@ var GlobUtil = class {
6133
6111
  signal;
6134
6112
  maxDepth;
6135
6113
  includeChildMatches;
6136
- constructor(patterns, path6, opts) {
6114
+ constructor(patterns, path12, opts) {
6137
6115
  this.patterns = patterns;
6138
- this.path = path6;
6116
+ this.path = path12;
6139
6117
  this.opts = opts;
6140
6118
  this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
6141
6119
  this.includeChildMatches = opts.includeChildMatches !== false;
@@ -6154,11 +6132,11 @@ var GlobUtil = class {
6154
6132
  });
6155
6133
  }
6156
6134
  }
6157
- #ignored(path6) {
6158
- return this.seen.has(path6) || !!this.#ignore?.ignored?.(path6);
6135
+ #ignored(path12) {
6136
+ return this.seen.has(path12) || !!this.#ignore?.ignored?.(path12);
6159
6137
  }
6160
- #childrenIgnored(path6) {
6161
- return !!this.#ignore?.childrenIgnored?.(path6);
6138
+ #childrenIgnored(path12) {
6139
+ return !!this.#ignore?.childrenIgnored?.(path12);
6162
6140
  }
6163
6141
  // backpressure mechanism
6164
6142
  pause() {
@@ -6373,8 +6351,8 @@ var GlobUtil = class {
6373
6351
  };
6374
6352
  var GlobWalker = class extends GlobUtil {
6375
6353
  matches = /* @__PURE__ */ new Set();
6376
- constructor(patterns, path6, opts) {
6377
- super(patterns, path6, opts);
6354
+ constructor(patterns, path12, opts) {
6355
+ super(patterns, path12, opts);
6378
6356
  }
6379
6357
  matchEmit(e) {
6380
6358
  this.matches.add(e);
@@ -6411,8 +6389,8 @@ var GlobWalker = class extends GlobUtil {
6411
6389
  };
6412
6390
  var GlobStream = class extends GlobUtil {
6413
6391
  results;
6414
- constructor(patterns, path6, opts) {
6415
- super(patterns, path6, opts);
6392
+ constructor(patterns, path12, opts) {
6393
+ super(patterns, path12, opts);
6416
6394
  this.results = new Minipass({
6417
6395
  signal: this.signal,
6418
6396
  objectMode: true
@@ -6706,16 +6684,17 @@ var glob = Object.assign(glob_, {
6706
6684
  glob.glob = glob;
6707
6685
 
6708
6686
  // src/build/patches/to-investigate/patch-read-file.ts
6709
- function patchReadFile(code, nextjsAppPaths) {
6687
+ import path2 from "node:path";
6688
+ function patchReadFile(code, config) {
6710
6689
  console.log("# patchReadFile");
6711
6690
  code = code.replace(
6712
6691
  "getBuildId() {",
6713
6692
  `getBuildId() {
6714
- return ${JSON.stringify(readFileSync(`${nextjsAppPaths.standaloneAppDotNextDir}/BUILD_ID`, "utf-8"))};
6693
+ return ${JSON.stringify(readFileSync(path2.join(config.paths.standaloneAppDotNext, "BUILD_ID"), "utf-8"))};
6715
6694
  `
6716
6695
  );
6717
- const manifestJsons = globSync(`${nextjsAppPaths.standaloneAppDotNextDir}/**/*-manifest.json`).map(
6718
- (file) => file.replace(nextjsAppPaths.standaloneAppDir + "/", "")
6696
+ const manifestJsons = globSync(path2.join(config.paths.standaloneAppDotNext, "**", "*-manifest.json")).map(
6697
+ (file) => file.replace(config.paths.standaloneApp + "/", "")
6719
6698
  );
6720
6699
  code = code.replace(
6721
6700
  /function loadManifest\((.+?), .+?\) {/,
@@ -6723,7 +6702,7 @@ function patchReadFile(code, nextjsAppPaths) {
6723
6702
  ${manifestJsons.map(
6724
6703
  (manifestJson) => `
6725
6704
  if ($1.endsWith("${manifestJson}")) {
6726
- return ${readFileSync(`${nextjsAppPaths.standaloneAppDir}/${manifestJson}`, "utf-8")};
6705
+ return ${readFileSync(path2.join(config.paths.standaloneApp, manifestJson), "utf-8")};
6727
6706
  }
6728
6707
  `
6729
6708
  ).join("\n")}
@@ -6734,15 +6713,20 @@ function patchReadFile(code, nextjsAppPaths) {
6734
6713
  }
6735
6714
 
6736
6715
  // src/build/patches/to-investigate/patch-find-dir.ts
6716
+ import path3 from "node:path";
6737
6717
  import { existsSync } from "node:fs";
6738
- function patchFindDir(code, nextjsAppPaths) {
6718
+ function patchFindDir(code, config) {
6739
6719
  console.log("# patchFindDir");
6740
6720
  return code.replace(
6741
6721
  "function findDir(dir, name) {",
6742
6722
  `function findDir(dir, name) {
6743
6723
  if (dir.endsWith(".next/server")) {
6744
- if (name === "app") return ${existsSync(`${nextjsAppPaths.standaloneAppServerDir}/app`)};
6745
- if (name === "pages") return ${existsSync(`${nextjsAppPaths.standaloneAppServerDir}/pages`)};
6724
+ if (name === "app") {
6725
+ return ${existsSync(`${path3.join(config.paths.standaloneAppServer, "app")}`)};
6726
+ }
6727
+ if (name === "pages") {
6728
+ return ${existsSync(`${path3.join(config.paths.standaloneAppServer, "pages")}`)};
6729
+ }
6746
6730
  }
6747
6731
  throw new Error("Unknown findDir call: " + dir + " " + name);
6748
6732
  `
@@ -6751,10 +6735,11 @@ function patchFindDir(code, nextjsAppPaths) {
6751
6735
 
6752
6736
  // src/build/patches/to-investigate/inline-next-require.ts
6753
6737
  import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
6754
- function inlineNextRequire(code, nextjsAppPaths) {
6738
+ import path4 from "node:path";
6739
+ function inlineNextRequire(code, config) {
6755
6740
  console.log("# inlineNextRequire");
6756
- const pagesManifestFile = `${nextjsAppPaths.standaloneAppServerDir}/pages-manifest.json`;
6757
- const appPathsManifestFile = `${nextjsAppPaths.standaloneAppServerDir}/app-paths-manifest.json`;
6741
+ const pagesManifestFile = path4.join(config.paths.standaloneAppServer, "pages-manifest.json");
6742
+ const appPathsManifestFile = path4.join(config.paths.standaloneAppServer, "app-paths-manifest.json");
6758
6743
  const pagesManifestFiles = existsSync2(pagesManifestFile) ? Object.values(JSON.parse(readFileSync2(pagesManifestFile, "utf-8"))).map(
6759
6744
  (file) => ".next/server/" + file
6760
6745
  ) : [];
@@ -6770,14 +6755,14 @@ function inlineNextRequire(code, nextjsAppPaths) {
6770
6755
  ${htmlPages.map(
6771
6756
  (htmlPage) => `
6772
6757
  if (pagePath.endsWith("${htmlPage}")) {
6773
- return ${JSON.stringify(readFileSync2(`${nextjsAppPaths.standaloneAppDir}/${htmlPage}`, "utf-8"))};
6758
+ return ${JSON.stringify(readFileSync2(path4.join(config.paths.standaloneApp, htmlPage), "utf-8"))};
6774
6759
  }
6775
6760
  `
6776
6761
  ).join("\n")}
6777
6762
  ${pageModules.map(
6778
6763
  (module) => `
6779
6764
  if (pagePath.endsWith("${module}")) {
6780
- return require("${nextjsAppPaths.standaloneAppDir}/${module}");
6765
+ return require("${path4.join(config.paths.standaloneApp, module)}");
6781
6766
  }
6782
6767
  `
6783
6768
  ).join("\n")}
@@ -6787,18 +6772,19 @@ function inlineNextRequire(code, nextjsAppPaths) {
6787
6772
  }
6788
6773
 
6789
6774
  // src/build/patches/to-investigate/inline-eval-manifest.ts
6790
- function inlineEvalManifest(code, nextjsAppPaths) {
6775
+ import path5 from "node:path";
6776
+ function inlineEvalManifest(code, config) {
6791
6777
  console.log("# inlineEvalManifest");
6792
6778
  const manifestJss = globSync(
6793
- `${nextjsAppPaths.standaloneAppDotNextDir}/**/*_client-reference-manifest.js`
6794
- ).map((file) => file.replace(`${nextjsAppPaths.standaloneAppDir}/`, ""));
6779
+ path5.join(config.paths.standaloneAppDotNext, "**", "*_client-reference-manifest.js")
6780
+ ).map((file) => file.replace(`${config.paths.standaloneApp}/`, ""));
6795
6781
  return code.replace(
6796
6782
  /function evalManifest\((.+?), .+?\) {/,
6797
6783
  `$&
6798
6784
  ${manifestJss.map(
6799
6785
  (manifestJs) => `
6800
6786
  if ($1.endsWith("${manifestJs}")) {
6801
- require("${nextjsAppPaths.standaloneAppDir}/${manifestJs}");
6787
+ require("${path5.join(config.paths.standaloneApp, manifestJs)}");
6802
6788
  return {
6803
6789
  __RSC_MANIFEST: {
6804
6790
  "${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}": globalThis.__RSC_MANIFEST["${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}"],
@@ -6813,13 +6799,12 @@ function inlineEvalManifest(code, nextjsAppPaths) {
6813
6799
  }
6814
6800
 
6815
6801
  // src/build/patches/to-investigate/wrangler-deps.ts
6816
- import path3 from "node:path";
6802
+ import path6 from "node:path";
6817
6803
  import fs, { writeFileSync } from "node:fs";
6818
- function patchWranglerDeps(paths) {
6804
+ function patchWranglerDeps(config) {
6819
6805
  console.log("# patchWranglerDeps");
6820
- console.log({ base: paths.standaloneAppDotNextDir });
6821
- const pagesRuntimeFile = path3.join(
6822
- paths.standaloneAppDir,
6806
+ const pagesRuntimeFile = path6.join(
6807
+ config.paths.standaloneApp,
6823
6808
  "node_modules",
6824
6809
  "next",
6825
6810
  "dist",
@@ -6829,8 +6814,8 @@ function patchWranglerDeps(paths) {
6829
6814
  );
6830
6815
  const patchedPagesRuntime = fs.readFileSync(pagesRuntimeFile, "utf-8").replace(`e.exports=require("critters")`, `e.exports={}`);
6831
6816
  fs.writeFileSync(pagesRuntimeFile, patchedPagesRuntime);
6832
- const tracerFile = path3.join(
6833
- paths.standaloneAppDir,
6817
+ const tracerFile = path6.join(
6818
+ config.paths.standaloneApp,
6834
6819
  "node_modules",
6835
6820
  "next",
6836
6821
  "dist",
@@ -6845,6 +6830,7 @@ function patchWranglerDeps(paths) {
6845
6830
 
6846
6831
  // src/build/patches/investigated/update-webpack-chunks-file/index.ts
6847
6832
  import { readdirSync as readdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
6833
+ import path7 from "node:path";
6848
6834
 
6849
6835
  // src/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.ts
6850
6836
  import * as ts from "ts-morph";
@@ -6957,11 +6943,11 @@ async function getUpdatedWebpackChunksFileContent(fileContent, chunks) {
6957
6943
  }
6958
6944
 
6959
6945
  // src/build/patches/investigated/update-webpack-chunks-file/index.ts
6960
- async function updateWebpackChunksFile(nextjsAppPaths) {
6946
+ async function updateWebpackChunksFile(config) {
6961
6947
  console.log("# updateWebpackChunksFile");
6962
- const webpackRuntimeFile = `${nextjsAppPaths.standaloneAppServerDir}/webpack-runtime.js`;
6948
+ const webpackRuntimeFile = path7.join(config.paths.standaloneAppServer, "webpack-runtime.js");
6963
6949
  const fileContent = readFileSync3(webpackRuntimeFile, "utf-8");
6964
- const chunks = readdirSync2(`${nextjsAppPaths.standaloneAppServerDir}/chunks`).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
6950
+ const chunks = readdirSync2(path7.join(config.paths.standaloneAppServer, "chunks")).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
6965
6951
  console.log(` - chunk ${chunk}`);
6966
6952
  return chunk.replace(/\.js$/, "");
6967
6953
  });
@@ -6969,18 +6955,53 @@ async function updateWebpackChunksFile(nextjsAppPaths) {
6969
6955
  writeFileSync2(webpackRuntimeFile, updatedFileContent);
6970
6956
  }
6971
6957
 
6958
+ // src/build/patches/investigated/patch-cache.ts
6959
+ import path8 from "node:path";
6960
+ function patchCache(code, config) {
6961
+ console.log("# patchCached");
6962
+ const cacheHandler = path8.join(config.paths.internalPackage, "cache-handler.mjs");
6963
+ const patchedCode = code.replace(
6964
+ "const { cacheHandler } = this.nextConfig;",
6965
+ `const cacheHandler = null;
6966
+ CacheHandler = (await import('${cacheHandler}')).default;
6967
+ CacheHandler.maybeKVNamespace = process.env["${config.cache.kvBindingName}"];
6968
+ `
6969
+ );
6970
+ if (patchedCode === code) {
6971
+ throw new Error("Cache patch not applied");
6972
+ }
6973
+ return patchedCode;
6974
+ }
6975
+
6972
6976
  // src/build/build-worker.ts
6973
- async function buildWorker(inputNextAppDir, outputDir2, nextjsAppPaths, templateSrcDir) {
6974
- const templateDir = copyTemplates(templateSrcDir, nextjsAppPaths);
6975
- const workerEntrypoint = `${templateDir}/worker.ts`;
6976
- const workerOutputFile = `${outputDir2}/index.mjs`;
6977
- const nextConfigStr = readFileSync4(nextjsAppPaths.standaloneAppDir + "/server.js", "utf8")?.match(
6977
+ var packageDir = path9.dirname(fileURLToPath3(import.meta.url));
6978
+ async function buildWorker(config) {
6979
+ console.log(`\x1B[35m\u2699\uFE0F Copying files...
6980
+ \x1B[0m`);
6981
+ await cp(
6982
+ path9.join(config.paths.dotNext, "static"),
6983
+ path9.join(config.paths.builderOutput, "assets", "_next", "static"),
6984
+ {
6985
+ recursive: true
6986
+ }
6987
+ );
6988
+ const publicDir = path9.join(config.paths.nextApp, "public");
6989
+ if (existsSync3(publicDir)) {
6990
+ await cp(publicDir, path9.join(config.paths.builderOutput, "assets"), {
6991
+ recursive: true
6992
+ });
6993
+ }
6994
+ copyPackage(packageDir, config);
6995
+ const templateDir = path9.join(config.paths.internalPackage, "templates");
6996
+ const workerEntrypoint = path9.join(templateDir, "worker.ts");
6997
+ const workerOutputFile = path9.join(config.paths.builderOutput, "index.mjs");
6998
+ const nextConfigStr = readFileSync4(path9.join(config.paths.standaloneApp, "/server.js"), "utf8")?.match(
6978
6999
  /const nextConfig = ({.+?})\n/
6979
7000
  )?.[1] ?? {};
6980
7001
  console.log(`\x1B[35m\u2699\uFE0F Bundling the worker file...
6981
7002
  \x1B[0m`);
6982
- patchWranglerDeps(nextjsAppPaths);
6983
- updateWebpackChunksFile(nextjsAppPaths);
7003
+ patchWranglerDeps(config);
7004
+ updateWebpackChunksFile(config);
6984
7005
  await build({
6985
7006
  entryPoints: [workerEntrypoint],
6986
7007
  bundle: true,
@@ -6993,15 +7014,15 @@ async function buildWorker(inputNextAppDir, outputDir2, nextjsAppPaths, template
6993
7014
  // Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
6994
7015
  // eval("require")("bufferutil");
6995
7016
  // eval("require")("utf-8-validate");
6996
- "next/dist/compiled/ws": `${templateDir}/shims/empty.ts`,
7017
+ "next/dist/compiled/ws": path9.join(templateDir, "shims", "empty.ts"),
6997
7018
  // Note: we apply an empty shim to next/dist/compiled/edge-runtime since (amongst others) it generated the following `eval`:
6998
7019
  // eval(getModuleCode)(module, module.exports, throwingRequire, params.context, ...Object.values(params.scopedContext));
6999
7020
  // which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
7000
7021
  // QUESTION: Why did I encountered this but mhart didn't?
7001
- "next/dist/compiled/edge-runtime": `${templateDir}/shims/empty.ts`,
7022
+ "next/dist/compiled/edge-runtime": path9.join(templateDir, "shims", "empty.ts"),
7002
7023
  // `@next/env` is a library Next.js uses for loading dotenv files, for obvious reasons we need to stub it here
7003
7024
  // source: https://github.com/vercel/next.js/tree/0ac10d79720/packages/next-env
7004
- "@next/env": `${templateDir}/shims/env.ts`
7025
+ "@next/env": path9.join(templateDir, "shims", "env.ts")
7005
7026
  },
7006
7027
  define: {
7007
7028
  // config file used by Next.js, see: https://github.com/vercel/next.js/blob/68a7128/packages/next/src/build/utils.ts#L2137-L2139
@@ -7035,22 +7056,21 @@ async function buildWorker(inputNextAppDir, outputDir2, nextjsAppPaths, template
7035
7056
  // Do not crash on cache not supported
7036
7057
  // https://github.com/cloudflare/workerd/pull/2434
7037
7058
  // compatibility flag "cache_option_enabled" -> does not support "force-cache"
7038
- let isPatchedAlready = globalThis.fetch.__nextPatched;
7039
7059
  const curFetch = globalThis.fetch;
7040
7060
  globalThis.fetch = (input, init) => {
7041
- console.log("globalThis.fetch", input);
7042
- if (init) delete init.cache;
7061
+ if (init) {
7062
+ delete init.cache;
7063
+ }
7043
7064
  return curFetch(input, init);
7044
7065
  };
7045
7066
  import { Readable } from 'node:stream';
7046
- globalThis.fetch.__nextPatched = isPatchedAlready;
7047
7067
  fetch = globalThis.fetch;
7048
7068
  const CustomRequest = class extends globalThis.Request {
7049
7069
  constructor(input, init) {
7050
- console.log("CustomRequest", input);
7051
7070
  if (init) {
7052
7071
  delete init.cache;
7053
7072
  if (init.body?.__node_stream__ === true) {
7073
+ // https://github.com/cloudflare/workerd/issues/2746
7054
7074
  init.body = Readable.toWeb(init.body);
7055
7075
  }
7056
7076
  }
@@ -7059,31 +7079,22 @@ const CustomRequest = class extends globalThis.Request {
7059
7079
  };
7060
7080
  globalThis.Request = CustomRequest;
7061
7081
  Request = globalThis.Request;
7062
- `
7082
+ `
7063
7083
  }
7064
7084
  });
7065
- await updateWorkerBundledCode(workerOutputFile, nextjsAppPaths);
7066
- console.log(`\x1B[35m\u2699\uFE0F Copying asset files...
7067
- \x1B[0m`);
7068
- await cp(`${nextjsAppPaths.dotNextDir}/static`, `${outputDir2}/assets/_next/static`, {
7069
- recursive: true
7070
- });
7071
- if (existsSync3(`${inputNextAppDir}/public`)) {
7072
- await cp(`${inputNextAppDir}/public`, `${outputDir2}/assets`, {
7073
- recursive: true
7074
- });
7075
- }
7085
+ await updateWorkerBundledCode(workerOutputFile, config);
7076
7086
  console.log(`\x1B[35mWorker saved in \`${workerOutputFile}\` \u{1F680}
7077
7087
  \x1B[0m`);
7078
7088
  }
7079
- async function updateWorkerBundledCode(workerOutputFile, nextjsAppPaths) {
7089
+ async function updateWorkerBundledCode(workerOutputFile, config) {
7080
7090
  const originalCode = await readFile(workerOutputFile, "utf8");
7081
7091
  let patchedCode = originalCode;
7082
7092
  patchedCode = patchRequire(patchedCode);
7083
- patchedCode = patchReadFile(patchedCode, nextjsAppPaths);
7084
- patchedCode = inlineNextRequire(patchedCode, nextjsAppPaths);
7085
- patchedCode = patchFindDir(patchedCode, nextjsAppPaths);
7086
- patchedCode = inlineEvalManifest(patchedCode, nextjsAppPaths);
7093
+ patchedCode = patchReadFile(patchedCode, config);
7094
+ patchedCode = inlineNextRequire(patchedCode, config);
7095
+ patchedCode = patchFindDir(patchedCode, config);
7096
+ patchedCode = inlineEvalManifest(patchedCode, config);
7097
+ patchedCode = patchCache(patchedCode, config);
7087
7098
  await writeFile(workerOutputFile, patchedCode);
7088
7099
  }
7089
7100
  function createFixRequiresESBuildPlugin(templateDir) {
@@ -7091,94 +7102,99 @@ function createFixRequiresESBuildPlugin(templateDir) {
7091
7102
  name: "replaceRelative",
7092
7103
  setup(build3) {
7093
7104
  build3.onResolve({ filter: /^\.\/require-hook$/ }, (args) => ({
7094
- path: `${templateDir}/shims/empty.ts`
7105
+ path: path9.join(templateDir, "shims", "empty.ts")
7095
7106
  }));
7096
7107
  build3.onResolve({ filter: /\.\/lib\/node-fs-methods$/ }, (args) => ({
7097
- path: `${templateDir}/shims/node-fs.ts`
7108
+ path: path9.join(templateDir, "shims", "empty.ts")
7098
7109
  }));
7099
7110
  }
7100
7111
  };
7101
7112
  }
7102
7113
 
7103
- // src/nextjs-paths.ts
7114
+ // src/config.ts
7104
7115
  import { readdirSync as readdirSync3, statSync as statSync2 } from "node:fs";
7105
- import path4, { relative } from "node:path";
7106
- function getNextjsAppPaths(nextAppDir2) {
7107
- const dotNextDir = getDotNextDirPath(nextAppDir2);
7108
- const appPath = getNextjsApplicationPath(dotNextDir).replace(/\/$/, "");
7109
- const standaloneAppDir = path4.join(dotNextDir, "standalone", appPath);
7116
+ import path10, { relative } from "node:path";
7117
+ var PACKAGE_NAME = "@opennextjs/cloudflare";
7118
+ var UserConfig = {
7119
+ cache: {
7120
+ bindingName: "NEXT_CACHE_WORKERS_KV"
7121
+ }
7122
+ };
7123
+ function getConfig(appDir, outputDir2) {
7124
+ const dotNext = path10.join(outputDir2, ".next");
7125
+ const appPath = getNextjsApplicationPath(dotNext).replace(/\/$/, "");
7126
+ const standaloneApp = path10.join(dotNext, "standalone", appPath);
7127
+ const standaloneAppDotNext = path10.join(standaloneApp, ".next");
7128
+ const standaloneAppServer = path10.join(standaloneAppDotNext, "server");
7129
+ const nodeModules = path10.join(standaloneApp, "node_modules");
7130
+ const internalPackage = path10.join(nodeModules, ...PACKAGE_NAME.split("/"));
7110
7131
  return {
7111
- appDir: nextAppDir2,
7112
- dotNextDir,
7113
- standaloneAppDir,
7114
- standaloneAppDotNextDir: path4.join(standaloneAppDir, ".next"),
7115
- standaloneAppServerDir: path4.join(standaloneAppDir, ".next", "server")
7132
+ paths: {
7133
+ nextApp: appDir,
7134
+ builderOutput: outputDir2,
7135
+ dotNext,
7136
+ standaloneApp,
7137
+ standaloneAppDotNext,
7138
+ standaloneAppServer,
7139
+ internalPackage
7140
+ },
7141
+ cache: {
7142
+ kvBindingName: UserConfig.cache.bindingName
7143
+ },
7144
+ internalPackageName: PACKAGE_NAME
7116
7145
  };
7117
7146
  }
7118
- function getDotNextDirPath(nextAppDir2) {
7119
- const dotNextDirPath = `${nextAppDir2}/.next`;
7147
+ function containsDotNextDir(folder) {
7120
7148
  try {
7121
- const dirStats = statSync2(dotNextDirPath);
7122
- if (!dirStats.isDirectory()) throw new Error();
7123
- } catch {
7124
- throw new Error(`Error: \`.next\` directory not found!`);
7149
+ return statSync2(path10.join(folder, ".next")).isDirectory();
7150
+ } catch (e) {
7151
+ return false;
7125
7152
  }
7126
- return dotNextDirPath;
7127
7153
  }
7128
7154
  function getNextjsApplicationPath(dotNextDir) {
7129
7155
  const serverPath = findServerParentPath(dotNextDir);
7130
7156
  if (!serverPath) {
7131
7157
  throw new Error(`Unexpected Error: no \`.next/server\` folder could be found in \`${serverPath}\``);
7132
7158
  }
7133
- return relative(`${dotNextDir}/standalone`, serverPath);
7134
- function findServerParentPath(path6) {
7135
- try {
7136
- if (statSync2(`${path6}/.next/server`).isDirectory()) {
7137
- return path6;
7138
- }
7139
- } catch {
7159
+ return relative(path10.join(dotNextDir, "standalone"), serverPath);
7160
+ }
7161
+ function findServerParentPath(parentPath) {
7162
+ try {
7163
+ if (statSync2(path10.join(parentPath, ".next", "server")).isDirectory()) {
7164
+ return parentPath;
7140
7165
  }
7141
- const files = readdirSync3(path6);
7142
- for (const file of files) {
7143
- if (statSync2(`${path6}/${file}`).isDirectory()) {
7144
- const dirServerPath = findServerParentPath(`${path6}/${file}`);
7145
- if (dirServerPath) {
7146
- return dirServerPath;
7147
- }
7166
+ } catch {
7167
+ }
7168
+ const folders = readdirSync3(parentPath);
7169
+ for (const folder of folders) {
7170
+ const subFolder = path10.join(parentPath, folder);
7171
+ if (statSync2(path10.join(parentPath, folder)).isDirectory()) {
7172
+ const dirServerPath = findServerParentPath(subFolder);
7173
+ if (dirServerPath) {
7174
+ return dirServerPath;
7148
7175
  }
7149
7176
  }
7150
7177
  }
7151
7178
  }
7152
7179
 
7153
7180
  // src/build/build.ts
7154
- import path5 from "node:path";
7155
- import { fileURLToPath as fileURLToPath3 } from "node:url";
7156
- import { cpSync as cpSync2, rmSync } from "node:fs";
7157
- var SAVE_DIR = ".save.next";
7158
- async function build2(inputNextAppDir, opts) {
7181
+ import { cpSync as cpSync3 } from "node:fs";
7182
+ import path11 from "node:path";
7183
+ async function build2(appDir, opts) {
7159
7184
  if (!opts.skipBuild) {
7160
- buildNextjsApp(inputNextAppDir);
7161
- rmSync(`${inputNextAppDir}/${SAVE_DIR}`, {
7162
- recursive: true,
7163
- force: true
7164
- });
7165
- cpSync2(`${inputNextAppDir}/.next`, `${inputNextAppDir}/${SAVE_DIR}`, {
7166
- recursive: true
7167
- });
7168
- } else {
7169
- rmSync(`${inputNextAppDir}/.next`, { recursive: true, force: true });
7170
- cpSync2(`${inputNextAppDir}/${SAVE_DIR}`, `${inputNextAppDir}/.next`, {
7171
- recursive: true
7172
- });
7185
+ buildNextjsApp(appDir);
7186
+ }
7187
+ if (!containsDotNextDir(appDir)) {
7188
+ throw new Error(`.next folder not found in ${appDir}`);
7173
7189
  }
7174
- const outputDir2 = `${opts.outputDir ?? inputNextAppDir}/.worker-next`;
7190
+ const outputDir2 = path11.resolve(opts.outputDir ?? appDir, ".worker-next");
7175
7191
  await cleanDirectory(outputDir2);
7176
- const nextjsAppPaths = getNextjsAppPaths(inputNextAppDir);
7177
- const templateDir = path5.join(path5.dirname(fileURLToPath3(import.meta.url)), "templates");
7178
- await buildWorker(inputNextAppDir, outputDir2, nextjsAppPaths, templateDir);
7192
+ cpSync3(path11.join(appDir, ".next"), path11.join(outputDir2, ".next"), { recursive: true });
7193
+ const config = getConfig(appDir, outputDir2);
7194
+ await buildWorker(config);
7179
7195
  }
7180
- async function cleanDirectory(path6) {
7181
- return await rm(path6, { recursive: true, force: true });
7196
+ async function cleanDirectory(path12) {
7197
+ return await rm(path12, { recursive: true, force: true });
7182
7198
  }
7183
7199
 
7184
7200
  // src/index.ts
@@ -102,7 +102,6 @@ function getWrappedStreams(request: Request, ctx: any) {
102
102
  },
103
103
  set: function (val) {
104
104
  if (this.finished || this.headersSent) {
105
- console.error("headers already sent");
106
105
  return;
107
106
  }
108
107
  statusCode = val;
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.0.0-0698638",
4
+ "version": "0.0.0-9758666",
5
5
  "bin": "dist/index.mjs",
6
6
  "files": [
7
7
  "README.md",
@@ -9,7 +9,7 @@
9
9
  ],
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/flarelabs-net/poc-next.git",
12
+ "url": "https://github.com/opennextjs/opennextjs-cloudflare.git",
13
13
  "directory": "packages/cloudflare"
14
14
  },
15
15
  "keywords": [
@@ -19,13 +19,15 @@
19
19
  ],
20
20
  "license": "MIT",
21
21
  "bugs": {
22
- "url": "https://github.com/flarelabs-net/poc-next/issues"
22
+ "url": "https://github.com/opennextjs/opennextjs-cloudflare/issues"
23
23
  },
24
- "homepage": "https://github.com/flarelabs-net/poc-next",
24
+ "homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
25
25
  "devDependencies": {
26
+ "@cloudflare/workers-types": "^4.20240919.0",
26
27
  "@types/node": "^22.2.0",
27
28
  "esbuild": "^0.23.0",
28
29
  "glob": "^11.0.0",
30
+ "next": "14.2.11",
29
31
  "tsup": "^8.2.4",
30
32
  "typescript": "^5.5.4",
31
33
  "vitest": "^2.1.1"