@opennextjs/aws 3.5.6 → 3.5.8
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/adapters/cache.js +4 -1
- package/dist/adapters/image-optimization-adapter.js +14 -12
- package/dist/build/copyTracedFiles.d.ts +1 -0
- package/dist/build/copyTracedFiles.js +41 -22
- package/dist/build/createAssets.d.ts +11 -1
- package/dist/build/createAssets.js +18 -3
- package/dist/build/createServerBundle.js +3 -1
- package/dist/build/patch/patches/index.d.ts +1 -0
- package/dist/build/patch/patches/index.js +1 -0
- package/dist/build/patch/patches/patchBackgroundRevalidation.d.ts +11 -0
- package/dist/build/patch/patches/patchBackgroundRevalidation.js +27 -0
- package/dist/core/requestHandler.js +6 -1
- package/dist/core/routing/middleware.js +15 -25
- package/dist/types/next-types.d.ts +1 -0
- package/package.json +1 -1
package/dist/adapters/cache.js
CHANGED
|
@@ -233,8 +233,11 @@ export default class Cache {
|
|
|
233
233
|
if (config?.disableTagCache || config?.disableIncrementalCache) {
|
|
234
234
|
return;
|
|
235
235
|
}
|
|
236
|
+
const _tags = Array.isArray(tags) ? tags : [tags];
|
|
237
|
+
if (_tags.length === 0) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
236
240
|
try {
|
|
237
|
-
const _tags = Array.isArray(tags) ? tags : [tags];
|
|
238
241
|
if (globalThis.tagCache.mode === "nextMode") {
|
|
239
242
|
const paths = (await globalThis.tagCache.getPathsByTags?.(_tags)) ?? [];
|
|
240
243
|
await globalThis.tagCache.writeTags(_tags);
|
|
@@ -50,6 +50,12 @@ export async function defaultHandler(event, options) {
|
|
|
50
50
|
process.env.HOST = headersHost;
|
|
51
51
|
}
|
|
52
52
|
const imageParams = validateImageParams(headers, queryString === null ? undefined : queryString);
|
|
53
|
+
// We return a 400 here if imageParams returns an errorMessage
|
|
54
|
+
// https://github.com/vercel/next.js/blob/512d8283054407ab92b2583ecce3b253c3be7b85/packages/next/src/server/next-server.ts#L937-L941
|
|
55
|
+
if ("errorMessage" in imageParams) {
|
|
56
|
+
error("Error during validation of image params", imageParams.errorMessage);
|
|
57
|
+
return buildFailureResponse(imageParams.errorMessage, options?.streamCreator, 400);
|
|
58
|
+
}
|
|
53
59
|
let etag;
|
|
54
60
|
// We don't cache any images, so in order to be able to return 304 responses, we compute an ETag from what is assumed to be static
|
|
55
61
|
if (process.env.OPENNEXT_STATIC_ETAG) {
|
|
@@ -68,7 +74,8 @@ export async function defaultHandler(event, options) {
|
|
|
68
74
|
return buildSuccessResponse(result, options?.streamCreator, etag);
|
|
69
75
|
}
|
|
70
76
|
catch (e) {
|
|
71
|
-
|
|
77
|
+
error("Failed to optimize image", e);
|
|
78
|
+
return buildFailureResponse("Internal server error", options?.streamCreator);
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
//////////////////////
|
|
@@ -81,9 +88,6 @@ function validateImageParams(headers, query) {
|
|
|
81
88
|
// @ts-ignore
|
|
82
89
|
{ headers }, query, nextConfig, false);
|
|
83
90
|
debug("image params", imageParams);
|
|
84
|
-
if ("errorMessage" in imageParams) {
|
|
85
|
-
throw new Error(imageParams.errorMessage);
|
|
86
|
-
}
|
|
87
91
|
return imageParams;
|
|
88
92
|
}
|
|
89
93
|
function computeEtag(imageParams) {
|
|
@@ -119,28 +123,26 @@ function buildSuccessResponse(result, streamCreator, etag) {
|
|
|
119
123
|
headers,
|
|
120
124
|
};
|
|
121
125
|
}
|
|
122
|
-
function buildFailureResponse(
|
|
123
|
-
debug(
|
|
126
|
+
function buildFailureResponse(errorMessage, streamCreator, statusCode = 500) {
|
|
127
|
+
debug(errorMessage, statusCode);
|
|
124
128
|
if (streamCreator) {
|
|
125
129
|
const response = new OpenNextNodeResponse(() => void 0, async () => void 0, streamCreator);
|
|
126
|
-
response.writeHead(
|
|
130
|
+
response.writeHead(statusCode, {
|
|
127
131
|
Vary: "Accept",
|
|
128
132
|
"Cache-Control": "public,max-age=60,immutable",
|
|
129
|
-
"Content-Type": "application/json",
|
|
130
133
|
});
|
|
131
|
-
response.end(
|
|
134
|
+
response.end(errorMessage);
|
|
132
135
|
}
|
|
133
136
|
return {
|
|
134
137
|
type: "core",
|
|
135
138
|
isBase64Encoded: false,
|
|
136
|
-
statusCode:
|
|
139
|
+
statusCode: statusCode,
|
|
137
140
|
headers: {
|
|
138
141
|
Vary: "Accept",
|
|
139
142
|
// For failed images, allow client to retry after 1 minute.
|
|
140
143
|
"Cache-Control": "public,max-age=60,immutable",
|
|
141
|
-
"Content-Type": "application/json",
|
|
142
144
|
},
|
|
143
|
-
body: toReadableStream(
|
|
145
|
+
body: toReadableStream(errorMessage),
|
|
144
146
|
};
|
|
145
147
|
}
|
|
146
148
|
const loader = await resolveImageLoader(globalThis.openNextConfig.imageOptimization?.loader ?? "s3");
|
|
@@ -17,6 +17,7 @@ export declare function getManifests(nextDir: string): {
|
|
|
17
17
|
};
|
|
18
18
|
export declare function copyTracedFiles({ buildOutputPath, packagePath, outputDir, routes, bundledNextServer, skipServerFiles, }: CopyTracedFilesOptions): Promise<{
|
|
19
19
|
tracedFiles: string[];
|
|
20
|
+
nodePackages: Map<string, string>;
|
|
20
21
|
manifests: {
|
|
21
22
|
buildId: string;
|
|
22
23
|
config: import("../types/next-types.js").NextConfig;
|
|
@@ -41,18 +41,38 @@ export async function copyTracedFiles({ buildOutputPath, packagePath, outputDir,
|
|
|
41
41
|
const standaloneNextDir = path.join(standaloneDir, packagePath, ".next");
|
|
42
42
|
const standaloneServerDir = path.join(standaloneNextDir, "server");
|
|
43
43
|
const outputNextDir = path.join(outputDir, packagePath, ".next");
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
// For next 13, we need to include them otherwise we get runtime error
|
|
47
|
-
const requiredServerFiles = JSON.parse(readFileSync(path.join(dotNextDir, bundledNextServer
|
|
48
|
-
? "next-minimal-server.js.nft.json"
|
|
49
|
-
: "next-server.js.nft.json"), "utf8"));
|
|
44
|
+
// Files to copy
|
|
45
|
+
// Map from files in the `.next/standalone` to files in the `.open-next` folder
|
|
50
46
|
const filesToCopy = new Map();
|
|
47
|
+
// Node packages
|
|
48
|
+
// Map from folders in the project to folders in the `.open-next` folder
|
|
49
|
+
// The map might also include the mono-repo path.
|
|
50
|
+
const nodePackages = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Extracts files and node packages from a .nft.json file
|
|
53
|
+
* @param nftFile path to the .nft.json file relative to `.next/`
|
|
54
|
+
*/
|
|
55
|
+
const processNftFile = (nftFile) => {
|
|
56
|
+
const subDir = path.dirname(nftFile);
|
|
57
|
+
const files = JSON.parse(readFileSync(path.join(dotNextDir, nftFile), "utf8")).files;
|
|
58
|
+
files.forEach((tracedPath) => {
|
|
59
|
+
const src = path.join(standaloneNextDir, subDir, tracedPath);
|
|
60
|
+
const dst = path.join(outputNextDir, subDir, tracedPath);
|
|
61
|
+
filesToCopy.set(src, dst);
|
|
62
|
+
const module = path.join(dotNextDir, subDir, tracedPath);
|
|
63
|
+
if (module.endsWith("package.json")) {
|
|
64
|
+
nodePackages.set(path.dirname(module), path.dirname(dst));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
51
68
|
// Files necessary by the server
|
|
52
69
|
if (!skipServerFiles) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
// On next 14+, we might not have to include those files
|
|
71
|
+
// For next 13, we need to include them otherwise we get runtime error
|
|
72
|
+
const nftFile = bundledNextServer
|
|
73
|
+
? "next-minimal-server.js.nft.json"
|
|
74
|
+
: "next-server.js.nft.json";
|
|
75
|
+
processNftFile(nftFile);
|
|
56
76
|
}
|
|
57
77
|
// create directory for pages
|
|
58
78
|
if (existsSync(path.join(standaloneNextDir, "server/pages"))) {
|
|
@@ -69,13 +89,12 @@ export async function copyTracedFiles({ buildOutputPath, packagePath, outputDir,
|
|
|
69
89
|
recursive: true,
|
|
70
90
|
});
|
|
71
91
|
const computeCopyFilesForPage = (pagePath) => {
|
|
72
|
-
const
|
|
73
|
-
let requiredFiles;
|
|
92
|
+
const serverPath = `server/${pagePath}.js`;
|
|
74
93
|
try {
|
|
75
|
-
|
|
94
|
+
processNftFile(`${serverPath}.nft.json`);
|
|
76
95
|
}
|
|
77
96
|
catch (e) {
|
|
78
|
-
if (existsSync(path.join(
|
|
97
|
+
if (existsSync(path.join(dotNextDir, serverPath))) {
|
|
79
98
|
//TODO: add a link to the docs
|
|
80
99
|
throw new Error(`
|
|
81
100
|
--------------------------------------------------------------------------------
|
|
@@ -88,18 +107,14 @@ See the docs for more information on how to bundle edge runtime functions.
|
|
|
88
107
|
throw new Error(`
|
|
89
108
|
--------------------------------------------------------------------------------
|
|
90
109
|
We cannot find the route for ${pagePath}.
|
|
91
|
-
File ${
|
|
110
|
+
File ${serverPath} does not exist
|
|
92
111
|
--------------------------------------------------------------------------------`);
|
|
93
112
|
}
|
|
94
|
-
|
|
95
|
-
extractFiles(requiredFiles.files, path.join(standaloneNextDir, dir)).forEach((f) => {
|
|
96
|
-
filesToCopy.set(f, f.replace(standaloneDir, outputDir));
|
|
97
|
-
});
|
|
98
|
-
if (!existsSync(path.join(standaloneNextDir, fullFilePath))) {
|
|
113
|
+
if (!existsSync(path.join(standaloneNextDir, serverPath))) {
|
|
99
114
|
throw new Error(`This error should only happen for static 404 and 500 page from page router. Report this if that's not the case.,
|
|
100
|
-
File ${
|
|
115
|
+
File ${serverPath} does not exist`);
|
|
101
116
|
}
|
|
102
|
-
filesToCopy.set(path.join(standaloneNextDir,
|
|
117
|
+
filesToCopy.set(path.join(standaloneNextDir, serverPath), path.join(outputNextDir, serverPath));
|
|
103
118
|
};
|
|
104
119
|
const safeComputeCopyFilesForPage = (pagePath, alternativePath) => {
|
|
105
120
|
try {
|
|
@@ -148,12 +163,15 @@ File ${fullFilePath} does not exist
|
|
|
148
163
|
routes.forEach((route) => {
|
|
149
164
|
computeCopyFilesForPage(route);
|
|
150
165
|
});
|
|
166
|
+
// Only files that are actually copied
|
|
167
|
+
const tracedFiles = [];
|
|
151
168
|
//Actually copy the files
|
|
152
169
|
filesToCopy.forEach((to, from) => {
|
|
153
170
|
// We don't want to copy excluded packages (i.e sharp)
|
|
154
171
|
if (isExcluded(from)) {
|
|
155
172
|
return;
|
|
156
173
|
}
|
|
174
|
+
tracedFiles.push(to);
|
|
157
175
|
mkdirSync(path.dirname(to), { recursive: true });
|
|
158
176
|
let symlink = null;
|
|
159
177
|
// For pnpm symlink we need to do that
|
|
@@ -233,7 +251,8 @@ File ${fullFilePath} does not exist
|
|
|
233
251
|
}
|
|
234
252
|
logger.debug("copyTracedFiles:", Date.now() - tsStart, "ms");
|
|
235
253
|
return {
|
|
236
|
-
tracedFiles
|
|
254
|
+
tracedFiles,
|
|
255
|
+
nodePackages,
|
|
237
256
|
manifests: getManifests(standaloneNextDir),
|
|
238
257
|
};
|
|
239
258
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { TagCacheMetaFile } from "../types/cache.js";
|
|
2
2
|
import * as buildHelper from "./helper.js";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Copy the static assets to the output folder
|
|
5
|
+
*
|
|
6
|
+
* WARNING: `useBasePath` should be set to `false` when the output file is used.
|
|
7
|
+
*
|
|
8
|
+
* @param options OpenNext build options
|
|
9
|
+
* @param useBasePath whether to copy files into the to Next.js configured basePath
|
|
10
|
+
*/
|
|
11
|
+
export declare function createStaticAssets(options: buildHelper.BuildOptions, { useBasePath }?: {
|
|
12
|
+
useBasePath?: boolean | undefined;
|
|
13
|
+
}): void;
|
|
4
14
|
/**
|
|
5
15
|
* Create the cache assets.
|
|
6
16
|
*
|
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { loadConfig } from "../adapters/config/util.js";
|
|
3
4
|
import logger from "../logger.js";
|
|
4
5
|
import { isBinaryContentType } from "../utils/binary.js";
|
|
5
6
|
import * as buildHelper from "./helper.js";
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Copy the static assets to the output folder
|
|
9
|
+
*
|
|
10
|
+
* WARNING: `useBasePath` should be set to `false` when the output file is used.
|
|
11
|
+
*
|
|
12
|
+
* @param options OpenNext build options
|
|
13
|
+
* @param useBasePath whether to copy files into the to Next.js configured basePath
|
|
14
|
+
*/
|
|
15
|
+
export function createStaticAssets(options, { useBasePath = false } = {}) {
|
|
7
16
|
logger.info("Bundling static assets...");
|
|
8
17
|
const { appBuildOutputPath, appPublicPath, outputDir, appPath } = options;
|
|
18
|
+
const NextConfig = loadConfig(path.join(appBuildOutputPath, ".next"));
|
|
19
|
+
const basePath = useBasePath ? (NextConfig.basePath ?? "") : "";
|
|
9
20
|
// Create output folder
|
|
10
|
-
const outputPath = path.join(outputDir, "assets");
|
|
21
|
+
const outputPath = path.join(outputDir, "assets", basePath);
|
|
11
22
|
fs.mkdirSync(outputPath, { recursive: true });
|
|
12
23
|
/**
|
|
13
|
-
* Next.js outputs assets into multiple files.
|
|
24
|
+
* Next.js outputs assets into multiple files.
|
|
25
|
+
*
|
|
26
|
+
* Copy into the same directory:
|
|
27
|
+
* - `.open-next/assets` when `useBasePath` is `false`
|
|
28
|
+
* - `.open-next/assets/basePath` when `useBasePath` is `true`
|
|
14
29
|
*
|
|
15
30
|
* Copy over:
|
|
16
31
|
* - .next/BUILD_ID => BUILD_ID
|
|
@@ -14,7 +14,7 @@ import { copyMiddlewareResources, generateEdgeBundle, } from "./edge/createEdgeB
|
|
|
14
14
|
import * as buildHelper from "./helper.js";
|
|
15
15
|
import { installDependencies } from "./installDeps.js";
|
|
16
16
|
import { applyCodePatches } from "./patch/codePatcher.js";
|
|
17
|
-
import { patchEnvVars, patchFetchCacheForISR, patchFetchCacheSetMissingWaitUntil, patchNextServer, patchUnstableCacheForISR, } from "./patch/patches/index.js";
|
|
17
|
+
import { patchBackgroundRevalidation, patchEnvVars, patchFetchCacheForISR, patchFetchCacheSetMissingWaitUntil, patchNextServer, patchUnstableCacheForISR, } from "./patch/patches/index.js";
|
|
18
18
|
export async function createServerBundle(options, codeCustomization) {
|
|
19
19
|
const { config } = options;
|
|
20
20
|
const foundRoutes = new Set();
|
|
@@ -121,6 +121,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
121
121
|
patchUnstableCacheForISR,
|
|
122
122
|
patchNextServer,
|
|
123
123
|
patchEnvVars,
|
|
124
|
+
patchBackgroundRevalidation,
|
|
124
125
|
...additionalCodePatches,
|
|
125
126
|
]);
|
|
126
127
|
// Build Lambda code
|
|
@@ -146,6 +147,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
146
147
|
...(disableNextPrebundledReact ? ["applyNextjsPrebundledReact"] : []),
|
|
147
148
|
...(disableRouting ? ["withRouting"] : []),
|
|
148
149
|
...(isAfter142 ? ["patchAsyncStorage"] : []),
|
|
150
|
+
...(isAfter141 ? ["appendPrefetch"] : []),
|
|
149
151
|
],
|
|
150
152
|
}),
|
|
151
153
|
openNextReplacementPlugin({
|
|
@@ -2,3 +2,4 @@ export { envVarRuleCreator, patchEnvVars } from "./patchEnvVar.js";
|
|
|
2
2
|
export { patchNextServer } from "./patchNextServer.js";
|
|
3
3
|
export { patchFetchCacheForISR, patchUnstableCacheForISR, } from "./patchFetchCacheISR.js";
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
|
+
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
@@ -2,3 +2,4 @@ export { envVarRuleCreator, patchEnvVars } from "./patchEnvVar.js";
|
|
|
2
2
|
export { patchNextServer } from "./patchNextServer.js";
|
|
3
3
|
export { patchFetchCacheForISR, patchUnstableCacheForISR, } from "./patchFetchCacheISR.js";
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
|
+
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const rule = "\nrule:\n kind: binary_expression\n all:\n - has:\n kind: unary_expression\n regex: \"!cachedResponse.isStale\"\n - has:\n kind: member_expression\n regex: \"context.isPrefetch\"\nfix:\n 'true'";
|
|
2
|
+
export declare const patchBackgroundRevalidation: {
|
|
3
|
+
name: string;
|
|
4
|
+
patches: {
|
|
5
|
+
versions: ">=14.1.0";
|
|
6
|
+
field: {
|
|
7
|
+
pathFilter: RegExp;
|
|
8
|
+
patchCode: import("../codePatcher.js").PatchCodeFn;
|
|
9
|
+
};
|
|
10
|
+
}[];
|
|
11
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getCrossPlatformPathRegex } from "../../../utils/regex.js";
|
|
2
|
+
import { createPatchCode } from "../astCodePatcher.js";
|
|
3
|
+
export const rule = `
|
|
4
|
+
rule:
|
|
5
|
+
kind: binary_expression
|
|
6
|
+
all:
|
|
7
|
+
- has:
|
|
8
|
+
kind: unary_expression
|
|
9
|
+
regex: "!cachedResponse.isStale"
|
|
10
|
+
- has:
|
|
11
|
+
kind: member_expression
|
|
12
|
+
regex: "context.isPrefetch"
|
|
13
|
+
fix:
|
|
14
|
+
'true'`;
|
|
15
|
+
export const patchBackgroundRevalidation = {
|
|
16
|
+
name: "patchBackgroundRevalidation",
|
|
17
|
+
patches: [
|
|
18
|
+
{
|
|
19
|
+
// TODO: test for earlier versions of Next
|
|
20
|
+
versions: ">=14.1.0",
|
|
21
|
+
field: {
|
|
22
|
+
pathFilter: getCrossPlatformPathRegex("server/response-cache/index.js"),
|
|
23
|
+
patchCode: createPatchCode(rule),
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
@@ -115,7 +115,12 @@ export async function openNextHandler(internalEvent, options) {
|
|
|
115
115
|
// 1. We could just let the revalidation go as normal, but due to race conditions the revalidation will be unreliable
|
|
116
116
|
// 2. We could alter the lastModified time of our cache to make next believe that the cache is fresh, but this could cause issues with stale data since the cdn will cache the stale data as if it was fresh
|
|
117
117
|
// 3. OUR CHOICE: We could pass a purpose prefetch header to the serverless function to make next believe that the request is a prefetch request and not trigger revalidation (This could potentially break in the future if next changes the behavior of prefetch requests)
|
|
118
|
-
headers: {
|
|
118
|
+
headers: {
|
|
119
|
+
...headers,
|
|
120
|
+
//#override appendPrefetch
|
|
121
|
+
purpose: "prefetch",
|
|
122
|
+
//#endOverride
|
|
123
|
+
},
|
|
119
124
|
body: preprocessedEvent.body,
|
|
120
125
|
remoteAddress: preprocessedEvent.remoteAddress,
|
|
121
126
|
};
|
|
@@ -71,13 +71,15 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
|
|
|
71
71
|
const responseHeaders = result.headers;
|
|
72
72
|
const reqHeaders = {};
|
|
73
73
|
const resHeaders = {};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
// These are internal headers used by Next.js, we don't want to expose them to the client
|
|
75
|
+
const filteredHeaders = [
|
|
76
|
+
"x-middleware-override-headers",
|
|
77
|
+
"x-middleware-set-cookie",
|
|
78
|
+
"x-middleware-next",
|
|
79
|
+
"x-middleware-rewrite",
|
|
80
|
+
// We need to drop `content-encoding` because it will be decoded
|
|
81
|
+
"content-encoding",
|
|
82
|
+
];
|
|
81
83
|
const xMiddlewareKey = "x-middleware-request-";
|
|
82
84
|
responseHeaders.forEach((value, key) => {
|
|
83
85
|
if (key.startsWith(xMiddlewareKey)) {
|
|
@@ -85,6 +87,8 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
|
|
|
85
87
|
reqHeaders[k] = value;
|
|
86
88
|
}
|
|
87
89
|
else {
|
|
90
|
+
if (filteredHeaders.includes(key.toLowerCase()))
|
|
91
|
+
return;
|
|
88
92
|
if (key.toLowerCase() === "set-cookie") {
|
|
89
93
|
resHeaders[key] = resHeaders[key]
|
|
90
94
|
? [...resHeaders[key], value]
|
|
@@ -95,20 +99,6 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
|
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
});
|
|
98
|
-
// If the middleware returned a Redirect, we set the `Location` header with
|
|
99
|
-
// the redirected url and end the response.
|
|
100
|
-
if (statusCode >= 300 && statusCode < 400) {
|
|
101
|
-
resHeaders.location =
|
|
102
|
-
responseHeaders.get("location") ?? resHeaders.location;
|
|
103
|
-
// res.setHeader("Location", location);
|
|
104
|
-
return {
|
|
105
|
-
body: emptyReadableStream(),
|
|
106
|
-
type: internalEvent.type,
|
|
107
|
-
statusCode: statusCode,
|
|
108
|
-
headers: resHeaders,
|
|
109
|
-
isBase64Encoded: false,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
102
|
// If the middleware returned a Rewrite, set the `url` to the pathname of the rewrite
|
|
113
103
|
// NOTE: the header was added to `req` from above
|
|
114
104
|
const rewriteUrl = responseHeaders.get("x-middleware-rewrite");
|
|
@@ -134,11 +124,11 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
|
|
|
134
124
|
});
|
|
135
125
|
}
|
|
136
126
|
}
|
|
137
|
-
// If the middleware
|
|
138
|
-
//
|
|
139
|
-
if (
|
|
127
|
+
// If the middleware wants to directly return a response (i.e. not using `NextResponse.next()` or `NextResponse.rewrite()`)
|
|
128
|
+
// we return the response directly
|
|
129
|
+
if (!rewriteUrl && !responseHeaders.get("x-middleware-next")) {
|
|
140
130
|
// transfer response body to res
|
|
141
|
-
const body = result.body;
|
|
131
|
+
const body = result.body ?? emptyReadableStream();
|
|
142
132
|
return {
|
|
143
133
|
type: internalEvent.type,
|
|
144
134
|
statusCode: statusCode,
|