@opennextjs/aws 3.2.2 → 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 (60) hide show
  1. package/README.md +6 -1
  2. package/dist/adapters/cache.js +1 -1
  3. package/dist/adapters/image-optimization-adapter.d.ts +1 -2
  4. package/dist/adapters/logger.js +32 -11
  5. package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +1 -0
  6. package/dist/adapters/plugins/image-optimization/image-optimization.js +0 -1
  7. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +1 -0
  8. package/dist/build/bundleNextServer.d.ts +2 -2
  9. package/dist/build/bundleNextServer.js +2 -2
  10. package/dist/build/copyTracedFiles.js +1 -1
  11. package/dist/build/createAssets.js +1 -1
  12. package/dist/build/createMiddleware.js +1 -1
  13. package/dist/build/createServerBundle.js +3 -3
  14. package/dist/build/edge/createEdgeBundle.d.ts +1 -1
  15. package/dist/build/edge/createEdgeBundle.js +23 -12
  16. package/dist/build/helper.d.ts +6 -1
  17. package/dist/build/helper.js +20 -5
  18. package/dist/build/validateConfig.js +3 -1
  19. package/dist/core/requestHandler.d.ts +1 -2
  20. package/dist/core/requestHandler.js +16 -16
  21. package/dist/core/routing/matcher.js +1 -1
  22. package/dist/core/routing/middleware.d.ts +3 -3
  23. package/dist/core/routing/middleware.js +3 -4
  24. package/dist/core/routing/util.d.ts +2 -2
  25. package/dist/core/routing/util.js +1 -1
  26. package/dist/core/routingHandler.d.ts +2 -8
  27. package/dist/core/routingHandler.js +8 -8
  28. package/dist/helpers/withCloudflare.d.ts +1 -1
  29. package/dist/helpers/withCloudflare.js +2 -2
  30. package/dist/http/openNextResponse.d.ts +2 -10
  31. package/dist/http/openNextResponse.js +5 -3
  32. package/dist/overrides/converters/aws-apigw-v2.js +2 -1
  33. package/dist/overrides/converters/aws-cloudfront.js +1 -1
  34. package/dist/overrides/converters/edge.d.ts +2 -5
  35. package/dist/overrides/converters/edge.js +5 -4
  36. package/dist/overrides/incrementalCache/dummy.js +4 -3
  37. package/dist/overrides/proxyExternalRequest/dummy.js +2 -1
  38. package/dist/overrides/proxyExternalRequest/node.js +2 -2
  39. package/dist/overrides/queue/dummy.js +2 -1
  40. package/dist/overrides/warmer/dummy.js +2 -1
  41. package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +1 -1
  42. package/dist/overrides/wrappers/aws-lambda-streaming.js +0 -4
  43. package/dist/overrides/wrappers/aws-lambda.js +0 -3
  44. package/dist/overrides/wrappers/cloudflare-edge.d.ts +9 -0
  45. package/dist/overrides/wrappers/{cloudflare.js → cloudflare-edge.js} +3 -3
  46. package/dist/overrides/wrappers/cloudflare-node.d.ts +8 -0
  47. package/dist/overrides/wrappers/cloudflare-node.js +47 -0
  48. package/dist/overrides/wrappers/dummy.d.ts +2 -2
  49. package/dist/overrides/wrappers/dummy.js +1 -1
  50. package/dist/overrides/wrappers/node.d.ts +1 -1
  51. package/dist/overrides/wrappers/node.js +0 -3
  52. package/dist/plugins/resolve.js +5 -1
  53. package/dist/types/open-next.d.ts +19 -1
  54. package/dist/types/overrides.d.ts +1 -2
  55. package/dist/{adapters → utils}/binary.js +1 -0
  56. package/dist/utils/error.d.ts +1 -0
  57. package/dist/utils/error.js +8 -0
  58. package/package.json +3 -3
  59. package/dist/overrides/wrappers/cloudflare.d.ts +0 -12
  60. /package/dist/{adapters → utils}/binary.d.ts +0 -0
package/README.md CHANGED
@@ -77,18 +77,23 @@ To run `OpenNext` locally:
77
77
 
78
78
  1. Clone this repository.
79
79
  1. Build `open-next`:
80
+
80
81
  ```bash
81
82
  cd packages/open-next
82
83
  pnpm build
83
84
  ```
85
+
84
86
  1. Run `open-next` in watch mode:
87
+
85
88
  ```bash
86
89
  pnpm dev
87
90
  ```
91
+
88
92
  1. Now, you can make changes in `open-next` and build your Next.js app to test the changes.
93
+
89
94
  ```bash
90
95
  cd path/to/my/nextjs/app
91
- path/to/open-next/packages/open-next/dist/index.js build
96
+ path/to/opennextjs-aws/packages/open-next/dist/index.js build
92
97
  ```
93
98
 
94
99
  ### Coldstart
@@ -1,4 +1,4 @@
1
- import { isBinaryContentType } from "./binary";
1
+ import { isBinaryContentType } from "../utils/binary";
2
2
  import { debug, error, warn } from "./logger";
3
3
  /** Beginning single backslash is intentional, to look for the dot + the extension. Do not escape it again. */
4
4
  const CACHE_EXTENSION_REGEX = /\.(cache|fetch)$/;
@@ -1,4 +1,3 @@
1
- import type { StreamCreator } from "../http/openNextResponse.js";
2
- import type { InternalEvent, InternalResult } from "../types/open-next.js";
1
+ import type { InternalEvent, InternalResult, StreamCreator } from "../types/open-next.js";
3
2
  export declare const handler: (...args: any[]) => any;
4
3
  export declare function defaultHandler(event: InternalEvent, streamCreator?: StreamCreator): Promise<InternalResult>;
