@opennextjs/aws 3.7.6 → 3.8.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/dist/adapters/middleware.js +3 -1
- package/dist/build/compileConfig.d.ts +20 -5
- package/dist/build/compileConfig.js +26 -11
- package/dist/build/copyTracedFiles.d.ts +1 -0
- package/dist/build/copyTracedFiles.js +7 -2
- package/dist/build/edge/createEdgeBundle.js +2 -1
- package/dist/build/installDeps.js +1 -1
- package/dist/build.js +2 -1
- package/dist/core/requestHandler.js +1 -1
- package/dist/core/routing/cacheInterceptor.d.ts +2 -2
- package/dist/core/routing/cacheInterceptor.js +10 -4
- package/dist/core/routing/middleware.d.ts +1 -6
- package/dist/core/routing/middleware.js +1 -1
- package/dist/core/routingHandler.js +14 -4
- package/dist/types/open-next.d.ts +15 -0
- package/dist/utils/cache.js +6 -2
- package/package.json +1 -1
|
@@ -75,7 +75,9 @@ const defaultHandler = async (internalEvent, options) => {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
if (process.env.OPEN_NEXT_REQUEST_ID_HEADER || globalThis.openNextDebug) {
|
|
79
|
+
result.headers[INTERNAL_EVENT_REQUEST_ID] = requestId;
|
|
80
|
+
}
|
|
79
81
|
debug("Middleware response", result);
|
|
80
82
|
return result;
|
|
81
83
|
});
|
|
@@ -4,18 +4,33 @@ import type { OpenNextConfig } from "../types/open-next.js";
|
|
|
4
4
|
*
|
|
5
5
|
* The configuration is always compiled for Node.js and for the edge only if needed.
|
|
6
6
|
*
|
|
7
|
-
* @param
|
|
8
|
-
* @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
|
|
7
|
+
* @param openNextConfigPath Path to the configuration file. Absolute or relative to cwd.
|
|
9
8
|
* @param nodeExternals Coma separated list of Externals for the Node.js compilation.
|
|
10
9
|
* @param compileEdge Force compiling for the edge runtime when true
|
|
11
10
|
* @return The configuration and the build directory.
|
|
12
11
|
*/
|
|
13
|
-
export declare function compileOpenNextConfig(
|
|
12
|
+
export declare function compileOpenNextConfig(openNextConfigPath: string, { nodeExternals, compileEdge }?: {
|
|
14
13
|
nodeExternals?: string | undefined;
|
|
15
14
|
compileEdge?: boolean | undefined;
|
|
16
15
|
}): Promise<{
|
|
17
16
|
config: OpenNextConfig;
|
|
18
17
|
buildDir: string;
|
|
19
18
|
}>;
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Compiles the OpenNext configuration for Node.
|
|
21
|
+
*
|
|
22
|
+
* @param openNextConfigPath Path to the configuration file. Absolute or relative to cwd.
|
|
23
|
+
* @param outputDir Folder where to output the compiled config file (`open-next.config.mjs`).
|
|
24
|
+
* @param externals List of packages that should not be bundled.
|
|
25
|
+
* @return Path to the compiled config.
|
|
26
|
+
*/
|
|
27
|
+
export declare function compileOpenNextConfigNode(openNextConfigPath: string, outputDir: string, externals: string[]): string;
|
|
28
|
+
/**
|
|
29
|
+
* Compiles the OpenNext configuration for Edge.
|
|
30
|
+
*
|
|
31
|
+
* @param openNextConfigPath Path to the configuration file. Absolute or relative to cwd.
|
|
32
|
+
* @param outputDir Folder where to output the compiled config file (`open-next.config.edge.mjs`).
|
|
33
|
+
* @param externals List of packages that should not be bundled.
|
|
34
|
+
* @return Path to the compiled config.
|
|
35
|
+
*/
|
|
36
|
+
export declare function compileOpenNextConfigEdge(openNextConfigPath: string, outputDir: string, externals: string[]): string;
|
|
@@ -9,16 +9,14 @@ import { validateConfig } from "./validateConfig.js";
|
|
|
9
9
|
*
|
|
10
10
|
* The configuration is always compiled for Node.js and for the edge only if needed.
|
|
11
11
|
*
|
|
12
|
-
* @param
|
|
13
|
-
* @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
|
|
12
|
+
* @param openNextConfigPath Path to the configuration file. Absolute or relative to cwd.
|
|
14
13
|
* @param nodeExternals Coma separated list of Externals for the Node.js compilation.
|
|
15
14
|
* @param compileEdge Force compiling for the edge runtime when true
|
|
16
15
|
* @return The configuration and the build directory.
|
|
17
16
|
*/
|
|
18
|
-
export async function compileOpenNextConfig(
|
|
19
|
-
const sourcePath = path.join(baseDir, openNextConfigPath ?? "open-next.config.ts");
|
|
17
|
+
export async function compileOpenNextConfig(openNextConfigPath, { nodeExternals = "", compileEdge = false } = {}) {
|
|
20
18
|
const buildDir = fs.mkdtempSync(path.join(os.tmpdir(), "open-next-tmp"));
|
|
21
|
-
let configPath = compileOpenNextConfigNode(
|
|
19
|
+
let configPath = compileOpenNextConfigNode(openNextConfigPath, buildDir, nodeExternals.split(","));
|
|
22
20
|
// On Windows, we need to use file:// protocol to load the config file using import()
|
|
23
21
|
if (process.platform === "win32")
|
|
24
22
|
configPath = `file://${configPath}`;
|
|
@@ -33,7 +31,7 @@ export async function compileOpenNextConfig(baseDir, openNextConfigPath, { nodeE
|
|
|
33
31
|
const usesEdgeRuntime = (config.middleware?.external && config.middleware.runtime !== "node") ||
|
|
34
32
|
Object.values(config.functions || {}).some((fn) => fn.runtime === "edge");
|
|
35
33
|
if (usesEdgeRuntime || compileEdge) {
|
|
36
|
-
compileOpenNextConfigEdge(
|
|
34
|
+
compileOpenNextConfigEdge(openNextConfigPath, buildDir, config.edgeExternals ?? []);
|
|
37
35
|
}
|
|
38
36
|
else {
|
|
39
37
|
// Skip compiling for the edge runtime.
|
|
@@ -41,18 +39,26 @@ export async function compileOpenNextConfig(baseDir, openNextConfigPath, { nodeE
|
|
|
41
39
|
}
|
|
42
40
|
return { config, buildDir };
|
|
43
41
|
}
|
|
44
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Compiles the OpenNext configuration for Node.
|
|
44
|
+
*
|
|
45
|
+
* @param openNextConfigPath Path to the configuration file. Absolute or relative to cwd.
|
|
46
|
+
* @param outputDir Folder where to output the compiled config file (`open-next.config.mjs`).
|
|
47
|
+
* @param externals List of packages that should not be bundled.
|
|
48
|
+
* @return Path to the compiled config.
|
|
49
|
+
*/
|
|
50
|
+
export function compileOpenNextConfigNode(openNextConfigPath, outputDir, externals) {
|
|
45
51
|
const outputPath = path.join(outputDir, "open-next.config.mjs");
|
|
46
52
|
logger.debug("Compiling open-next.config.ts for Node.", outputPath);
|
|
47
53
|
//Check if open-next.config.ts exists
|
|
48
|
-
if (!fs.existsSync(
|
|
54
|
+
if (!fs.existsSync(openNextConfigPath)) {
|
|
49
55
|
//Create a simple open-next.config.mjs file
|
|
50
56
|
logger.debug("Cannot find open-next.config.ts. Using default config.");
|
|
51
57
|
fs.writeFileSync(outputPath, "export default { default: { } };");
|
|
52
58
|
}
|
|
53
59
|
else {
|
|
54
60
|
buildSync({
|
|
55
|
-
entryPoints: [
|
|
61
|
+
entryPoints: [openNextConfigPath],
|
|
56
62
|
outfile: outputPath,
|
|
57
63
|
bundle: true,
|
|
58
64
|
format: "esm",
|
|
@@ -71,11 +77,19 @@ export function compileOpenNextConfigNode(sourcePath, outputDir, externals) {
|
|
|
71
77
|
}
|
|
72
78
|
return outputPath;
|
|
73
79
|
}
|
|
74
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Compiles the OpenNext configuration for Edge.
|
|
82
|
+
*
|
|
83
|
+
* @param openNextConfigPath Path to the configuration file. Absolute or relative to cwd.
|
|
84
|
+
* @param outputDir Folder where to output the compiled config file (`open-next.config.edge.mjs`).
|
|
85
|
+
* @param externals List of packages that should not be bundled.
|
|
86
|
+
* @return Path to the compiled config.
|
|
87
|
+
*/
|
|
88
|
+
export function compileOpenNextConfigEdge(openNextConfigPath, outputDir, externals) {
|
|
75
89
|
const outputPath = path.join(outputDir, "open-next.config.edge.mjs");
|
|
76
90
|
logger.debug("Compiling open-next.config.ts for edge runtime.", outputPath);
|
|
77
91
|
buildSync({
|
|
78
|
-
entryPoints: [
|
|
92
|
+
entryPoints: [openNextConfigPath],
|
|
79
93
|
outfile: outputPath,
|
|
80
94
|
bundle: true,
|
|
81
95
|
format: "esm",
|
|
@@ -88,4 +102,5 @@ export function compileOpenNextConfigEdge(sourcePath, outputDir, externals) {
|
|
|
88
102
|
"process.env.NODE_ENV": '"production"',
|
|
89
103
|
},
|
|
90
104
|
});
|
|
105
|
+
return outputPath;
|
|
91
106
|
}
|
|
@@ -18,8 +18,13 @@ const EXCLUDED_PACKAGES = [
|
|
|
18
18
|
"next/dist/compiled/babel-packages",
|
|
19
19
|
"next/dist/compiled/amphtml-validator",
|
|
20
20
|
];
|
|
21
|
-
function isExcluded(srcPath) {
|
|
22
|
-
return EXCLUDED_PACKAGES.some((excluded) =>
|
|
21
|
+
export function isExcluded(srcPath) {
|
|
22
|
+
return EXCLUDED_PACKAGES.some((excluded) =>
|
|
23
|
+
// `pnpm` can create a symbolic link that points to the pnpm store folder
|
|
24
|
+
// This will live under `/node_modules/sharp`. We need to handle this in our regex
|
|
25
|
+
srcPath.match(getCrossPlatformPathRegex(`/node_modules/${excluded}(?:/|$)`, {
|
|
26
|
+
escape: false,
|
|
27
|
+
})));
|
|
23
28
|
}
|
|
24
29
|
function copyPatchFile(outputDir) {
|
|
25
30
|
const patchFile = path.join(__dirname, "patch", "patchedAsyncStorage.js");
|
|
@@ -15,7 +15,8 @@ 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
16
|
const isInCloudflare = await isEdgeRuntime(overrides);
|
|
17
17
|
function override(target) {
|
|
18
|
-
return typeof overrides?.[target] === "string"
|
|
18
|
+
return typeof overrides?.[target] === "string" ||
|
|
19
|
+
typeof overrides?.[target] === "function"
|
|
19
20
|
? overrides[target]
|
|
20
21
|
: undefined;
|
|
21
22
|
}
|
|
@@ -63,7 +63,7 @@ export function installDependencies(outputDir, installOptions) {
|
|
|
63
63
|
logger.info(`Dependencies installed for ${name}`);
|
|
64
64
|
}
|
|
65
65
|
catch (e) {
|
|
66
|
-
logger.error(e.
|
|
66
|
+
logger.error(e.toString());
|
|
67
67
|
logger.error("Could not install dependencies");
|
|
68
68
|
}
|
|
69
69
|
}
|
package/dist/build.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import url from "node:url";
|
|
2
3
|
import { buildNextjsApp, setStandaloneBuildMode, } from "./build/buildNextApp.js";
|
|
3
4
|
import { compileCache } from "./build/compileCache.js";
|
|
@@ -17,7 +18,7 @@ export async function build(openNextConfigPath, nodeExternals) {
|
|
|
17
18
|
showWarningOnWindows();
|
|
18
19
|
const baseDir = process.cwd();
|
|
19
20
|
const openNextDistDir = url.fileURLToPath(new URL(".", import.meta.url));
|
|
20
|
-
const { config, buildDir } = await compileOpenNextConfig(baseDir, openNextConfigPath, { nodeExternals });
|
|
21
|
+
const { config, buildDir } = await compileOpenNextConfig(path.join(baseDir, openNextConfigPath ?? "open-next.config.ts"), { nodeExternals });
|
|
21
22
|
// Initialize options
|
|
22
23
|
const options = buildHelper.normalizeOptions(config, openNextDistDir, buildDir);
|
|
23
24
|
logger.setLevel(options.debug ? "debug" : "info");
|
|
@@ -31,7 +31,7 @@ export async function openNextHandler(internalEvent, options) {
|
|
|
31
31
|
initialHeaders.host = initialHeaders["x-forwarded-host"];
|
|
32
32
|
}
|
|
33
33
|
debug("internalEvent", internalEvent);
|
|
34
|
-
// These
|
|
34
|
+
// These 3 will get overwritten by the routing handler if not using an external middleware
|
|
35
35
|
const internalHeaders = {
|
|
36
36
|
initialPath: initialHeaders[INTERNAL_HEADER_INITIAL_URL] ?? internalEvent.rawPath,
|
|
37
37
|
resolvedRoutes: initialHeaders[INTERNAL_HEADER_RESOLVED_ROUTES]
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { InternalEvent, InternalResult } from "../../types/open-next";
|
|
2
|
-
export declare function cacheInterceptor(event:
|
|
1
|
+
import type { InternalEvent, InternalResult, MiddlewareEvent } from "../../types/open-next";
|
|
2
|
+
export declare function cacheInterceptor(event: MiddlewareEvent): Promise<InternalEvent | InternalResult>;
|
|
@@ -103,8 +103,12 @@ async function generateResult(event, localizedPath, cachedValue, lastModified) {
|
|
|
103
103
|
const cacheControl = await computeCacheControl(localizedPath, body, event.headers.host, cachedValue.revalidate, lastModified);
|
|
104
104
|
return {
|
|
105
105
|
type: "core",
|
|
106
|
-
//
|
|
107
|
-
|
|
106
|
+
// Sometimes other status codes can be cached, like 404. For these cases, we should return the correct status code
|
|
107
|
+
// Also set the status code to the rewriteStatusCode if defined
|
|
108
|
+
// This can happen in handleMiddleware in routingHandler.
|
|
109
|
+
// `NextResponse.rewrite(url, { status: xxx})
|
|
110
|
+
// The rewrite status code should take precedence over the cached one
|
|
111
|
+
statusCode: event.rewriteStatusCode ?? cachedValue.meta?.status ?? 200,
|
|
108
112
|
body: toReadableStream(body, false),
|
|
109
113
|
isBase64Encoded: false,
|
|
110
114
|
headers: {
|
|
@@ -178,7 +182,9 @@ export async function cacheInterceptor(event) {
|
|
|
178
182
|
if (cachedData.value?.type === "app" ||
|
|
179
183
|
cachedData.value?.type === "route") {
|
|
180
184
|
const tags = getTagsFromValue(cachedData.value);
|
|
181
|
-
const _hasBeenRevalidated =
|
|
185
|
+
const _hasBeenRevalidated = cachedData.shouldBypassTagCache
|
|
186
|
+
? false
|
|
187
|
+
: await hasBeenRevalidated(localizedPath, tags, cachedData);
|
|
182
188
|
if (_hasBeenRevalidated) {
|
|
183
189
|
return event;
|
|
184
190
|
}
|
|
@@ -207,7 +213,7 @@ export async function cacheInterceptor(event) {
|
|
|
207
213
|
const isBinary = isBinaryContentType(String(cachedData.value.meta?.headers?.["content-type"]));
|
|
208
214
|
return {
|
|
209
215
|
type: "core",
|
|
210
|
-
statusCode: cachedData.value.meta?.status ?? 200,
|
|
216
|
+
statusCode: event.rewriteStatusCode ?? cachedData.value.meta?.status ?? 200,
|
|
211
217
|
body: toReadableStream(cachedData.value.body, isBinary),
|
|
212
218
|
headers: {
|
|
213
219
|
...cacheControl,
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import type { InternalEvent, InternalResult } from "../../types/open-next.js";
|
|
2
|
-
type MiddlewareEvent = InternalEvent & {
|
|
3
|
-
responseHeaders?: Record<string, string | string[]>;
|
|
4
|
-
isExternalRewrite?: boolean;
|
|
5
|
-
rewriteStatusCode?: number;
|
|
6
|
-
};
|
|
1
|
+
import type { InternalEvent, InternalResult, MiddlewareEvent } from "../../types/open-next.js";
|
|
7
2
|
type Middleware = (request: Request) => Response | Promise<Response>;
|
|
8
3
|
type MiddlewareLoader = () => Promise<{
|
|
9
4
|
default: Middleware;
|
|
@@ -151,6 +151,6 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
|
|
|
151
151
|
cookies: internalEvent.cookies,
|
|
152
152
|
remoteAddress: internalEvent.remoteAddress,
|
|
153
153
|
isExternalRewrite,
|
|
154
|
-
rewriteStatusCode: statusCode,
|
|
154
|
+
rewriteStatusCode: rewriteUrl && !isExternalRewrite ? statusCode : undefined,
|
|
155
155
|
};
|
|
156
156
|
}
|
|
@@ -79,10 +79,20 @@ export default async function routingHandler(event, { assetResolver }) {
|
|
|
79
79
|
if (isInternalResult(middlewareEventOrResult)) {
|
|
80
80
|
return middlewareEventOrResult;
|
|
81
81
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
const middlewareHeadersPrioritized = globalThis.openNextConfig.dangerous
|
|
83
|
+
?.middlewareHeadersOverrideNextConfigHeaders ?? false;
|
|
84
|
+
if (middlewareHeadersPrioritized) {
|
|
85
|
+
headers = {
|
|
86
|
+
...headers,
|
|
87
|
+
...middlewareEventOrResult.responseHeaders,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
headers = {
|
|
92
|
+
...middlewareEventOrResult.responseHeaders,
|
|
93
|
+
...headers,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
86
96
|
let isExternalRewrite = middlewareEventOrResult.isExternalRewrite ?? false;
|
|
87
97
|
eventOrResult = middlewareEventOrResult;
|
|
88
98
|
if (!isExternalRewrite) {
|
|
@@ -15,6 +15,11 @@ export type InternalEvent = {
|
|
|
15
15
|
readonly cookies: Record<string, string>;
|
|
16
16
|
readonly remoteAddress: string;
|
|
17
17
|
} & BaseEventOrResult<"core">;
|
|
18
|
+
export type MiddlewareEvent = InternalEvent & {
|
|
19
|
+
responseHeaders?: Record<string, string | string[]>;
|
|
20
|
+
isExternalRewrite?: boolean;
|
|
21
|
+
rewriteStatusCode?: number;
|
|
22
|
+
};
|
|
18
23
|
export type InternalResult = {
|
|
19
24
|
statusCode: number;
|
|
20
25
|
headers: Record<string, string | string[]>;
|
|
@@ -58,6 +63,16 @@ export interface DangerousOptions {
|
|
|
58
63
|
* This is executed for every request and after next config headers and middleware has executed.
|
|
59
64
|
*/
|
|
60
65
|
headersAndCookiesPriority?: (event: InternalEvent) => "middleware" | "handler";
|
|
66
|
+
/**
|
|
67
|
+
* Configuration option to prioritize headers set via middleware over headers set via the option in the Next config.
|
|
68
|
+
*
|
|
69
|
+
* The default will change to 'true' in v4.
|
|
70
|
+
*
|
|
71
|
+
* See also {@link https://nextjs.org/docs/app/api-reference/file-conventions/middleware#execution-order}
|
|
72
|
+
*
|
|
73
|
+
* @default false
|
|
74
|
+
*/
|
|
75
|
+
middlewareHeadersOverrideNextConfigHeaders?: boolean;
|
|
61
76
|
}
|
|
62
77
|
export type BaseOverride = {
|
|
63
78
|
name: string;
|
package/dist/utils/cache.js
CHANGED
|
@@ -13,7 +13,9 @@ export async function hasBeenRevalidated(key, tags, cacheEntry) {
|
|
|
13
13
|
}
|
|
14
14
|
const lastModified = cacheEntry.lastModified ?? Date.now();
|
|
15
15
|
if (globalThis.tagCache.mode === "nextMode") {
|
|
16
|
-
return
|
|
16
|
+
return tags.length === 0
|
|
17
|
+
? false
|
|
18
|
+
: await globalThis.tagCache.hasBeenRevalidated(tags, lastModified);
|
|
17
19
|
}
|
|
18
20
|
// TODO: refactor this, we should introduce a new method in the tagCache interface so that both implementations use hasBeenRevalidated
|
|
19
21
|
const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified);
|
|
@@ -25,7 +27,9 @@ export function getTagsFromValue(value) {
|
|
|
25
27
|
}
|
|
26
28
|
// The try catch is necessary for older version of next.js that may fail on this
|
|
27
29
|
try {
|
|
28
|
-
|
|
30
|
+
const cacheTags = value.meta?.headers?.["x-next-cache-tags"]?.split(",") ?? [];
|
|
31
|
+
delete value.meta?.headers?.["x-next-cache-tags"];
|
|
32
|
+
return cacheTags;
|
|
29
33
|
}
|
|
30
34
|
catch (e) {
|
|
31
35
|
return [];
|