@opennextjs/aws 3.2.0 → 3.2.2

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.
Files changed (140) hide show
  1. package/README.md +15 -1
  2. package/dist/adapters/cache.d.ts +1 -23
  3. package/dist/adapters/cache.js +22 -18
  4. package/dist/adapters/config/index.js +1 -1
  5. package/dist/adapters/config/util.js +2 -2
  6. package/dist/adapters/dynamo-provider.js +3 -5
  7. package/dist/adapters/edge-adapter.d.ts +0 -3
  8. package/dist/adapters/edge-adapter.js +43 -38
  9. package/dist/adapters/image-optimization-adapter.js +4 -4
  10. package/dist/adapters/logger.d.ts +0 -3
  11. package/dist/adapters/logger.js +3 -5
  12. package/dist/adapters/middleware.js +42 -18
  13. package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +0 -3
  14. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +0 -3
  15. package/dist/adapters/revalidate.js +2 -2
  16. package/dist/adapters/server-adapter.d.ts +0 -3
  17. package/dist/adapters/server-adapter.js +3 -1
  18. package/dist/adapters/util.js +2 -2
  19. package/dist/build/bundleNextServer.d.ts +3 -1
  20. package/dist/build/bundleNextServer.js +3 -3
  21. package/dist/build/compileConfig.js +3 -3
  22. package/dist/build/copyTracedFiles.js +16 -27
  23. package/dist/build/createAssets.js +35 -26
  24. package/dist/build/createImageOptimizationBundle.js +4 -1
  25. package/dist/build/createMiddleware.d.ts +4 -4
  26. package/dist/build/createMiddleware.js +16 -19
  27. package/dist/build/createRevalidationBundle.js +1 -1
  28. package/dist/build/createServerBundle.js +34 -45
  29. package/dist/build/createWarmerBundle.js +1 -1
  30. package/dist/build/edge/createEdgeBundle.d.ts +9 -7
  31. package/dist/build/edge/createEdgeBundle.js +19 -14
  32. package/dist/build/generateOutput.js +7 -13
  33. package/dist/build/helper.d.ts +22 -4
  34. package/dist/build/helper.js +26 -12
  35. package/dist/build/installDeps.js +12 -2
  36. package/dist/build/patch/patchedAsyncStorage.js +1 -1
  37. package/dist/build/utils.js +3 -2
  38. package/dist/build/validateConfig.js +1 -0
  39. package/dist/core/createGenericHandler.d.ts +2 -4
  40. package/dist/core/createGenericHandler.js +6 -7
  41. package/dist/core/createMainHandler.d.ts +0 -17
  42. package/dist/core/createMainHandler.js +10 -9
  43. package/dist/core/edgeFunctionHandler.d.ts +1 -51
  44. package/dist/core/patchAsyncStorage.js +5 -6
  45. package/dist/core/requestHandler.js +98 -89
  46. package/dist/core/require-hooks.js +8 -7
  47. package/dist/core/resolve.d.ts +13 -7
  48. package/dist/core/resolve.js +29 -35
  49. package/dist/core/routing/cacheInterceptor.js +12 -13
  50. package/dist/core/routing/i18n/accept-header.js +3 -2
  51. package/dist/core/routing/matcher.d.ts +2 -4
  52. package/dist/core/routing/matcher.js +29 -31
  53. package/dist/core/routing/middleware.js +22 -18
  54. package/dist/core/routing/util.d.ts +0 -13
  55. package/dist/core/routing/util.js +32 -91
  56. package/dist/core/routingHandler.d.ts +2 -0
  57. package/dist/core/routingHandler.js +30 -12
  58. package/dist/core/util.js +5 -3
  59. package/dist/helpers/withSST.d.ts +1 -1
  60. package/dist/http/openNextResponse.d.ts +5 -9
  61. package/dist/http/openNextResponse.js +29 -31
  62. package/dist/http/request.d.ts +0 -3
  63. package/dist/http/request.js +4 -2
  64. package/dist/http/util.d.ts +1 -1
  65. package/dist/http/util.js +8 -12
  66. package/dist/minimize-js.js +19 -19
  67. package/dist/overrides/converters/aws-apigw-v1.d.ts +2 -2
  68. package/dist/overrides/converters/aws-apigw-v1.js +2 -1
  69. package/dist/overrides/converters/aws-apigw-v2.d.ts +2 -2
  70. package/dist/overrides/converters/aws-apigw-v2.js +6 -7
  71. package/dist/overrides/converters/aws-cloudfront.d.ts +2 -2
  72. package/dist/overrides/converters/aws-cloudfront.js +11 -30
  73. package/dist/overrides/converters/dummy.d.ts +1 -1
  74. package/dist/overrides/converters/edge.d.ts +5 -1
  75. package/dist/overrides/converters/edge.js +16 -17
  76. package/dist/overrides/converters/node.d.ts +1 -1
  77. package/dist/overrides/converters/node.js +1 -1
  78. package/dist/overrides/converters/sqs-revalidate.d.ts +1 -1
  79. package/dist/overrides/imageLoader/dummy.d.ts +1 -1
  80. package/dist/overrides/imageLoader/host.d.ts +1 -1
  81. package/dist/overrides/imageLoader/s3.d.ts +1 -1
  82. package/dist/overrides/imageLoader/s3.js +1 -1
  83. package/dist/overrides/incrementalCache/dummy.d.ts +1 -1
  84. package/dist/overrides/incrementalCache/s3-lite.d.ts +1 -1
  85. package/dist/overrides/incrementalCache/s3-lite.js +15 -19
  86. package/dist/overrides/incrementalCache/s3.d.ts +1 -1
  87. package/dist/overrides/incrementalCache/s3.js +1 -1
  88. package/dist/overrides/originResolver/dummy.d.ts +1 -1
  89. package/dist/overrides/originResolver/pattern-env.d.ts +1 -1
  90. package/dist/overrides/originResolver/pattern-env.js +10 -11
  91. package/dist/overrides/proxyExternalRequest/dummy.d.ts +3 -0
  92. package/dist/overrides/proxyExternalRequest/dummy.js +7 -0
  93. package/dist/overrides/proxyExternalRequest/fetch.d.ts +3 -0
  94. package/dist/overrides/proxyExternalRequest/fetch.js +25 -0
  95. package/dist/overrides/proxyExternalRequest/node.d.ts +3 -0
  96. package/dist/overrides/proxyExternalRequest/node.js +67 -0
  97. package/dist/overrides/queue/dummy.d.ts +1 -1
  98. package/dist/overrides/queue/sqs-lite.d.ts +1 -1
  99. package/dist/overrides/queue/sqs-lite.js +7 -9
  100. package/dist/overrides/queue/sqs.d.ts +1 -1
  101. package/dist/overrides/queue/sqs.js +1 -1
  102. package/dist/overrides/tagCache/constants.js +2 -2
  103. package/dist/overrides/tagCache/dummy.d.ts +1 -1
  104. package/dist/overrides/tagCache/dynamodb-lite.d.ts +1 -1
  105. package/dist/overrides/tagCache/dynamodb-lite.js +10 -12
  106. package/dist/overrides/tagCache/dynamodb.d.ts +1 -1
  107. package/dist/overrides/tagCache/dynamodb.js +2 -2
  108. package/dist/overrides/warmer/aws-lambda.d.ts +1 -1
  109. package/dist/overrides/warmer/dummy.d.ts +1 -1
  110. package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +2 -2
  111. package/dist/overrides/wrappers/aws-lambda.d.ts +2 -2
  112. package/dist/overrides/wrappers/cloudflare.d.ts +2 -1
  113. package/dist/overrides/wrappers/cloudflare.js +21 -3
  114. package/dist/overrides/wrappers/dummy.d.ts +2 -2
  115. package/dist/overrides/wrappers/node.d.ts +2 -2
  116. package/dist/overrides/wrappers/node.js +3 -3
  117. package/dist/plugins/edge.d.ts +3 -2
  118. package/dist/plugins/edge.js +33 -34
  119. package/dist/plugins/replacement.d.ts +1 -1
  120. package/dist/plugins/replacement.js +5 -6
  121. package/dist/plugins/resolve.d.ts +3 -1
  122. package/dist/plugins/resolve.js +4 -1
  123. package/dist/types/aws-lambda.d.ts +2 -5
  124. package/dist/types/cache.d.ts +0 -2
  125. package/dist/types/global.d.ts +188 -0
  126. package/dist/types/next-types.d.ts +1 -3
  127. package/dist/types/open-next.d.ts +24 -45
  128. package/dist/types/overrides.d.ts +87 -0
  129. package/dist/utils/promise.d.ts +3 -0
  130. package/dist/utils/promise.js +44 -0
  131. package/dist/utils/stream.d.ts +0 -1
  132. package/package.json +2 -2
  133. package/dist/adapters/plugins/without-routing/requestHandler.d.ts +0 -2
  134. package/dist/adapters/plugins/without-routing/requestHandler.js +0 -10
  135. package/dist/overrides/incrementalCache/types.d.ts +0 -34
  136. package/dist/overrides/queue/types.d.ts +0 -12
  137. package/dist/overrides/tagCache/types.d.ts +0 -11
  138. package/dist/overrides/tagCache/types.js +0 -1
  139. /package/dist/{overrides/incrementalCache/types.js → types/global.js} +0 -0
  140. /package/dist/{overrides/queue/types.js → types/overrides.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  import url from "node:url";
2
- import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "fs";
3
- import path from "path";
2
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
3
+ import path from "node:path";
4
4
  import logger from "../logger.js";
5
5
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
6
6
  function copyPatchFile(outputDir) {
@@ -15,9 +15,7 @@ export async function copyTracedFiles(buildOutputPath, packagePath, outputDir, r
15
15
  const standaloneDir = path.join(dotNextDir, "standalone");
16
16
  const standaloneNextDir = path.join(standaloneDir, packagePath, ".next");
17
17
  const outputNextDir = path.join(outputDir, packagePath, ".next");
18
- const extractFiles = (files, from = standaloneNextDir) => {
19
- return files.map((f) => path.resolve(from, f));
20
- };
18
+ const extractFiles = (files, from = standaloneNextDir) => files.map((f) => path.resolve(from, f));
21
19
  // On next 14+, we might not have to include those files
22
20
  // For next 13, we need to include them otherwise we get runtime error
23
21
  const requiredServerFiles = JSON.parse(readFileSync(path.join(dotNextDir, bundledNextServer
@@ -54,24 +52,22 @@ export async function copyTracedFiles(buildOutputPath, packagePath, outputDir, r
54
52
  throw new Error(`
55
53
  --------------------------------------------------------------------------------
56
54
  ${pagePath} cannot use the edge runtime.
57
- OpenNext requires edge runtime function to be defined in a separate function.
55
+ OpenNext requires edge runtime function to be defined in a separate function.
58
56
  See the docs for more information on how to bundle edge runtime functions.
59
57
  --------------------------------------------------------------------------------
60
58
  `);
61
59
  }
62
- else {
63
- throw new Error(`
60
+ throw new Error(`
64
61
  --------------------------------------------------------------------------------
65
62
  We cannot find the route for ${pagePath}.
66
63
  File ${fullFilePath} does not exist
67
64
  --------------------------------------------------------------------------------`);
68
- }
69
65
  }
70
66
  const dir = path.dirname(fullFilePath);
71
67
  extractFiles(requiredFiles.files, path.join(standaloneNextDir, dir)).forEach((f) => {
72
68
  filesToCopy.set(f, f.replace(standaloneDir, outputDir));
73
69
  });
74
- if (!existsSync(path.join(standaloneNextDir, `${fullFilePath}`))) {
70
+ if (!existsSync(path.join(standaloneNextDir, fullFilePath))) {
75
71
  throw new Error(`This error should only happen for static 404 and 500 page from page router. Report this if that's not the case.,
76
72
  File ${fullFilePath} does not exist`);
77
73
  }
@@ -144,20 +140,15 @@ File ${fullFilePath} does not exist
144
140
  copyFileSync(from, to);
145
141
  }
146
142
  });
147
- readdirSync(standaloneNextDir).forEach((f) => {
148
- if (statSync(path.join(standaloneNextDir, f)).isDirectory())
149
- return;
150
- copyFileSync(path.join(standaloneNextDir, f), path.join(outputNextDir, f));
151
- });
143
+ readdirSync(standaloneNextDir)
144
+ .filter((fileOrDir) => !statSync(path.join(standaloneNextDir, fileOrDir)).isDirectory())
145
+ .forEach((file) => copyFileSync(path.join(standaloneNextDir, file), path.join(outputNextDir, file)));
152
146
  // We then need to copy all the files at the root of server
153
147
  mkdirSync(path.join(outputNextDir, "server"), { recursive: true });
154
- readdirSync(path.join(standaloneNextDir, "server")).forEach((f) => {
155
- if (statSync(path.join(standaloneNextDir, "server", f)).isDirectory())
156
- return;
157
- if (f !== "server.js") {
158
- copyFileSync(path.join(standaloneNextDir, "server", f), path.join(path.join(outputNextDir, "server"), f));
159
- }
160
- });
148
+ readdirSync(path.join(standaloneNextDir, "server"))
149
+ .filter((fileOrDir) => !statSync(path.join(standaloneNextDir, "server", fileOrDir)).isDirectory())
150
+ .filter((file) => file !== "server.js")
151
+ .forEach((file) => copyFileSync(path.join(standaloneNextDir, "server", file), path.join(path.join(outputNextDir, "server"), file)));
161
152
  // Copy patch file
162
153
  copyPatchFile(path.join(outputDir, packagePath));
163
154
  // TODO: Recompute all the files.
@@ -198,11 +189,9 @@ File ${fullFilePath} does not exist
198
189
  }
199
190
  }
200
191
  });
201
- staticFiles.forEach((f) => {
202
- if (f.endsWith(".html")) {
203
- copyStaticFile(`server/${f}`);
204
- }
205
- });
192
+ staticFiles
193
+ .filter((file) => file.endsWith(".html"))
194
+ .forEach((file) => copyStaticFile(`server/${file}`));
206
195
  }
207
196
  logger.debug("copyTracedFiles:", Date.now() - tsStart, "ms");
208
197
  }
@@ -4,17 +4,22 @@ import { isBinaryContentType } from "../adapters/binary.js";
4
4
  import logger from "../logger.js";
5
5
  import * as buildHelper from "./helper.js";
6
6
  export function createStaticAssets(options) {
7
- logger.info(`Bundling static assets...`);
7
+ logger.info("Bundling static assets...");
8
8
  const { appBuildOutputPath, appPublicPath, outputDir, appPath } = options;
9
9
  // Create output folder
10
10
  const outputPath = path.join(outputDir, "assets");
11
11
  fs.mkdirSync(outputPath, { recursive: true });
12
- // Next.js outputs assets into multiple files. Copy into the same directory.
13
- // Copy over:
14
- // - .next/BUILD_ID => _next/BUILD_ID
15
- // - .next/static => _next/static
16
- // - public/* => *
17
- // - app/favicon.ico or src/app/favicon.ico => favicon.ico
12
+ /**
13
+ * Next.js outputs assets into multiple files. Copy into the same directory.
14
+ *
15
+ * Copy over:
16
+ * - .next/BUILD_ID => BUILD_ID
17
+ * - .next/static => _next/static
18
+ * - public/* => *
19
+ * - app/favicon.ico or src/app/favicon.ico => favicon.ico
20
+ *
21
+ * Note: BUILD_ID is used by the SST infra.
22
+ */
18
23
  fs.copyFileSync(path.join(appBuildOutputPath, ".next/BUILD_ID"), path.join(outputPath, "BUILD_ID"));
19
24
  fs.cpSync(path.join(appBuildOutputPath, ".next/static"), path.join(outputPath, "_next", "static"), { recursive: true });
20
25
  if (fs.existsSync(appPublicPath)) {
@@ -24,7 +29,9 @@ export function createStaticAssets(options) {
24
29
  ? "src/app"
25
30
  : "app";
26
31
  const faviconPath = path.join(appPath, appSrcPath, "favicon.ico");
27
- if (fs.existsSync(faviconPath)) {
32
+ // We need to check if the favicon is either a file or directory.
33
+ // If it's a directory, we assume it's a route handler and ignore it.
34
+ if (fs.existsSync(faviconPath) && fs.lstatSync(faviconPath).isFile()) {
28
35
  fs.copyFileSync(faviconPath, path.join(outputPath, "favicon.ico"));
29
36
  }
30
37
  }
@@ -35,7 +42,7 @@ export function createStaticAssets(options) {
35
42
  * @returns Whether tag cache is used.
36
43
  */
37
44
  export function createCacheAssets(options) {
38
- logger.info(`Bundling cache assets...`);
45
+ logger.info("Bundling cache assets...");
39
46
  const { appBuildOutputPath, outputDir } = options;
40
47
  const packagePath = path.relative(options.monorepoRoot, appBuildOutputPath);
41
48
  const buildId = buildHelper.getBuildId(appBuildOutputPath);
@@ -49,27 +56,29 @@ export function createCacheAssets(options) {
49
56
  .forEach((dir) => fs.cpSync(dir, outputPath, { recursive: true }));
50
57
  // Remove non-cache files
51
58
  const htmlPages = buildHelper.getHtmlPages(dotNextPath);
52
- buildHelper.removeFiles(outputPath, (file) => file.endsWith(".js") ||
53
- file.endsWith(".js.nft.json") ||
54
- (file.endsWith(".html") && htmlPages.has(file)));
59
+ buildHelper.removeFiles(outputPath, ({ relativePath }) => relativePath.endsWith(".js") ||
60
+ relativePath.endsWith(".js.nft.json") ||
61
+ (relativePath.endsWith(".html") && htmlPages.has(relativePath)));
55
62
  // Merge cache files into a single file
56
63
  const cacheFilesPath = {};
57
- buildHelper.traverseFiles(outputPath, () => true, (filepath) => {
58
- const ext = path.extname(filepath);
64
+ buildHelper.traverseFiles(outputPath, () => true, ({ absolutePath }) => {
65
+ const ext = path.extname(absolutePath);
59
66
  switch (ext) {
60
67
  case ".meta":
61
68
  case ".html":
62
69
  case ".json":
63
70
  case ".body":
64
- case ".rsc":
65
- const newFilePath = filepath
66
- .substring(0, filepath.length - ext.length)
67
- .replace(/\.prefetch$/, "") + ".cache";
71
+ case ".rsc": {
72
+ const newFilePath = absolutePath
73
+ .substring(0, absolutePath.length - ext.length)
74
+ .replace(/\.prefetch$/, "")
75
+ .concat(".cache");
68
76
  cacheFilesPath[newFilePath] = {
69
- [ext.slice(1)]: filepath,
77
+ [ext.slice(1)]: absolutePath,
70
78
  ...cacheFilesPath[newFilePath],
71
79
  };
72
80
  break;
81
+ }
73
82
  case ".map":
74
83
  break;
75
84
  default:
@@ -106,8 +115,8 @@ export function createCacheAssets(options) {
106
115
  const metaFiles = [];
107
116
  // Compute dynamodb cache data
108
117
  // Traverse files inside cache to find all meta files and cache tags associated with them
109
- buildHelper.traverseFiles(outputPath, (file) => file.endsWith(".meta"), (filePath) => {
110
- const fileContent = fs.readFileSync(filePath, "utf8");
118
+ buildHelper.traverseFiles(outputPath, ({ absolutePath }) => absolutePath.endsWith(".meta"), ({ absolutePath, relativePath }) => {
119
+ const fileContent = fs.readFileSync(absolutePath, "utf8");
111
120
  const fileData = JSON.parse(fileContent);
112
121
  if (fileData.headers?.["x-next-cache-tags"]) {
113
122
  fileData.headers["x-next-cache-tags"]
@@ -117,7 +126,7 @@ export function createCacheAssets(options) {
117
126
  metaFiles.push({
118
127
  tag: { S: path.posix.join(buildId, tag.trim()) },
119
128
  path: {
120
- S: path.posix.join(buildId, path.relative(outputPath, filePath).replace(".meta", "")),
129
+ S: path.posix.join(buildId, relativePath.replace(".meta", "")),
121
130
  },
122
131
  // We don't care about the revalidation time here, we just need to make sure it's there
123
132
  revalidatedAt: { N: "1" },
@@ -131,14 +140,14 @@ export function createCacheAssets(options) {
131
140
  const fetchOutputPath = path.join(outputDir, "cache", "__fetch", buildId);
132
141
  fs.mkdirSync(fetchOutputPath, { recursive: true });
133
142
  fs.cpSync(fetchCachePath, fetchOutputPath, { recursive: true });
134
- buildHelper.traverseFiles(fetchCachePath, () => true, (filepath) => {
135
- const fileContent = fs.readFileSync(filepath, "utf8");
143
+ buildHelper.traverseFiles(fetchCachePath, () => true, ({ absolutePath, relativePath }) => {
144
+ const fileContent = fs.readFileSync(absolutePath, "utf8");
136
145
  const fileData = JSON.parse(fileContent);
137
146
  fileData?.tags?.forEach((tag) => {
138
147
  metaFiles.push({
139
148
  tag: { S: path.posix.join(buildId, tag) },
140
149
  path: {
141
- S: path.posix.join(buildId, path.relative(fetchCachePath, filepath)),
150
+ S: path.posix.join(buildId, relativePath),
142
151
  },
143
152
  revalidatedAt: { N: "1" },
144
153
  });
@@ -156,6 +165,6 @@ export function createCacheAssets(options) {
156
165
  }
157
166
  }
158
167
  // We need to remove files later because we need the metafiles for dynamodb tags cache
159
- buildHelper.removeFiles(outputPath, (file) => !file.endsWith(".cache"));
168
+ buildHelper.removeFiles(outputPath, ({ relativePath }) => !relativePath.endsWith(".cache"));
160
169
  return { useTagCache };
161
170
  }
@@ -8,7 +8,7 @@ import * as buildHelper from "./helper.js";
8
8
  import { installDependencies } from "./installDeps.js";
9
9
  const require = createRequire(import.meta.url);
10
10
  export async function createImageOptimizationBundle(options) {
11
- logger.info(`Bundling image optimization function...`);
11
+ logger.info("Bundling image optimization function...");
12
12
  const { appBuildOutputPath, config, outputDir } = options;
13
13
  // Create output folder
14
14
  const outputPath = path.join(outputDir, "image-optimization-function");
@@ -75,5 +75,8 @@ export async function createImageOptimizationBundle(options) {
75
75
  const sharpVersion = process.env.SHARP_VERSION ?? "0.32.6";
76
76
  installDependencies(outputPath, config.imageOptimization?.install ?? {
77
77
  packages: [`sharp@${sharpVersion}`],
78
+ arch: "arm64",
79
+ nodeVersion: "18",
80
+ libc: "glibc",
78
81
  });
79
82
  }
@@ -3,8 +3,8 @@ import * as buildHelper from "./helper.js";
3
3
  * Compiles the middleware bundle.
4
4
  *
5
5
  * @param options Build Options.
6
- * @returns Whether the app uses a Middleware.
6
+ * @param forceOnlyBuildOnce force to build only once.
7
7
  */
8
- export declare function createMiddleware(options: buildHelper.BuildOptions): Promise<{
9
- useMiddleware: boolean;
10
- }>;
8
+ export declare function createMiddleware(options: buildHelper.BuildOptions, { forceOnlyBuildOnce }?: {
9
+ forceOnlyBuildOnce?: boolean | undefined;
10
+ }): Promise<void>;
@@ -8,26 +8,16 @@ import { installDependencies } from "./installDeps.js";
8
8
  * Compiles the middleware bundle.
9
9
  *
10
10
  * @param options Build Options.
11
- * @returns Whether the app uses a Middleware.
11
+ * @param forceOnlyBuildOnce force to build only once.
12
12
  */
13
- export async function createMiddleware(options) {
14
- logger.info(`Bundling middleware function...`);
13
+ export async function createMiddleware(options, { forceOnlyBuildOnce = false } = {}) {
14
+ logger.info("Bundling middleware function...");
15
15
  const { appBuildOutputPath, config, outputDir } = options;
16
16
  // Get middleware manifest
17
17
  const middlewareManifest = JSON.parse(fs.readFileSync(path.join(appBuildOutputPath, ".next/server/middleware-manifest.json"), "utf8"));
18
- const entry = middlewareManifest.middleware["/"];
19
- if (!entry) {
20
- return { useMiddleware: false };
21
- }
22
- // Create output folder
23
- let outputPath = path.join(outputDir, "server-function");
24
- const commonMiddlewareOptions = {
25
- middlewareInfo: entry,
26
- options,
27
- appBuildOutputPath,
28
- };
18
+ const middlewareInfo = middlewareManifest.middleware["/"];
29
19
  if (config.middleware?.external) {
30
- outputPath = path.join(outputDir, "middleware");
20
+ const outputPath = path.join(outputDir, "middleware");
31
21
  fs.mkdirSync(outputPath, { recursive: true });
32
22
  // Copy open-next.config.mjs
33
23
  buildHelper.copyOpenNextConfig(options.buildDir, outputPath, config.middleware.override?.wrapper === "cloudflare");
@@ -35,11 +25,17 @@ export async function createMiddleware(options) {
35
25
  await buildEdgeBundle({
36
26
  entrypoint: path.join(options.openNextDistDir, "adapters", "middleware.js"),
37
27
  outfile: path.join(outputPath, "handler.mjs"),
38
- ...commonMiddlewareOptions,
39
- overrides: config.middleware?.override,
28
+ middlewareInfo,
29
+ options,
30
+ overrides: {
31
+ ...config.middleware.override,
32
+ originResolver: config.middleware.originResolver,
33
+ },
40
34
  defaultConverter: "aws-cloudfront",
41
35
  includeCache: config.dangerous?.enableCacheInterception,
42
36
  additionalExternals: config.edgeExternals,
37
+ onlyBuildOnce: forceOnlyBuildOnce === true,
38
+ name: "middleware",
43
39
  });
44
40
  installDependencies(outputPath, config.middleware?.install);
45
41
  }
@@ -47,9 +43,10 @@ export async function createMiddleware(options) {
47
43
  await buildEdgeBundle({
48
44
  entrypoint: path.join(options.openNextDistDir, "core", "edgeFunctionHandler.js"),
49
45
  outfile: path.join(options.buildDir, "middleware.mjs"),
50
- ...commonMiddlewareOptions,
46
+ middlewareInfo,
47
+ options,
51
48
  onlyBuildOnce: true,
49
+ name: "middleware",
52
50
  });
53
51
  }
54
- return { useMiddleware: true };
55
52
  }
@@ -5,7 +5,7 @@ import { openNextResolvePlugin } from "../plugins/resolve.js";
5
5
  import * as buildHelper from "./helper.js";
6
6
  import { installDependencies } from "./installDeps.js";
7
7
  export async function createRevalidationBundle(options) {
8
- logger.info(`Bundling revalidation function...`);
8
+ logger.info("Bundling revalidation function...");
9
9
  const { appBuildOutputPath, config, outputDir } = options;
10
10
  // Create output folder
11
11
  const outputPath = path.join(outputDir, "revalidation-function");
@@ -1,5 +1,4 @@
1
1
  import fs from "node:fs";
2
- import { createRequire } from "node:module";
3
2
  import path from "node:path";
4
3
  import logger from "../logger.js";
5
4
  import { minifyAll } from "../minimize-js.js";
@@ -11,7 +10,6 @@ import { copyTracedFiles } from "./copyTracedFiles.js";
11
10
  import { generateEdgeBundle } from "./edge/createEdgeBundle.js";
12
11
  import * as buildHelper from "./helper.js";
13
12
  import { installDependencies } from "./installDeps.js";
14
- const require = createRequire(import.meta.url);
15
13
  export async function createServerBundle(options) {
16
14
  const { config } = options;
17
15
  const foundRoutes = new Set();
@@ -27,56 +25,50 @@ export async function createServerBundle(options) {
27
25
  const routes = fnOptions.routes;
28
26
  routes.forEach((route) => foundRoutes.add(route));
29
27
  if (fnOptions.runtime === "edge") {
30
- await generateEdgeBundle(name, config, options, fnOptions);
28
+ await generateEdgeBundle(name, options, fnOptions);
31
29
  }
32
30
  else {
33
- await generateBundle(name, config, options, fnOptions);
31
+ await generateBundle(name, options, fnOptions);
34
32
  }
35
33
  });
36
34
  //TODO: throw an error if not all edge runtime routes has been bundled in a separate function
37
35
  // We build every other function than default before so we know which route there is left
38
36
  await Promise.all(promises);
39
37
  const remainingRoutes = new Set();
40
- const { monorepoRoot, appBuildOutputPath } = options;
38
+ const { appBuildOutputPath, monorepoRoot } = options;
41
39
  const packagePath = path.relative(monorepoRoot, appBuildOutputPath);
42
40
  // Find remaining routes
43
41
  const serverPath = path.join(appBuildOutputPath, ".next", "standalone", packagePath, ".next", "server");
44
42
  // Find app dir routes
45
43
  if (fs.existsSync(path.join(serverPath, "app"))) {
46
44
  const appPath = path.join(serverPath, "app");
47
- buildHelper.traverseFiles(appPath, (file) => {
48
- if (file.endsWith("page.js") || file.endsWith("route.js")) {
49
- const route = `app/${file.replace(/\.js$/, "")}`;
50
- if (!foundRoutes.has(route)) {
51
- remainingRoutes.add(route);
52
- }
45
+ buildHelper.traverseFiles(appPath, ({ relativePath }) => relativePath.endsWith("page.js") || relativePath.endsWith("route.js"), ({ relativePath }) => {
46
+ const route = `app/${relativePath.replace(/\.js$/, "")}`;
47
+ if (!foundRoutes.has(route)) {
48
+ remainingRoutes.add(route);
53
49
  }
54
- return false;
55
- }, () => { });
50
+ });
56
51
  }
57
52
  // Find pages dir routes
58
53
  if (fs.existsSync(path.join(serverPath, "pages"))) {
59
54
  const pagePath = path.join(serverPath, "pages");
60
- buildHelper.traverseFiles(pagePath, (file) => {
61
- if (file.endsWith(".js")) {
62
- const route = `pages/${file.replace(/\.js$/, "")}`;
63
- if (!foundRoutes.has(route)) {
64
- remainingRoutes.add(route);
65
- }
55
+ buildHelper.traverseFiles(pagePath, ({ relativePath }) => relativePath.endsWith(".js"), ({ relativePath }) => {
56
+ const route = `pages/${relativePath.replace(/\.js$/, "")}`;
57
+ if (!foundRoutes.has(route)) {
58
+ remainingRoutes.add(route);
66
59
  }
67
- return false;
68
- }, () => { });
60
+ });
69
61
  }
70
62
  // Generate default function
71
- await generateBundle("default", config, options, {
63
+ await generateBundle("default", options, {
72
64
  ...defaultFn,
73
65
  // @ts-expect-error - Those string are RouteTemplate
74
66
  routes: Array.from(remainingRoutes),
75
67
  patterns: ["*"],
76
68
  });
77
69
  }
78
- async function generateBundle(name, config, options, fnOptions) {
79
- const { appPath, appBuildOutputPath, outputDir, monorepoRoot } = options;
70
+ async function generateBundle(name, options, fnOptions) {
71
+ const { appPath, appBuildOutputPath, config, outputDir, monorepoRoot } = options;
80
72
  logger.info(`Building server function: ${name}...`);
81
73
  // Create output folder
82
74
  const outputPath = path.join(outputDir, "server-functions", name);
@@ -96,11 +88,12 @@ async function generateBundle(name, config, options, fnOptions) {
96
88
  // Bundle next server if necessary
97
89
  const isBundled = fnOptions.experimentalBundledNextServer ?? false;
98
90
  if (isBundled) {
99
- await bundleNextServer(path.join(outputPath, packagePath), appPath);
91
+ await bundleNextServer(path.join(outputPath, packagePath), appPath, {
92
+ debug: options.debug,
93
+ });
100
94
  }
101
95
  // Copy middleware
102
- if (!config.middleware?.external &&
103
- fs.existsSync(path.join(options.buildDir, "middleware.mjs"))) {
96
+ if (!config.middleware?.external) {
104
97
  fs.copyFileSync(path.join(options.buildDir, "middleware.mjs"), path.join(outputPath, packagePath, "middleware.mjs"));
105
98
  }
106
99
  // Copy open-next.config.mjs
@@ -123,12 +116,10 @@ async function generateBundle(name, config, options, fnOptions) {
123
116
  openNextReplacementPlugin({
124
117
  name: `requestHandlerOverride ${name}`,
125
118
  target: /core(\/|\\)requestHandler\.js/g,
126
- deletes: disableNextPrebundledReact ? ["applyNextjsPrebundledReact"] : [],
127
- replacements: disableRouting
128
- ? [
129
- require.resolve("../adapters/plugins/without-routing/requestHandler.js"),
130
- ]
131
- : [],
119
+ deletes: [
120
+ ...(disableNextPrebundledReact ? ["applyNextjsPrebundledReact"] : []),
121
+ ...(disableRouting ? ["withRouting"] : []),
122
+ ],
132
123
  }),
133
124
  openNextReplacementPlugin({
134
125
  name: `utilOverride ${name}`,
@@ -137,20 +128,16 @@ async function generateBundle(name, config, options, fnOptions) {
137
128
  ...(disableNextPrebundledReact ? ["requireHooks"] : []),
138
129
  ...(disableRouting ? ["trustHostHeader"] : []),
139
130
  ...(!isBefore13413 ? ["requestHandlerHost"] : []),
140
- ...(!isAfter141 ? ["stableIncrementalCache"] : []),
141
- ...(isAfter141 ? ["experimentalIncrementalCacheHandler"] : []),
131
+ ...(isAfter141
132
+ ? ["experimentalIncrementalCacheHandler"]
133
+ : ["stableIncrementalCache"]),
142
134
  ],
143
135
  }),
144
136
  openNextResolvePlugin({
145
137
  fnName: name,
146
- overrides: overrides,
138
+ overrides,
147
139
  }),
148
140
  ];
149
- if (plugins && plugins.length > 0) {
150
- logger.debug(`Applying plugins:: [${plugins
151
- .map(({ name }) => name)
152
- .join(",")}] for Next version: ${options.nextVersion}`);
153
- }
154
141
  const outfileExt = fnOptions.runtime === "deno" ? "ts" : "mjs";
155
142
  await buildHelper.esbuildAsync({
156
143
  entryPoints: [
@@ -172,9 +159,11 @@ async function generateBundle(name, config, options, fnOptions) {
172
159
  },
173
160
  plugins,
174
161
  alias: {
175
- "next/dist/server/next-server.js": isBundled
176
- ? "./next-server.runtime.prod.js"
177
- : "next/dist/server/next-server.js",
162
+ ...(isBundled
163
+ ? {
164
+ "next/dist/server/next-server.js": "./next-server.runtime.prod.js",
165
+ }
166
+ : {}),
178
167
  },
179
168
  }, options);
180
169
  if (isMonorepo) {
@@ -222,7 +211,7 @@ function addMonorepoEntrypoint(outputPath, packagePath) {
222
211
  fs.writeFileSync(path.join(outputPath, "index.mjs"), [`export * from "./${packagePosixPath}/index.mjs";`].join(""));
223
212
  }
224
213
  async function minifyServerBundle(outputDir) {
225
- logger.info(`Minimizing server function...`);
214
+ logger.info("Minimizing server function...");
226
215
  await minifyAll(outputDir, {
227
216
  compress_json: true,
228
217
  mangle: true,
@@ -5,7 +5,7 @@ import { openNextResolvePlugin } from "../plugins/resolve.js";
5
5
  import * as buildHelper from "./helper.js";
6
6
  import { installDependencies } from "./installDeps.js";
7
7
  export async function createWarmerBundle(options) {
8
- logger.info(`Bundling warmer function...`);
8
+ logger.info("Bundling warmer function...");
9
9
  const { config, outputDir } = options;
10
10
  // Create output folder
11
11
  const outputPath = path.join(outputDir, "warmer-function");
@@ -1,20 +1,22 @@
1
1
  import type { MiddlewareInfo } from "../../types/next-types";
2
- import type { IncludedConverter, OpenNextConfig, OverrideOptions, SplittedFunctionOptions } from "../../types/open-next";
2
+ import type { IncludedConverter, IncludedOriginResolver, LazyLoadedOverride, OverrideOptions, SplittedFunctionOptions } from "../../types/open-next";
3
+ import type { OriginResolver } from "../../types/overrides.js";
3
4
  import type { BuildOptions } from "../helper.js";
4
5
  interface BuildEdgeBundleOptions {
5
- appBuildOutputPath: string;
6
- middlewareInfo: MiddlewareInfo;
6
+ middlewareInfo?: MiddlewareInfo;
7
7
  entrypoint: string;
8
8
  outfile: string;
9
9
  options: BuildOptions;
10
- overrides?: OverrideOptions;
10
+ overrides?: OverrideOptions & {
11
+ originResolver?: LazyLoadedOverride<OriginResolver> | IncludedOriginResolver;
12
+ };
11
13
  defaultConverter?: IncludedConverter;
12
14
  additionalInject?: string;
13
15
  includeCache?: boolean;
14
16
  additionalExternals?: string[];
15
17
  onlyBuildOnce?: boolean;
18
+ name: string;
16
19
  }
17
- export declare function buildEdgeBundle({ appBuildOutputPath, middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, }: BuildEdgeBundleOptions): Promise<void>;
18
- export declare function copyMiddlewareAssetsAndWasm({}: {}): void;
19
- export declare function generateEdgeBundle(name: string, config: OpenNextConfig, options: BuildOptions, fnOptions: SplittedFunctionOptions): Promise<void>;
20
+ export declare function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, }: BuildEdgeBundleOptions): Promise<void>;
21
+ export declare function generateEdgeBundle(name: string, options: BuildOptions, fnOptions: SplittedFunctionOptions): Promise<void>;
20
22
  export {};
@@ -1,19 +1,18 @@
1
1
  import { mkdirSync } from "node:fs";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
2
4
  import { build } from "esbuild";
3
- import fs from "fs";
4
- import path from "path";
5
5
  import logger from "../../logger.js";
6
6
  import { openNextEdgePlugins } from "../../plugins/edge.js";
7
7
  import { openNextReplacementPlugin } from "../../plugins/replacement.js";
8
8
  import { openNextResolvePlugin } from "../../plugins/resolve.js";
9
9
  import { copyOpenNextConfig, esbuildAsync } from "../helper.js";
10
- export async function buildEdgeBundle({ appBuildOutputPath, middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, }) {
10
+ export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, }) {
11
11
  const isInCloudfare = typeof overrides?.wrapper === "string"
12
12
  ? overrides.wrapper === "cloudflare"
13
13
  : (await overrides?.wrapper?.())?.edgeRuntime;
14
14
  await esbuildAsync({
15
15
  entryPoints: [entrypoint],
16
- // inject: ,
17
16
  bundle: true,
18
17
  outfile,
19
18
  external: ["node:*", "next", "@aws-sdk/*"],
@@ -41,7 +40,14 @@ export async function buildEdgeBundle({ appBuildOutputPath, middlewareInfo, entr
41
40
  : "sqs-lite",
42
41
  }
43
42
  : {}),
43
+ originResolver: typeof overrides?.originResolver === "string"
44
+ ? overrides.originResolver
45
+ : "pattern-env",
46
+ proxyExternalRequest: typeof overrides?.proxyExternalRequest === "string"
47
+ ? overrides.proxyExternalRequest
48
+ : "node",
44
49
  },
50
+ fnName: name,
45
51
  }),
46
52
  openNextReplacementPlugin({
47
53
  name: "externalMiddlewareOverrides",
@@ -50,7 +56,7 @@ export async function buildEdgeBundle({ appBuildOutputPath, middlewareInfo, entr
50
56
  }),
51
57
  openNextEdgePlugins({
52
58
  middlewareInfo,
53
- nextDir: path.join(appBuildOutputPath, ".next"),
59
+ nextDir: path.join(options.appBuildOutputPath, ".next"),
54
60
  edgeFunctionHandlerPath: path.join(options.openNextDistDir, "core", "edgeFunctionHandler.js"),
55
61
  isInCloudfare,
56
62
  }),
@@ -95,7 +101,7 @@ globalThis.AsyncLocalStorage = AsyncLocalStorage;
95
101
  outfile,
96
102
  allowOverwrite: true,
97
103
  bundle: true,
98
- minify: true,
104
+ minify: !options.debug,
99
105
  platform: "node",
100
106
  format: "esm",
101
107
  conditions: ["workerd", "worker", "browser"],
@@ -106,8 +112,7 @@ globalThis.AsyncLocalStorage = AsyncLocalStorage;
106
112
  });
107
113
  }
108
114
  }
109
- export function copyMiddlewareAssetsAndWasm({}) { }
110
- export async function generateEdgeBundle(name, config, options, fnOptions) {
115
+ export async function generateEdgeBundle(name, options, fnOptions) {
111
116
  const { appBuildOutputPath, outputDir } = options;
112
117
  logger.info(`Generating edge bundle for: ${name}`);
113
118
  // Create output folder
@@ -122,26 +127,26 @@ export async function generateEdgeBundle(name, config, options, fnOptions) {
122
127
  if (functions.length > 1) {
123
128
  throw new Error("Only one function is supported for now");
124
129
  }
125
- const fn = functions[0];
130
+ const middlewareInfo = functions[0];
126
131
  //Copy wasm files
127
- const wasmFiles = fn.wasm;
132
+ const wasmFiles = middlewareInfo.wasm;
128
133
  mkdirSync(path.join(outputPath, "wasm"), { recursive: true });
129
134
  for (const wasmFile of wasmFiles) {
130
135
  fs.copyFileSync(path.join(appBuildOutputPath, ".next", wasmFile.filePath), path.join(outputPath, `wasm/${wasmFile.name}.wasm`));
131
136
  }
132
137
  // Copy assets
133
- const assets = fn.assets;
138
+ const assets = middlewareInfo.assets;
134
139
  mkdirSync(path.join(outputPath, "assets"), { recursive: true });
135
140
  for (const asset of assets) {
136
141
  fs.copyFileSync(path.join(appBuildOutputPath, ".next", asset.filePath), path.join(outputPath, `assets/${asset.name}`));
137
142
  }
138
143
  await buildEdgeBundle({
139
- appBuildOutputPath,
140
- middlewareInfo: fn,
144
+ middlewareInfo,
141
145
  entrypoint: path.join(options.openNextDistDir, "adapters", "edge-adapter.js"),
142
146
  outfile: path.join(outputPath, "index.mjs"),
143
147
  options,
144
148
  overrides: fnOptions.override,
145
- additionalExternals: config.edgeExternals,
149
+ additionalExternals: options.config.edgeExternals,
150
+ name,
146
151
  });
147
152
  }