@opennextjs/aws 3.2.1 → 3.3.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.
Files changed (155) hide show
  1. package/README.md +21 -2
  2. package/dist/adapters/cache.d.ts +0 -23
  3. package/dist/adapters/cache.js +10 -12
  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.d.ts +1 -2
  10. package/dist/adapters/image-optimization-adapter.js +4 -4
  11. package/dist/adapters/logger.d.ts +0 -3
  12. package/dist/adapters/logger.js +32 -13
  13. package/dist/adapters/middleware.js +42 -18
  14. package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +1 -3
  15. package/dist/adapters/plugins/image-optimization/image-optimization.js +0 -1
  16. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +1 -3
  17. package/dist/adapters/revalidate.js +2 -2
  18. package/dist/adapters/server-adapter.d.ts +0 -3
  19. package/dist/adapters/server-adapter.js +3 -1
  20. package/dist/adapters/util.js +2 -2
  21. package/dist/build/bundleNextServer.d.ts +3 -1
  22. package/dist/build/bundleNextServer.js +3 -3
  23. package/dist/build/compileConfig.js +1 -1
  24. package/dist/build/copyTracedFiles.js +15 -26
  25. package/dist/build/createAssets.js +36 -27
  26. package/dist/build/createImageOptimizationBundle.js +1 -1
  27. package/dist/build/createMiddleware.js +8 -3
  28. package/dist/build/createRevalidationBundle.js +1 -1
  29. package/dist/build/createServerBundle.js +25 -31
  30. package/dist/build/createWarmerBundle.js +1 -1
  31. package/dist/build/edge/createEdgeBundle.d.ts +8 -4
  32. package/dist/build/edge/createEdgeBundle.js +34 -16
  33. package/dist/build/generateOutput.js +7 -13
  34. package/dist/build/helper.d.ts +28 -5
  35. package/dist/build/helper.js +44 -15
  36. package/dist/build/installDeps.js +1 -1
  37. package/dist/build/patch/patchedAsyncStorage.js +1 -1
  38. package/dist/build/utils.js +3 -2
  39. package/dist/build/validateConfig.js +4 -1
  40. package/dist/core/createGenericHandler.d.ts +2 -4
  41. package/dist/core/createGenericHandler.js +1 -2
  42. package/dist/core/createMainHandler.d.ts +0 -17
  43. package/dist/core/createMainHandler.js +5 -4
  44. package/dist/core/edgeFunctionHandler.d.ts +1 -51
  45. package/dist/core/patchAsyncStorage.js +5 -6
  46. package/dist/core/requestHandler.d.ts +1 -2
  47. package/dist/core/requestHandler.js +99 -90
  48. package/dist/core/require-hooks.js +8 -7
  49. package/dist/core/resolve.d.ts +13 -7
  50. package/dist/core/resolve.js +29 -35
  51. package/dist/core/routing/cacheInterceptor.js +12 -13
  52. package/dist/core/routing/i18n/accept-header.js +3 -2
  53. package/dist/core/routing/matcher.d.ts +2 -4
  54. package/dist/core/routing/matcher.js +18 -27
  55. package/dist/core/routing/middleware.d.ts +3 -3
  56. package/dist/core/routing/middleware.js +20 -20
  57. package/dist/core/routing/util.d.ts +2 -15
  58. package/dist/core/routing/util.js +26 -88
  59. package/dist/core/routingHandler.d.ts +4 -8
  60. package/dist/core/routingHandler.js +36 -18
  61. package/dist/core/util.js +5 -3
  62. package/dist/helpers/withCloudflare.d.ts +1 -1
  63. package/dist/helpers/withCloudflare.js +2 -2
  64. package/dist/helpers/withSST.d.ts +1 -1
  65. package/dist/http/openNextResponse.d.ts +6 -18
  66. package/dist/http/openNextResponse.js +32 -32
  67. package/dist/http/request.d.ts +0 -3
  68. package/dist/http/request.js +4 -2
  69. package/dist/http/util.d.ts +1 -1
  70. package/dist/http/util.js +8 -12
  71. package/dist/minimize-js.js +19 -19
  72. package/dist/overrides/converters/aws-apigw-v1.d.ts +2 -2
  73. package/dist/overrides/converters/aws-apigw-v1.js +2 -1
  74. package/dist/overrides/converters/aws-apigw-v2.d.ts +2 -2
  75. package/dist/overrides/converters/aws-apigw-v2.js +8 -8
  76. package/dist/overrides/converters/aws-cloudfront.d.ts +2 -2
  77. package/dist/overrides/converters/aws-cloudfront.js +11 -30
  78. package/dist/overrides/converters/dummy.d.ts +1 -1
  79. package/dist/overrides/converters/edge.d.ts +3 -5
  80. package/dist/overrides/converters/edge.js +15 -18
  81. package/dist/overrides/converters/node.d.ts +1 -1
  82. package/dist/overrides/converters/node.js +1 -1
  83. package/dist/overrides/converters/sqs-revalidate.d.ts +1 -1
  84. package/dist/overrides/imageLoader/dummy.d.ts +1 -1
  85. package/dist/overrides/imageLoader/host.d.ts +1 -1
  86. package/dist/overrides/imageLoader/s3.d.ts +1 -1
  87. package/dist/overrides/imageLoader/s3.js +1 -1
  88. package/dist/overrides/incrementalCache/dummy.d.ts +1 -1
  89. package/dist/overrides/incrementalCache/dummy.js +4 -3
  90. package/dist/overrides/incrementalCache/s3-lite.d.ts +1 -1
  91. package/dist/overrides/incrementalCache/s3-lite.js +15 -19
  92. package/dist/overrides/incrementalCache/s3.d.ts +1 -1
  93. package/dist/overrides/incrementalCache/s3.js +1 -1
  94. package/dist/overrides/originResolver/dummy.d.ts +1 -1
  95. package/dist/overrides/originResolver/pattern-env.d.ts +1 -1
  96. package/dist/overrides/originResolver/pattern-env.js +10 -11
  97. package/dist/overrides/proxyExternalRequest/dummy.d.ts +3 -0
  98. package/dist/overrides/proxyExternalRequest/dummy.js +8 -0
  99. package/dist/overrides/proxyExternalRequest/fetch.d.ts +3 -0
  100. package/dist/overrides/proxyExternalRequest/fetch.js +25 -0
  101. package/dist/overrides/proxyExternalRequest/node.d.ts +3 -0
  102. package/dist/overrides/proxyExternalRequest/node.js +67 -0
  103. package/dist/overrides/queue/dummy.d.ts +1 -1
  104. package/dist/overrides/queue/dummy.js +2 -1
  105. package/dist/overrides/queue/sqs-lite.d.ts +1 -1
  106. package/dist/overrides/queue/sqs-lite.js +7 -9
  107. package/dist/overrides/queue/sqs.d.ts +1 -1
  108. package/dist/overrides/queue/sqs.js +1 -1
  109. package/dist/overrides/tagCache/constants.js +2 -2
  110. package/dist/overrides/tagCache/dummy.d.ts +1 -1
  111. package/dist/overrides/tagCache/dynamodb-lite.d.ts +1 -1
  112. package/dist/overrides/tagCache/dynamodb-lite.js +10 -12
  113. package/dist/overrides/tagCache/dynamodb.d.ts +1 -1
  114. package/dist/overrides/tagCache/dynamodb.js +2 -2
  115. package/dist/overrides/warmer/aws-lambda.d.ts +1 -1
  116. package/dist/overrides/warmer/dummy.d.ts +1 -1
  117. package/dist/overrides/warmer/dummy.js +2 -1
  118. package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +3 -3
  119. package/dist/overrides/wrappers/aws-lambda-streaming.js +0 -4
  120. package/dist/overrides/wrappers/aws-lambda.d.ts +2 -2
  121. package/dist/overrides/wrappers/aws-lambda.js +0 -3
  122. package/dist/overrides/wrappers/cloudflare-edge.d.ts +9 -0
  123. package/dist/overrides/wrappers/cloudflare-edge.js +38 -0
  124. package/dist/overrides/wrappers/cloudflare-node.d.ts +8 -0
  125. package/dist/overrides/wrappers/cloudflare-node.js +47 -0
  126. package/dist/overrides/wrappers/dummy.d.ts +3 -3
  127. package/dist/overrides/wrappers/dummy.js +1 -1
  128. package/dist/overrides/wrappers/node.d.ts +3 -3
  129. package/dist/overrides/wrappers/node.js +3 -6
  130. package/dist/plugins/edge.js +6 -5
  131. package/dist/plugins/replacement.js +2 -2
  132. package/dist/plugins/resolve.d.ts +3 -1
  133. package/dist/plugins/resolve.js +9 -2
  134. package/dist/types/aws-lambda.d.ts +2 -5
  135. package/dist/types/cache.d.ts +0 -2
  136. package/dist/types/global.d.ts +188 -0
  137. package/dist/types/next-types.d.ts +1 -3
  138. package/dist/types/open-next.d.ts +33 -41
  139. package/dist/types/overrides.d.ts +86 -0
  140. package/dist/{adapters → utils}/binary.js +1 -0
  141. package/dist/utils/error.d.ts +1 -0
  142. package/dist/utils/error.js +8 -0
  143. package/dist/utils/promise.d.ts +3 -0
  144. package/dist/utils/promise.js +44 -0
  145. package/dist/utils/stream.d.ts +0 -1
  146. package/package.json +3 -3
  147. package/dist/overrides/incrementalCache/types.d.ts +0 -34
  148. package/dist/overrides/queue/types.d.ts +0 -12
  149. package/dist/overrides/tagCache/types.d.ts +0 -11
  150. package/dist/overrides/tagCache/types.js +0 -1
  151. package/dist/overrides/wrappers/cloudflare.d.ts +0 -11
  152. package/dist/overrides/wrappers/cloudflare.js +0 -20
  153. /package/dist/{overrides/incrementalCache/types.js → types/global.js} +0 -0
  154. /package/dist/{overrides/queue/types.js → types/overrides.js} +0 -0
  155. /package/dist/{adapters → utils}/binary.d.ts +0 -0
