@opennextjs/cloudflare 0.0.0-11802c4 → 0.0.0-28d3ca1

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
@@ -13,7 +13,13 @@ You can use [`create-next-app`](https://nextjs.org/docs/pages/api-reference/cli/
13
13
  - add the following `devDependencies` to the `package.json`:
14
14
 
15
15
  ```bash
16
+ npm add -D wrangler@latest @opennextjs/cloudflare
17
+ # or
16
18
  pnpm add -D wrangler@latest @opennextjs/cloudflare
19
+ # or
20
+ yarn add -D wrangler@latest @opennextjs/cloudflare
21
+ # or
22
+ bun add -D wrangler@latest @opennextjs/cloudflare
17
23
  ```
18
24
 
19
25
  - add a `wrangler.toml` at the root of your project
@@ -36,6 +42,12 @@ You can enable Incremental Static Regeneration ([ISR](https://nextjs.org/docs/ap
36
42
 
37
43
  ```bash
38
44
  npx wrangler kv namespace create NEXT_CACHE_WORKERS_KV
45
+ # or
46
+ pnpm wrangler kv namespace create NEXT_CACHE_WORKERS_KV
47
+ # or
48
+ yarn wrangler kv namespace create NEXT_CACHE_WORKERS_KV
49
+ # or
50
+ bun wrangler kv namespace create NEXT_CACHE_WORKERS_KV
39
51
  ```
40
52
 
41
53
  - Paste the snippet to your `wrangler.toml`:
@@ -60,13 +72,25 @@ Run the following commands to preview the production build of your application l
60
72
  - build the app and adapt it for Cloudflare
61
73
 
62
74
  ```bash
63
- pnpx cloudflare
75
+ npx cloudflare
76
+ # or
77
+ pnpm cloudflare
78
+ # or
79
+ yarn cloudflare
80
+ # or
81
+ bun cloudflare
64
82
  ```
65
83
 
66
84
  - Preview the app in Wrangler
67
85
 
68
86
  ```bash
87
+ npx wrangler dev
88
+ # or
69
89
  pnpm wrangler dev
90
+ # or
91
+ yarn wrangler dev
92
+ # or
93
+ bun wrangler dev
70
94
  ```
71
95
 
72
96
  ## Deploy your app
@@ -76,9 +100,11 @@ Deploy your application to production with the following:
76
100
  - build the app and adapt it for Cloudflare
77
101
 
78
102
  ```bash
79
- pnpx cloudflare
80
- ```
81
-
82
- ```bash
83
- pnpm wrangler deploy
103
+ npx cloudflare && npx wrangler deploy
104
+ # or
105
+ pnpm cloudflare && pnpm wrangler deploy
106
+ # or
107
+ yarn cloudflare && yarn wrangler deploy
108
+ # or
109
+ bun cloudflare && bun wrangler deploy
84
110
  ```
@@ -18,7 +18,7 @@ var CfWorkersKvCacheHandler = class _CfWorkersKvCacheHandler {
18
18
  return null;
19
19
  }
20
20
  }
21
- async set(key, entry, ctx) {
21
+ async set(key, entry, _ctx) {
22
22
  if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
23
23
  return;
24
24
  }
@@ -213,61 +213,72 @@ var require_brace_expansion = __commonJS({
213
213
  }
214
214
  });
215
215
 
216
- // src/cli/index.ts
217
- import { resolve as resolve2 } from "node:path";
218
-
219
- // src/cli/args.ts
220
- import { mkdirSync, statSync } from "node:fs";
221
- import { parseArgs } from "node:util";
222
- import { resolve } from "node:path";
223
- function getArgs() {
224
- const {
225
- values: { skipBuild: skipBuild2, output }
226
- } = parseArgs({
227
- options: {
228
- skipBuild: {
229
- type: "boolean",
230
- short: "s",
231
- default: false
232
- },
233
- output: {
234
- type: "string",
235
- short: "o"
236
- }
237
- },
238
- allowPositionals: false
239
- });
240
- const outputDir2 = output ? resolve(output) : void 0;
241
- if (outputDir2) {
242
- assertDirArg(outputDir2, "output", true);
216
+ // src/cli/config.ts
217
+ import path, { relative } from "node:path";
218
+ import { readdirSync, statSync } from "node:fs";
219
+ var PACKAGE_NAME = "@opennextjs/cloudflare";
220
+ var UserConfig = {
221
+ cache: {
222
+ bindingName: "NEXT_CACHE_WORKERS_KV"
243
223
  }
224
+ };
225
+ function getConfig(appDir, outputDir2) {
226
+ const dotNext = path.join(outputDir2, ".next");
227
+ const appPath = getNextjsApplicationPath(dotNext).replace(/\/$/, "");
228
+ const standaloneApp = path.join(dotNext, "standalone", appPath);
229
+ const standaloneAppDotNext = path.join(standaloneApp, ".next");
230
+ const standaloneAppServer = path.join(standaloneAppDotNext, "server");
231
+ const nodeModules = path.join(standaloneApp, "node_modules");
232
+ const internalPackage = path.join(nodeModules, ...PACKAGE_NAME.split("/"));
244
233
  return {
245
- outputDir: outputDir2,
246
- skipBuild: skipBuild2 || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD))
234
+ paths: {
235
+ nextApp: appDir,
236
+ builderOutput: outputDir2,
237
+ dotNext,
238
+ standaloneApp,
239
+ standaloneAppDotNext,
240
+ standaloneAppServer,
241
+ internalPackage
242
+ },
243
+ cache: {
244
+ kvBindingName: UserConfig.cache.bindingName
245
+ },
246
+ internalPackageName: PACKAGE_NAME
247
247
  };
248
248
  }
249
- function assertDirArg(path13, argName, make) {
250
- let dirStats;
249
+ function containsDotNextDir(folder) {
251
250
  try {
252
- dirStats = statSync(path13);
251
+ return statSync(path.join(folder, ".next")).isDirectory();
253
252
  } catch {
254
- if (!make) {
255
- throw new Error(`Error: the provided${argName ? ` "${argName}"` : ""} input is not a valid path`);
253
+ return false;
254
+ }
255
+ }
256
+ function getNextjsApplicationPath(dotNextDir) {
257
+ const serverPath = findServerParentPath(dotNextDir);
258
+ if (!serverPath) {
259
+ throw new Error(`Unexpected Error: no \`.next/server\` folder could be found in \`${serverPath}\``);
260
+ }
261
+ return relative(path.join(dotNextDir, "standalone"), serverPath);
262
+ }
263
+ function findServerParentPath(parentPath) {
264
+ try {
265
+ if (statSync(path.join(parentPath, ".next", "server")).isDirectory()) {
266
+ return parentPath;
256
267
  }
257
- mkdirSync(path13);
258
- return;
268
+ } catch {
259
269
  }
260
- if (!dirStats.isDirectory()) {
261
- throw new Error(`Error: the provided${argName ? ` "${argName}"` : ""} input is not a directory`);
270
+ const folders = readdirSync(parentPath);
271
+ for (const folder of folders) {
272
+ const subFolder = path.join(parentPath, folder);
273
+ if (statSync(path.join(parentPath, folder)).isDirectory()) {
274
+ const dirServerPath = findServerParentPath(subFolder);
275
+ if (dirServerPath) {
276
+ return dirServerPath;
277
+ }
278
+ }
262
279
  }
263
280
  }
264
281
 
265
- // src/cli/index.ts
266
- import { existsSync as existsSync4 } from "node:fs";
267
-
268
- // src/cli/build/index.ts
269
- import { rm } from "node:fs/promises";
270
-
271
282
  // src/cli/build/build-next-app.ts
272
283
  import { execSync } from "node:child_process";
273
284
  function buildNextjsApp(nextAppDir2) {
@@ -289,29 +300,21 @@ function runNextBuildCommand(packager, nextAppDir2) {
289
300
 
290
301
  // src/cli/build/build-worker.ts
291
302
  import { build } from "esbuild";
292
- import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
293
303
  import { cp, readFile, writeFile } from "node:fs/promises";
294
- import path10 from "node:path";
295
- import { fileURLToPath as fileURLToPath3 } from "node:url";
296
-
297
- // src/cli/build/patches/investigated/patch-require.ts
298
- function patchRequire(code) {
299
- console.log("# patchRequire");
300
- return code.replace(/__require\d?\(/g, "require(").replace(/__require\d?\./g, "require.");
301
- }
304
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
302
305
 
303
306
  // src/cli/build/patches/investigated/copy-package-cli-files.ts
304
307
  import { cpSync } from "node:fs";
305
- import path from "node:path";
308
+ import path2 from "node:path";
306
309
  function copyPackageCliFiles(packageDistDir2, config) {
307
310
  console.log("# copyPackageTemplateFiles");
308
- const sourceDir = path.join(packageDistDir2, "cli");
309
- const destinationDir = path.join(config.paths.internalPackage, "cli");
311
+ const sourceDir = path2.join(packageDistDir2, "cli");
312
+ const destinationDir = path2.join(config.paths.internalPackage, "cli");
310
313
  cpSync(sourceDir, destinationDir, { recursive: true });
311
314
  }
312
315
 
313
- // src/cli/build/patches/to-investigate/patch-read-file.ts
314
- import { readFileSync } from "node:fs";
316
+ // src/cli/build/build-worker.ts
317
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
315
318
 
316
319
  // ../../node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/esm/index.js
317
320
  var import_brace_expansion = __toESM(require_brace_expansion(), 1);
@@ -984,11 +987,11 @@ var qmarksTestNoExtDot = ([$0]) => {
984
987
  return (f) => f.length === len && f !== "." && f !== "..";
985
988
  };
986
989
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
987
- var path2 = {
990
+ var path3 = {
988
991
  win32: { sep: "\\" },
989
992
  posix: { sep: "/" }
990
993
  };
991
- var sep = defaultPlatform === "win32" ? path2.win32.sep : path2.posix.sep;
994
+ var sep = defaultPlatform === "win32" ? path3.win32.sep : path3.posix.sep;
992
995
  minimatch.sep = sep;
993
996
  var GLOBSTAR = Symbol("globstar **");
994
997
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -3018,7 +3021,7 @@ var LRUCache = class _LRUCache {
3018
3021
  // ../../node_modules/.pnpm/path-scurry@2.0.0/node_modules/path-scurry/dist/esm/index.js
3019
3022
  import { posix, win32 } from "node:path";
3020
3023
  import { fileURLToPath } from "node:url";
3021
- import { lstatSync, readdir as readdirCB, readdirSync, readlinkSync, realpathSync as rps } from "fs";
3024
+ import { lstatSync, readdir as readdirCB, readdirSync as readdirSync2, readlinkSync, realpathSync as rps } from "fs";
3022
3025
  import * as actualFS from "node:fs";
3023
3026
  import { lstat, readdir, readlink, realpath } from "node:fs/promises";
3024
3027
 
@@ -3905,7 +3908,7 @@ var realpathSync = rps.native;
3905
3908
  var defaultFS = {
3906
3909
  lstatSync,
3907
3910
  readdir: readdirCB,
3908
- readdirSync,
3911
+ readdirSync: readdirSync2,
3909
3912
  readlinkSync,
3910
3913
  realpathSync,
3911
3914
  promises: {
@@ -6686,67 +6689,44 @@ var glob = Object.assign(glob_, {
6686
6689
  });
6687
6690
  glob.glob = glob;
6688
6691
 
6689
- // src/cli/build/patches/to-investigate/patch-read-file.ts
6690
- import path3 from "node:path";
6691
- function patchReadFile(code, config) {
6692
- console.log("# patchReadFile");
6693
- code = code.replace(
6694
- "getBuildId() {",
6695
- `getBuildId() {
6696
- return ${JSON.stringify(readFileSync(path3.join(config.paths.standaloneAppDotNext, "BUILD_ID"), "utf-8"))};
6697
- `
6698
- );
6699
- const manifestJsons = globSync(path3.join(config.paths.standaloneAppDotNext, "**", "*-manifest.json")).map(
6700
- (file) => file.replace(config.paths.standaloneApp + "/", "")
6701
- );
6702
- code = code.replace(
6703
- /function loadManifest\((.+?), .+?\) {/,
6704
- `$&
6705
- ${manifestJsons.map(
6706
- (manifestJson) => `
6707
- if ($1.endsWith("${manifestJson}")) {
6708
- return ${readFileSync(path3.join(config.paths.standaloneApp, manifestJson), "utf-8")};
6709
- }
6710
- `
6711
- ).join("\n")}
6712
- throw new Error("Unknown loadManifest: " + $1);
6713
- `
6714
- );
6715
- return code;
6716
- }
6717
-
6718
- // src/cli/build/patches/to-investigate/patch-find-dir.ts
6692
+ // src/cli/build/patches/to-investigate/inline-eval-manifest.ts
6719
6693
  import path4 from "node:path";
6720
- import { existsSync } from "node:fs";
6721
- function patchFindDir(code, config) {
6722
- console.log("# patchFindDir");
6694
+ function inlineEvalManifest(code, config) {
6695
+ console.log("# inlineEvalManifest");
6696
+ const manifestJss = globSync(
6697
+ path4.join(config.paths.standaloneAppDotNext, "**", "*_client-reference-manifest.js")
6698
+ ).map((file) => file.replace(`${config.paths.standaloneApp}/`, ""));
6723
6699
  return code.replace(
6724
- "function findDir(dir, name) {",
6725
- `function findDir(dir, name) {
6726
- if (dir.endsWith(".next/server")) {
6727
- if (name === "app") {
6728
- return ${existsSync(`${path4.join(config.paths.standaloneAppServer, "app")}`)};
6729
- }
6730
- if (name === "pages") {
6731
- return ${existsSync(`${path4.join(config.paths.standaloneAppServer, "pages")}`)};
6732
- }
6733
- }
6734
- throw new Error("Unknown findDir call: " + dir + " " + name);
6700
+ /function evalManifest\((.+?), .+?\) {/,
6701
+ `$&
6702
+ ${manifestJss.map(
6703
+ (manifestJs) => `
6704
+ if ($1.endsWith("${manifestJs}")) {
6705
+ require("${path4.join(config.paths.standaloneApp, manifestJs)}");
6706
+ return {
6707
+ __RSC_MANIFEST: {
6708
+ "${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}": globalThis.__RSC_MANIFEST["${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}"],
6709
+ },
6710
+ };
6711
+ }
6712
+ `
6713
+ ).join("\n")}
6714
+ throw new Error("Unknown evalManifest: " + $1);
6735
6715
  `
6736
6716
  );
6737
6717
  }
6738
6718
 
6739
6719
  // src/cli/build/patches/to-investigate/inline-next-require.ts
6740
- import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
6720
+ import { existsSync, readFileSync } from "node:fs";
6741
6721
  import path5 from "node:path";
6742
6722
  function inlineNextRequire(code, config) {
6743
6723
  console.log("# inlineNextRequire");
6744
6724
  const pagesManifestFile = path5.join(config.paths.standaloneAppServer, "pages-manifest.json");
6745
6725
  const appPathsManifestFile = path5.join(config.paths.standaloneAppServer, "app-paths-manifest.json");
6746
- const pagesManifestFiles = existsSync2(pagesManifestFile) ? Object.values(JSON.parse(readFileSync2(pagesManifestFile, "utf-8"))).map(
6726
+ const pagesManifestFiles = existsSync(pagesManifestFile) ? Object.values(JSON.parse(readFileSync(pagesManifestFile, "utf-8"))).map(
6747
6727
  (file) => ".next/server/" + file
6748
6728
  ) : [];
6749
- const appPathsManifestFiles = existsSync2(appPathsManifestFile) ? Object.values(JSON.parse(readFileSync2(appPathsManifestFile, "utf-8"))).map(
6729
+ const appPathsManifestFiles = existsSync(appPathsManifestFile) ? Object.values(JSON.parse(readFileSync(appPathsManifestFile, "utf-8"))).map(
6750
6730
  (file) => ".next/server/" + file
6751
6731
  ) : [];
6752
6732
  const allManifestFiles = pagesManifestFiles.concat(appPathsManifestFiles);
@@ -6758,7 +6738,7 @@ function inlineNextRequire(code, config) {
6758
6738
  ${htmlPages.map(
6759
6739
  (htmlPage) => `
6760
6740
  if (pagePath.endsWith("${htmlPage}")) {
6761
- return ${JSON.stringify(readFileSync2(path5.join(config.paths.standaloneApp, htmlPage), "utf-8"))};
6741
+ return ${JSON.stringify(readFileSync(path5.join(config.paths.standaloneApp, htmlPage), "utf-8"))};
6762
6742
  }
6763
6743
  `
6764
6744
  ).join("\n")}
@@ -6774,39 +6754,87 @@ function inlineNextRequire(code, config) {
6774
6754
  );
6775
6755
  }
6776
6756
 
6777
- // src/cli/build/patches/to-investigate/inline-eval-manifest.ts
6757
+ // src/cli/build/patches/investigated/patch-cache.ts
6778
6758
  import path6 from "node:path";
6779
- function inlineEvalManifest(code, config) {
6780
- console.log("# inlineEvalManifest");
6781
- const manifestJss = globSync(
6782
- path6.join(config.paths.standaloneAppDotNext, "**", "*_client-reference-manifest.js")
6783
- ).map((file) => file.replace(`${config.paths.standaloneApp}/`, ""));
6759
+ function patchCache(code, config) {
6760
+ console.log("# patchCached");
6761
+ const cacheHandler = path6.join(config.paths.internalPackage, "cli", "cache-handler.mjs");
6762
+ const patchedCode = code.replace(
6763
+ "const { cacheHandler } = this.nextConfig;",
6764
+ `const cacheHandler = null;
6765
+ CacheHandler = (await import('${cacheHandler}')).default;
6766
+ CacheHandler.maybeKVNamespace = process.env["${config.cache.kvBindingName}"];
6767
+ `
6768
+ );
6769
+ if (patchedCode === code) {
6770
+ throw new Error("Cache patch not applied");
6771
+ }
6772
+ return patchedCode;
6773
+ }
6774
+
6775
+ // src/cli/build/patches/to-investigate/patch-find-dir.ts
6776
+ import { existsSync as existsSync2 } from "node:fs";
6777
+ import path7 from "node:path";
6778
+ function patchFindDir(code, config) {
6779
+ console.log("# patchFindDir");
6784
6780
  return code.replace(
6785
- /function evalManifest\((.+?), .+?\) {/,
6781
+ "function findDir(dir, name) {",
6782
+ `function findDir(dir, name) {
6783
+ if (dir.endsWith(".next/server")) {
6784
+ if (name === "app") {
6785
+ return ${existsSync2(`${path7.join(config.paths.standaloneAppServer, "app")}`)};
6786
+ }
6787
+ if (name === "pages") {
6788
+ return ${existsSync2(`${path7.join(config.paths.standaloneAppServer, "pages")}`)};
6789
+ }
6790
+ }
6791
+ throw new Error("Unknown findDir call: " + dir + " " + name);
6792
+ `
6793
+ );
6794
+ }
6795
+
6796
+ // src/cli/build/patches/to-investigate/patch-read-file.ts
6797
+ import path8 from "node:path";
6798
+ import { readFileSync as readFileSync2 } from "node:fs";
6799
+ function patchReadFile(code, config) {
6800
+ console.log("# patchReadFile");
6801
+ code = code.replace(
6802
+ "getBuildId() {",
6803
+ `getBuildId() {
6804
+ return ${JSON.stringify(readFileSync2(path8.join(config.paths.standaloneAppDotNext, "BUILD_ID"), "utf-8"))};
6805
+ `
6806
+ );
6807
+ const manifestJsons = globSync(path8.join(config.paths.standaloneAppDotNext, "**", "*-manifest.json")).map(
6808
+ (file) => file.replace(config.paths.standaloneApp + "/", "")
6809
+ );
6810
+ code = code.replace(
6811
+ /function loadManifest\((.+?), .+?\) {/,
6786
6812
  `$&
6787
- ${manifestJss.map(
6788
- (manifestJs) => `
6789
- if ($1.endsWith("${manifestJs}")) {
6790
- require("${path6.join(config.paths.standaloneApp, manifestJs)}");
6791
- return {
6792
- __RSC_MANIFEST: {
6793
- "${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}": globalThis.__RSC_MANIFEST["${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}"],
6794
- },
6795
- };
6796
- }
6797
- `
6813
+ ${manifestJsons.map(
6814
+ (manifestJson) => `
6815
+ if ($1.endsWith("${manifestJson}")) {
6816
+ return ${readFileSync2(path8.join(config.paths.standaloneApp, manifestJson), "utf-8")};
6817
+ }
6818
+ `
6798
6819
  ).join("\n")}
6799
- throw new Error("Unknown evalManifest: " + $1);
6800
- `
6820
+ throw new Error("Unknown loadManifest: " + $1);
6821
+ `
6801
6822
  );
6823
+ return code;
6824
+ }
6825
+
6826
+ // src/cli/build/patches/investigated/patch-require.ts
6827
+ function patchRequire(code) {
6828
+ console.log("# patchRequire");
6829
+ return code.replace(/__require\d?\(/g, "require(").replace(/__require\d?\./g, "require.");
6802
6830
  }
6803
6831
 
6804
6832
  // src/cli/build/patches/to-investigate/wrangler-deps.ts
6805
- import path7 from "node:path";
6806
6833
  import fs, { writeFileSync } from "node:fs";
6834
+ import path9 from "node:path";
6807
6835
  function patchWranglerDeps(config) {
6808
6836
  console.log("# patchWranglerDeps");
6809
- const pagesRuntimeFile = path7.join(
6837
+ const pagesRuntimeFile = path9.join(
6810
6838
  config.paths.standaloneApp,
6811
6839
  "node_modules",
6812
6840
  "next",
@@ -6817,7 +6845,7 @@ function patchWranglerDeps(config) {
6817
6845
  );
6818
6846
  const patchedPagesRuntime = fs.readFileSync(pagesRuntimeFile, "utf-8").replace(`e.exports=require("critters")`, `e.exports={}`);
6819
6847
  fs.writeFileSync(pagesRuntimeFile, patchedPagesRuntime);
6820
- const tracerFile = path7.join(
6848
+ const tracerFile = path9.join(
6821
6849
  config.paths.standaloneApp,
6822
6850
  "node_modules",
6823
6851
  "next",
@@ -6831,9 +6859,11 @@ function patchWranglerDeps(config) {
6831
6859
  writeFileSync(tracerFile, pacthedTracer);
6832
6860
  }
6833
6861
 
6862
+ // src/cli/build/build-worker.ts
6863
+ import path11 from "node:path";
6864
+
6834
6865
  // src/cli/build/patches/investigated/update-webpack-chunks-file/index.ts
6835
- import { readdirSync as readdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
6836
- import path8 from "node:path";
6866
+ import { readFileSync as readFileSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync2 } from "node:fs";
6837
6867
 
6838
6868
  // src/cli/build/patches/investigated/update-webpack-chunks-file/get-chunk-installation-identifiers.ts
6839
6869
  import * as ts from "ts-morph";
@@ -6946,11 +6976,12 @@ async function getUpdatedWebpackChunksFileContent(fileContent, chunks) {
6946
6976
  }
6947
6977
 
6948
6978
  // src/cli/build/patches/investigated/update-webpack-chunks-file/index.ts
6979
+ import path10 from "node:path";
6949
6980
  async function updateWebpackChunksFile(config) {
6950
6981
  console.log("# updateWebpackChunksFile");
6951
- const webpackRuntimeFile = path8.join(config.paths.standaloneAppServer, "webpack-runtime.js");
6982
+ const webpackRuntimeFile = path10.join(config.paths.standaloneAppServer, "webpack-runtime.js");
6952
6983
  const fileContent = readFileSync3(webpackRuntimeFile, "utf-8");
6953
- const chunks = readdirSync2(path8.join(config.paths.standaloneAppServer, "chunks")).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
6984
+ const chunks = readdirSync3(path10.join(config.paths.standaloneAppServer, "chunks")).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
6954
6985
  console.log(` - chunk ${chunk}`);
6955
6986
  return chunk.replace(/\.js$/, "");
6956
6987
  });
@@ -6958,47 +6989,29 @@ async function updateWebpackChunksFile(config) {
6958
6989
  writeFileSync2(webpackRuntimeFile, updatedFileContent);
6959
6990
  }
6960
6991
 
6961
- // src/cli/build/patches/investigated/patch-cache.ts
6962
- import path9 from "node:path";
6963
- function patchCache(code, config) {
6964
- console.log("# patchCached");
6965
- const cacheHandler = path9.join(config.paths.internalPackage, "cli", "cache-handler.mjs");
6966
- const patchedCode = code.replace(
6967
- "const { cacheHandler } = this.nextConfig;",
6968
- `const cacheHandler = null;
6969
- CacheHandler = (await import('${cacheHandler}')).default;
6970
- CacheHandler.maybeKVNamespace = process.env["${config.cache.kvBindingName}"];
6971
- `
6972
- );
6973
- if (patchedCode === code) {
6974
- throw new Error("Cache patch not applied");
6975
- }
6976
- return patchedCode;
6977
- }
6978
-
6979
6992
  // src/cli/build/build-worker.ts
6980
- var packageDistDir = path10.join(path10.dirname(fileURLToPath3(import.meta.url)), "..");
6993
+ var packageDistDir = path11.join(path11.dirname(fileURLToPath3(import.meta.url)), "..");
6981
6994
  async function buildWorker(config) {
6982
6995
  console.log(`\x1B[35m\u2699\uFE0F Copying files...
6983
6996
  \x1B[0m`);
6984
6997
  await cp(
6985
- path10.join(config.paths.dotNext, "static"),
6986
- path10.join(config.paths.builderOutput, "assets", "_next", "static"),
6998
+ path11.join(config.paths.dotNext, "static"),
6999
+ path11.join(config.paths.builderOutput, "assets", "_next", "static"),
6987
7000
  {
6988
7001
  recursive: true
6989
7002
  }
6990
7003
  );
6991
- const publicDir = path10.join(config.paths.nextApp, "public");
7004
+ const publicDir = path11.join(config.paths.nextApp, "public");
6992
7005
  if (existsSync3(publicDir)) {
6993
- await cp(publicDir, path10.join(config.paths.builderOutput, "assets"), {
7006
+ await cp(publicDir, path11.join(config.paths.builderOutput, "assets"), {
6994
7007
  recursive: true
6995
7008
  });
6996
7009
  }
6997
7010
  copyPackageCliFiles(packageDistDir, config);
6998
- const templateDir = path10.join(config.paths.internalPackage, "cli", "templates");
6999
- const workerEntrypoint = path10.join(templateDir, "worker.ts");
7000
- const workerOutputFile = path10.join(config.paths.builderOutput, "index.mjs");
7001
- const nextConfigStr = readFileSync4(path10.join(config.paths.standaloneApp, "/server.js"), "utf8")?.match(
7011
+ const templateDir = path11.join(config.paths.internalPackage, "cli", "templates");
7012
+ const workerEntrypoint = path11.join(templateDir, "worker.ts");
7013
+ const workerOutputFile = path11.join(config.paths.builderOutput, "index.mjs");
7014
+ const nextConfigStr = readFileSync4(path11.join(config.paths.standaloneApp, "/server.js"), "utf8")?.match(
7002
7015
  /const nextConfig = ({.+?})\n/
7003
7016
  )?.[1] ?? {};
7004
7017
  console.log(`\x1B[35m\u2699\uFE0F Bundling the worker file...
@@ -7017,15 +7030,15 @@ async function buildWorker(config) {
7017
7030
  // Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
7018
7031
  // eval("require")("bufferutil");
7019
7032
  // eval("require")("utf-8-validate");
7020
- "next/dist/compiled/ws": path10.join(templateDir, "shims", "empty.ts"),
7033
+ "next/dist/compiled/ws": path11.join(templateDir, "shims", "empty.ts"),
7021
7034
  // Note: we apply an empty shim to next/dist/compiled/edge-runtime since (amongst others) it generated the following `eval`:
7022
7035
  // eval(getModuleCode)(module, module.exports, throwingRequire, params.context, ...Object.values(params.scopedContext));
7023
7036
  // which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
7024
7037
  // QUESTION: Why did I encountered this but mhart didn't?
7025
- "next/dist/compiled/edge-runtime": path10.join(templateDir, "shims", "empty.ts"),
7038
+ "next/dist/compiled/edge-runtime": path11.join(templateDir, "shims", "empty.ts"),
7026
7039
  // `@next/env` is a library Next.js uses for loading dotenv files, for obvious reasons we need to stub it here
7027
7040
  // source: https://github.com/vercel/next.js/tree/0ac10d79720/packages/next-env
7028
- "@next/env": path10.join(templateDir, "shims", "env.ts")
7041
+ "@next/env": path11.join(templateDir, "shims", "env.ts")
7029
7042
  },
7030
7043
  define: {
7031
7044
  // config file used by Next.js, see: https://github.com/vercel/next.js/blob/68a7128/packages/next/src/build/utils.ts#L2137-L2139
@@ -7104,85 +7117,20 @@ function createFixRequiresESBuildPlugin(templateDir) {
7104
7117
  return {
7105
7118
  name: "replaceRelative",
7106
7119
  setup(build3) {
7107
- build3.onResolve({ filter: /^\.\/require-hook$/ }, (args) => ({
7108
- path: path10.join(templateDir, "shims", "empty.ts")
7120
+ build3.onResolve({ filter: /^\.\/require-hook$/ }, () => ({
7121
+ path: path11.join(templateDir, "shims", "empty.ts")
7109
7122
  }));
7110
- build3.onResolve({ filter: /\.\/lib\/node-fs-methods$/ }, (args) => ({
7111
- path: path10.join(templateDir, "shims", "empty.ts")
7123
+ build3.onResolve({ filter: /\.\/lib\/node-fs-methods$/ }, () => ({
7124
+ path: path11.join(templateDir, "shims", "empty.ts")
7112
7125
  }));
7113
7126
  }
7114
7127
  };
7115
7128
  }
7116
7129
 
7117
- // src/cli/config.ts
7118
- import { readdirSync as readdirSync3, statSync as statSync2 } from "node:fs";
7119
- import path11, { relative } from "node:path";
7120
- var PACKAGE_NAME = "@opennextjs/cloudflare";
7121
- var UserConfig = {
7122
- cache: {
7123
- bindingName: "NEXT_CACHE_WORKERS_KV"
7124
- }
7125
- };
7126
- function getConfig(appDir, outputDir2) {
7127
- const dotNext = path11.join(outputDir2, ".next");
7128
- const appPath = getNextjsApplicationPath(dotNext).replace(/\/$/, "");
7129
- const standaloneApp = path11.join(dotNext, "standalone", appPath);
7130
- const standaloneAppDotNext = path11.join(standaloneApp, ".next");
7131
- const standaloneAppServer = path11.join(standaloneAppDotNext, "server");
7132
- const nodeModules = path11.join(standaloneApp, "node_modules");
7133
- const internalPackage = path11.join(nodeModules, ...PACKAGE_NAME.split("/"));
7134
- return {
7135
- paths: {
7136
- nextApp: appDir,
7137
- builderOutput: outputDir2,
7138
- dotNext,
7139
- standaloneApp,
7140
- standaloneAppDotNext,
7141
- standaloneAppServer,
7142
- internalPackage
7143
- },
7144
- cache: {
7145
- kvBindingName: UserConfig.cache.bindingName
7146
- },
7147
- internalPackageName: PACKAGE_NAME
7148
- };
7149
- }
7150
- function containsDotNextDir(folder) {
7151
- try {
7152
- return statSync2(path11.join(folder, ".next")).isDirectory();
7153
- } catch (e) {
7154
- return false;
7155
- }
7156
- }
7157
- function getNextjsApplicationPath(dotNextDir) {
7158
- const serverPath = findServerParentPath(dotNextDir);
7159
- if (!serverPath) {
7160
- throw new Error(`Unexpected Error: no \`.next/server\` folder could be found in \`${serverPath}\``);
7161
- }
7162
- return relative(path11.join(dotNextDir, "standalone"), serverPath);
7163
- }
7164
- function findServerParentPath(parentPath) {
7165
- try {
7166
- if (statSync2(path11.join(parentPath, ".next", "server")).isDirectory()) {
7167
- return parentPath;
7168
- }
7169
- } catch {
7170
- }
7171
- const folders = readdirSync3(parentPath);
7172
- for (const folder of folders) {
7173
- const subFolder = path11.join(parentPath, folder);
7174
- if (statSync2(path11.join(parentPath, folder)).isDirectory()) {
7175
- const dirServerPath = findServerParentPath(subFolder);
7176
- if (dirServerPath) {
7177
- return dirServerPath;
7178
- }
7179
- }
7180
- }
7181
- }
7182
-
7183
7130
  // src/cli/build/index.ts
7184
7131
  import { cpSync as cpSync2 } from "node:fs";
7185
7132
  import path12 from "node:path";
7133
+ import { rm } from "node:fs/promises";
7186
7134
  async function build2(appDir, opts) {
7187
7135
  if (!opts.skipBuild) {
7188
7136
  buildNextjsApp(appDir);
@@ -7201,6 +7149,56 @@ async function cleanDirectory(path13) {
7201
7149
  }
7202
7150
 
7203
7151
  // src/cli/index.ts
7152
+ import { existsSync as existsSync4 } from "node:fs";
7153
+
7154
+ // src/cli/args.ts
7155
+ import { mkdirSync, statSync as statSync2 } from "node:fs";
7156
+ import { parseArgs } from "node:util";
7157
+ import { resolve } from "node:path";
7158
+ function getArgs() {
7159
+ const {
7160
+ values: { skipBuild: skipBuild2, output }
7161
+ } = parseArgs({
7162
+ options: {
7163
+ skipBuild: {
7164
+ type: "boolean",
7165
+ short: "s",
7166
+ default: false
7167
+ },
7168
+ output: {
7169
+ type: "string",
7170
+ short: "o"
7171
+ }
7172
+ },
7173
+ allowPositionals: false
7174
+ });
7175
+ const outputDir2 = output ? resolve(output) : void 0;
7176
+ if (outputDir2) {
7177
+ assertDirArg(outputDir2, "output", true);
7178
+ }
7179
+ return {
7180
+ outputDir: outputDir2,
7181
+ skipBuild: skipBuild2 || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD))
7182
+ };
7183
+ }
7184
+ function assertDirArg(path13, argName, make) {
7185
+ let dirStats;
7186
+ try {
7187
+ dirStats = statSync2(path13);
7188
+ } catch {
7189
+ if (!make) {
7190
+ throw new Error(`Error: the provided${argName ? ` "${argName}"` : ""} input is not a valid path`);
7191
+ }
7192
+ mkdirSync(path13);
7193
+ return;
7194
+ }
7195
+ if (!dirStats.isDirectory()) {
7196
+ throw new Error(`Error: the provided${argName ? ` "${argName}"` : ""} input is not a directory`);
7197
+ }
7198
+ }
7199
+
7200
+ // src/cli/index.ts
7201
+ import { resolve as resolve2 } from "node:path";
7204
7202
  var nextAppDir = resolve2(".");
7205
7203
  console.log(`Building the Next.js app in the current folder (${nextAppDir})`);
7206
7204
  if (!["js", "cjs", "mjs", "ts"].some((ext2) => existsSync4(`./next.config.${ext2}`))) {
@@ -17,7 +17,7 @@ function existsSync(path: string) {
17
17
  return FILES.has(path);
18
18
  }
19
19
 
20
- async function readFile(path: string, options: unknown): Promise<any> {
20
+ async function readFile(path: string, options: unknown): Promise<unknown> {
21
21
  console.log(
22
22
  "readFile",
23
23
  { path, options }
@@ -1,17 +1,18 @@
1
- import { AsyncLocalStorage } from "node:async_hooks";
2
- import Stream from "node:stream";
3
- import type { NextConfig } from "next";
4
- import { NodeNextRequest, NodeNextResponse } from "next/dist/server/base-http/node";
5
- import { MockedResponse } from "next/dist/server/lib/mock-request";
6
1
  import NextNodeServer, { NodeRequestHandler } from "next/dist/server/next-server";
7
- import type { IncomingMessage } from "node:http";
2
+ import { NodeNextRequest, NodeNextResponse } from "next/dist/server/base-http/node";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
8
4
  import { type CloudflareContext } from "../../api";
5
+ import type { IncomingMessage } from "node:http";
6
+ import { MockedResponse } from "next/dist/server/lib/mock-request";
7
+ import type { NextConfig } from "next";
8
+ import Stream from "node:stream";
9
9
 
10
10
  const NON_BODY_RESPONSES = new Set([101, 204, 205, 304]);
11
11
 
12
12
  const cloudflareContextALS = new AsyncLocalStorage<CloudflareContext>();
13
13
 
14
14
  // Note: this symbol needs to be kept in sync with the one defined in `src/api/get-cloudflare-context.ts`
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
16
  (globalThis as any)[Symbol.for("__cloudflare-context__")] = new Proxy(
16
17
  {},
17
18
  {
@@ -29,6 +30,7 @@ const nextConfig: NextConfig = JSON.parse(process.env.__NEXT_PRIVATE_STANDALONE_
29
30
  let requestHandler: NodeRequestHandler | null = null;
30
31
 
31
32
  export default {
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
34
  async fetch(request: Request & { cf: IncomingRequestCfProperties }, env: any, ctx: any) {
33
35
  return cloudflareContextALS.run({ env, ctx, cf: request.cf }, async () => {
34
36
  if (requestHandler == null) {
@@ -45,12 +47,13 @@ export default {
45
47
  const url = new URL(request.url);
46
48
 
47
49
  if (url.pathname === "/_next/image") {
48
- let imageUrl =
50
+ const imageUrl =
49
51
  url.searchParams.get("url") ?? "https://developers.cloudflare.com/_astro/logo.BU9hiExz.svg";
50
52
  if (imageUrl.startsWith("/")) {
51
53
  return env.ASSETS.fetch(new URL(imageUrl, request.url));
52
54
  }
53
- return fetch(imageUrl, { cf: { cacheEverything: true } } as any);
55
+ // @ts-ignore
56
+ return fetch(imageUrl, { cf: { cacheEverything: true } } as unknown);
54
57
  }
55
58
 
56
59
  const { req, res, webResponse } = getWrappedStreams(request, ctx);
@@ -62,12 +65,12 @@ export default {
62
65
  },
63
66
  };
64
67
 
65
- function getWrappedStreams(request: Request, ctx: any) {
68
+ function getWrappedStreams(request: Request, ctx: ExecutionContext) {
66
69
  const url = new URL(request.url);
67
70
 
68
- const req = (
69
- request.body ? Stream.Readable.fromWeb(request.body as any) : Stream.Readable.from([])
70
- ) as IncomingMessage;
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ const reqBody = request.body && Stream.Readable.fromWeb(request.body as any);
73
+ const req = (reqBody ?? Stream.Readable.from([])) as IncomingMessage;
71
74
  req.httpVersion = "1.0";
72
75
  req.httpVersionMajor = 1;
73
76
  req.httpVersionMinor = 0;
@@ -94,7 +97,7 @@ function getWrappedStreams(request: Request, ctx: any) {
94
97
 
95
98
  const res = new MockedResponse({
96
99
  resWriter: (chunk) => {
97
- resBodyWriter.write(typeof chunk === "string" ? Buffer.from(chunk) : chunk).catch((err: any) => {
100
+ resBodyWriter.write(typeof chunk === "string" ? Buffer.from(chunk) : chunk).catch((err) => {
98
101
  if (
99
102
  err.message.includes("WritableStream has been closed") ||
100
103
  err.message.includes("Network connection lost")
@@ -110,6 +113,7 @@ function getWrappedStreams(request: Request, ctx: any) {
110
113
  });
111
114
 
112
115
  // It's implemented as a no-op, but really it should mark the headers as done
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
117
  res.flushHeaders = () => (res as any).headPromiseResolve();
114
118
 
115
119
  // Only allow statusCode to be modified if not sent
@@ -127,6 +131,7 @@ function getWrappedStreams(request: Request, ctx: any) {
127
131
  });
128
132
 
129
133
  // Make sure the writer is eventually closed
134
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
135
  ctx.waitUntil((res as any).hasStreamed.finally(() => resBodyWriter.close().catch(() => {})));
131
136
 
132
137
  return {
@@ -138,6 +143,7 @@ function getWrappedStreams(request: Request, ctx: any) {
138
143
  res.setHeader("content-encoding", "identity");
139
144
  return new Response(NON_BODY_RESPONSES.has(res.statusCode) ? null : readable, {
140
145
  status: res.statusCode,
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
147
  headers: (res as any).headers,
142
148
  });
143
149
  },
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-11802c4",
4
+ "version": "0.0.0-28d3ca1",
5
5
  "bin": "dist/cli/index.mjs",
6
6
  "main": "./dist/api/index.mjs",
7
7
  "types": "./dist/api/index.d.mts",
@@ -32,12 +32,17 @@
32
32
  "homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
33
33
  "devDependencies": {
34
34
  "@cloudflare/workers-types": "^4.20240925.0",
35
+ "@eslint/js": "^9.11.1",
35
36
  "@types/node": "^22.2.0",
36
37
  "esbuild": "^0.23.0",
38
+ "eslint": "^9.11.1",
39
+ "eslint-plugin-unicorn": "^55.0.0",
37
40
  "glob": "^11.0.0",
41
+ "globals": "^15.9.0",
38
42
  "next": "14.2.11",
39
43
  "tsup": "^8.2.4",
40
44
  "typescript": "^5.5.4",
45
+ "typescript-eslint": "^8.7.0",
41
46
  "vitest": "^2.1.1"
42
47
  },
43
48
  "dependencies": {
@@ -49,6 +54,8 @@
49
54
  "scripts": {
50
55
  "build": "tsup",
51
56
  "build:watch": "tsup --watch src",
57
+ "lint:check": "eslint",
58
+ "lint:fix": "eslint --fix",
52
59
  "test": "vitest --run",
53
60
  "test:watch": "vitest"
54
61
  }