@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.
- package/README.md +6 -1
- package/dist/adapters/cache.js +1 -1
- package/dist/adapters/image-optimization-adapter.d.ts +1 -2
- package/dist/adapters/logger.js +32 -11
- package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +1 -0
- package/dist/adapters/plugins/image-optimization/image-optimization.js +0 -1
- package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +1 -0
- package/dist/build/bundleNextServer.d.ts +2 -2
- package/dist/build/bundleNextServer.js +2 -2
- package/dist/build/copyTracedFiles.js +1 -1
- package/dist/build/createAssets.js +1 -1
- package/dist/build/createMiddleware.js +1 -1
- package/dist/build/createServerBundle.js +3 -3
- package/dist/build/edge/createEdgeBundle.d.ts +1 -1
- package/dist/build/edge/createEdgeBundle.js +23 -12
- package/dist/build/helper.d.ts +6 -1
- package/dist/build/helper.js +20 -5
- package/dist/build/validateConfig.js +3 -1
- package/dist/core/requestHandler.d.ts +1 -2
- package/dist/core/requestHandler.js +16 -16
- package/dist/core/routing/matcher.js +1 -1
- package/dist/core/routing/middleware.d.ts +3 -3
- package/dist/core/routing/middleware.js +3 -4
- package/dist/core/routing/util.d.ts +2 -2
- package/dist/core/routing/util.js +1 -1
- package/dist/core/routingHandler.d.ts +2 -8
- package/dist/core/routingHandler.js +8 -8
- package/dist/helpers/withCloudflare.d.ts +1 -1
- package/dist/helpers/withCloudflare.js +2 -2
- package/dist/http/openNextResponse.d.ts +2 -10
- package/dist/http/openNextResponse.js +5 -3
- package/dist/overrides/converters/aws-apigw-v2.js +2 -1
- package/dist/overrides/converters/aws-cloudfront.js +1 -1
- package/dist/overrides/converters/edge.d.ts +2 -5
- package/dist/overrides/converters/edge.js +5 -4
- package/dist/overrides/incrementalCache/dummy.js +4 -3
- package/dist/overrides/proxyExternalRequest/dummy.js +2 -1
- package/dist/overrides/proxyExternalRequest/node.js +2 -2
- package/dist/overrides/queue/dummy.js +2 -1
- package/dist/overrides/warmer/dummy.js +2 -1
- package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +1 -1
- package/dist/overrides/wrappers/aws-lambda-streaming.js +0 -4
- package/dist/overrides/wrappers/aws-lambda.js +0 -3
- package/dist/overrides/wrappers/cloudflare-edge.d.ts +9 -0
- package/dist/overrides/wrappers/{cloudflare.js → cloudflare-edge.js} +3 -3
- package/dist/overrides/wrappers/cloudflare-node.d.ts +8 -0
- package/dist/overrides/wrappers/cloudflare-node.js +47 -0
- package/dist/overrides/wrappers/dummy.d.ts +2 -2
- package/dist/overrides/wrappers/dummy.js +1 -1
- package/dist/overrides/wrappers/node.d.ts +1 -1
- package/dist/overrides/wrappers/node.js +0 -3
- package/dist/plugins/resolve.js +5 -1
- package/dist/types/open-next.d.ts +19 -1
- package/dist/types/overrides.d.ts +1 -2
- package/dist/{adapters → utils}/binary.js +1 -0
- package/dist/utils/error.d.ts +1 -0
- package/dist/utils/error.js +8 -0
- package/package.json +3 -3
- package/dist/overrides/wrappers/cloudflare.d.ts +0 -12
- /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/
|
|
96
|
+
path/to/opennextjs-aws/packages/open-next/dist/index.js build
|
|
92
97
|
```
|
|
93
98
|
|
|
94
99
|
### Coldstart
|
package/dist/adapters/cache.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isBinaryContentType } from "
|
|
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 "../
|
|
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>;
|
package/dist/adapters/logger.js
CHANGED
|
@@ -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
|
|
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
|
|
28
|
-
if (error.logLevel
|
|
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
|
-
|
|
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
|
+
}
|
|
@@ -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;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare function bundleNextServer(outputDir: string, appPath: string, {
|
|
2
|
-
|
|
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, {
|
|
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
|
|
49
|
+
minify,
|
|
50
50
|
outfile: path.join(outputDir, "next-server.runtime.prod.js"),
|
|
51
51
|
sourcemap: false,
|
|
52
52
|
plugins: [
|
|
@@ -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
|
|
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
|
-
|
|
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"),
|
|
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
|
|
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 =
|
|
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:
|
|
115
|
+
minify: options.minify,
|
|
105
116
|
platform: "node",
|
|
106
117
|
format: "esm",
|
|
107
118
|
conditions: ["workerd", "worker", "browser"],
|
package/dist/build/helper.d.ts
CHANGED
|
@@ -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>;
|
package/dist/build/helper.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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 "../
|
|
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
|
|
20
|
-
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
|
-
|
|
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
|
|
34
|
-
?
|
|
35
|
-
:
|
|
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
|
|
47
|
-
|
|
46
|
+
if ("isExternalRewrite" in routingResult &&
|
|
47
|
+
routingResult.isExternalRewrite === true) {
|
|
48
48
|
try {
|
|
49
|
-
|
|
49
|
+
routingResult = await globalThis.proxyExternalRequest.proxy(routingResult.internalEvent);
|
|
50
50
|
}
|
|
51
51
|
catch (e) {
|
|
52
52
|
error("External request failed.", e);
|
|
53
|
-
|
|
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
|
|
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 =
|
|
75
|
+
response.statusCode = routingResult.statusCode;
|
|
76
76
|
response.flushHeaders();
|
|
77
|
-
const [bodyToConsume, bodyToReturn] =
|
|
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
|
-
|
|
82
|
+
routingResult.body = bodyToReturn;
|
|
83
83
|
}
|
|
84
|
-
return
|
|
84
|
+
return routingResult;
|
|
85
85
|
}
|
|
86
|
-
const preprocessedEvent =
|
|
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 =
|
|
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
|
|
2
|
+
type MiddlewareEvent = InternalEvent & {
|
|
3
3
|
responseHeaders?: Record<string, string | string[]>;
|
|
4
|
-
|
|
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<
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
171
|
+
isExternalRewrite,
|
|
173
172
|
};
|
|
174
173
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { OutgoingHttpHeaders } from "node:http";
|
|
2
|
-
import type { IncomingMessage
|
|
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,
|
|
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
|
|
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
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
return
|
|
63
|
+
const eventOrResult = await handleMiddleware(internalEvent);
|
|
64
|
+
const isResult = "statusCode" in eventOrResult;
|
|
65
|
+
if (isResult) {
|
|
66
|
+
return eventOrResult;
|
|
67
67
|
}
|
|
68
|
-
middlewareResponseHeaders =
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
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);
|
|
@@ -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
|
|
3
|
+
import type { TransformCallback } from "node:stream";
|
|
4
4
|
import { Transform } from "node:stream";
|
|
5
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
5
|
+
throw new IgnorableError('"Dummy" cache does not cache anything');
|
|
5
6
|
},
|
|
6
7
|
set: async () => {
|
|
7
|
-
throw new
|
|
8
|
+
throw new IgnorableError('"Dummy" cache does not cache anything');
|
|
8
9
|
},
|
|
9
10
|
delete: async () => {
|
|
10
|
-
throw new
|
|
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
|
|
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 {
|
|
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 dummyWarmer = {
|
|
2
3
|
name: "dummy",
|
|
3
4
|
invoke: async (_) => {
|
|
4
|
-
throw new
|
|
5
|
+
throw new FatalError("Dummy warmer is not implemented");
|
|
5
6
|
},
|
|
6
7
|
};
|
|
7
8
|
export default dummyWarmer;
|
|
@@ -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;
|
|
@@ -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
|
|
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
|
+
};
|
package/dist/plugins/resolve.js
CHANGED
|
@@ -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 (
|
|
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: {
|
package/dist/utils/error.d.ts
CHANGED
package/dist/utils/error.js
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"access": "public"
|
|
4
4
|
},
|
|
5
5
|
"name": "@opennextjs/aws",
|
|
6
|
-
"version": "3.
|
|
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": "
|
|
50
|
+
"@types/node": "20.17.6",
|
|
51
51
|
"tsc-alias": "^1.8.8",
|
|
52
|
-
"typescript": "
|
|
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
|