@@ -21,6 +21,7 @@ export function normalizeOptions(config, distDir, tempBuildDir) {
21
21
  else {
22
22
  appPackageJsonPath = findNextPackageJsonPath(appPath, monorepoRoot);
23
23
  }
24
+ const debug = Boolean(process.env.OPEN_NEXT_DEBUG) ?? false;
24
25
  return {
25
26
  appBuildOutputPath: buildOutputPath,
26
27
  appPackageJsonPath,
@@ -28,7 +29,9 @@ export function normalizeOptions(config, distDir, tempBuildDir) {
28
29
  appPublicPath: path.join(appPath, "public"),
29
30
  buildDir: path.join(outputDir, ".build"),
30
31
  config,
31
- debug: Boolean(process.env.OPEN_NEXT_DEBUG) ?? false,
32
+ debug,
33
+ // Whether ESBuild should minify the code
34
+ minify: !debug,
32
35
  monorepoRoot,
33
36
  nextVersion: getNextVersion(appPath),
34
37
  openNextVersion: getOpenNextVersion(),
@@ -68,13 +71,13 @@ function findNextPackageJsonPath(appPath, root) {
68
71
  : path.join(root, "./package.json");
69
72
  }
70
73
  export function esbuildSync(esbuildOptions, options) {
71
- const { openNextVersion, debug } = options;
74
+ const { openNextVersion, debug, minify } = options;
72
75
  const result = buildSync({
73
76
  target: "esnext",
74
77
  format: "esm",
75
78
  platform: "node",
76
79
  bundle: true,
77
- minify: debug ? false : true,
80
+ minify,
78
81
  mainFields: ["module", "main"],
79
82
  sourcemap: debug ? "inline" : false,
80
83
  sourcesContent: false,
@@ -95,13 +98,13 @@ export function esbuildSync(esbuildOptions, options) {
95
98
  }
96
99
  }
97
100
  export async function esbuildAsync(esbuildOptions, options) {
98
- const { openNextVersion, debug } = options;
101
+ const { openNextVersion, debug, minify } = options;
99
102
  const result = await buildAsync({
100
103
  target: "esnext",
101
104
  format: "esm",
102
105
  platform: "node",
103
106
  bundle: true,
104
- minify: debug ? false : true,
107
+ minify,
105
108
  mainFields: ["module", "main"],
106
109
  sourcemap: debug ? "inline" : false,
107
110
  sourcesContent: false,
@@ -125,28 +128,40 @@ export async function esbuildAsync(esbuildOptions, options) {
125
128
  throw new Error(`There was a problem bundling ${esbuildOptions.entryPoints[0]}.`);
126
129
  }
127
130
  }
128
- export function removeFiles(root, conditionFn, searchingDir = "") {
129
- traverseFiles(root, conditionFn, (filePath) => fs.rmSync(filePath, { force: true }), searchingDir);
130
- }
131
131
  /**
132
132
  * Recursively traverse files in a directory and call `callbackFn` when `conditionFn` returns true
133
+ *
134
+ * The callbacks are passed both the absolute and relative (to root) path to files.
135
+ *
133
136
  * @param root - Root directory to search
134
- * @param conditionFn - Called to determine if `callbackFn` should be called
135
- * @param callbackFn - Called when `conditionFn` returns true
137
+ * @param conditionFn - Called to determine if `callbackFn` should be called.
138
+ * @param callbackFn - Called when `conditionFn` returns true.
136
139
  * @param searchingDir - Directory to search (used for recursion)
137
140
  */
138
141
  export function traverseFiles(root, conditionFn, callbackFn, searchingDir = "") {
139
142
  fs.readdirSync(path.join(root, searchingDir)).forEach((file) => {
140
- const filePath = path.join(root, searchingDir, file);
141
- if (fs.statSync(filePath).isDirectory()) {
142
- traverseFiles(root, conditionFn, callbackFn, path.join(searchingDir, file));
143
+ const relativePath = path.join(searchingDir, file);
144
+ const absolutePath = path.join(root, relativePath);
145
+ if (fs.statSync(absolutePath).isDirectory()) {
146
+ traverseFiles(root, conditionFn, callbackFn, relativePath);
143
147
  return;
144
148
  }
145
- if (conditionFn(path.join(searchingDir, file))) {
146
- callbackFn(filePath);
149
+ if (conditionFn({ absolutePath, relativePath })) {
150
+ callbackFn({ absolutePath, relativePath });
147
151
  }
148
152
  });
149
153
  }
154
+ /**
155
+ * Recursively delete files.
156
+ *
157
+ * @see `traverseFiles`.
158
+ *
159
+ * @param root Root directory to search.
160
+ * @param conditionFn Predicate used to delete the files.
161
+ */
162
+ export function removeFiles(root, conditionFn) {
163
+ traverseFiles(root, conditionFn, ({ absolutePath }) => fs.rmSync(absolutePath, { force: true }));
164
+ }
150
165
  export function getHtmlPages(dotNextPath) {
151
166
  // Get a list of HTML pages
152
167
  //
@@ -187,9 +202,11 @@ export function compareSemver(v1, v2) {
187
202
  if (v1 === "latest")
188
203
  return 1;
189
204
  if (/^[^\d]/.test(v1)) {
205
+ // biome-ignore lint/style/noParameterAssign:
190
206
  v1 = v1.substring(1);
191
207
  }
192
208
  if (/^[^\d]/.test(v2)) {
209
+ // biome-ignore lint/style/noParameterAssign:
193
210
  v2 = v2.substring(1);
194
211
  }
195
212
  const [major1, minor1, patch1] = v1.split(".").map(Number);
@@ -247,3 +264,15 @@ export function initOutputDir(options) {
247
264
  fs.mkdirSync(buildDir, { recursive: true });
248
265
  fs.cpSync(options.tempBuildDir, buildDir, { recursive: true });
249
266
  }
267
+ /**
268
+ * @returns Whether the edge runtime is used
269
+ */
270
+ export async function isEdgeRuntime(overrides) {
271
+ if (!overrides?.wrapper) {
272
+ return false;
273
+ }
274
+ if (typeof overrides.wrapper === "string") {
275
+ return ["cloudflare-edge", "cloudflare"].includes(overrides.wrapper);
276
+ }
277
+ return (await overrides?.wrapper?.())?.edgeRuntime;
278
+ }
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import { execSync } from "child_process";
4
+ import { execSync } from "node:child_process";
5
5
  import logger from "../logger.js";
6
6
  export function installDependencies(outputDir, installOptions) {
7
7
  try {
@@ -8,7 +8,7 @@ const staticGenerationAsyncStorage = {
8
8
  if (store) {
9
9
  store.isOnDemandRevalidate =
10
10
  store.isOnDemandRevalidate &&
11
- !globalThis.__als.getStore().isISRRevalidation;
11
+ !globalThis.__openNextAls.getStore().isISRRevalidation;
12
12
  }
13
13
  return store;
14
14
  },
@@ -1,12 +1,13 @@
1
1
  import os from "node:os";
2
2
  import logger from "../logger.js";
3
3
  export function printHeader(header) {
4
+ // biome-ignore lint/style/noParameterAssign:
4
5
  header = `OpenNext — ${header}`;
5
6
  logger.info([
6
7
  "",
7
- "┌" + "─".repeat(header.length + 2) + "┐",
8
+ `┌${"─".repeat(header.length + 2)}┐`,
8
9
  `│ ${header} │`,
9
- "└" + "─".repeat(header.length + 2) + "┘",
10
+ `└${"─".repeat(header.length + 2)}┘`,
10
11
  "",
11
12
  ].join("\n"));
12
13
  }
@@ -8,7 +8,10 @@ const compatibilityMatrix = {
8
8
  ],
9
9
  "aws-lambda-streaming": ["aws-apigw-v2"],
10
10
  cloudflare: ["edge"],
11
+ "cloudflare-edge": ["edge"],
12
+ "cloudflare-node": ["edge"],
11
13
  node: ["node"],
14
+ dummy: [],
12
15
  };
13
16
  function validateFunctionOptions(fnOptions) {
14
17
  if (fnOptions.runtime === "edge" && fnOptions.experimentalBundledNextServer) {
@@ -62,7 +65,7 @@ export function validateConfig(config) {
62
65
  logger.warn("You've disabled incremental cache. This means that ISR and SSG will not work.");
63
66
  }
64
67
  if (config.dangerous?.disableTagCache) {
65
- logger.warn(`You've disabled tag cache.
68
+ logger.warn(`You've disabled tag cache.
66
69
  This means that revalidatePath and revalidateTag from next/cache will not work.
67
70
  It is safe to disable if you only use page router`);
68
71
  }
@@ -1,7 +1,5 @@
1
- import type { BaseEventOrResult, InternalEvent, InternalResult, OpenNextConfig, OpenNextHandler } from "../types/open-next";
2
- declare global {
3
- var openNextConfig: Partial<OpenNextConfig>;
4
- }
1
+ import type { BaseEventOrResult, InternalEvent, InternalResult } from "../types/open-next";
2
+ import type { OpenNextHandler } from "../types/overrides";
5
3
  type HandlerType = "imageOptimization" | "revalidate" | "warmer" | "middleware" | "initializationFunction";
6
4
  type GenericHandler<Type extends HandlerType, E extends BaseEventOrResult = InternalEvent, R extends BaseEventOrResult = InternalResult> = {
7
5
  handler: OpenNextHandler<E, R>;
@@ -1,8 +1,7 @@
1
1
  import { debug } from "../adapters/logger";
2
2
  import { resolveConverter, resolveWrapper } from "./resolve";
3
3
  export async function createGenericHandler(handler) {
4
- //First we load the config
5
- // @ts-expect-error
4
+ // @ts-expect-error `./open-next.config.mjs` exists only in the build output
6
5
  const config = await import("./open-next.config.mjs").then((m) => m.default);
7
6
  globalThis.openNextConfig = config;
8
7
  const override = config[handler.type]
@@ -1,18 +1 @@
1
- /// <reference types="node" />
2
- import type { AsyncLocalStorage } from "node:async_hooks";
3
- import type { DetachedPromiseRunner } from "../utils/promise";
4
- import type { IncrementalCache } from "../overrides/incrementalCache/types";
5
- import type { Queue } from "../overrides/queue/types";
6
- declare global {
7
- var queue: Queue;
8
- var incrementalCache: IncrementalCache;
9
- var fnName: string | undefined;
10
- var serverId: string;
11
- var __als: AsyncLocalStorage<{
12
- requestId: string;
13
- pendingPromiseRunner: DetachedPromiseRunner;
14
- isISRRevalidation?: boolean;
15
- mergeHeadersPriority?: "middleware" | "handler";
16
- }>;
17
- }
18
1
  export declare function createMainHandler(): Promise<(...args: any[]) => any>;
@@ -1,10 +1,10 @@
1
1
  import { debug } from "../adapters/logger";
2
2
  import { generateUniqueId } from "../adapters/util";
3
- import { openNextHandler } from "./requestHandler.js";
4
- import { resolveConverter, resolveIncrementalCache, resolveQueue, resolveTagCache, resolveWrapper, } from "./resolve";
3
+ import { openNextHandler } from "./requestHandler";
4
+ import { resolveConverter, resolveIncrementalCache, resolveProxyRequest, resolveQueue, resolveTagCache, resolveWrapper, } from "./resolve";
5
5
  export async function createMainHandler() {
6
- //First we load the config
7
- const config = await import(process.cwd() + "/open-next.config.mjs").then((m) => m.default);
6
+ // @ts-expect-error `./open-next.config.mjs` exists only in the build output
7
+ const config = await import("./open-next.config.mjs").then((m) => m.default);
8
8
  const thisFunction = globalThis.fnName
9
9
  ? config.functions[globalThis.fnName]
10
10
  : config.default;
@@ -14,6 +14,7 @@ export async function createMainHandler() {
14
14
  globalThis.queue = await resolveQueue(thisFunction.override?.queue);
15
15
  globalThis.incrementalCache = await resolveIncrementalCache(thisFunction.override?.incrementalCache);
16
16
  globalThis.tagCache = await resolveTagCache(thisFunction.override?.tagCache);
17
+ globalThis.proxyExternalRequest = await resolveProxyRequest(thisFunction.override?.proxyExternalRequest);
17
18
  globalThis.lastModified = {};
18
19
  // From the config, we create the converter
19
20
  const converter = await resolveConverter(thisFunction.override?.converter);
@@ -1,54 +1,4 @@
1
- /// <reference types="node" />
2
- import type { OutgoingHttpHeaders } from "http";
3
- interface RequestData {
4
- geo?: {
5
- city?: string;
6
- country?: string;
7
- region?: string;
8
- latitude?: string;
9
- longitude?: string;
10
- };
11
- headers: OutgoingHttpHeaders;
12
- ip?: string;
13
- method: string;
14
- nextConfig?: {
15
- basePath?: string;
16
- i18n?: any;
17
- trailingSlash?: boolean;
18
- };
19
- page?: {
20
- name?: string;
21
- params?: {
22
- [key: string]: string | string[];
23
- };
24
- };
25
- url: string;
26
- body?: ReadableStream<Uint8Array>;
27
- signal: AbortSignal;
28
- }
29
- interface Entries {
30
- [k: string]: {
31
- default: (props: {
32
- page: string;
33
- request: RequestData;
34
- }) => Promise<{
35
- response: Response;
36
- waitUntil: Promise<void>;
37
- }>;
38
- };
39
- }
40
- declare global {
41
- var _ENTRIES: Entries;
42
- var _ROUTES: EdgeRoute[];
43
- var __storage__: Map<unknown, unknown>;
44
- var AsyncContext: any;
45
- var AsyncLocalStorage: any;
46
- }
47
- export interface EdgeRoute {
48
- name: string;
49
- page: string;
50
- regex: string[];
51
- }
1
+ import type { RequestData } from "../types/global";
52
2
  type EdgeRequest = Omit<RequestData, "page">;
53
3
  export default function edgeFunctionHandler(request: EdgeRequest): Promise<Response>;
54
4
  export {};
@@ -1,16 +1,15 @@
1
- const mod = require("module");
1
+ const mod = require("node:module");
2
2
  const resolveFilename = mod._resolveFilename;
3
3
  export function patchAsyncStorage() {
4
- mod._resolveFilename = function (originalResolveFilename, request, parent, isMain, options) {
4
+ mod._resolveFilename = ((originalResolveFilename, request, parent, isMain, options) => {
5
5
  if (request.endsWith("static-generation-async-storage.external") ||
6
6
  request.endsWith("static-generation-async-storage.external.js")) {
7
7
  return require.resolve("./patchedAsyncStorage.cjs");
8
8
  }
9
- else if (request.endsWith("static-generation-async-storage.external.original")) {
9
+ if (request.endsWith("static-generation-async-storage.external.original")) {
10
10
  return originalResolveFilename.call(mod, request.replace(".original", ".js"), parent, isMain, options);
11
11
  }
12
- else
13
- return originalResolveFilename.call(mod, request, parent, isMain, options);
12
+ return originalResolveFilename.call(mod, request, parent, isMain, options);
14
13
  // We use `bind` here to avoid referencing outside variables to create potential memory leaks.
15
- }.bind(null, resolveFilename);
14
+ }).bind(null, resolveFilename);
16
15
  }
@@ -1,3 +1,2 @@
1
- import type { StreamCreator } from "../http/index.js";
2
- import type { InternalEvent, InternalResult } from "../types/open-next";
1
+ import type { InternalEvent, InternalResult, StreamCreator } from "../types/open-next";
3
2
  export declare function openNextHandler(internalEvent: InternalEvent, responseStreaming?: StreamCreator): Promise<InternalResult>;
@@ -1,66 +1,89 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import { IncomingMessage } from "../http/index.js";
3
- import { DetachedPromiseRunner } from "../utils/promise";
3
+ import { runWithOpenNextRequestContext } from "../utils/promise";
4
4
  import { debug, error, warn } from "../adapters/logger";
5
5
  import { patchAsyncStorage } from "./patchAsyncStorage";
6
- import { convertRes, createServerResponse, proxyRequest } from "./routing/util";
7
- import routingHandler from "./routingHandler";
6
+ import { convertRes, createServerResponse } from "./routing/util";
7
+ import routingHandler, { MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_HEADER_PREFIX_LEN, } from "./routingHandler";
8
8
  import { requestHandler, setNextjsPrebundledReact } from "./util";
9
9
  // This is used to identify requests in the cache
10
- globalThis.__als = new AsyncLocalStorage();
10
+ globalThis.__openNextAls = new AsyncLocalStorage();
11
11
  patchAsyncStorage();
12
12
  export async function openNextHandler(internalEvent, responseStreaming) {
13
- if (internalEvent.headers["x-forwarded-host"]) {
14
- internalEvent.headers.host = internalEvent.headers["x-forwarded-host"];
15
- }
16
- debug("internalEvent", internalEvent);
17
- let preprocessResult = {
18
- internalEvent: internalEvent,
19
- isExternalRewrite: false,
20
- origin: false,
21
- isISR: false,
22
- };
23
- //#override withRouting
24
- try {
25
- preprocessResult = await routingHandler(internalEvent);
26
- }
27
- catch (e) {
28
- warn("Routing failed.", e);
29
- }
30
- //#endOverride
31
- const headers = "type" in preprocessResult
32
- ? preprocessResult.headers
33
- : preprocessResult.internalEvent.headers;
34
- const overwrittenResponseHeaders = Object.entries("type" in preprocessResult
35
- ? preprocessResult.headers
36
- : preprocessResult.internalEvent.headers).reduce((acc, [key, value]) => {
37
- if (!key.startsWith("x-middleware-response-")) {
38
- return acc;
13
+ // We run everything in the async local storage context so that it is available in the middleware as well as in NextServer
14
+ return runWithOpenNextRequestContext({ isISRRevalidation: internalEvent.headers["x-isr"] === "1" }, async () => {
15
+ if (internalEvent.headers["x-forwarded-host"]) {
16
+ internalEvent.headers.host = internalEvent.headers["x-forwarded-host"];
39
17
  }
40
- else {
41
- const newKey = key.replace("x-middleware-response-", "");
42
- delete headers[key];
43
- headers[newKey] = value;
44
- return { ...acc, [newKey]: value };
18
+ debug("internalEvent", internalEvent);
19
+ let routingResult = {
20
+ internalEvent,
21
+ isExternalRewrite: false,
22
+ origin: false,
23
+ isISR: false,
24
+ };
25
+ //#override withRouting
26
+ try {
27
+ routingResult = await routingHandler(internalEvent);
28
+ }
29
+ catch (e) {
30
+ warn("Routing failed.", e);
45
31
  }
46
- }, {});
47
- if ("type" in preprocessResult) {
48
- // // res is used only in the streaming case
49
- if (responseStreaming) {
50
- const res = createServerResponse(internalEvent, headers, responseStreaming);
51
- res.statusCode = preprocessResult.statusCode;
52
- res.flushHeaders();
53
- const [bodyToConsume, bodyToReturn] = preprocessResult.body.tee();
54
- for await (const chunk of bodyToConsume) {
55
- res.write(chunk);
32
+ //#endOverride
33
+ const headers = "type" in routingResult
34
+ ? routingResult.headers
35
+ : routingResult.internalEvent.headers;
36
+ const overwrittenResponseHeaders = {};
37
+ for (const [rawKey, value] of Object.entries(headers)) {
38
+ if (!rawKey.startsWith(MIDDLEWARE_HEADER_PREFIX)) {
39
+ continue;
56
40
  }
57
- res.end();
58
- preprocessResult.body = bodyToReturn;
41
+ const key = rawKey.slice(MIDDLEWARE_HEADER_PREFIX_LEN);
42
+ overwrittenResponseHeaders[key] = value;
43
+ headers[key] = value;
44
+ delete headers[rawKey];
59
45
  }
60
- return preprocessResult;
61
- }
62
- else {
63
- const preprocessedEvent = preprocessResult.internalEvent;
46
+ if ("isExternalRewrite" in routingResult &&
47
+ routingResult.isExternalRewrite === true) {
48
+ try {
49
+ routingResult = await globalThis.proxyExternalRequest.proxy(routingResult.internalEvent);
50
+ }
51
+ catch (e) {
52
+ error("External request failed.", e);
53
+ routingResult = {
54
+ internalEvent: {
55
+ type: "core",
56
+ rawPath: "/500",
57
+ method: "GET",
58
+ headers: {},
59
+ url: "/500",
60
+ query: {},
61
+ cookies: {},
62
+ remoteAddress: "",
63
+ },
64
+ // On error we need to rewrite to the 500 page which is an internal rewrite
65
+ isExternalRewrite: false,
66
+ isISR: false,
67
+ origin: false,
68
+ };
69
+ }
70
+ }
71
+ if ("type" in routingResult) {
72
+ // response is used only in the streaming case
73
+ if (responseStreaming) {
74
+ const response = createServerResponse(internalEvent, headers, responseStreaming);
75
+ response.statusCode = routingResult.statusCode;
76
+ response.flushHeaders();
77
+ const [bodyToConsume, bodyToReturn] = routingResult.body.tee();
78
+ for await (const chunk of bodyToConsume) {
79
+ response.write(chunk);
80
+ }
81
+ response.end();
82
+ routingResult.body = bodyToReturn;
83
+ }
84
+ return routingResult;
85
+ }
86
+ const preprocessedEvent = routingResult.internalEvent;
64
87
  debug("preprocessedEvent", preprocessedEvent);
65
88
  const reqProps = {
66
89
  method: preprocessedEvent.method,
@@ -74,58 +97,44 @@ export async function openNextHandler(internalEvent, responseStreaming) {
74
97
  body: preprocessedEvent.body,
75
98
  remoteAddress: preprocessedEvent.remoteAddress,
76
99
  };
77
- const requestId = Math.random().toString(36);
78
- const pendingPromiseRunner = new DetachedPromiseRunner();
79
- const isISRRevalidation = headers["x-isr"] === "1";
80
100
  const mergeHeadersPriority = globalThis.openNextConfig.dangerous
81
101
  ?.headersAndCookiesPriority
82
102
  ? globalThis.openNextConfig.dangerous.headersAndCookiesPriority(preprocessedEvent)
83
103
  : "middleware";
84
- const internalResult = await globalThis.__als.run({
85
- requestId,
86
- pendingPromiseRunner,
87
- isISRRevalidation,
88
- mergeHeadersPriority,
89
- }, async () => {
90
- const preprocessedResult = preprocessResult;
91
- const req = new IncomingMessage(reqProps);
92
- const res = createServerResponse(preprocessedEvent, overwrittenResponseHeaders, responseStreaming);
93
- await processRequest(req, res, preprocessedEvent, preprocessedResult.isExternalRewrite);
94
- const { statusCode, headers, isBase64Encoded, body } = convertRes(res);
95
- const internalResult = {
96
- type: internalEvent.type,
97
- statusCode,
98
- headers,
99
- body,
100
- isBase64Encoded,
101
- };
104
+ const store = globalThis.__openNextAls.getStore();
105
+ if (store) {
106
+ store.mergeHeadersPriority = mergeHeadersPriority;
107
+ }
108
+ const req = new IncomingMessage(reqProps);
109
+ const res = createServerResponse(preprocessedEvent, overwrittenResponseHeaders, responseStreaming);
110
+ await processRequest(req, res, preprocessedEvent);
111
+ const { statusCode, headers: responseHeaders, isBase64Encoded, body, } = convertRes(res);
112
+ const internalResult = {
113
+ type: internalEvent.type,
114
+ statusCode,
115
+ headers: responseHeaders,
116
+ body,
117
+ isBase64Encoded,
118
+ };
119
+ const requestId = store?.requestId;
120
+ if (requestId) {
102
121
  // reset lastModified. We need to do this to avoid memory leaks
103
122
  delete globalThis.lastModified[requestId];
104
- await pendingPromiseRunner.await();
105
- return internalResult;
106
- });
123
+ }
107
124
  return internalResult;
108
- }
125
+ });
109
126
  }
110
- async function processRequest(req, res, internalEvent, isExternalRewrite) {
127
+ async function processRequest(req, res, internalEvent) {
111
128
  // @ts-ignore
112
129
  // Next.js doesn't parse body if the property exists
113
130
  // https://github.com/dougmoscrop/serverless-http/issues/227
114
131
  delete req.body;
115
132
  try {
116
- // `serverHandler` is replaced at build time depending on user's
117
- // nextjs version to patch Nextjs 13.4.x and future breaking changes.
118
- const { rawPath } = internalEvent;
119
- if (isExternalRewrite) {
120
- return proxyRequest(internalEvent, res);
121
- }
122
- else {
123
- //#override applyNextjsPrebundledReact
124
- setNextjsPrebundledReact(rawPath);
125
- //#endOverride
126
- // Next Server
127
- await requestHandler(req, res);
128
- }
133
+ //#override applyNextjsPrebundledReact
134
+ setNextjsPrebundledReact(internalEvent.rawPath);
135
+ //#endOverride
136
+ // Next Server
137
+ await requestHandler(req, res);
129
138
  }
130
139
  catch (e) {
131
140
  // This might fail when using bundled next, importing won't do the trick either
@@ -3,7 +3,7 @@
3
3
  // Individually compiled modules are as defined for the compilation in bundles/webpack/packages/*.
4
4
  import { error } from "../adapters/logger.js";
5
5
  // This module will only be loaded once per process.
6
- const mod = require("module");
6
+ const mod = require("node:module");
7
7
  const resolveFilename = mod._resolveFilename;
8
8
  const hookPropertyMapApp = new Map();
9
9
  const hookPropertyMapPage = new Map();
@@ -17,7 +17,7 @@ export function overrideHooks(config) {
17
17
  throw e;
18
18
  }
19
19
  }
20
- function addHookAliases(aliases = [], type) {
20
+ function addHookAliases(aliases, type) {
21
21
  for (const [key, value] of aliases) {
22
22
  type === "app"
23
23
  ? hookPropertyMapApp.set(key, value)
@@ -68,12 +68,12 @@ function overrideDefault() {
68
68
  const toResolveMap = (map) => Object.entries(map).map(([key, value]) => [key, require.resolve(value)]);
69
69
  // Override built-in React packages if necessary
70
70
  function overrideReact(config) {
71
- addHookAliases([["react", require.resolve(`react`)]], "page");
71
+ addHookAliases([["react", require.resolve("react")]], "page");
72
72
  // ignore: react/jsx-dev-runtime is not available on older version of Next.js ie. v13.1.6
73
73
  // react/jsx-runtime is not available on newer version of Next.js ie. v13.4.10-canary.3
74
74
  try {
75
- addHookAliases([["react/jsx-runtime", require.resolve(`react/jsx-runtime`)]], "page");
76
- addHookAliases([["react/jsx-dev-runtime", require.resolve(`react/jsx-dev-runtime`)]], "page");
75
+ addHookAliases([["react/jsx-runtime", require.resolve("react/jsx-runtime")]], "page");
76
+ addHookAliases([["react/jsx-dev-runtime", require.resolve("react/jsx-dev-runtime")]], "page");
77
77
  }
78
78
  catch (e) { }
79
79
  if (config.experimental.appDir) {
@@ -90,13 +90,14 @@ function isApp() {
90
90
  process.env.__NEXT_PRIVATE_PREBUNDLED_REACT === "experimental");
91
91
  }
92
92
  export function applyOverride() {
93
- mod._resolveFilename = function (originalResolveFilename, requestMapApp, requestMapPage, request, parent, isMain, options) {
93
+ mod._resolveFilename = ((originalResolveFilename, requestMapApp, requestMapPage, request, parent, isMain, options) => {
94
94
  const hookResolved = isApp()
95
95
  ? requestMapApp.get(request)
96
96
  : requestMapPage.get(request);
97
+ // biome-ignore lint/style/noParameterAssign:
97
98
  if (hookResolved)
98
99
  request = hookResolved;
99
100
  return originalResolveFilename.call(mod, request, parent, isMain, options);
100
101
  // We use `bind` here to avoid referencing outside variables to create potential memory leaks.
101
- }.bind(null, resolveFilename, hookPropertyMapApp, hookPropertyMapPage);
102
+ }).bind(null, resolveFilename, hookPropertyMapApp, hookPropertyMapPage);
102
103
  }