@opennextjs/aws 3.5.3 → 3.5.5
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/dist/build/compileConfig.d.ts +6 -2
- package/dist/build/compileConfig.js +8 -7
- package/dist/build/copyTracedFiles.js +3 -3
- package/dist/build/createMiddleware.js +1 -0
- package/dist/build/createServerBundle.js +11 -7
- package/dist/build/edge/createEdgeBundle.d.ts +4 -0
- package/dist/build/edge/createEdgeBundle.js +17 -15
- package/dist/build/helper.js +1 -1
- package/dist/build.js +1 -1
- package/dist/core/requestHandler.js +2 -7
- package/dist/core/routing/middleware.js +6 -4
- package/dist/core/routing/util.js +3 -1
- package/dist/core/routingHandler.js +140 -112
- package/dist/overrides/wrappers/node.js +0 -1
- package/dist/plugins/edge.d.ts +3 -3
- package/dist/plugins/edge.js +18 -8
- package/dist/types/next-types.d.ts +3 -0
- package/package.json +1 -1
|
@@ -6,10 +6,14 @@ import type { OpenNextConfig } from "../types/open-next.js";
|
|
|
6
6
|
*
|
|
7
7
|
* @param baseDir Directory where to look for the configuration.
|
|
8
8
|
* @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
|
|
9
|
-
* @param nodeExternals Externals for the Node.js compilation.
|
|
9
|
+
* @param nodeExternals Coma separated list of Externals for the Node.js compilation.
|
|
10
|
+
* @param compileEdge Force compiling for the edge runtime when true
|
|
10
11
|
* @return The configuration and the build directory.
|
|
11
12
|
*/
|
|
12
|
-
export declare function compileOpenNextConfig(baseDir: string, openNextConfigPath?: string, nodeExternals?:
|
|
13
|
+
export declare function compileOpenNextConfig(baseDir: string, openNextConfigPath?: string, { nodeExternals, compileEdge }?: {
|
|
14
|
+
nodeExternals?: string | undefined;
|
|
15
|
+
compileEdge?: boolean | undefined;
|
|
16
|
+
}): Promise<{
|
|
13
17
|
config: OpenNextConfig;
|
|
14
18
|
buildDir: string;
|
|
15
19
|
}>;
|
|
@@ -11,13 +11,14 @@ import { validateConfig } from "./validateConfig.js";
|
|
|
11
11
|
*
|
|
12
12
|
* @param baseDir Directory where to look for the configuration.
|
|
13
13
|
* @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
|
|
14
|
-
* @param nodeExternals Externals for the Node.js compilation.
|
|
14
|
+
* @param nodeExternals Coma separated list of Externals for the Node.js compilation.
|
|
15
|
+
* @param compileEdge Force compiling for the edge runtime when true
|
|
15
16
|
* @return The configuration and the build directory.
|
|
16
17
|
*/
|
|
17
|
-
export async function compileOpenNextConfig(baseDir, openNextConfigPath, nodeExternals) {
|
|
18
|
+
export async function compileOpenNextConfig(baseDir, openNextConfigPath, { nodeExternals = "", compileEdge = false } = {}) {
|
|
18
19
|
const sourcePath = path.join(baseDir, openNextConfigPath ?? "open-next.config.ts");
|
|
19
20
|
const buildDir = fs.mkdtempSync(path.join(os.tmpdir(), "open-next-tmp"));
|
|
20
|
-
let configPath = compileOpenNextConfigNode(sourcePath, buildDir, nodeExternals
|
|
21
|
+
let configPath = compileOpenNextConfigNode(sourcePath, buildDir, nodeExternals.split(","));
|
|
21
22
|
// On Windows, we need to use file:// protocol to load the config file using import()
|
|
22
23
|
if (process.platform === "win32")
|
|
23
24
|
configPath = `file://${configPath}`;
|
|
@@ -31,12 +32,12 @@ export async function compileOpenNextConfig(baseDir, openNextConfigPath, nodeExt
|
|
|
31
32
|
// If it does, we need to compile it with the edge runtime
|
|
32
33
|
const usesEdgeRuntime = (config.middleware?.external && config.middleware.runtime !== "node") ||
|
|
33
34
|
Object.values(config.functions || {}).some((fn) => fn.runtime === "edge");
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
//Nothing to do here
|
|
35
|
+
if (usesEdgeRuntime || compileEdge) {
|
|
36
|
+
compileOpenNextConfigEdge(sourcePath, buildDir, config.edgeExternals ?? []);
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
|
|
39
|
+
// Skip compiling for the edge runtime.
|
|
40
|
+
logger.debug("No edge runtime found in the open-next.config.ts. Using default config.");
|
|
40
41
|
}
|
|
41
42
|
return { config, buildDir };
|
|
42
43
|
}
|
|
@@ -55,12 +55,12 @@ export async function copyTracedFiles({ buildOutputPath, packagePath, outputDir,
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
// create directory for pages
|
|
58
|
-
if (existsSync(path.join(
|
|
58
|
+
if (existsSync(path.join(standaloneNextDir, "server/pages"))) {
|
|
59
59
|
mkdirSync(path.join(outputNextDir, "server/pages"), {
|
|
60
60
|
recursive: true,
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
|
-
if (existsSync(path.join(
|
|
63
|
+
if (existsSync(path.join(standaloneNextDir, "server/app"))) {
|
|
64
64
|
mkdirSync(path.join(outputNextDir, "server/app"), {
|
|
65
65
|
recursive: true,
|
|
66
66
|
});
|
|
@@ -210,7 +210,7 @@ File ${fullFilePath} does not exist
|
|
|
210
210
|
// Maybe even move this to s3 directly
|
|
211
211
|
if (hasPageDir) {
|
|
212
212
|
// First we get truly static files - i.e. pages without getStaticProps
|
|
213
|
-
const staticFiles = Object.values(
|
|
213
|
+
const staticFiles = Object.values(loadPagesManifest(standaloneNextDir));
|
|
214
214
|
// Then we need to get all fallback: true dynamic routes html
|
|
215
215
|
const prerenderManifest = loadPrerenderManifest(standaloneNextDir);
|
|
216
216
|
const config = loadConfig(standaloneNextDir);
|
|
@@ -58,6 +58,7 @@ export async function createMiddleware(options, { forceOnlyBuildOnce = false } =
|
|
|
58
58
|
outfile: path.join(options.buildDir, "middleware.mjs"),
|
|
59
59
|
middlewareInfo: edgeMiddlewareInfo,
|
|
60
60
|
options,
|
|
61
|
+
overrides: config.default.override,
|
|
61
62
|
onlyBuildOnce: true,
|
|
62
63
|
name: "middleware",
|
|
63
64
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { loadMiddlewareManifest } from "../adapters/config/util.js";
|
|
3
4
|
import logger from "../logger.js";
|
|
4
5
|
import { minifyAll } from "../minimize-js.js";
|
|
5
6
|
import { ContentUpdater } from "../plugins/content-updater.js";
|
|
@@ -9,7 +10,7 @@ import { getCrossPlatformPathRegex } from "../utils/regex.js";
|
|
|
9
10
|
import { bundleNextServer } from "./bundleNextServer.js";
|
|
10
11
|
import { compileCache } from "./compileCache.js";
|
|
11
12
|
import { copyTracedFiles } from "./copyTracedFiles.js";
|
|
12
|
-
import { generateEdgeBundle } from "./edge/createEdgeBundle.js";
|
|
13
|
+
import { copyMiddlewareResources, generateEdgeBundle, } from "./edge/createEdgeBundle.js";
|
|
13
14
|
import * as buildHelper from "./helper.js";
|
|
14
15
|
import { installDependencies } from "./installDeps.js";
|
|
15
16
|
import { applyCodePatches } from "./patch/codePatcher.js";
|
|
@@ -82,25 +83,28 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
82
83
|
// `.next/standalone/package/path` (ie. `.next`, `server.js`).
|
|
83
84
|
// We need to output the handler file inside the package path.
|
|
84
85
|
const packagePath = buildHelper.getPackagePath(options);
|
|
85
|
-
|
|
86
|
+
const outPackagePath = path.join(outputPath, packagePath);
|
|
87
|
+
fs.mkdirSync(outPackagePath, { recursive: true });
|
|
86
88
|
const ext = fnOptions.runtime === "deno" ? "mjs" : "cjs";
|
|
87
|
-
fs.copyFileSync(path.join(options.buildDir, `cache.${ext}`), path.join(
|
|
89
|
+
fs.copyFileSync(path.join(options.buildDir, `cache.${ext}`), path.join(outPackagePath, "cache.cjs"));
|
|
88
90
|
if (fnOptions.runtime === "deno") {
|
|
89
91
|
addDenoJson(outputPath, packagePath);
|
|
90
92
|
}
|
|
91
93
|
// Bundle next server if necessary
|
|
92
94
|
const isBundled = fnOptions.experimentalBundledNextServer ?? false;
|
|
93
95
|
if (isBundled) {
|
|
94
|
-
await bundleNextServer(
|
|
96
|
+
await bundleNextServer(outPackagePath, appPath, {
|
|
95
97
|
minify: options.minify,
|
|
96
98
|
});
|
|
97
99
|
}
|
|
98
100
|
// Copy middleware
|
|
99
101
|
if (!config.middleware?.external) {
|
|
100
|
-
fs.copyFileSync(path.join(options.buildDir, "middleware.mjs"), path.join(
|
|
102
|
+
fs.copyFileSync(path.join(options.buildDir, "middleware.mjs"), path.join(outPackagePath, "middleware.mjs"));
|
|
103
|
+
const middlewareManifest = loadMiddlewareManifest(path.join(options.appBuildOutputPath, ".next"));
|
|
104
|
+
copyMiddlewareResources(options, middlewareManifest.middleware["/"], outPackagePath);
|
|
101
105
|
}
|
|
102
106
|
// Copy open-next.config.mjs
|
|
103
|
-
buildHelper.copyOpenNextConfig(options.buildDir,
|
|
107
|
+
buildHelper.copyOpenNextConfig(options.buildDir, outPackagePath);
|
|
104
108
|
// Copy env files
|
|
105
109
|
buildHelper.copyEnvFile(appBuildOutputPath, packagePath, outputPath);
|
|
106
110
|
// Copy all necessary traced files
|
|
@@ -233,7 +237,7 @@ function addMonorepoEntrypoint(outputPath, packagePath) {
|
|
|
233
237
|
// that re-exports the real handler.
|
|
234
238
|
// Always use posix path for import path
|
|
235
239
|
const packagePosixPath = packagePath.split(path.sep).join(path.posix.sep);
|
|
236
|
-
fs.writeFileSync(path.join(outputPath, "index.mjs"), `export
|
|
240
|
+
fs.writeFileSync(path.join(outputPath, "index.mjs"), `export { handler } from "./${packagePosixPath}/index.mjs";`);
|
|
237
241
|
}
|
|
238
242
|
async function minifyServerBundle(outputDir) {
|
|
239
243
|
logger.info("Minimizing server function...");
|
|
@@ -23,4 +23,8 @@ interface BuildEdgeBundleOptions {
|
|
|
23
23
|
}
|
|
24
24
|
export declare function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, additionalPlugins: additionalPluginsFn, }: BuildEdgeBundleOptions): Promise<void>;
|
|
25
25
|
export declare function generateEdgeBundle(name: string, options: BuildOptions, fnOptions: SplittedFunctionOptions, additionalPlugins?: (contentUpdater: ContentUpdater) => Plugin[]): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Copy wasm files and assets into the destDir.
|
|
28
|
+
*/
|
|
29
|
+
export declare function copyMiddlewareResources(options: BuildOptions, middlewareInfo: MiddlewareInfo | undefined, destDir: string): void;
|
|
26
30
|
export {};
|
|
@@ -13,7 +13,7 @@ import { getCrossPlatformPathRegex } from "../../utils/regex.js";
|
|
|
13
13
|
import { isEdgeRuntime } from "../helper.js";
|
|
14
14
|
import { copyOpenNextConfig, esbuildAsync } from "../helper.js";
|
|
15
15
|
export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, options, defaultConverter, overrides, additionalInject, includeCache, additionalExternals, onlyBuildOnce, name, additionalPlugins: additionalPluginsFn, }) {
|
|
16
|
-
const
|
|
16
|
+
const isInCloudflare = await isEdgeRuntime(overrides);
|
|
17
17
|
function override(target) {
|
|
18
18
|
return typeof overrides?.[target] === "string"
|
|
19
19
|
? overrides[target]
|
|
@@ -56,7 +56,7 @@ export async function buildEdgeBundle({ middlewareInfo, entrypoint, outfile, opt
|
|
|
56
56
|
openNextEdgePlugins({
|
|
57
57
|
middlewareInfo,
|
|
58
58
|
nextDir: path.join(options.appBuildOutputPath, ".next"),
|
|
59
|
-
|
|
59
|
+
isInCloudflare,
|
|
60
60
|
}),
|
|
61
61
|
...additionalPlugins,
|
|
62
62
|
// The content updater plugin must be the last plugin
|
|
@@ -97,7 +97,7 @@ Object.defineProperty = function(o, p, a) {
|
|
|
97
97
|
return defaultDefineProperty(o, p, a);
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
-
${
|
|
100
|
+
${isInCloudflare
|
|
101
101
|
? ""
|
|
102
102
|
: `
|
|
103
103
|
const require = (await import("node:module")).createRequire(import.meta.url);
|
|
@@ -141,18 +141,7 @@ export async function generateEdgeBundle(name, options, fnOptions, additionalPlu
|
|
|
141
141
|
throw new Error("Only one function is supported for now");
|
|
142
142
|
}
|
|
143
143
|
const middlewareInfo = functions[0];
|
|
144
|
-
|
|
145
|
-
const wasmFiles = middlewareInfo.wasm;
|
|
146
|
-
mkdirSync(path.join(outputDir, "wasm"), { recursive: true });
|
|
147
|
-
for (const wasmFile of wasmFiles) {
|
|
148
|
-
fs.copyFileSync(path.join(buildOutputDotNextDir, wasmFile.filePath), path.join(outputDir, `wasm/${wasmFile.name}.wasm`));
|
|
149
|
-
}
|
|
150
|
-
// Copy assets
|
|
151
|
-
const assets = middlewareInfo.assets;
|
|
152
|
-
mkdirSync(path.join(outputDir, "assets"), { recursive: true });
|
|
153
|
-
for (const asset of assets) {
|
|
154
|
-
fs.copyFileSync(path.join(buildOutputDotNextDir, asset.filePath), path.join(outputDir, `assets/${asset.name}`));
|
|
155
|
-
}
|
|
144
|
+
copyMiddlewareResources(options, middlewareInfo, outputDir);
|
|
156
145
|
await buildEdgeBundle({
|
|
157
146
|
middlewareInfo,
|
|
158
147
|
entrypoint: path.join(options.openNextDistDir, "adapters/edge-adapter.js"),
|
|
@@ -164,3 +153,16 @@ export async function generateEdgeBundle(name, options, fnOptions, additionalPlu
|
|
|
164
153
|
additionalPlugins,
|
|
165
154
|
});
|
|
166
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Copy wasm files and assets into the destDir.
|
|
158
|
+
*/
|
|
159
|
+
export function copyMiddlewareResources(options, middlewareInfo, destDir) {
|
|
160
|
+
mkdirSync(path.join(destDir, "wasm"), { recursive: true });
|
|
161
|
+
for (const file of middlewareInfo?.wasm ?? []) {
|
|
162
|
+
fs.copyFileSync(path.join(options.appBuildOutputPath, ".next", file.filePath), path.join(destDir, `wasm/${file.name}.wasm`));
|
|
163
|
+
}
|
|
164
|
+
mkdirSync(path.join(destDir, "assets"), { recursive: true });
|
|
165
|
+
for (const file of middlewareInfo?.assets ?? []) {
|
|
166
|
+
fs.copyFileSync(path.join(options.appBuildOutputPath, ".next", file.filePath), path.join(destDir, `assets/${file.name}`));
|
|
167
|
+
}
|
|
168
|
+
}
|
package/dist/build/helper.js
CHANGED
|
@@ -317,7 +317,7 @@ export async function isEdgeRuntime(overrides) {
|
|
|
317
317
|
return false;
|
|
318
318
|
}
|
|
319
319
|
if (typeof overrides.wrapper === "string") {
|
|
320
|
-
return ["cloudflare-edge", "cloudflare"].includes(overrides.wrapper);
|
|
320
|
+
return ["cloudflare-edge", "cloudflare", "cloudflare-node"].includes(overrides.wrapper);
|
|
321
321
|
}
|
|
322
322
|
return (await overrides?.wrapper?.())?.edgeRuntime;
|
|
323
323
|
}
|
package/dist/build.js
CHANGED
|
@@ -17,7 +17,7 @@ export async function build(openNextConfigPath, nodeExternals) {
|
|
|
17
17
|
showWarningOnWindows();
|
|
18
18
|
const baseDir = process.cwd();
|
|
19
19
|
const openNextDistDir = url.fileURLToPath(new URL(".", import.meta.url));
|
|
20
|
-
const { config, buildDir } = await compileOpenNextConfig(baseDir, openNextConfigPath, nodeExternals);
|
|
20
|
+
const { config, buildDir } = await compileOpenNextConfig(baseDir, openNextConfigPath, { nodeExternals });
|
|
21
21
|
// Initialize options
|
|
22
22
|
const options = buildHelper.normalizeOptions(config, openNextDistDir, buildDir);
|
|
23
23
|
logger.setLevel(options.debug ? "debug" : "info");
|
|
@@ -2,7 +2,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
2
2
|
import { IncomingMessage } from "../http/index.js";
|
|
3
3
|
import { runWithOpenNextRequestContext } from "../utils/promise";
|
|
4
4
|
import { NextConfig } from "../adapters/config/index";
|
|
5
|
-
import { debug, error
|
|
5
|
+
import { debug, error } from "../adapters/logger";
|
|
6
6
|
import { patchAsyncStorage } from "./patchAsyncStorage";
|
|
7
7
|
import { constructNextUrl, convertRes, convertToQuery, createServerResponse, } from "./routing/util";
|
|
8
8
|
import routingHandler, { INTERNAL_HEADER_INITIAL_URL, INTERNAL_HEADER_RESOLVED_ROUTES, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_HEADER_PREFIX_LEN, } from "./routingHandler";
|
|
@@ -39,12 +39,7 @@ export async function openNextHandler(internalEvent, options) {
|
|
|
39
39
|
...internalHeaders,
|
|
40
40
|
};
|
|
41
41
|
//#override withRouting
|
|
42
|
-
|
|
43
|
-
routingResult = await routingHandler(internalEvent);
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
warn("Routing failed.", e);
|
|
47
|
-
}
|
|
42
|
+
routingResult = await routingHandler(internalEvent);
|
|
48
43
|
//#endOverride
|
|
49
44
|
const headers = "type" in routingResult
|
|
50
45
|
? routingResult.headers
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FunctionsConfigManifest, MiddlewareManifest, NextConfig, } from "../../adapters/config/index.js";
|
|
1
|
+
import { FunctionsConfigManifest, MiddlewareManifest, NextConfig, PrerenderManifest, } from "../../adapters/config/index.js";
|
|
2
2
|
import { emptyReadableStream } from "../../utils/stream.js";
|
|
3
3
|
import { localizePath } from "./i18n/index.js";
|
|
4
4
|
//NOTE: we should try to avoid importing stuff from next as much as possible
|
|
@@ -24,7 +24,11 @@ function defaultMiddlewareLoader() {
|
|
|
24
24
|
export async function handleMiddleware(internalEvent, middlewareLoader = defaultMiddlewareLoader) {
|
|
25
25
|
const headers = internalEvent.headers;
|
|
26
26
|
// We bypass the middleware if the request is internal
|
|
27
|
-
if
|
|
27
|
+
// We should only do that if the request has the correct `x-prerender-revalidate` header
|
|
28
|
+
// The `x-prerender-revalidate` header is set at build time and should be safe to trust
|
|
29
|
+
if (headers["x-isr"] &&
|
|
30
|
+
headers["x-prerender-revalidate"] ===
|
|
31
|
+
PrerenderManifest.preview.previewModeId)
|
|
28
32
|
return internalEvent;
|
|
29
33
|
// We only need the normalizedPath to check if the middleware should run
|
|
30
34
|
const normalizedPath = localizePath(internalEvent);
|
|
@@ -113,13 +117,11 @@ export async function handleMiddleware(internalEvent, middlewareLoader = default
|
|
|
113
117
|
// If the middleware returned a Rewrite, set the `url` to the pathname of the rewrite
|
|
114
118
|
// NOTE: the header was added to `req` from above
|
|
115
119
|
const rewriteUrl = responseHeaders.get("x-middleware-rewrite");
|
|
116
|
-
let rewritten = false;
|
|
117
120
|
let isExternalRewrite = false;
|
|
118
121
|
let middlewareQueryString = internalEvent.query;
|
|
119
122
|
let newUrl = internalEvent.url;
|
|
120
123
|
if (rewriteUrl) {
|
|
121
124
|
newUrl = rewriteUrl;
|
|
122
|
-
rewritten = true;
|
|
123
125
|
// If not a string, it should probably throw
|
|
124
126
|
if (isExternal(newUrl, internalEvent.headers.host)) {
|
|
125
127
|
isExternalRewrite = true;
|
|
@@ -202,7 +202,9 @@ export function fixCacheHeaderForHtmlPages(internalEvent, headers) {
|
|
|
202
202
|
const localizedPath = localizePath(internalEvent);
|
|
203
203
|
// WORKAROUND: `NextServer` does not set cache headers for HTML pages
|
|
204
204
|
// https://opennext.js.org/aws/v2/advanced/workaround#workaround-nextserver-does-not-set-cache-headers-for-html-pages
|
|
205
|
-
|
|
205
|
+
// Requests containing an `x-middleware-prefetch` header must not be cached
|
|
206
|
+
if (HtmlPages.includes(localizedPath) &&
|
|
207
|
+
!internalEvent.headers["x-middleware-prefetch"]) {
|
|
206
208
|
headers[CommonHeaders.CACHE_CONTROL] =
|
|
207
209
|
"public, max-age=0, s-maxage=31536000, must-revalidate";
|
|
208
210
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BuildId, ConfigHeaders, NextConfig, PrerenderManifest, RoutesManifest, } from "../adapters/config/index";
|
|
2
|
-
import { debug } from "../adapters/logger";
|
|
2
|
+
import { debug, error } from "../adapters/logger";
|
|
3
3
|
import { cacheInterceptor } from "./routing/cacheInterceptor";
|
|
4
4
|
import { detectLocale } from "./routing/i18n";
|
|
5
5
|
import { fixDataPage, getNextConfigHeaders, handleFallbackFalse, handleRedirects, handleRewrites, } from "./routing/matcher";
|
|
@@ -32,121 +32,149 @@ function applyMiddlewareHeaders(eventHeaders, middlewareHeaders, setPrefix = tru
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
export default async function routingHandler(event) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
try {
|
|
36
|
+
// Add Next geo headers
|
|
37
|
+
for (const [openNextGeoName, nextGeoName] of Object.entries(geoHeaderToNextHeader)) {
|
|
38
|
+
const value = event.headers[openNextGeoName];
|
|
39
|
+
if (value) {
|
|
40
|
+
event.headers[nextGeoName] = value;
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
// First we remove internal headers
|
|
44
|
+
// We don't want to allow users to set these headers
|
|
45
|
+
for (const key of Object.keys(event.headers)) {
|
|
46
|
+
if (key.startsWith(INTERNAL_HEADER_PREFIX) ||
|
|
47
|
+
key.startsWith(MIDDLEWARE_HEADER_PREFIX)) {
|
|
48
|
+
delete event.headers[key];
|
|
49
|
+
}
|
|
48
50
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
let internalEvent = fixDataPage(event, BuildId);
|
|
52
|
-
if ("statusCode" in internalEvent) {
|
|
53
|
-
return internalEvent;
|
|
54
|
-
}
|
|
55
|
-
const redirect = handleRedirects(internalEvent, RoutesManifest.redirects);
|
|
56
|
-
if (redirect) {
|
|
57
|
-
debug("redirect", redirect);
|
|
58
|
-
return redirect;
|
|
59
|
-
}
|
|
60
|
-
const eventOrResult = await handleMiddleware(internalEvent);
|
|
61
|
-
const isResult = "statusCode" in eventOrResult;
|
|
62
|
-
if (isResult) {
|
|
63
|
-
return eventOrResult;
|
|
64
|
-
}
|
|
65
|
-
const middlewareResponseHeaders = eventOrResult.responseHeaders;
|
|
66
|
-
let isExternalRewrite = eventOrResult.isExternalRewrite ?? false;
|
|
67
|
-
// internalEvent is `InternalEvent | MiddlewareEvent`
|
|
68
|
-
internalEvent = eventOrResult;
|
|
69
|
-
if (!isExternalRewrite) {
|
|
70
|
-
// First rewrite to be applied
|
|
71
|
-
const beforeRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.beforeFiles);
|
|
72
|
-
internalEvent = beforeRewrites.internalEvent;
|
|
73
|
-
isExternalRewrite = beforeRewrites.isExternalRewrite;
|
|
74
|
-
}
|
|
75
|
-
const foundStaticRoute = staticRouteMatcher(internalEvent.rawPath);
|
|
76
|
-
const isStaticRoute = !isExternalRewrite && foundStaticRoute.length > 0;
|
|
77
|
-
if (!(isStaticRoute || isExternalRewrite)) {
|
|
78
|
-
// Second rewrite to be applied
|
|
79
|
-
const afterRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.afterFiles);
|
|
80
|
-
internalEvent = afterRewrites.internalEvent;
|
|
81
|
-
isExternalRewrite = afterRewrites.isExternalRewrite;
|
|
82
|
-
}
|
|
83
|
-
// We want to run this just before the dynamic route check
|
|
84
|
-
const { event: fallbackEvent, isISR } = handleFallbackFalse(internalEvent, PrerenderManifest);
|
|
85
|
-
internalEvent = fallbackEvent;
|
|
86
|
-
const foundDynamicRoute = dynamicRouteMatcher(internalEvent.rawPath);
|
|
87
|
-
const isDynamicRoute = !isExternalRewrite && foundDynamicRoute.length > 0;
|
|
88
|
-
if (!(isDynamicRoute || isStaticRoute || isExternalRewrite)) {
|
|
89
|
-
// Fallback rewrite to be applied
|
|
90
|
-
const fallbackRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.fallback);
|
|
91
|
-
internalEvent = fallbackRewrites.internalEvent;
|
|
92
|
-
isExternalRewrite = fallbackRewrites.isExternalRewrite;
|
|
93
|
-
}
|
|
94
|
-
// Api routes are not present in the routes manifest except if they're not behind /api
|
|
95
|
-
// /api even if it's a page route doesn't get generated in the manifest
|
|
96
|
-
// Ideally we would need to properly check api routes here
|
|
97
|
-
const isApiRoute = internalEvent.rawPath === apiPrefix ||
|
|
98
|
-
internalEvent.rawPath.startsWith(`${apiPrefix}/`);
|
|
99
|
-
const isNextImageRoute = internalEvent.rawPath.startsWith("/_next/image");
|
|
100
|
-
const isRouteFoundBeforeAllRewrites = isStaticRoute || isDynamicRoute || isExternalRewrite;
|
|
101
|
-
// If we still haven't found a route, we show the 404 page
|
|
102
|
-
// We need to ensure that rewrites are applied before showing the 404 page
|
|
103
|
-
if (!(isRouteFoundBeforeAllRewrites ||
|
|
104
|
-
isApiRoute ||
|
|
105
|
-
isNextImageRoute ||
|
|
106
|
-
// We need to check again once all rewrites have been applied
|
|
107
|
-
staticRouteMatcher(internalEvent.rawPath).length > 0 ||
|
|
108
|
-
dynamicRouteMatcher(internalEvent.rawPath).length > 0)) {
|
|
109
|
-
internalEvent = {
|
|
110
|
-
...internalEvent,
|
|
111
|
-
rawPath: "/404",
|
|
112
|
-
url: constructNextUrl(internalEvent.url, "/404"),
|
|
113
|
-
headers: {
|
|
114
|
-
...internalEvent.headers,
|
|
115
|
-
"x-middleware-response-cache-control": "private, no-cache, no-store, max-age=0, must-revalidate",
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
if (globalThis.openNextConfig.dangerous?.enableCacheInterception &&
|
|
120
|
-
!("statusCode" in internalEvent)) {
|
|
121
|
-
debug("Cache interception enabled");
|
|
122
|
-
internalEvent = await cacheInterceptor(internalEvent);
|
|
51
|
+
const nextHeaders = getNextConfigHeaders(event, ConfigHeaders);
|
|
52
|
+
let internalEvent = fixDataPage(event, BuildId);
|
|
123
53
|
if ("statusCode" in internalEvent) {
|
|
124
|
-
applyMiddlewareHeaders(internalEvent.headers, {
|
|
125
|
-
...middlewareResponseHeaders,
|
|
126
|
-
...nextHeaders,
|
|
127
|
-
}, false);
|
|
128
54
|
return internalEvent;
|
|
129
55
|
}
|
|
56
|
+
const redirect = handleRedirects(internalEvent, RoutesManifest.redirects);
|
|
57
|
+
if (redirect) {
|
|
58
|
+
debug("redirect", redirect);
|
|
59
|
+
return redirect;
|
|
60
|
+
}
|
|
61
|
+
const eventOrResult = await handleMiddleware(internalEvent);
|
|
62
|
+
const isResult = "statusCode" in eventOrResult;
|
|
63
|
+
if (isResult) {
|
|
64
|
+
return eventOrResult;
|
|
65
|
+
}
|
|
66
|
+
const middlewareResponseHeaders = eventOrResult.responseHeaders;
|
|
67
|
+
let isExternalRewrite = eventOrResult.isExternalRewrite ?? false;
|
|
68
|
+
// internalEvent is `InternalEvent | MiddlewareEvent`
|
|
69
|
+
internalEvent = eventOrResult;
|
|
70
|
+
if (!isExternalRewrite) {
|
|
71
|
+
// First rewrite to be applied
|
|
72
|
+
const beforeRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.beforeFiles);
|
|
73
|
+
internalEvent = beforeRewrites.internalEvent;
|
|
74
|
+
isExternalRewrite = beforeRewrites.isExternalRewrite;
|
|
75
|
+
}
|
|
76
|
+
const foundStaticRoute = staticRouteMatcher(internalEvent.rawPath);
|
|
77
|
+
const isStaticRoute = !isExternalRewrite && foundStaticRoute.length > 0;
|
|
78
|
+
if (!(isStaticRoute || isExternalRewrite)) {
|
|
79
|
+
// Second rewrite to be applied
|
|
80
|
+
const afterRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.afterFiles);
|
|
81
|
+
internalEvent = afterRewrites.internalEvent;
|
|
82
|
+
isExternalRewrite = afterRewrites.isExternalRewrite;
|
|
83
|
+
}
|
|
84
|
+
// We want to run this just before the dynamic route check
|
|
85
|
+
const { event: fallbackEvent, isISR } = handleFallbackFalse(internalEvent, PrerenderManifest);
|
|
86
|
+
internalEvent = fallbackEvent;
|
|
87
|
+
const foundDynamicRoute = dynamicRouteMatcher(internalEvent.rawPath);
|
|
88
|
+
const isDynamicRoute = !isExternalRewrite && foundDynamicRoute.length > 0;
|
|
89
|
+
if (!(isDynamicRoute || isStaticRoute || isExternalRewrite)) {
|
|
90
|
+
// Fallback rewrite to be applied
|
|
91
|
+
const fallbackRewrites = handleRewrites(internalEvent, RoutesManifest.rewrites.fallback);
|
|
92
|
+
internalEvent = fallbackRewrites.internalEvent;
|
|
93
|
+
isExternalRewrite = fallbackRewrites.isExternalRewrite;
|
|
94
|
+
}
|
|
95
|
+
// Api routes are not present in the routes manifest except if they're not behind /api
|
|
96
|
+
// /api even if it's a page route doesn't get generated in the manifest
|
|
97
|
+
// Ideally we would need to properly check api routes here
|
|
98
|
+
const isApiRoute = internalEvent.rawPath === apiPrefix ||
|
|
99
|
+
internalEvent.rawPath.startsWith(`${apiPrefix}/`);
|
|
100
|
+
const isNextImageRoute = internalEvent.rawPath.startsWith("/_next/image");
|
|
101
|
+
const isRouteFoundBeforeAllRewrites = isStaticRoute || isDynamicRoute || isExternalRewrite;
|
|
102
|
+
// If we still haven't found a route, we show the 404 page
|
|
103
|
+
// We need to ensure that rewrites are applied before showing the 404 page
|
|
104
|
+
if (!(isRouteFoundBeforeAllRewrites ||
|
|
105
|
+
isApiRoute ||
|
|
106
|
+
isNextImageRoute ||
|
|
107
|
+
// We need to check again once all rewrites have been applied
|
|
108
|
+
staticRouteMatcher(internalEvent.rawPath).length > 0 ||
|
|
109
|
+
dynamicRouteMatcher(internalEvent.rawPath).length > 0)) {
|
|
110
|
+
internalEvent = {
|
|
111
|
+
...internalEvent,
|
|
112
|
+
rawPath: "/404",
|
|
113
|
+
url: constructNextUrl(internalEvent.url, "/404"),
|
|
114
|
+
headers: {
|
|
115
|
+
...internalEvent.headers,
|
|
116
|
+
"x-middleware-response-cache-control": "private, no-cache, no-store, max-age=0, must-revalidate",
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (globalThis.openNextConfig.dangerous?.enableCacheInterception &&
|
|
121
|
+
!("statusCode" in internalEvent)) {
|
|
122
|
+
debug("Cache interception enabled");
|
|
123
|
+
internalEvent = await cacheInterceptor(internalEvent);
|
|
124
|
+
if ("statusCode" in internalEvent) {
|
|
125
|
+
applyMiddlewareHeaders(internalEvent.headers, {
|
|
126
|
+
...middlewareResponseHeaders,
|
|
127
|
+
...nextHeaders,
|
|
128
|
+
}, false);
|
|
129
|
+
return internalEvent;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// We apply the headers from the middleware response last
|
|
133
|
+
applyMiddlewareHeaders(internalEvent.headers, {
|
|
134
|
+
...middlewareResponseHeaders,
|
|
135
|
+
...nextHeaders,
|
|
136
|
+
});
|
|
137
|
+
const resolvedRoutes = [
|
|
138
|
+
...foundStaticRoute,
|
|
139
|
+
...foundDynamicRoute,
|
|
140
|
+
];
|
|
141
|
+
debug("resolvedRoutes", resolvedRoutes);
|
|
142
|
+
return {
|
|
143
|
+
internalEvent,
|
|
144
|
+
isExternalRewrite,
|
|
145
|
+
origin: false,
|
|
146
|
+
isISR,
|
|
147
|
+
resolvedRoutes,
|
|
148
|
+
initialURL: event.url,
|
|
149
|
+
locale: NextConfig.i18n
|
|
150
|
+
? detectLocale(internalEvent, NextConfig.i18n)
|
|
151
|
+
: undefined,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
error("Error in routingHandler", e);
|
|
156
|
+
// In case of an error, we want to return the 500 page from Next.js
|
|
157
|
+
return {
|
|
158
|
+
internalEvent: {
|
|
159
|
+
type: "core",
|
|
160
|
+
method: "GET",
|
|
161
|
+
rawPath: "/500",
|
|
162
|
+
url: constructNextUrl(event.url, "/500"),
|
|
163
|
+
headers: {
|
|
164
|
+
...event.headers,
|
|
165
|
+
},
|
|
166
|
+
query: event.query,
|
|
167
|
+
cookies: event.cookies,
|
|
168
|
+
remoteAddress: event.remoteAddress,
|
|
169
|
+
},
|
|
170
|
+
isExternalRewrite: false,
|
|
171
|
+
origin: false,
|
|
172
|
+
isISR: false,
|
|
173
|
+
resolvedRoutes: [],
|
|
174
|
+
initialURL: event.url,
|
|
175
|
+
locale: NextConfig.i18n
|
|
176
|
+
? detectLocale(event, NextConfig.i18n)
|
|
177
|
+
: undefined,
|
|
178
|
+
};
|
|
130
179
|
}
|
|
131
|
-
// We apply the headers from the middleware response last
|
|
132
|
-
applyMiddlewareHeaders(internalEvent.headers, {
|
|
133
|
-
...middlewareResponseHeaders,
|
|
134
|
-
...nextHeaders,
|
|
135
|
-
});
|
|
136
|
-
const resolvedRoutes = [
|
|
137
|
-
...foundStaticRoute,
|
|
138
|
-
...foundDynamicRoute,
|
|
139
|
-
];
|
|
140
|
-
debug("resolvedRoutes", resolvedRoutes);
|
|
141
|
-
return {
|
|
142
|
-
internalEvent,
|
|
143
|
-
isExternalRewrite,
|
|
144
|
-
origin: false,
|
|
145
|
-
isISR,
|
|
146
|
-
resolvedRoutes,
|
|
147
|
-
initialURL: event.url,
|
|
148
|
-
locale: NextConfig.i18n
|
|
149
|
-
? detectLocale(internalEvent, NextConfig.i18n)
|
|
150
|
-
: undefined,
|
|
151
|
-
};
|
|
152
180
|
}
|
package/dist/plugins/edge.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import type { MiddlewareInfo } from "../types/next-types.js";
|
|
|
3
3
|
export interface IPluginSettings {
|
|
4
4
|
nextDir: string;
|
|
5
5
|
middlewareInfo?: MiddlewareInfo;
|
|
6
|
-
|
|
6
|
+
isInCloudflare?: boolean;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* @param opts.nextDir - The path to the .next directory
|
|
10
10
|
* @param opts.middlewareInfo - Information about the middleware
|
|
11
|
-
* @param opts.
|
|
11
|
+
* @param opts.isInCloudflare - Whether the code runs on the cloudflare runtime
|
|
12
12
|
* @returns
|
|
13
13
|
*/
|
|
14
|
-
export declare function openNextEdgePlugins({ nextDir, middlewareInfo,
|
|
14
|
+
export declare function openNextEdgePlugins({ nextDir, middlewareInfo, isInCloudflare, }: IPluginSettings): Plugin;
|
package/dist/plugins/edge.js
CHANGED
|
@@ -7,10 +7,10 @@ import { getCrossPlatformPathRegex } from "../utils/regex.js";
|
|
|
7
7
|
/**
|
|
8
8
|
* @param opts.nextDir - The path to the .next directory
|
|
9
9
|
* @param opts.middlewareInfo - Information about the middleware
|
|
10
|
-
* @param opts.
|
|
10
|
+
* @param opts.isInCloudflare - Whether the code runs on the cloudflare runtime
|
|
11
11
|
* @returns
|
|
12
12
|
*/
|
|
13
|
-
export function openNextEdgePlugins({ nextDir, middlewareInfo,
|
|
13
|
+
export function openNextEdgePlugins({ nextDir, middlewareInfo, isInCloudflare, }) {
|
|
14
14
|
const entryFiles = middlewareInfo?.files.map((file) => path.join(nextDir, file)) ?? [];
|
|
15
15
|
const routes = middlewareInfo
|
|
16
16
|
? [
|
|
@@ -54,7 +54,7 @@ globalThis._ENTRIES = {};
|
|
|
54
54
|
globalThis.self = globalThis;
|
|
55
55
|
globalThis._ROUTES = ${JSON.stringify(routes)};
|
|
56
56
|
|
|
57
|
-
${
|
|
57
|
+
${isInCloudflare
|
|
58
58
|
? ""
|
|
59
59
|
: `
|
|
60
60
|
import {readFileSync} from "node:fs";
|
|
@@ -97,11 +97,7 @@ if (!globalThis.URLPattern) {
|
|
|
97
97
|
await import("urlpattern-polyfill");
|
|
98
98
|
}
|
|
99
99
|
`}
|
|
100
|
-
${wasmFiles
|
|
101
|
-
.map((file) => isInCloudfare
|
|
102
|
-
? `import ${file.name} from './wasm/${file.name}.wasm';`
|
|
103
|
-
: `const ${file.name} = readFileSync(path.join(__dirname,'/wasm/${file.name}.wasm'));`)
|
|
104
|
-
.join("\n")}
|
|
100
|
+
${importWasm(wasmFiles, { isInCloudflare })}
|
|
105
101
|
${entryFiles.map((file) => `require("${file}");`).join("\n")}
|
|
106
102
|
${contents}
|
|
107
103
|
`;
|
|
@@ -153,3 +149,17 @@ ${contents}
|
|
|
153
149
|
},
|
|
154
150
|
};
|
|
155
151
|
}
|
|
152
|
+
function importWasm(files, { isInCloudflare }) {
|
|
153
|
+
return files
|
|
154
|
+
.map(({ name }) => {
|
|
155
|
+
if (isInCloudflare) {
|
|
156
|
+
// As `.next/server/src/middleware.js` references the name,
|
|
157
|
+
// using `import ${name} from '...'` would cause ESBuild to rename the import.
|
|
158
|
+
// We use `globalThis.${name}` to make sure `middleware.js` reference name will match.
|
|
159
|
+
return `import __onw_${name}__ from './wasm/${name}.wasm'
|
|
160
|
+
globalThis.${name} = __onw_${name}__`;
|
|
161
|
+
}
|
|
162
|
+
return `const ${name} = readFileSync(path.join(__dirname,'/wasm/${name}.wasm'));`;
|
|
163
|
+
})
|
|
164
|
+
.join("\n");
|
|
165
|
+
}
|