@@ -1,3 +1,4 @@
1
+ import { isOpenNextError } from "../utils/error";
1
2
  export function debug(...args) {
2
3
  if (globalThis.openNextDebug) {
3
4
  console.log(...args);
@@ -22,23 +23,24 @@ export function error(...args) {
22
23
  if (args.some((arg) => isDownplayedErrorLog(arg))) {
23
24
  debug(...args);
24
25
  }
25
- else if (args.some((arg) => arg.__openNextInternal)) {
26
+ else if (args.some((arg) => isOpenNextError(arg))) {
26
27
  // In case of an internal error, we log it with the appropriate log level
27
- const error = args.find((arg) => arg.__openNextInternal);
28
- if (error.logLevel === 0) {
29
- debug(...args);
28
+ const error = args.find((arg) => isOpenNextError(arg));
29
+ if (error.logLevel < getOpenNextErrorLogLevel()) {
30
30
  return;
31
31
  }
32
+ if (error.logLevel === 0) {
33
+ // Display the name and the message instead of full Open Next errors.
34
+ // console.log is used so that logging does not depend on openNextDebug.
35
+ return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
36
+ }
32
37
  if (error.logLevel === 1) {
33
- warn(...args);
34
- return;
38
+ // Display the name and the message instead of full Open Next errors.
39
+ return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg));
35
40
  }
36
- console.error(...args);
37
- return;
38
- }
39
- else {
40
- console.error(...args);
41
+ return console.error(...args);
41
42
  }
43
+ console.error(...args);
42
44
  }
43
45
  export const awsLogger = {
44
46
  trace: () => { },
@@ -47,3 +49,22 @@ export const awsLogger = {
47
49
  warn,
48
50
  error,
49
51
  };
52
+ /**
53
+ * Retrieves the log level for internal errors from the
54
+ * OPEN_NEXT_ERROR_LOG_LEVEL environment variable.
55
+ *
56
+ * @returns The numerical log level 0 (debug), 1 (warn), or 2 (error)
57
+ */
58
+ function getOpenNextErrorLogLevel() {
59
+ const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1";
60
+ switch (strLevel.toLowerCase()) {
61
+ case "debug":
62
+ case "0":
63
+ return 0;
64
+ case "error":
65
+ case "2":
66
+ return 2;
67
+ default:
68
+ return 1;
69
+ }
70
+ }
@@ -8,4 +8,5 @@ export declare function optimizeImage(headers: APIGatewayProxyEventHeaders, imag
8
8
  maxAge: number;
9
9
  etag: string;
10
10
  upstreamEtag: string;
11
+ error?: unknown;
11
12
  }>;
@@ -5,7 +5,6 @@ import { debug } from "../../logger.js";
5
5
  export async function optimizeImage(headers, imageParams, nextConfig, handleRequest) {
6
6
  const result = await imageOptimizer({ headers }, {}, // res object is not necessary as it's not actually used.
7
7
  imageParams, nextConfig, false, // not in dev mode
8
- // @ts-expect-error - This file is used only for Next 14.1 and below. Typing is correct for these versions.
9
8
  handleRequest);
10
9
  debug("optimized result", result);
11
10
  return result;
@@ -8,4 +8,5 @@ export declare function optimizeImage(headers: APIGatewayProxyEventHeaders, imag
8
8
  maxAge: number;
9
9
  etag: string;
10
10
  upstreamEtag: string;
11
+ error?: unknown;
11
12
  }>;
@@ -1,3 +1,3 @@
1
- export declare function bundleNextServer(outputDir: string, appPath: string, { debug }: {
2
- debug?: boolean | undefined;
1
+ export declare function bundleNextServer(outputDir: string, appPath: string, { minify }: {
2
+ minify?: boolean | undefined;
3
3
  }): Promise<void>;
@@ -35,7 +35,7 @@ const externals = [
35
35
  // Adding it cause to add a lot of unnecessary deps
36
36
  "next/dist/compiled/next-server",
37
37
  ];
38
- export async function bundleNextServer(outputDir, appPath, { debug = false }) {
38
+ export async function bundleNextServer(outputDir, appPath, { minify = true }) {
39
39
  const require = createRequire(`${appPath}/package.json`);
40
40
  const entrypoint = require.resolve("next/dist/esm/server/next-server.js");
41
41
  await build({
@@ -46,7 +46,7 @@ export async function bundleNextServer(outputDir, appPath, { debug = false }) {
46
46
  // packages: "external",
47
47
  format: "cjs",
48
48
  external: externals,
49
- minify: !debug,
49
+ minify,
50
50
  outfile: path.join(outputDir, "next-server.runtime.prod.js"),
51
51
  sourcemap: false,
52
52
  plugins: [
@@ -79,7 +79,7 @@ File ${fullFilePath} does not exist
79
79
  }
80
80
  catch (e) {
81
81
  if (alternativePath) {
82
- computeCopyFilesForPage(alternativePath);
82
+ safeComputeCopyFilesForPage(alternativePath);
83
83
  }
84
84
  }
85
85
  };
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { isBinaryContentType } from "../adapters/binary.js";
4
3
  import logger from "../logger.js";
4
+ import { isBinaryContentType } from "../utils/binary.js";
5
5
  import * as buildHelper from "./helper.js";
6
6
  export function createStaticAssets(options) {
7
7
  logger.info("Bundling static assets...");
@@ -20,7 +20,7 @@ export async function createMiddleware(options, { forceOnlyBuildOnce = false } =
20
20
  const outputPath = path.join(outputDir, "middleware");
21
21
  fs.mkdirSync(outputPath, { recursive: true });
22
22
  // Copy open-next.config.mjs
23
- buildHelper.copyOpenNextConfig(options.buildDir, outputPath, config.middleware.override?.wrapper === "cloudflare");
23
+ buildHelper.copyOpenNextConfig(options.buildDir, outputPath, await buildHelper.isEdgeRuntime(config.middleware.override));
24
24
  // Bundle middleware
25
25
  await buildEdgeBundle({
26
26
  entrypoint: path.join(options.openNextDistDir, "adapters", "middleware.js"),
@@ -77,7 +77,6 @@ async function generateBundle(name, options, fnOptions) {
77
77
  // `node_modules` inside `.next/standalone`, and others inside
78
78
  // `.next/standalone/package/path` (ie. `.next`, `server.js`).
79
79
  // We need to output the handler file inside the package path.
80
- const isMonorepo = monorepoRoot !== appPath;
81
80
  const packagePath = path.relative(monorepoRoot, appBuildOutputPath);
82
81
  fs.mkdirSync(path.join(outputPath, packagePath), { recursive: true });
83
82
  const ext = fnOptions.runtime === "deno" ? "mjs" : "cjs";
@@ -89,7 +88,7 @@ async function generateBundle(name, options, fnOptions) {
89
88
  const isBundled = fnOptions.experimentalBundledNextServer ?? false;
90
89
  if (isBundled) {
91
90
  await bundleNextServer(path.join(outputPath, packagePath), appPath, {
92
- debug: options.debug,
91
+ minify: options.minify,
93
92
  });
94
93
  }
95
94
  // Copy middleware
@@ -166,6 +165,7 @@ async function generateBundle(name, options, fnOptions) {
166
165
  : {}),
167
166
  },
168
167
  }, options);
168
+ const isMonorepo = monorepoRoot !== appPath;
169
169
  if (isMonorepo) {
170
170
  addMonorepoEntrypoint(outputPath, packagePath);
171
171
  }
@@ -208,7 +208,7 @@ function addMonorepoEntrypoint(outputPath, packagePath) {
208
208
  // that re-exports the real handler.
209
209
  // Always use posix path for import path
210
210
  const packagePosixPath = packagePath.split(path.sep).join(path.posix.sep);
211
- fs.writeFileSync(path.join(outputPath, "index.mjs"), [`export * from "./${packagePosixPath}/index.mjs";`].join(""));
211
+ fs.writeFileSync(path.join(outputPath, "index.mjs"), `export * from "./${packagePosixPath}/index.mjs";`);
212
212
  }
213
213
  async function minifyServerBundle(outputDir) {
214
214
  logger.info("Minimizing server function...");
@@ -1,7 +1,7 @@
1
1
  import type { MiddlewareInfo } from "../../types/next-types";
2
2
  import type { IncludedConverter, IncludedOriginResolver, LazyLoadedOverride, OverrideOptions, SplittedFunctionOptions } from "../../types/open-next";
3
3
  import type { OriginResolver } from "../../types/overrides.js";
4
- import type { BuildOptions } from "../helper.js";
4
+ import { type BuildOptions } from "../helper.js";
5
5
  interface BuildEdgeBundleOptions {
6
6
  middlewareInfo?: MiddlewareInfo;
7
7
  entrypoint: string;
@@ -6,11 +6,10 @@ 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
+ import { isEdgeRuntime } from "../helper.js";
9
10
  import { copyOpenNextConfig, esbuildAsync } from "../helper.js";
10
11
  export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, }) {
11
- const isInCloudfare = typeof overrides?.wrapper === "string"
12
- ? overrides.wrapper === "cloudflare"
13
- : (await overrides?.wrapper?.())?.edgeRuntime;
12
+ const isInCloudfare = await isEdgeRuntime(overrides);
14
13
  await esbuildAsync({
15
14
  entryPoints: [entrypoint],
16
15
  bundle: true,
@@ -76,20 +75,32 @@ globalThis.Buffer = Buffer;
76
75
 
77
76
  import {AsyncLocalStorage} from "node:async_hooks";
78
77
  globalThis.AsyncLocalStorage = AsyncLocalStorage;
78
+
79
+ ${""
80
+ /**
81
+ * Next.js sets this `__import_unsupported` on `globalThis` (with `configurable: false`):
82
+ * https://github.com/vercel/next.js/blob/5b7833e3/packages/next/src/server/web/globals.ts#L94-L98
83
+ *
84
+ * It does so in both the middleware and the main server, so if the middleware runs in the same place
85
+ * as the main handler this code gets run twice triggering a runtime error.
86
+ *
87
+ * For this reason we need to patch `Object.defineProperty` to avoid this issue.
88
+ */
89
+ }
90
+ const defaultDefineProperty = Object.defineProperty;
91
+ Object.defineProperty = function(o, p, a) {
92
+ if(p=== '__import_unsupported' && Boolean(globalThis.__import_unsupported)) {
93
+ return;
94
+ }
95
+ return defaultDefineProperty(o, p, a);
96
+ };
97
+
79
98
  ${isInCloudfare
80
99
  ? ""
81
100
  : `
82
101
  const require = (await import("node:module")).createRequire(import.meta.url);
83
102
  const __filename = (await import("node:url")).fileURLToPath(import.meta.url);
84
103
  const __dirname = (await import("node:path")).dirname(__filename);
85
-
86
- const defaultDefineProperty = Object.defineProperty;
87
- Object.defineProperty = function(o, p, a) {
88
- if(p=== '__import_unsupported' && Boolean(globalThis.__import_unsupported)) {
89
- return;
90
- }
91
- return defaultDefineProperty(o, p, a);
92
- };
93
104
  `}
94
105
  ${additionalInject ?? ""}
95
106
  `,
@@ -101,7 +112,7 @@ globalThis.AsyncLocalStorage = AsyncLocalStorage;
101
112
  outfile,
102
113
  allowOverwrite: true,
103
114
  bundle: true,
104
- minify: !options.debug,
115
+ minify: options.minify,
105
116
  platform: "node",
106
117
  format: "esm",
107
118
  conditions: ["workerd", "worker", "browser"],
@@ -1,5 +1,5 @@
1
1
  import type { BuildOptions as ESBuildOptions } from "esbuild";
2
- import type { OpenNextConfig } from "../types/open-next.js";
2
+ import type { DefaultOverrideOptions, OpenNextConfig } from "../types/open-next.js";
3
3
  export type BuildOptions = ReturnType<typeof normalizeOptions>;
4
4
  export declare function normalizeOptions(config: OpenNextConfig, distDir: string, tempBuildDir: string): {
5
5
  appBuildOutputPath: string;
@@ -9,6 +9,7 @@ export declare function normalizeOptions(config: OpenNextConfig, distDir: string
9
9
  buildDir: string;
10
10
  config: OpenNextConfig;
11
11
  debug: boolean;
12
+ minify: boolean;
12
13
  monorepoRoot: string;
13
14
  nextVersion: string;
14
15
  openNextVersion: string;
@@ -68,3 +69,7 @@ export declare function printOpenNextVersion(options: BuildOptions): void;
68
69
  * the app directory, but the compiled config is in the root of the monorepo.
69
70
  */
70
71
  export declare function initOutputDir(options: BuildOptions): void;
72
+ /**
73
+ * @returns Whether the edge runtime is used
74
+ */
75
+ export declare function isEdgeRuntime(overrides: DefaultOverrideOptions | undefined): Promise<boolean | undefined>;
@@ -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,
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,
107
+ minify,
105
108
  mainFields: ["module", "main"],
106
109
  sourcemap: debug ? "inline" : false,
107
110
  sourcesContent: false,
@@ -261,3 +264,15 @@ export function initOutputDir(options) {
261
264
  fs.mkdirSync(buildDir, { recursive: true });
262
265
  fs.cpSync(options.tempBuildDir, buildDir, { recursive: true });
263
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
+ }
@@ -8,6 +8,8 @@ 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"],
12
14
  dummy: [],
13
15
  };
@@ -63,7 +65,7 @@ export function validateConfig(config) {
63
65
  logger.warn("You've disabled incremental cache. This means that ISR and SSG will not work.");
64
66
  }
65
67
  if (config.dangerous?.disableTagCache) {
66
- logger.warn(`You've disabled tag cache.
68
+ logger.warn(`You've disabled tag cache.
67
69
  This means that revalidatePath and revalidateTag from next/cache will not work.
68
70
  It is safe to disable if you only use page router`);
69
71
  }
@@ -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>;
@@ -16,23 +16,23 @@ export async function openNextHandler(internalEvent, responseStreaming) {
16
16
  internalEvent.headers.host = internalEvent.headers["x-forwarded-host"];
17
17
  }
18
18
  debug("internalEvent", internalEvent);
19
- let preprocessResult = {
20
- internalEvent: internalEvent,
19
+ let routingResult = {
20
+ internalEvent,
21
21
  isExternalRewrite: false,
22
22
  origin: false,
23
23
  isISR: false,
24
24
  };
25
25
  //#override withRouting
26
26
  try {
27
- preprocessResult = await routingHandler(internalEvent);
27
+ routingResult = await routingHandler(internalEvent);
28
28
  }
29
29
  catch (e) {
30
30
  warn("Routing failed.", e);
31
31
  }
32
32
  //#endOverride
33
- const headers = "type" in preprocessResult
34
- ? preprocessResult.headers
35
- : preprocessResult.internalEvent.headers;
33
+ const headers = "type" in routingResult
34
+ ? routingResult.headers
35
+ : routingResult.internalEvent.headers;
36
36
  const overwrittenResponseHeaders = {};
37
37
  for (const [rawKey, value] of Object.entries(headers)) {
38
38
  if (!rawKey.startsWith(MIDDLEWARE_HEADER_PREFIX)) {
@@ -43,14 +43,14 @@ export async function openNextHandler(internalEvent, responseStreaming) {
43
43
  headers[key] = value;
44
44
  delete headers[rawKey];
45
45
  }
46
- if ("isExternalRewrite" in preprocessResult &&
47
- preprocessResult.isExternalRewrite === true) {
46
+ if ("isExternalRewrite" in routingResult &&
47
+ routingResult.isExternalRewrite === true) {
48
48
  try {
49
- preprocessResult = await globalThis.proxyExternalRequest.proxy(preprocessResult.internalEvent);
49
+ routingResult = await globalThis.proxyExternalRequest.proxy(routingResult.internalEvent);
50
50
  }
51
51
  catch (e) {
52
52
  error("External request failed.", e);
53
- preprocessResult = {
53
+ routingResult = {
54
54
  internalEvent: {
55
55
  type: "core",
56
56
  rawPath: "/500",
@@ -68,22 +68,22 @@ export async function openNextHandler(internalEvent, responseStreaming) {
68
68
  };
69
69
  }
70
70
  }
71
- if ("type" in preprocessResult) {
71
+ if ("type" in routingResult) {
72
72
  // response is used only in the streaming case
73
73
  if (responseStreaming) {
74
74
  const response = createServerResponse(internalEvent, headers, responseStreaming);
75
- response.statusCode = preprocessResult.statusCode;
75
+ response.statusCode = routingResult.statusCode;
76
76
  response.flushHeaders();
77
- const [bodyToConsume, bodyToReturn] = preprocessResult.body.tee();
77
+ const [bodyToConsume, bodyToReturn] = routingResult.body.tee();
78
78
  for await (const chunk of bodyToConsume) {
79
79
  response.write(chunk);
80
80
  }
81
81
  response.end();
82
- preprocessResult.body = bodyToReturn;
82
+ routingResult.body = bodyToReturn;
83
83
  }
84
- return preprocessResult;
84
+ return routingResult;
85
85
  }
86
- const preprocessedEvent = preprocessResult.internalEvent;
86
+ const preprocessedEvent = routingResult.internalEvent;
87
87
  debug("preprocessedEvent", preprocessedEvent);
88
88
  const reqProps = {
89
89
  method: preprocessedEvent.method,
@@ -227,7 +227,7 @@ export function handleRedirects(event, redirects) {
227
227
  }
228
228
  export function fixDataPage(internalEvent, buildId) {
229
229
  const { rawPath, query } = internalEvent;
230
- const dataPattern = `/_next/data/${buildId}`;
230
+ const dataPattern = `${NextConfig.basePath ?? ""}/_next/data/${buildId}`;
231
231
  // Return 404 for data requests that don't match the buildId
232
232
  if (rawPath.startsWith("/_next/data") && !rawPath.startsWith(dataPattern)) {
233
233
  return {
@@ -1,11 +1,11 @@
1
1
  import type { InternalEvent, InternalResult } from "../../types/open-next.js";
2
- type MiddlewareOutputEvent = InternalEvent & {
2
+ type MiddlewareEvent = InternalEvent & {
3
3
  responseHeaders?: Record<string, string | string[]>;
4
- externalRewrite?: boolean;
4
+ isExternalRewrite?: boolean;
5
5
  };
6
6
  type Middleware = (request: Request) => Response | Promise<Response>;
7
7
  type MiddlewareLoader = () => Promise<{
8
8
  default: Middleware;
9
9
  }>;
10
- export declare function handleMiddleware(internalEvent: InternalEvent, middlewareLoader?: MiddlewareLoader): Promise<MiddlewareOutputEvent | InternalResult>;
10
+ export declare function handleMiddleware(internalEvent: InternalEvent, middlewareLoader?: MiddlewareLoader): Promise<MiddlewareEvent | InternalResult>;
11
11
  export {};
@@ -114,7 +114,7 @@ export async function handleMiddleware(internalEvent, middlewareLoader = default
114
114
  // NOTE: the header was added to `req` from above
115
115
  const rewriteUrl = responseHeaders.get("x-middleware-rewrite");
116
116
  let rewritten = false;
117
- let externalRewrite = false;
117
+ let isExternalRewrite = false;
118
118
  let middlewareQueryString = internalEvent.query;
119
119
  let newUrl = internalEvent.url;
120
120
  if (rewriteUrl) {
@@ -122,7 +122,7 @@ export async function handleMiddleware(internalEvent, middlewareLoader = default
122
122
  if (isExternal(rewriteUrl, internalEvent.headers.host)) {
123
123
  newUrl = rewriteUrl;
124
124
  rewritten = true;
125
- externalRewrite = true;
125
+ isExternalRewrite = true;
126
126
  }
127
127
  else {
128
128
  const rewriteUrlObject = new URL(rewriteUrl);
@@ -147,7 +147,6 @@ export async function handleMiddleware(internalEvent, middlewareLoader = default
147
147
  if (result.body) {
148
148
  // transfer response body to res
149
149
  const body = result.body;
150
- // await pipeReadable(result.response.body, res);
151
150
  return {
152
151
  type: internalEvent.type,
153
152
  statusCode: statusCode,
@@ -169,6 +168,6 @@ export async function handleMiddleware(internalEvent, middlewareLoader = default
169
168
  query: middlewareQueryString,
170
169
  cookies: internalEvent.cookies,
171
170
  remoteAddress: internalEvent.remoteAddress,
172
- externalRewrite,
171
+ isExternalRewrite,
173
172
  };
174
173
  }
@@ -1,8 +1,8 @@
1
1
  import type { OutgoingHttpHeaders } from "node:http";
2
- import type { IncomingMessage, StreamCreator } from "../../http/index.js";
2
+ import type { IncomingMessage } from "../../http/index.js";
3
3
  import { OpenNextNodeResponse } from "../../http/openNextResponse.js";
4
4
  import type { MiddlewareManifest } from "../../types/next-types";
5
- import type { InternalEvent, InternalResult } from "../../types/open-next.js";
5
+ import type { InternalEvent, InternalResult, StreamCreator } from "../../types/open-next.js";
6
6
  /**
7
7
  *
8
8
  * @__PURE__
@@ -3,8 +3,8 @@ import { Readable } from "node:stream";
3
3
  import { BuildId, HtmlPages, NextConfig } from "../../adapters/config/index.js";
4
4
  import { OpenNextNodeResponse } from "../../http/openNextResponse.js";
5
5
  import { parseHeaders } from "../../http/util.js";
6
- import { isBinaryContentType } from "../../adapters/binary.js";
7
6
  import { debug, error } from "../../adapters/logger.js";
7
+ import { isBinaryContentType } from "../../utils/binary.js";
8
8
  /**
9
9
  *
10
10
  * @__PURE__
@@ -1,10 +1,4 @@
1
- import type { InternalEvent, InternalResult, Origin } from "../types/open-next";
1
+ import type { InternalEvent, InternalResult, RoutingResult } from "../types/open-next";
2
2
  export declare const MIDDLEWARE_HEADER_PREFIX = "x-middleware-response-";
3
3
  export declare const MIDDLEWARE_HEADER_PREFIX_LEN: number;
4
- export interface MiddlewareOutputEvent {
5
- internalEvent: InternalEvent;
6
- isExternalRewrite: boolean;
7
- origin: Origin | false;
8
- isISR: boolean;
9
- }
10
- export default function routingHandler(event: InternalEvent): Promise<InternalResult | MiddlewareOutputEvent>;
4
+ export default function routingHandler(event: InternalEvent): Promise<InternalResult | RoutingResult>;
@@ -60,15 +60,15 @@ export default async function routingHandler(event) {
60
60
  debug("redirect", redirect);
61
61
  return redirect;
62
62
  }
63
- const middleware = await handleMiddleware(internalEvent);
64
- let middlewareResponseHeaders = {};
65
- if ("statusCode" in middleware) {
66
- return middleware;
63
+ const eventOrResult = await handleMiddleware(internalEvent);
64
+ const isResult = "statusCode" in eventOrResult;
65
+ if (isResult) {
66
+ return eventOrResult;
67
67
  }
68
- middlewareResponseHeaders = middleware.responseHeaders || {};
69
- internalEvent = middleware;
70
- // At this point internalEvent is an InternalEvent or a MiddlewareOutputEvent
71
- let isExternalRewrite = middleware.externalRewrite ?? false;
68
+ const middlewareResponseHeaders = eventOrResult.responseHeaders;
69
+ let isExternalRewrite = eventOrResult.isExternalRewrite ?? false;
70
+ // internalEvent is `InternalEvent | MiddlewareEvent`
71
+ internalEvent = eventOrResult;
72
72
  if (!isExternalRewrite) {
73
73
  // First rewrite to be applied
74
74
  const beforeRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.beforeFiles);
@@ -57,7 +57,7 @@ export declare function withCloudflare<Fn extends Record<string, CloudflareCompa
57
57
  external: true;
58
58
  originResolver: "pattern-env";
59
59
  override: {
60
- wrapper: "cloudflare";
60
+ wrapper: "cloudflare-edge";
61
61
  converter: "edge";
62
62
  };
63
63
  };
@@ -36,7 +36,7 @@ export function withCloudflare(config) {
36
36
  routes: [fn.routes],
37
37
  patterns: [fn.patterns],
38
38
  override: {
39
- wrapper: "cloudflare",
39
+ wrapper: "cloudflare-edge",
40
40
  converter: "edge",
41
41
  },
42
42
  }
@@ -50,7 +50,7 @@ export function withCloudflare(config) {
50
50
  external: true,
51
51
  originResolver: "pattern-env",
52
52
  override: {
53
- wrapper: "cloudflare",
53
+ wrapper: "cloudflare-edge",
54
54
  converter: "edge",
55
55
  },
56
56
  },
@@ -1,16 +1,8 @@
1
1
  import type { IncomingMessage, OutgoingHttpHeader, OutgoingHttpHeaders, ServerResponse } from "node:http";
2
2
  import type { Socket } from "node:net";
3
- import type { TransformCallback, Writable } from "node:stream";
3
+ import type { TransformCallback } from "node:stream";
4
4
  import { Transform } from "node:stream";
5
- export interface StreamCreator {
6
- writeHeaders(prelude: {
7
- statusCode: number;
8
- cookies: string[];
9
- headers: Record<string, string>;
10
- }): Writable;
11
- onWrite?: () => void;
12
- onFinish: (length: number) => void;
13
- }
5
+ import type { StreamCreator } from "../types/open-next";
14
6
  export declare class OpenNextNodeResponse extends Transform implements ServerResponse {
15
7
  private fixHeaders;
16
8
  private onEnd;
@@ -64,7 +64,9 @@ export class OpenNextNodeResponse extends Transform {
64
64
  return this;
65
65
  }
66
66
  get finished() {
67
- return Boolean(this.writableFinished && this.responseStream?.writableFinished);
67
+ return this.responseStream
68
+ ? this.responseStream?.writableFinished
69
+ : this.writableFinished;
68
70
  }
69
71
  setHeader(name, value) {
70
72
  const key = name.toLowerCase();
@@ -125,7 +127,7 @@ export class OpenNextNodeResponse extends Transform {
125
127
  ...this.initialHeaders,
126
128
  ...this.headers,
127
129
  };
128
- const initialCookies = parseCookies(this.initialHeaders[SET_COOKIE_HEADER]);
130
+ const initialCookies = parseCookies(this.initialHeaders[SET_COOKIE_HEADER]?.toString());
129
131
  this._cookies =
130
132
  mergeHeadersPriority === "middleware"
131
133
  ? [...this._cookies, ...initialCookies]
@@ -226,7 +228,7 @@ export class OpenNextNodeResponse extends Transform {
226
228
  ?.getStore()
227
229
  ?.pendingPromiseRunner.add(this.onEnd(this.headers));
228
230
  const bodyLength = this.getBody().length;
229
- this.streamCreator?.onFinish(bodyLength);
231
+ this.streamCreator?.onFinish?.(bodyLength);
230
232
  //This is only here because of aws broken streaming implementation.
231
233
  //Hopefully one day they will be able to give us a working streaming implementation in lambda for everyone
232
234
  //If you're lucky you have a working streaming implementation in your aws account and don't need this
@@ -3,7 +3,8 @@ import { fromReadableStream } from "../../utils/stream";
3
3
  import { debug } from "../../adapters/logger";
4
4
  import { convertToQuery } from "../../core/routing/util";
5
5
  import { removeUndefinedFromQuery } from "./utils";
6
- // Not sure which one is reallly needed as this is not documented anywhere but server actions redirect are not working without this, it causes a 500 error from cloudfront itself with a 'x-amzErrortype: InternalFailure' header
6
+ // Not sure which one is really needed as this is not documented anywhere but server actions redirect are not working without this,
7
+ // it causes a 500 error from cloudfront itself with a 'x-amzErrortype: InternalFailure' header
7
8
  const CloudFrontBlacklistedHeaders = [
8
9
  "connection",
9
10
  "expect",
@@ -1,7 +1,7 @@
1
1
  import { parseCookies } from "../../http/util";
2
2
  import { fromReadableStream } from "../../utils/stream";
3
3
  import { debug } from "../../adapters/logger";
4
- import { convertToQuery, convertToQueryString, } from "../../core/routing/util";
4
+ import { convertToQuery, convertToQueryString } from "../../core/routing/util";
5
5
  const cloudfrontBlacklistedHeaders = [
6
6
  // Disallowed headers, see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-function-restrictions-all.html#function-restrictions-disallowed-headers
7
7
  "connection",
@@ -1,10 +1,7 @@
1
- import type { InternalEvent, InternalResult } from "../../types/open-next";
1
+ import type { InternalEvent, InternalResult, MiddlewareResult } from "../../types/open-next";
2
2
  import type { Converter } from "../../types/overrides";
3
- import type { MiddlewareOutputEvent } from "../../core/routingHandler";
4
3
  declare global {
5
4
  var __dangerous_ON_edge_converter_returns_request: boolean | undefined;
6
5
  }
7
- declare const converter: Converter<InternalEvent, InternalResult | ({
8
- type: "middleware";
9
- } & MiddlewareOutputEvent)>;
6
+ declare const converter: Converter<InternalEvent, InternalResult | MiddlewareResult>;
10
7
  export default converter;
@@ -2,7 +2,8 @@ import { Buffer } from "node:buffer";
2
2
  import { parseCookies } from "../../http/util";
3
3
  const converter = {
4
4
  convertFrom: async (event) => {
5
- const searchParams = new URL(event.url).searchParams;
5
+ const url = new URL(event.url);
6
+ const searchParams = url.searchParams;
6
7
  const query = {};
7
8
  for (const [key, value] of searchParams.entries()) {
8
9
  if (key in query) {
@@ -17,13 +18,13 @@ const converter = {
17
18
  query[key] = value;
18
19
  }
19
20
  }
20
- //Transform body into Buffer
21
+ // Transform body into Buffer
21
22
  const body = await event.arrayBuffer();
22
23
  const headers = {};
23
24
  event.headers.forEach((value, key) => {
24
25
  headers[key] = value;
25
26
  });
26
- const rawPath = new URL(event.url).pathname;
27
+ const rawPath = url.pathname;
27
28
  const method = event.method;
28
29
  const shouldHaveBody = method !== "GET" && method !== "HEAD";
29
30
  const cookies = Object.fromEntries(parseCookies(event.headers.get("cookie")).map((cookie) => cookie.split("=")));
@@ -79,7 +80,7 @@ const converter = {
79
80
  }
80
81
  return new Response(result.body, {
81
82
  status: result.statusCode,
82
- headers: headers,
83
+ headers,
83
84
  });
84
85
  },
85
86
  name: "edge",
@@ -1,13 +1,14 @@
1
+ import { IgnorableError } from "../../utils/error";
1
2
  const dummyIncrementalCache = {
2
3
  name: "dummy",
3
4
  get: async () => {
4
- throw new Error("Dummy cache is not implemented");
5
+ throw new IgnorableError('"Dummy" cache does not cache anything');
5
6
  },
6
7
  set: async () => {
7
- throw new Error("Dummy cache is not implemented");
8
+ throw new IgnorableError('"Dummy" cache does not cache anything');
8
9
  },
9
10
  delete: async () => {
10
- throw new Error("Dummy cache is not implemented");
11
+ throw new IgnorableError('"Dummy" cache does not cache anything');
11
12
  },
12
13
  };
13
14
  export default dummyIncrementalCache;
@@ -1,7 +1,8 @@
1
+ import { FatalError } from "../../utils/error";
1
2
  const DummyProxyExternalRequest = {
2
3
  name: "dummy",
3
4
  proxy: async (_event) => {
4
- throw new Error("This is a dummy implementation");
5
+ throw new FatalError("This is a dummy implementation");
5
6
  },
6
7
  };
7
8
  export default DummyProxyExternalRequest;
@@ -1,7 +1,7 @@
1
- import { debug, error } from "node:console";
2
1
  import { request } from "node:https";
3
2
  import { Readable } from "node:stream";
4
- import { isBinaryContentType } from "../../adapters/binary";
3
+ import { debug, error } from "../../adapters/logger";
4
+ import { isBinaryContentType } from "../../utils/binary";
5
5
  function filterHeadersForProxy(headers) {
6
6
  const filteredHeaders = {};
7
7
  const disallowedHeaders = [
@@ -1,7 +1,8 @@
1
+ import { FatalError } from "../../utils/error";
1
2
  const dummyQueue = {
2
3
  name: "dummy",
3
4
  send: async () => {
4
- throw new Error("Dummy queue is not implemented");
5
+ throw new FatalError("Dummy queue is not implemented");
5
6
  },
6
7
  };
7
8
  export default dummyQueue;
@@ -1,7 +1,8 @@
1
+ import { FatalError } from "../../utils/error";
1
2
  const dummyWarmer = {
2
3
  name: "dummy",
3
4
  invoke: async (_) => {
4
- throw new Error("Dummy warmer is not implemented");
5
+ throw new FatalError("Dummy warmer is not implemented");
5
6
  },
6
7
  };
7
8
  export default dummyWarmer;
@@ -2,6 +2,6 @@ import type { WrapperHandler } from "../../types/overrides";
2
2
  declare const _default: {
3
3
  wrapper: WrapperHandler;
4
4
  name: string;
5
- supportStreaming: boolean;
5
+ supportStreaming: true;
6
6
  };
7
7
  export default _default;
@@ -62,10 +62,6 @@ const handler = async (handler, converter) => awslambda.streamifyResponse(async
62
62
  responseStream.write(new Uint8Array(8));
63
63
  return compressedStream ?? responseStream;
64
64
  },
65
- onWrite: () => {
66
- // _hasWriten = true;
67
- },
68
- onFinish: () => { },
69
65
  };
70
66
  const response = await handler(internalEvent, streamCreator);
71
67
  const isUsingEdge = globalThis.isEdgeRuntime ?? false;
@@ -25,9 +25,6 @@ const handler = async (handler, converter) => async (event) => {
25
25
  },
26
26
  });
27
27
  },
28
- onFinish: () => {
29
- // Do nothing
30
- },
31
28
  };
32
29
  const response = await handler(internalEvent, fakeStream);
33
30
  return converter.convertTo(response, event);
@@ -0,0 +1,9 @@
1
+ import type { InternalEvent, InternalResult, MiddlewareResult } from "../../types/open-next";
2
+ import type { WrapperHandler } from "../../types/overrides";
3
+ declare const _default: {
4
+ wrapper: WrapperHandler<InternalEvent, InternalResult | MiddlewareResult>;
5
+ name: string;
6
+ supportStreaming: true;
7
+ edgeRuntime: true;
8
+ };
9
+ export default _default;
@@ -21,8 +21,8 @@ const handler = async (handler, converter) => async (request, env, ctx) => {
21
21
  // Note: This code could be moved to a cloudflare specific converter when one is created.
22
22
  const cfProperties = request.cf;
23
23
  for (const [propName, headerName] of Object.entries(cfPropNameToHeaderName)) {
24
- const propValue = cfProperties[propName];
25
- if (propValue !== null) {
24
+ const propValue = cfProperties?.[propName];
25
+ if (propValue != null) {
26
26
  internalEvent.headers[headerName] = propValue;
27
27
  }
28
28
  }
@@ -32,7 +32,7 @@ const handler = async (handler, converter) => async (request, env, ctx) => {
32
32
  };
33
33
  export default {
34
34
  wrapper: handler,
35
- name: "cloudflare",
35
+ name: "cloudflare-edge",
36
36
  supportStreaming: true,
37
37
  edgeRuntime: true,
38
38
  };
@@ -0,0 +1,8 @@
1
+ import type { InternalEvent, InternalResult } from "../../types/open-next";
2
+ import type { WrapperHandler } from "../../types/overrides";
3
+ declare const _default: {
4
+ wrapper: WrapperHandler<InternalEvent, InternalResult>;
5
+ name: string;
6
+ supportStreaming: true;
7
+ };
8
+ export default _default;
@@ -0,0 +1,47 @@
1
+ import { Writable } from "node:stream";
2
+ const handler = async (handler, converter) => async (request, env, ctx) => {
3
+ globalThis.process = process;
4
+ globalThis.openNextWaitUntil = ctx.waitUntil.bind(ctx);
5
+ // Set the environment variables
6
+ // Cloudflare suggests to not override the process.env object but instead apply the values to it
7
+ for (const [key, value] of Object.entries(env)) {
8
+ if (typeof value === "string") {
9
+ process.env[key] = value;
10
+ }
11
+ }
12
+ const internalEvent = await converter.convertFrom(request);
13
+ // TODO:
14
+ // The edge converter populate event.url with the url including the origin.
15
+ // This is required for middleware to keep track of the protocol (i.e. http with wrangler dev).
16
+ // However the server expects that the origin is not included.
17
+ const url = new URL(internalEvent.url);
18
+ internalEvent.url = url.href.slice(url.origin.length);
19
+ const { promise: promiseResponse, resolve: resolveResponse } = Promise.withResolvers();
20
+ const streamCreator = {
21
+ writeHeaders(prelude) {
22
+ const { statusCode, cookies, headers } = prelude;
23
+ const responseHeaders = new Headers(headers);
24
+ for (const cookie of cookies) {
25
+ responseHeaders.append("Set-Cookie", cookie);
26
+ }
27
+ const { readable, writable } = new TransformStream({
28
+ transform(chunk, controller) {
29
+ controller.enqueue(Uint8Array.from(chunk.chunk ?? chunk));
30
+ },
31
+ });
32
+ const response = new Response(readable, {
33
+ status: statusCode,
34
+ headers: responseHeaders,
35
+ });
36
+ resolveResponse(response);
37
+ return Writable.fromWeb(writable);
38
+ },
39
+ };
40
+ ctx.waitUntil(handler(internalEvent, streamCreator));
41
+ return promiseResponse;
42
+ };
43
+ export default {
44
+ wrapper: handler,
45
+ name: "cloudflare-node",
46
+ supportStreaming: true,
47
+ };
@@ -1,7 +1,7 @@
1
1
  import type { WrapperHandler } from "../../types/overrides";
2
2
  declare const _default: {
3
3
  name: string;
4
- handler: WrapperHandler;
5
- supportStreaming: boolean;
4
+ wrapper: WrapperHandler;
5
+ supportStreaming: false;
6
6
  };
7
7
  export default _default;
@@ -1,6 +1,6 @@
1
1
  const dummyWrapper = async () => async () => undefined;
2
2
  export default {
3
3
  name: "dummy",
4
- handler: dummyWrapper,
4
+ wrapper: dummyWrapper,
5
5
  supportStreaming: false,
6
6
  };
@@ -2,6 +2,6 @@ import type { WrapperHandler } from "../../types/overrides";
2
2
  declare const _default: {
3
3
  wrapper: WrapperHandler;
4
4
  name: string;
5
- supportStreaming: boolean;
5
+ supportStreaming: true;
6
6
  };
7
7
  export default _default;
@@ -11,9 +11,6 @@ const wrapper = async (handler, converter) => {
11
11
  res.uncork();
12
12
  return res;
13
13
  },
14
- onFinish: () => {
15
- // Is it necessary to do something here?
16
- },
17
14
  };
18
15
  if (internalEvent.rawPath === "/__health") {
19
16
  res.writeHead(200, {
@@ -43,10 +43,14 @@ export function openNextResolvePlugin({ overrides, fnName, }) {
43
43
  build.onLoad({ filter: /core(\/|\\)resolve\.js/g }, async (args) => {
44
44
  let contents = readFileSync(args.path, "utf-8");
45
45
  const overridesEntries = Object.entries(overrides ?? {});
46
- for (const [overrideName, overrideValue] of overridesEntries) {
46
+ for (let [overrideName, overrideValue] of overridesEntries) {
47
47
  if (!overrideValue) {
48
48
  continue;
49
49
  }
50
+ if (overrideName === "wrapper" && overrideValue === "cloudflare") {
51
+ // "cloudflare" is deprecated and replaced by "cloudflare-edge".
52
+ overrideValue = "cloudflare-edge";
53
+ }
50
54
  const folder = nameToFolder[overrideName];
51
55
  const defaultOverride = defaultOverrides[overrideName];
52
56
  contents = contents.replace(`../overrides/${folder}/${defaultOverride}.js`, `../overrides/${folder}/${getOverrideOrDummy(overrideValue)}.js`);
@@ -1,4 +1,5 @@
1
1
  import type { ReadableStream } from "node:stream/web";
2
+ import type { Writable } from "node:stream";
2
3
  import type { WarmerEvent, WarmerResponse } from "../adapters/warmer-function";
3
4
  import type { Converter, ImageLoader, IncrementalCache, OriginResolver, ProxyExternalRequest, Queue, TagCache, Warmer, Wrapper } from "./overrides";
4
5
  export type BaseEventOrResult<T extends string = string> = {
@@ -20,6 +21,15 @@ export type InternalResult = {
20
21
  body: ReadableStream;
21
22
  isBase64Encoded: boolean;
22
23
  } & BaseEventOrResult<"core">;
24
+ export interface StreamCreator {
25
+ writeHeaders(prelude: {
26
+ statusCode: number;
27
+ cookies: string[];
28
+ headers: Record<string, string>;
29
+ }): Writable;
30
+ onWrite?: () => void;
31
+ onFinish?: (length: number) => void;
32
+ }
23
33
  export interface DangerousOptions {
24
34
  /**
25
35
  * The tag cache is used for revalidateTags and revalidatePath.
@@ -56,8 +66,16 @@ export interface Origin {
56
66
  port?: number;
57
67
  customHeaders?: Record<string, string>;
58
68
  }
59
- export type IncludedWrapper = "aws-lambda" | "aws-lambda-streaming" | "node" | "cloudflare" | "dummy";
69
+ export type IncludedWrapper = "aws-lambda" | "aws-lambda-streaming" | "node" | "cloudflare" | "cloudflare-edge" | "cloudflare-node" | "dummy";
60
70
  export type IncludedConverter = "aws-apigw-v2" | "aws-apigw-v1" | "aws-cloudfront" | "edge" | "node" | "sqs-revalidate" | "dummy";
71
+ export interface RoutingResult {
72
+ internalEvent: InternalEvent;
73
+ isExternalRewrite: boolean;
74
+ origin: Origin | false;
75
+ isISR: boolean;
76
+ }
77
+ export interface MiddlewareResult extends RoutingResult, BaseEventOrResult<"middleware"> {
78
+ }
61
79
  export type IncludedQueue = "sqs" | "sqs-lite" | "dummy";
62
80
  export type IncludedIncrementalCache = "s3" | "s3-lite" | "dummy";
63
81
  export type IncludedTagCache = "dynamodb" | "dynamodb-lite" | "dummy";
@@ -1,7 +1,6 @@
1
1
  import type { Readable } from "node:stream";
2
- import type { StreamCreator } from "../http/index";
3
2
  import type { Meta } from "./cache";
4
- import type { BaseEventOrResult, BaseOverride, InternalEvent, InternalResult, Origin } from "./open-next";
3
+ import type { BaseEventOrResult, BaseOverride, InternalEvent, InternalResult, Origin, StreamCreator } from "./open-next";
5
4
  export interface QueueMessage {
6
5
  MessageDeduplicationId: string;
7
6
  MessageBody: {
@@ -27,6 +27,7 @@ const commonBinaryMimeTypes = new Set([
27
27
  "audio/3gpp",
28
28
  "audio/aac",
29
29
  "audio/basic",
30
+ "audio/flac",
30
31
  "audio/mpeg",
31
32
  "audio/ogg",
32
33
  "audio/wavaudio/webm",
@@ -21,3 +21,4 @@ export declare class FatalError extends Error implements BaseOpenNextError {
21
21
  readonly logLevel = 2;
22
22
  constructor(message: string);
23
23
  }
24
+ export declare function isOpenNextError(e: any): e is BaseOpenNextError & Error;
@@ -30,3 +30,11 @@ export class FatalError extends Error {
30
30
  this.name = "FatalError";
31
31
  }
32
32
  }
33
+ export function isOpenNextError(e) {
34
+ try {
35
+ return "__openNextInternal" in e;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "access": "public"
4
4
  },
5
5
  "name": "@opennextjs/aws",
6
- "version": "3.2.2",
6
+ "version": "3.3.0",
7
7
  "bin": {
8
8
  "open-next": "./dist/index.js"
9
9
  },
@@ -47,9 +47,9 @@
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/aws-lambda": "^8.10.109",
50
- "@types/node": "^18.16.1",
50
+ "@types/node": "20.17.6",
51
51
  "tsc-alias": "^1.8.8",
52
- "typescript": "^5.6.3"
52
+ "typescript": "5.6.3"
53
53
  },
54
54
  "bugs": {
55
55
  "url": "https://github.com/opennextjs/opennextjs-aws/issues"
@@ -1,12 +0,0 @@
1
- import type { InternalEvent, InternalResult } from "../../types/open-next";
2
- import type { WrapperHandler } from "../../types/overrides";
3
- import type { MiddlewareOutputEvent } from "../../core/routingHandler";
4
- declare const _default: {
5
- wrapper: WrapperHandler<InternalEvent, InternalResult | ({
6
- type: "middleware";
7
- } & MiddlewareOutputEvent)>;
8
- name: string;
9
- supportStreaming: boolean;
10
- edgeRuntime: boolean;
11
- };
12
- export default _default;
File without changes