@opennextjs/cloudflare 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ export const RSC_PREFETCH_SUFFIX = ".prefetch.rsc";
2
+ export const RSC_SUFFIX = ".rsc";
3
+ export const NEXT_DATA_SUFFIX = ".json";
4
+ export const NEXT_META_SUFFIX = ".meta";
5
+ export const NEXT_BODY_SUFFIX = ".body";
6
+ export const NEXT_HTML_SUFFIX = ".html";
7
+
8
+ export const SEED_DATA_DIR = "cdn-cgi/_cf_seed_data";
@@ -1,10 +1,29 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- NEXT_META_SUFFIX,
4
- SEED_DATA_DIR,
5
- __commonJS,
6
- __toESM
7
- } from "./chunk-F7LECSR5.mjs";
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
+ ));
8
27
 
9
28
  // ../../node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js
10
29
  var require_balanced_match = __commonJS({
@@ -219,11 +238,6 @@ var require_brace_expansion = __commonJS({
219
238
  import path, { relative } from "node:path";
220
239
  import { readdirSync, statSync } from "node:fs";
221
240
  var PACKAGE_NAME = "@opennextjs/cloudflare";
222
- var UserConfig = {
223
- cache: {
224
- bindingName: "NEXT_CACHE_WORKERS_KV"
225
- }
226
- };
227
241
  function getConfig(appDir, outputDir2) {
228
242
  const dotNext = path.join(outputDir2, ".next");
229
243
  const appPath = getNextjsApplicationPath(dotNext).replace(/\/$/, "");
@@ -233,6 +247,8 @@ function getConfig(appDir, outputDir2) {
233
247
  const standaloneAppServer = path.join(standaloneAppDotNext, "server");
234
248
  const nodeModules = path.join(standaloneApp, "node_modules");
235
249
  const internalPackage = path.join(nodeModules, ...PACKAGE_NAME.split("/"));
250
+ const internalTemplates = path.join(internalPackage, "cli", "templates");
251
+ process.env.__OPENNEXT_KV_BINDING_NAME ??= "NEXT_CACHE_WORKERS_KV";
236
252
  return {
237
253
  buildTimestamp: Date.now(),
238
254
  paths: {
@@ -243,10 +259,11 @@ function getConfig(appDir, outputDir2) {
243
259
  standaloneApp,
244
260
  standaloneAppDotNext,
245
261
  standaloneAppServer,
246
- internalPackage
262
+ internalPackage,
263
+ internalTemplates
247
264
  },
248
265
  cache: {
249
- kvBindingName: UserConfig.cache.bindingName
266
+ kvBindingName: process.env.__OPENNEXT_KV_BINDING_NAME
250
267
  },
251
268
  internalPackageName: PACKAGE_NAME
252
269
  };
@@ -394,7 +411,7 @@ function runNextBuildCommand(packager, nextAppDir2) {
394
411
  }
395
412
 
396
413
  // src/cli/build/build-worker.ts
397
- import { build } from "esbuild";
414
+ import { build as build2 } from "esbuild";
398
415
  import { cp, readFile, writeFile } from "node:fs/promises";
399
416
  import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
400
417
 
@@ -416,6 +433,10 @@ function tsParseFile(fileContent) {
416
433
  return sourceFile;
417
434
  }
418
435
 
436
+ // src/cli/constants/incremental-cache.ts
437
+ var NEXT_META_SUFFIX = ".meta";
438
+ var SEED_DATA_DIR = "cdn-cgi/_cf_seed_data";
439
+
419
440
  // src/cli/build/utils/copy-prerendered-routes.ts
420
441
  import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
421
442
  import { dirname, join as join2 } from "node:path";
@@ -4313,12 +4334,12 @@ var PathBase = class {
4313
4334
  /**
4314
4335
  * Get the Path object referenced by the string path, resolved from this Path
4315
4336
  */
4316
- resolve(path15) {
4317
- if (!path15) {
4337
+ resolve(path14) {
4338
+ if (!path14) {
4318
4339
  return this;
4319
4340
  }
4320
- const rootPath = this.getRootString(path15);
4321
- const dir = path15.substring(rootPath.length);
4341
+ const rootPath = this.getRootString(path14);
4342
+ const dir = path14.substring(rootPath.length);
4322
4343
  const dirParts = dir.split(this.splitSep);
4323
4344
  const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
4324
4345
  return result;
@@ -5070,8 +5091,8 @@ var PathWin32 = class _PathWin32 extends PathBase {
5070
5091
  /**
5071
5092
  * @internal
5072
5093
  */
5073
- getRootString(path15) {
5074
- return win32.parse(path15).root;
5094
+ getRootString(path14) {
5095
+ return win32.parse(path14).root;
5075
5096
  }
5076
5097
  /**
5077
5098
  * @internal
@@ -5117,8 +5138,8 @@ var PathPosix = class _PathPosix extends PathBase {
5117
5138
  /**
5118
5139
  * @internal
5119
5140
  */
5120
- getRootString(path15) {
5121
- return path15.startsWith("/") ? "/" : "";
5141
+ getRootString(path14) {
5142
+ return path14.startsWith("/") ? "/" : "";
5122
5143
  }
5123
5144
  /**
5124
5145
  * @internal
@@ -5207,11 +5228,11 @@ var PathScurryBase = class {
5207
5228
  /**
5208
5229
  * Get the depth of a provided path, string, or the cwd
5209
5230
  */
5210
- depth(path15 = this.cwd) {
5211
- if (typeof path15 === "string") {
5212
- path15 = this.cwd.resolve(path15);
5231
+ depth(path14 = this.cwd) {
5232
+ if (typeof path14 === "string") {
5233
+ path14 = this.cwd.resolve(path14);
5213
5234
  }
5214
- return path15.depth();
5235
+ return path14.depth();
5215
5236
  }
5216
5237
  /**
5217
5238
  * Return the cache of child entries. Exposed so subclasses can create
@@ -5698,9 +5719,9 @@ var PathScurryBase = class {
5698
5719
  process3();
5699
5720
  return results;
5700
5721
  }
5701
- chdir(path15 = this.cwd) {
5722
+ chdir(path14 = this.cwd) {
5702
5723
  const oldCwd = this.cwd;
5703
- this.cwd = typeof path15 === "string" ? this.cwd.resolve(path15) : path15;
5724
+ this.cwd = typeof path14 === "string" ? this.cwd.resolve(path14) : path14;
5704
5725
  this.cwd[setAsCwd](oldCwd);
5705
5726
  }
5706
5727
  };
@@ -6056,8 +6077,8 @@ var MatchRecord = class {
6056
6077
  }
6057
6078
  // match, absolute, ifdir
6058
6079
  entries() {
6059
- return [...this.store.entries()].map(([path15, n]) => [
6060
- path15,
6080
+ return [...this.store.entries()].map(([path14, n]) => [
6081
+ path14,
6061
6082
  !!(n & 2),
6062
6083
  !!(n & 1)
6063
6084
  ]);
@@ -6262,9 +6283,9 @@ var GlobUtil = class {
6262
6283
  signal;
6263
6284
  maxDepth;
6264
6285
  includeChildMatches;
6265
- constructor(patterns, path15, opts) {
6286
+ constructor(patterns, path14, opts) {
6266
6287
  this.patterns = patterns;
6267
- this.path = path15;
6288
+ this.path = path14;
6268
6289
  this.opts = opts;
6269
6290
  this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
6270
6291
  this.includeChildMatches = opts.includeChildMatches !== false;
@@ -6283,11 +6304,11 @@ var GlobUtil = class {
6283
6304
  });
6284
6305
  }
6285
6306
  }
6286
- #ignored(path15) {
6287
- return this.seen.has(path15) || !!this.#ignore?.ignored?.(path15);
6307
+ #ignored(path14) {
6308
+ return this.seen.has(path14) || !!this.#ignore?.ignored?.(path14);
6288
6309
  }
6289
- #childrenIgnored(path15) {
6290
- return !!this.#ignore?.childrenIgnored?.(path15);
6310
+ #childrenIgnored(path14) {
6311
+ return !!this.#ignore?.childrenIgnored?.(path14);
6291
6312
  }
6292
6313
  // backpressure mechanism
6293
6314
  pause() {
@@ -6502,8 +6523,8 @@ var GlobUtil = class {
6502
6523
  };
6503
6524
  var GlobWalker = class extends GlobUtil {
6504
6525
  matches = /* @__PURE__ */ new Set();
6505
- constructor(patterns, path15, opts) {
6506
- super(patterns, path15, opts);
6526
+ constructor(patterns, path14, opts) {
6527
+ super(patterns, path14, opts);
6507
6528
  }
6508
6529
  matchEmit(e) {
6509
6530
  this.matches.add(e);
@@ -6540,8 +6561,8 @@ var GlobWalker = class extends GlobUtil {
6540
6561
  };
6541
6562
  var GlobStream = class extends GlobUtil {
6542
6563
  results;
6543
- constructor(patterns, path15, opts) {
6544
- super(patterns, path15, opts);
6564
+ constructor(patterns, path14, opts) {
6565
+ super(patterns, path14, opts);
6545
6566
  this.results = new Minipass({
6546
6567
  signal: this.signal,
6547
6568
  objectMode: true
@@ -6839,15 +6860,17 @@ import path5 from "node:path";
6839
6860
  function inlineEvalManifest(code, config) {
6840
6861
  console.log("# inlineEvalManifest");
6841
6862
  const manifestJss = globSync(
6842
- path5.join(config.paths.standaloneAppDotNext, "**", "*_client-reference-manifest.js")
6843
- ).map((file) => file.replace(`${config.paths.standaloneApp}/`, ""));
6863
+ path5.join(config.paths.standaloneAppDotNext, "**", "*_client-reference-manifest.js").replaceAll(path5.sep, path5.posix.sep)
6864
+ ).map(
6865
+ (file) => file.replaceAll(path5.sep, path5.posix.sep).replace(config.paths.standaloneApp.replaceAll(path5.sep, path5.posix.sep) + path5.posix.sep, "")
6866
+ );
6844
6867
  return code.replace(
6845
6868
  /function evalManifest\((.+?), .+?\) {/,
6846
6869
  `$&
6847
6870
  ${manifestJss.map(
6848
6871
  (manifestJs) => `
6849
6872
  if ($1.endsWith("${manifestJs}")) {
6850
- require("${path5.join(config.paths.standaloneApp, manifestJs)}");
6873
+ require(${JSON.stringify(path5.join(config.paths.standaloneApp, manifestJs))});
6851
6874
  return {
6852
6875
  __RSC_MANIFEST: {
6853
6876
  "${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}": globalThis.__RSC_MANIFEST["${manifestJs.replace(".next/server/app", "").replace("_client-reference-manifest.js", "")}"],
@@ -6907,7 +6930,7 @@ function inlineNextRequire(code, config) {
6907
6930
  ${pageModules.map(
6908
6931
  (module) => `
6909
6932
  if (pagePath.endsWith("${module}")) {
6910
- return require("${path7.join(config.paths.standaloneApp, module)}");
6933
+ return require(${JSON.stringify(path7.join(config.paths.standaloneApp, module))});
6911
6934
  }
6912
6935
  `
6913
6936
  ).join("\n")}
@@ -6917,19 +6940,32 @@ function inlineNextRequire(code, config) {
6917
6940
  }
6918
6941
 
6919
6942
  // src/cli/build/patches/investigated/patch-cache.ts
6920
- import path8 from "node:path";
6921
- function patchCache(code, config) {
6943
+ import { build } from "esbuild";
6944
+ import { join as join3 } from "node:path";
6945
+ async function patchCache(code, config) {
6922
6946
  console.log("# patchCache");
6923
- const cacheHandler = path8.join(config.paths.internalPackage, "cli", "cache-handler", "index.mjs");
6947
+ const cacheHandlerFileName = "cache-handler.mjs";
6948
+ const cacheHandlerEntrypoint = join3(config.paths.internalTemplates, "cache-handler", "index.ts");
6949
+ const cacheHandlerOutputFile = join3(config.paths.builderOutput, cacheHandlerFileName);
6950
+ await build({
6951
+ entryPoints: [cacheHandlerEntrypoint],
6952
+ bundle: true,
6953
+ outfile: cacheHandlerOutputFile,
6954
+ format: "esm",
6955
+ target: "esnext",
6956
+ minify: true,
6957
+ define: {
6958
+ "process.env.__OPENNEXT_KV_BINDING_NAME": `"${config.cache.kvBindingName}"`
6959
+ }
6960
+ });
6924
6961
  const patchedCode = code.replace(
6925
6962
  "const { cacheHandler } = this.nextConfig;",
6926
6963
  `const cacheHandler = null;
6927
- CacheHandler = (await import('${cacheHandler}')).OpenNextCacheHandler;
6928
- CacheHandler.maybeKVNamespace = process.env["${config.cache.kvBindingName}"];
6964
+ CacheHandler = (await import('./${cacheHandlerFileName}')).OpenNextCacheHandler;
6929
6965
  `
6930
6966
  );
6931
6967
  if (patchedCode === code) {
6932
- throw new Error("Cache patch not applied");
6968
+ throw new Error("Patch `patchCache` not applied");
6933
6969
  }
6934
6970
  return patchedCode;
6935
6971
  }
@@ -6946,7 +6982,7 @@ function patchExceptionBubbling(code) {
6946
6982
 
6947
6983
  // src/cli/build/patches/to-investigate/patch-find-dir.ts
6948
6984
  import { existsSync as existsSync4 } from "node:fs";
6949
- import path9 from "node:path";
6985
+ import path8 from "node:path";
6950
6986
  function patchFindDir(code, config) {
6951
6987
  console.log("# patchFindDir");
6952
6988
  return code.replace(
@@ -6954,10 +6990,10 @@ function patchFindDir(code, config) {
6954
6990
  `function findDir(dir, name) {
6955
6991
  if (dir.endsWith(".next/server")) {
6956
6992
  if (name === "app") {
6957
- return ${existsSync4(`${path9.join(config.paths.standaloneAppServer, "app")}`)};
6993
+ return ${existsSync4(`${path8.join(config.paths.standaloneAppServer, "app")}`)};
6958
6994
  }
6959
6995
  if (name === "pages") {
6960
- return ${existsSync4(`${path9.join(config.paths.standaloneAppServer, "pages")}`)};
6996
+ return ${existsSync4(`${path8.join(config.paths.standaloneAppServer, "pages")}`)};
6961
6997
  }
6962
6998
  }
6963
6999
  throw new Error("Unknown findDir call: " + dir + " " + name);
@@ -6966,18 +7002,20 @@ function patchFindDir(code, config) {
6966
7002
  }
6967
7003
 
6968
7004
  // src/cli/build/patches/to-investigate/patch-read-file.ts
6969
- import path10 from "node:path";
7005
+ import path9 from "node:path";
6970
7006
  import { readFileSync as readFileSync4 } from "node:fs";
6971
7007
  function patchReadFile(code, config) {
6972
7008
  console.log("# patchReadFile");
6973
7009
  code = code.replace(
6974
7010
  "getBuildId() {",
6975
7011
  `getBuildId() {
6976
- return ${JSON.stringify(readFileSync4(path10.join(config.paths.standaloneAppDotNext, "BUILD_ID"), "utf-8"))};
7012
+ return ${JSON.stringify(readFileSync4(path9.join(config.paths.standaloneAppDotNext, "BUILD_ID"), "utf-8"))};
6977
7013
  `
6978
7014
  );
6979
- const manifestJsons = globSync(path10.join(config.paths.standaloneAppDotNext, "**", "*-manifest.json")).map(
6980
- (file) => file.replace(config.paths.standaloneApp + "/", "")
7015
+ const manifestJsons = globSync(
7016
+ path9.join(config.paths.standaloneAppDotNext, "**", "*-manifest.json").replaceAll(path9.sep, path9.posix.sep)
7017
+ ).map(
7018
+ (file) => file.replaceAll(path9.sep, path9.posix.sep).replace(config.paths.standaloneApp.replaceAll(path9.sep, path9.posix.sep) + path9.posix.sep, "")
6981
7019
  );
6982
7020
  code = code.replace(
6983
7021
  /function loadManifest\((.+?), .+?\) {/,
@@ -6985,7 +7023,7 @@ function patchReadFile(code, config) {
6985
7023
  ${manifestJsons.map(
6986
7024
  (manifestJson) => `
6987
7025
  if ($1.endsWith("${manifestJson}")) {
6988
- return ${readFileSync4(path10.join(config.paths.standaloneApp, manifestJson), "utf-8")};
7026
+ return ${readFileSync4(path9.join(config.paths.standaloneApp, manifestJson), "utf-8")};
6989
7027
  }
6990
7028
  `
6991
7029
  ).join("\n")}
@@ -7003,17 +7041,17 @@ function patchRequire(code) {
7003
7041
 
7004
7042
  // src/cli/build/patches/to-investigate/wrangler-deps.ts
7005
7043
  import { readFileSync as readFileSync5, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
7006
- import path11 from "node:path";
7044
+ import path10 from "node:path";
7007
7045
  function patchWranglerDeps(config) {
7008
7046
  console.log("# patchWranglerDeps");
7009
7047
  const distPath = getDistPath(config);
7010
- const pagesRuntimeFile = path11.join(distPath, "compiled", "next-server", "pages.runtime.prod.js");
7048
+ const pagesRuntimeFile = path10.join(distPath, "compiled", "next-server", "pages.runtime.prod.js");
7011
7049
  const patchedPagesRuntime = readFileSync5(pagesRuntimeFile, "utf-8").replace(
7012
7050
  `e.exports=require("critters")`,
7013
7051
  `e.exports={}`
7014
7052
  );
7015
7053
  writeFileSync2(pagesRuntimeFile, patchedPagesRuntime);
7016
- const tracerFile = path11.join(distPath, "server", "lib", "trace", "tracer.js");
7054
+ const tracerFile = path10.join(distPath, "server", "lib", "trace", "tracer.js");
7017
7055
  const patchedTracer = readFileSync5(tracerFile, "utf-8").replaceAll(
7018
7056
  /\w+\s*=\s*require\([^/]*opentelemetry.*\)/g,
7019
7057
  `throw new Error("@opentelemetry/api")`
@@ -7023,7 +7061,7 @@ function patchWranglerDeps(config) {
7023
7061
  function getDistPath(config) {
7024
7062
  for (const root of [config.paths.standaloneApp, config.paths.standaloneRoot]) {
7025
7063
  try {
7026
- const distPath = path11.join(root, "node_modules", "next", "dist");
7064
+ const distPath = path10.join(root, "node_modules", "next", "dist");
7027
7065
  if (statSync2(distPath).isDirectory()) return distPath;
7028
7066
  } catch {
7029
7067
  }
@@ -7032,7 +7070,7 @@ function getDistPath(config) {
7032
7070
  }
7033
7071
 
7034
7072
  // src/cli/build/build-worker.ts
7035
- import path13 from "node:path";
7073
+ import path12 from "node:path";
7036
7074
 
7037
7075
  // src/cli/build/patches/investigated/update-webpack-chunks-file/index.ts
7038
7076
  import { readFileSync as readFileSync6, readdirSync as readdirSync4, writeFileSync as writeFileSync3 } from "node:fs";
@@ -7140,12 +7178,12 @@ async function getUpdatedWebpackChunksFileContent(fileContent, chunks) {
7140
7178
  }
7141
7179
 
7142
7180
  // src/cli/build/patches/investigated/update-webpack-chunks-file/index.ts
7143
- import path12 from "node:path";
7181
+ import path11 from "node:path";
7144
7182
  async function updateWebpackChunksFile(config) {
7145
7183
  console.log("# updateWebpackChunksFile");
7146
- const webpackRuntimeFile = path12.join(config.paths.standaloneAppServer, "webpack-runtime.js");
7184
+ const webpackRuntimeFile = path11.join(config.paths.standaloneAppServer, "webpack-runtime.js");
7147
7185
  const fileContent = readFileSync6(webpackRuntimeFile, "utf-8");
7148
- const chunks = readdirSync4(path12.join(config.paths.standaloneAppServer, "chunks")).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
7186
+ const chunks = readdirSync4(path11.join(config.paths.standaloneAppServer, "chunks")).filter((chunk) => /^\d+\.js$/.test(chunk)).map((chunk) => {
7149
7187
  console.log(` - chunk ${chunk}`);
7150
7188
  return chunk.replace(/\.js$/, "");
7151
7189
  });
@@ -7154,56 +7192,55 @@ async function updateWebpackChunksFile(config) {
7154
7192
  }
7155
7193
 
7156
7194
  // src/cli/build/build-worker.ts
7157
- var packageDistDir = path13.join(path13.dirname(fileURLToPath3(import.meta.url)), "..");
7195
+ var packageDistDir = path12.join(path12.dirname(fileURLToPath3(import.meta.url)), "..");
7158
7196
  async function buildWorker(config) {
7159
7197
  console.log(`\x1B[35m\u2699\uFE0F Copying files...
7160
7198
  \x1B[0m`);
7161
7199
  await cp(
7162
- path13.join(config.paths.dotNext, "static"),
7163
- path13.join(config.paths.builderOutput, "assets", "_next", "static"),
7200
+ path12.join(config.paths.dotNext, "static"),
7201
+ path12.join(config.paths.builderOutput, "assets", "_next", "static"),
7164
7202
  {
7165
7203
  recursive: true
7166
7204
  }
7167
7205
  );
7168
- const publicDir = path13.join(config.paths.nextApp, "public");
7206
+ const publicDir = path12.join(config.paths.nextApp, "public");
7169
7207
  if (existsSync5(publicDir)) {
7170
- await cp(publicDir, path13.join(config.paths.builderOutput, "assets"), {
7208
+ await cp(publicDir, path12.join(config.paths.builderOutput, "assets"), {
7171
7209
  recursive: true
7172
7210
  });
7173
7211
  }
7174
7212
  copyPrerenderedRoutes(config);
7175
7213
  copyPackageCliFiles(packageDistDir, config);
7176
- const templateDir = path13.join(config.paths.internalPackage, "cli", "templates");
7177
- const workerEntrypoint = path13.join(templateDir, "worker.ts");
7178
- const workerOutputFile = path13.join(config.paths.builderOutput, "index.mjs");
7179
- const nextConfigStr = readFileSync7(path13.join(config.paths.standaloneApp, "/server.js"), "utf8")?.match(
7214
+ const workerEntrypoint = path12.join(config.paths.internalTemplates, "worker.ts");
7215
+ const workerOutputFile = path12.join(config.paths.builderOutput, "index.mjs");
7216
+ const nextConfigStr = readFileSync7(path12.join(config.paths.standaloneApp, "/server.js"), "utf8")?.match(
7180
7217
  /const nextConfig = ({.+?})\n/
7181
7218
  )?.[1] ?? {};
7182
7219
  console.log(`\x1B[35m\u2699\uFE0F Bundling the worker file...
7183
7220
  \x1B[0m`);
7184
7221
  patchWranglerDeps(config);
7185
7222
  updateWebpackChunksFile(config);
7186
- await build({
7223
+ await build2({
7187
7224
  entryPoints: [workerEntrypoint],
7188
7225
  bundle: true,
7189
7226
  outfile: workerOutputFile,
7190
7227
  format: "esm",
7191
7228
  target: "esnext",
7192
7229
  minify: false,
7193
- plugins: [createFixRequiresESBuildPlugin(templateDir)],
7230
+ plugins: [createFixRequiresESBuildPlugin(config)],
7194
7231
  alias: {
7195
7232
  // Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
7196
7233
  // eval("require")("bufferutil");
7197
7234
  // eval("require")("utf-8-validate");
7198
- "next/dist/compiled/ws": path13.join(templateDir, "shims", "empty.ts"),
7235
+ "next/dist/compiled/ws": path12.join(config.paths.internalTemplates, "shims", "empty.ts"),
7199
7236
  // Note: we apply an empty shim to next/dist/compiled/edge-runtime since (amongst others) it generated the following `eval`:
7200
7237
  // eval(getModuleCode)(module, module.exports, throwingRequire, params.context, ...Object.values(params.scopedContext));
7201
7238
  // which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
7202
7239
  // QUESTION: Why did I encountered this but mhart didn't?
7203
- "next/dist/compiled/edge-runtime": path13.join(templateDir, "shims", "empty.ts"),
7240
+ "next/dist/compiled/edge-runtime": path12.join(config.paths.internalTemplates, "shims", "empty.ts"),
7204
7241
  // `@next/env` is a library Next.js uses for loading dotenv files, for obvious reasons we need to stub it here
7205
7242
  // source: https://github.com/vercel/next.js/tree/0ac10d79720/packages/next-env
7206
- "@next/env": path13.join(templateDir, "shims", "env.ts")
7243
+ "@next/env": path12.join(config.paths.internalTemplates, "shims", "env.ts")
7207
7244
  },
7208
7245
  define: {
7209
7246
  // config file used by Next.js, see: https://github.com/vercel/next.js/blob/68a7128/packages/next/src/build/utils.ts#L2137-L2139
@@ -7271,20 +7308,20 @@ async function updateWorkerBundledCode(workerOutputFile, config) {
7271
7308
  patchedCode = inlineNextRequire(patchedCode, config);
7272
7309
  patchedCode = patchFindDir(patchedCode, config);
7273
7310
  patchedCode = inlineEvalManifest(patchedCode, config);
7274
- patchedCode = patchCache(patchedCode, config);
7311
+ patchedCode = await patchCache(patchedCode, config);
7275
7312
  patchedCode = inlineMiddlewareManifestRequire(patchedCode, config);
7276
7313
  patchedCode = patchExceptionBubbling(patchedCode);
7277
7314
  await writeFile(workerOutputFile, patchedCode);
7278
7315
  }
7279
- function createFixRequiresESBuildPlugin(templateDir) {
7316
+ function createFixRequiresESBuildPlugin(config) {
7280
7317
  return {
7281
7318
  name: "replaceRelative",
7282
- setup(build3) {
7283
- build3.onResolve({ filter: /^\.\/require-hook$/ }, () => ({
7284
- path: path13.join(templateDir, "shims", "empty.ts")
7319
+ setup(build4) {
7320
+ build4.onResolve({ filter: /^\.\/require-hook$/ }, () => ({
7321
+ path: path12.join(config.paths.internalTemplates, "shims", "empty.ts")
7285
7322
  }));
7286
- build3.onResolve({ filter: /\.\/lib\/node-fs-methods$/ }, () => ({
7287
- path: path13.join(templateDir, "shims", "empty.ts")
7323
+ build4.onResolve({ filter: /\.\/lib\/node-fs-methods$/ }, () => ({
7324
+ path: path12.join(config.paths.internalTemplates, "shims", "empty.ts")
7288
7325
  }));
7289
7326
  }
7290
7327
  };
@@ -7292,23 +7329,23 @@ function createFixRequiresESBuildPlugin(templateDir) {
7292
7329
 
7293
7330
  // src/cli/build/index.ts
7294
7331
  import { cpSync as cpSync2 } from "node:fs";
7295
- import path14 from "node:path";
7332
+ import path13 from "node:path";
7296
7333
  import { rm } from "node:fs/promises";
7297
- async function build2(appDir, opts) {
7334
+ async function build3(appDir, opts) {
7298
7335
  if (!opts.skipBuild) {
7299
7336
  await buildNextjsApp(appDir);
7300
7337
  }
7301
7338
  if (!containsDotNextDir(appDir)) {
7302
7339
  throw new Error(`.next folder not found in ${appDir}`);
7303
7340
  }
7304
- const outputDir2 = path14.resolve(opts.outputDir ?? appDir, ".worker-next");
7341
+ const outputDir2 = path13.resolve(opts.outputDir ?? appDir, ".worker-next");
7305
7342
  await cleanDirectory(outputDir2);
7306
- cpSync2(path14.join(appDir, ".next"), path14.join(outputDir2, ".next"), { recursive: true });
7343
+ cpSync2(path13.join(appDir, ".next"), path13.join(outputDir2, ".next"), { recursive: true });
7307
7344
  const config = getConfig(appDir, outputDir2);
7308
7345
  await buildWorker(config);
7309
7346
  }
7310
- async function cleanDirectory(path15) {
7311
- return await rm(path15, { recursive: true, force: true });
7347
+ async function cleanDirectory(path14) {
7348
+ return await rm(path14, { recursive: true, force: true });
7312
7349
  }
7313
7350
 
7314
7351
  // src/cli/index.ts
@@ -7344,15 +7381,15 @@ function getArgs() {
7344
7381
  skipBuild: skipBuild2 || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD))
7345
7382
  };
7346
7383
  }
7347
- function assertDirArg(path15, argName, make) {
7384
+ function assertDirArg(path14, argName, make) {
7348
7385
  let dirStats;
7349
7386
  try {
7350
- dirStats = statSync3(path15);
7387
+ dirStats = statSync3(path14);
7351
7388
  } catch {
7352
7389
  if (!make) {
7353
7390
  throw new Error(`Error: the provided${argName ? ` "${argName}"` : ""} input is not a valid path`);
7354
7391
  }
7355
- mkdirSync2(path15);
7392
+ mkdirSync2(path14);
7356
7393
  return;
7357
7394
  }
7358
7395
  if (!dirStats.isDirectory()) {
@@ -7368,7 +7405,7 @@ if (!["js", "cjs", "mjs", "ts"].some((ext2) => existsSync6(`./next.config.${ext2
7368
7405
  throw new Error("Error: Not in a Next.js app project");
7369
7406
  }
7370
7407
  var { skipBuild, outputDir } = getArgs();
7371
- await build2(nextAppDir, {
7408
+ await build3(nextAppDir, {
7372
7409
  outputDir,
7373
7410
  skipBuild: !!skipBuild
7374
7411
  });
@@ -0,0 +1 @@
1
+ export * from "./open-next-cache-handler";
@@ -0,0 +1,148 @@
1
+ import type {
2
+ CacheHandler,
3
+ CacheHandlerContext,
4
+ CacheHandlerValue,
5
+ } from "next/dist/server/lib/incremental-cache";
6
+ import {
7
+ NEXT_BODY_SUFFIX,
8
+ NEXT_DATA_SUFFIX,
9
+ NEXT_HTML_SUFFIX,
10
+ RSC_PREFETCH_SUFFIX,
11
+ RSC_SUFFIX,
12
+ SEED_DATA_DIR,
13
+ } from "../../constants/incremental-cache";
14
+ import { getSeedBodyFile, getSeedMetaFile, getSeedTextFile, parseCtx } from "./utils";
15
+ import type { IncrementalCacheValue } from "next/dist/server/response-cache";
16
+ import type { KVNamespace } from "@cloudflare/workers-types";
17
+
18
+ type CacheEntry = {
19
+ lastModified: number;
20
+ value: IncrementalCacheValue | null;
21
+ };
22
+
23
+ export class OpenNextCacheHandler implements CacheHandler {
24
+ protected kv: KVNamespace | undefined;
25
+
26
+ protected debug: boolean = !!process.env.NEXT_PRIVATE_DEBUG_CACHE;
27
+
28
+ constructor(protected ctx: CacheHandlerContext) {
29
+ this.kv = process.env[process.env.__OPENNEXT_KV_BINDING_NAME] as KVNamespace | undefined;
30
+ }
31
+
32
+ async get(...args: Parameters<CacheHandler["get"]>): Promise<CacheHandlerValue | null> {
33
+ const [key, _ctx] = args;
34
+ const ctx = parseCtx(_ctx);
35
+
36
+ if (this.debug) console.log(`cache - get: ${key}, ${ctx?.kind}`);
37
+
38
+ if (this.kv !== undefined) {
39
+ try {
40
+ const value = await this.kv.get<CacheEntry>(key, "json");
41
+ if (value) return value;
42
+ } catch (e) {
43
+ console.error(`Failed to get value for key = ${key}: ${e}`);
44
+ }
45
+ }
46
+
47
+ // Check for seed data from the file-system.
48
+
49
+ // we don't check for seed data for fetch or image cache entries
50
+ if (ctx?.kind === "FETCH" || ctx?.kind === "IMAGE") return null;
51
+
52
+ const seedKey = `http://assets.local/${SEED_DATA_DIR}/${key}`.replace(/\/\//g, "/");
53
+
54
+ if (ctx?.kind === "APP" || ctx?.kind === "APP_ROUTE") {
55
+ const fallbackBody = await getSeedBodyFile(seedKey, NEXT_BODY_SUFFIX);
56
+ if (fallbackBody) {
57
+ const meta = await getSeedMetaFile(seedKey);
58
+ return {
59
+ lastModified: meta?.lastModified,
60
+ value: {
61
+ kind: (ctx.kind === "APP_ROUTE" ? ctx.kind : "ROUTE") as Extract<
62
+ IncrementalCacheValue["kind"],
63
+ "ROUTE"
64
+ >,
65
+ body: fallbackBody,
66
+ status: meta?.status ?? 200,
67
+ headers: meta?.headers ?? {},
68
+ },
69
+ };
70
+ }
71
+
72
+ if (ctx.kind === "APP_ROUTE") {
73
+ return null;
74
+ }
75
+ }
76
+
77
+ const seedHtml = await getSeedTextFile(seedKey, NEXT_HTML_SUFFIX);
78
+ if (!seedHtml) return null; // we're only checking for prerendered routes at the moment
79
+
80
+ if (ctx?.kind === "PAGES" || ctx?.kind === "APP" || ctx?.kind === "APP_PAGE") {
81
+ const metaPromise = getSeedMetaFile(seedKey);
82
+
83
+ let pageDataPromise: Promise<Buffer | string | undefined> = Promise.resolve(undefined);
84
+ if (!ctx.isFallback) {
85
+ const rscSuffix = ctx.isRoutePPREnabled ? RSC_PREFETCH_SUFFIX : RSC_SUFFIX;
86
+
87
+ if (ctx.kind === "APP_PAGE") {
88
+ pageDataPromise = getSeedBodyFile(seedKey, rscSuffix);
89
+ } else {
90
+ pageDataPromise = getSeedTextFile(seedKey, ctx.kind === "APP" ? rscSuffix : NEXT_DATA_SUFFIX);
91
+ }
92
+ }
93
+
94
+ const [meta, pageData] = await Promise.all([metaPromise, pageDataPromise]);
95
+
96
+ return {
97
+ lastModified: meta?.lastModified,
98
+ value: {
99
+ kind: (ctx.kind === "APP_PAGE" ? "APP_PAGE" : "PAGE") as Extract<
100
+ IncrementalCacheValue["kind"],
101
+ "PAGE"
102
+ >,
103
+ html: seedHtml,
104
+ pageData: pageData ?? "",
105
+ ...(ctx.kind === "APP_PAGE" && { rscData: pageData }),
106
+ postponed: meta?.postponed,
107
+ status: meta?.status,
108
+ headers: meta?.headers,
109
+ },
110
+ };
111
+ }
112
+
113
+ return null;
114
+ }
115
+
116
+ async set(...args: Parameters<CacheHandler["set"]>) {
117
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
118
+ const [key, entry, _ctx] = args;
119
+
120
+ if (this.kv === undefined) {
121
+ return;
122
+ }
123
+
124
+ if (this.debug) console.log(`cache - set: ${key}`);
125
+
126
+ const data: CacheEntry = {
127
+ lastModified: Date.now(),
128
+ value: entry,
129
+ };
130
+
131
+ try {
132
+ await this.kv.put(key, JSON.stringify(data));
133
+ } catch (e) {
134
+ console.error(`Failed to set value for key = ${key}: ${e}`);
135
+ }
136
+ }
137
+
138
+ async revalidateTag(...args: Parameters<CacheHandler["revalidateTag"]>) {
139
+ const [tags] = args;
140
+ if (this.kv === undefined) {
141
+ return;
142
+ }
143
+
144
+ if (this.debug) console.log(`cache - revalidateTag: ${JSON.stringify([tags].flat())}`);
145
+ }
146
+
147
+ resetRequestCache(): void {}
148
+ }
@@ -0,0 +1,41 @@
1
+ import type { IncrementalCache } from "next/dist/server/lib/incremental-cache";
2
+ import { NEXT_META_SUFFIX } from "../../constants/incremental-cache";
3
+
4
+ type PrerenderedRouteMeta = {
5
+ lastModified: number;
6
+ status?: number;
7
+ headers?: Record<string, string>;
8
+ postponed?: string;
9
+ };
10
+
11
+ type EntryKind =
12
+ | "APP" // .body, .html - backwards compat
13
+ | "PAGES"
14
+ | "FETCH"
15
+ | "APP_ROUTE" // .body
16
+ | "APP_PAGE" // .html
17
+ | "IMAGE"
18
+ | undefined;
19
+
20
+ async function getAsset<T>(key: string, cb: (resp: Response) => T): Promise<Awaited<T> | undefined> {
21
+ const resp = await process.env.ASSETS.fetch(key);
22
+ return resp.status === 200 ? await cb(resp) : undefined;
23
+ }
24
+
25
+ export function getSeedBodyFile(key: string, suffix: string) {
26
+ return getAsset(key + suffix, (resp) => resp.arrayBuffer() as Promise<Buffer>);
27
+ }
28
+
29
+ export function getSeedTextFile(key: string, suffix: string) {
30
+ return getAsset(key + suffix, (resp) => resp.text());
31
+ }
32
+
33
+ export function getSeedMetaFile(key: string) {
34
+ return getAsset(key + NEXT_META_SUFFIX, (resp) => resp.json<PrerenderedRouteMeta>());
35
+ }
36
+
37
+ export function parseCtx(ctx: Parameters<IncrementalCache["get"]>[1] = {}) {
38
+ return { ...ctx, kind: ctx?.kindHint?.toUpperCase() } as
39
+ | (typeof ctx & { kind?: EntryKind; isFallback?: boolean; isRoutePPREnabled?: boolean })
40
+ | undefined;
41
+ }
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.3",
4
+ "version": "0.1.0",
5
5
  "bin": "dist/cli/index.mjs",
6
6
  "main": "./dist/api/index.mjs",
7
7
  "types": "./dist/api/index.d.mts",
@@ -1,20 +0,0 @@
1
- import {
2
- NEXT_BODY_SUFFIX,
3
- NEXT_DATA_SUFFIX,
4
- NEXT_HTML_SUFFIX,
5
- NEXT_META_SUFFIX,
6
- OpenNextCacheHandler,
7
- RSC_PREFETCH_SUFFIX,
8
- RSC_SUFFIX,
9
- SEED_DATA_DIR
10
- } from "../chunk-F7LECSR5.mjs";
11
- export {
12
- NEXT_BODY_SUFFIX,
13
- NEXT_DATA_SUFFIX,
14
- NEXT_HTML_SUFFIX,
15
- NEXT_META_SUFFIX,
16
- OpenNextCacheHandler,
17
- RSC_PREFETCH_SUFFIX,
18
- RSC_SUFFIX,
19
- SEED_DATA_DIR
20
- };
@@ -1,160 +0,0 @@
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
- // src/cli/cache-handler/constants.ts
28
- var RSC_PREFETCH_SUFFIX = ".prefetch.rsc";
29
- var RSC_SUFFIX = ".rsc";
30
- var NEXT_DATA_SUFFIX = ".json";
31
- var NEXT_META_SUFFIX = ".meta";
32
- var NEXT_BODY_SUFFIX = ".body";
33
- var NEXT_HTML_SUFFIX = ".html";
34
- var SEED_DATA_DIR = "cdn-cgi/_cf_seed_data";
35
-
36
- // src/cli/cache-handler/utils.ts
37
- async function getAsset(key, cb) {
38
- const resp = await process.env.ASSETS.fetch(key);
39
- return resp.status === 200 ? await cb(resp) : void 0;
40
- }
41
- function getSeedBodyFile(key, suffix) {
42
- return getAsset(key + suffix, (resp) => resp.arrayBuffer());
43
- }
44
- function getSeedTextFile(key, suffix) {
45
- return getAsset(key + suffix, (resp) => resp.text());
46
- }
47
- function getSeedMetaFile(key) {
48
- return getAsset(key + NEXT_META_SUFFIX, (resp) => resp.json());
49
- }
50
- function parseCtx(ctx = {}) {
51
- return { ...ctx, kind: ctx?.kindHint?.toUpperCase() };
52
- }
53
-
54
- // src/cli/cache-handler/open-next-cache-handler.ts
55
- var OpenNextCacheHandler = class _OpenNextCacheHandler {
56
- constructor(ctx) {
57
- this.ctx = ctx;
58
- }
59
- static maybeKVNamespace = void 0;
60
- debug = !!process.env.NEXT_PRIVATE_DEBUG_CACHE;
61
- async get(...args) {
62
- const [key, _ctx] = args;
63
- const ctx = parseCtx(_ctx);
64
- if (this.debug) console.log(`cache - get: ${key}, ${ctx?.kind}`);
65
- if (_OpenNextCacheHandler.maybeKVNamespace !== void 0) {
66
- try {
67
- const value = await _OpenNextCacheHandler.maybeKVNamespace.get(key, "json");
68
- if (value) return value;
69
- } catch (e) {
70
- console.error(`Failed to get value for key = ${key}: ${e}`);
71
- }
72
- }
73
- if (ctx?.kind === "FETCH" || ctx?.kind === "IMAGE") return null;
74
- const seedKey = `http://assets.local/${SEED_DATA_DIR}/${key}`.replace(/\/\//g, "/");
75
- if (ctx?.kind === "APP" || ctx?.kind === "APP_ROUTE") {
76
- const fallbackBody = await getSeedBodyFile(seedKey, NEXT_BODY_SUFFIX);
77
- if (fallbackBody) {
78
- const meta = await getSeedMetaFile(seedKey);
79
- return {
80
- lastModified: meta?.lastModified,
81
- value: {
82
- kind: ctx.kind === "APP_ROUTE" ? ctx.kind : "ROUTE",
83
- body: fallbackBody,
84
- status: meta?.status ?? 200,
85
- headers: meta?.headers ?? {}
86
- }
87
- };
88
- }
89
- if (ctx.kind === "APP_ROUTE") {
90
- return null;
91
- }
92
- }
93
- const seedHtml = await getSeedTextFile(seedKey, NEXT_HTML_SUFFIX);
94
- if (!seedHtml) return null;
95
- if (ctx?.kind === "PAGES" || ctx?.kind === "APP" || ctx?.kind === "APP_PAGE") {
96
- const metaPromise = getSeedMetaFile(seedKey);
97
- let pageDataPromise = Promise.resolve(void 0);
98
- if (!ctx.isFallback) {
99
- const rscSuffix = ctx.isRoutePPREnabled ? RSC_PREFETCH_SUFFIX : RSC_SUFFIX;
100
- if (ctx.kind === "APP_PAGE") {
101
- pageDataPromise = getSeedBodyFile(seedKey, rscSuffix);
102
- } else {
103
- pageDataPromise = getSeedTextFile(seedKey, ctx.kind === "APP" ? rscSuffix : NEXT_DATA_SUFFIX);
104
- }
105
- }
106
- const [meta, pageData] = await Promise.all([metaPromise, pageDataPromise]);
107
- return {
108
- lastModified: meta?.lastModified,
109
- value: {
110
- kind: ctx.kind === "APP_PAGE" ? "APP_PAGE" : "PAGE",
111
- html: seedHtml,
112
- pageData: pageData ?? "",
113
- ...ctx.kind === "APP_PAGE" && { rscData: pageData },
114
- postponed: meta?.postponed,
115
- status: meta?.status,
116
- headers: meta?.headers
117
- }
118
- };
119
- }
120
- return null;
121
- }
122
- async set(...args) {
123
- const [key, entry, _ctx] = args;
124
- if (_OpenNextCacheHandler.maybeKVNamespace === void 0) {
125
- return;
126
- }
127
- if (this.debug) console.log(`cache - set: ${key}`);
128
- const data = {
129
- lastModified: Date.now(),
130
- value: entry
131
- };
132
- try {
133
- await _OpenNextCacheHandler.maybeKVNamespace.put(key, JSON.stringify(data));
134
- } catch (e) {
135
- console.error(`Failed to set value for key = ${key}: ${e}`);
136
- }
137
- }
138
- async revalidateTag(...args) {
139
- const [tags] = args;
140
- if (_OpenNextCacheHandler.maybeKVNamespace === void 0) {
141
- return;
142
- }
143
- if (this.debug) console.log(`cache - revalidateTag: ${JSON.stringify([tags].flat())}`);
144
- }
145
- resetRequestCache() {
146
- }
147
- };
148
-
149
- export {
150
- __commonJS,
151
- __toESM,
152
- RSC_PREFETCH_SUFFIX,
153
- RSC_SUFFIX,
154
- NEXT_DATA_SUFFIX,
155
- NEXT_META_SUFFIX,
156
- NEXT_BODY_SUFFIX,
157
- NEXT_HTML_SUFFIX,
158
- SEED_DATA_DIR,
159
- OpenNextCacheHandler
160
- };