@opennextjs/aws 3.7.3 → 3.7.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/copyTracedFiles.js +5 -1
- package/dist/build/createServerBundle.js +1 -0
- package/dist/build/installDeps.js +3 -2
- package/dist/build/patch/patches/index.d.ts +1 -0
- package/dist/build/patch/patches/index.js +1 -0
- package/dist/build/patch/patches/patchNextServer.d.ts +0 -4
- package/dist/build/patch/patches/patchNextServer.js +0 -16
- package/dist/build/patch/patches/patchNodeEnvironment.d.ts +8 -0
- package/dist/build/patch/patches/patchNodeEnvironment.js +27 -0
- package/dist/build.js +1 -1
- package/dist/core/routing/cacheInterceptor.js +16 -0
- package/dist/http/openNextResponse.js +12 -1
- package/dist/overrides/wrappers/cloudflare-node.js +5 -1
- package/dist/overrides/wrappers/express-dev.js +5 -0
- package/dist/overrides/wrappers/node.js +8 -1
- package/dist/types/open-next.d.ts +1 -0
- package/package.json +1 -1
|
@@ -13,6 +13,10 @@ const EXCLUDED_PACKAGES = [
|
|
|
13
13
|
// This seems to be only in Next 15
|
|
14
14
|
// Some of sharp deps are under the @img scope
|
|
15
15
|
"@img",
|
|
16
|
+
"typescript",
|
|
17
|
+
"next/dist/compiled/babel",
|
|
18
|
+
"next/dist/compiled/babel-packages",
|
|
19
|
+
"next/dist/compiled/amphtml-validator",
|
|
16
20
|
];
|
|
17
21
|
function isExcluded(srcPath) {
|
|
18
22
|
return EXCLUDED_PACKAGES.some((excluded) => srcPath.match(getCrossPlatformPathRegex(`/node_modules/${excluded}/`)));
|
|
@@ -167,7 +171,7 @@ File ${serverPath} does not exist
|
|
|
167
171
|
const tracedFiles = [];
|
|
168
172
|
//Actually copy the files
|
|
169
173
|
filesToCopy.forEach((to, from) => {
|
|
170
|
-
// We don't want to copy excluded packages (
|
|
174
|
+
// We don't want to copy excluded packages (e.g. sharp)
|
|
171
175
|
if (isExcluded(from)) {
|
|
172
176
|
return;
|
|
173
177
|
}
|
|
@@ -126,6 +126,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
126
126
|
patches.patchEnvVars,
|
|
127
127
|
patches.patchBackgroundRevalidation,
|
|
128
128
|
patches.patchUseCacheForISR,
|
|
129
|
+
patches.patchNodeEnvironment,
|
|
129
130
|
...additionalCodePatches,
|
|
130
131
|
]);
|
|
131
132
|
// Build Lambda code
|
|
@@ -3,6 +3,7 @@ import os from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { execSync } from "node:child_process";
|
|
5
5
|
import logger from "../logger.js";
|
|
6
|
+
const AFFECTED_NODE_VERSIONS = ["22.17.0", "22.17.1", "22.18.0"];
|
|
6
7
|
export function installDependencies(outputDir, installOptions) {
|
|
7
8
|
try {
|
|
8
9
|
if (!installOptions) {
|
|
@@ -37,8 +38,8 @@ export function installDependencies(outputDir, installOptions) {
|
|
|
37
38
|
fs.cpSync(path.join(tempInstallDir, "node_modules"), path.join(outputDir, "node_modules"), { recursive: true, force: true, dereference: true });
|
|
38
39
|
// This is a workaround for Node `22.17.0` and `22.17.1`
|
|
39
40
|
// https://github.com/nodejs/node/issues/59168
|
|
40
|
-
const nodeVersion = process.
|
|
41
|
-
if (
|
|
41
|
+
const nodeVersion = process.versions.node;
|
|
42
|
+
if (AFFECTED_NODE_VERSIONS.includes(nodeVersion)) {
|
|
42
43
|
const tempBinDir = path.join(tempInstallDir, "node_modules", ".bin");
|
|
43
44
|
const outputBinDir = path.join(outputDir, "node_modules", ".bin");
|
|
44
45
|
for (const fileName of fs.readdirSync(tempBinDir)) {
|
|
@@ -3,3 +3,4 @@ export { patchNextServer } from "./patchNextServer.js";
|
|
|
3
3
|
export { patchFetchCacheForISR, patchUnstableCacheForISR, patchUseCacheForISR, } from "./patchFetchCacheISR.js";
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
5
|
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
6
|
+
export { patchNodeEnvironment } from "./patchNodeEnvironment.js";
|
|
@@ -3,3 +3,4 @@ export { patchNextServer } from "./patchNextServer.js";
|
|
|
3
3
|
export { patchFetchCacheForISR, patchUnstableCacheForISR, patchUseCacheForISR, } from "./patchFetchCacheISR.js";
|
|
4
4
|
export { patchFetchCacheSetMissingWaitUntil } from "./patchFetchCacheWaitUntil.js";
|
|
5
5
|
export { patchBackgroundRevalidation } from "./patchBackgroundRevalidation.js";
|
|
6
|
+
export { patchNodeEnvironment } from "./patchNodeEnvironment.js";
|
|
@@ -8,8 +8,4 @@ export declare const removeMiddlewareManifestRule = "\nrule:\n kind: statement_
|
|
|
8
8
|
* @returns A rule to replace the body with a `throw`
|
|
9
9
|
*/
|
|
10
10
|
export declare function createEmptyBodyRule(methodName: string): string;
|
|
11
|
-
/**
|
|
12
|
-
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
13
|
-
*/
|
|
14
|
-
export declare const errorInspectRule = "\nrule:\n pattern: require(\"./node-environment-extensions/error-inspect\");\nfix: |-\n // Removed by OpenNext\n // require(\"./node-environment-extensions/error-inspect\");\n";
|
|
15
11
|
export declare const patchNextServer: CodePatcher;
|
|
@@ -48,16 +48,6 @@ fix: |-
|
|
|
48
48
|
}
|
|
49
49
|
`;
|
|
50
50
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
53
|
-
*/
|
|
54
|
-
export const errorInspectRule = `
|
|
55
|
-
rule:
|
|
56
|
-
pattern: require("./node-environment-extensions/error-inspect");
|
|
57
|
-
fix: |-
|
|
58
|
-
// Removed by OpenNext
|
|
59
|
-
// require("./node-environment-extensions/error-inspect");
|
|
60
|
-
`;
|
|
61
51
|
const pathFilter = getCrossPlatformPathRegex(String.raw `/next/dist/server/next-server\.js$`, {
|
|
62
52
|
escape: false,
|
|
63
53
|
});
|
|
@@ -81,12 +71,6 @@ const babelPatches = [
|
|
|
81
71
|
contentFilter: /runEdgeFunction\(/,
|
|
82
72
|
patchCode: createPatchCode(createEmptyBodyRule("runEdgeFunction")),
|
|
83
73
|
},
|
|
84
|
-
// Drop `error-inspect` that pulls babel
|
|
85
|
-
{
|
|
86
|
-
pathFilter,
|
|
87
|
-
contentFilter: /error-inspect/,
|
|
88
|
-
patchCode: createPatchCode(errorInspectRule),
|
|
89
|
-
},
|
|
90
74
|
];
|
|
91
75
|
export const patchNextServer = {
|
|
92
76
|
name: "patch-next-server",
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CodePatcher } from "../codePatcher.js";
|
|
2
|
+
/**
|
|
3
|
+
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
4
|
+
*
|
|
5
|
+
* This is to avoid pulling babel (~4MB)
|
|
6
|
+
*/
|
|
7
|
+
export declare const rule = "\nrule:\n pattern: require(\"./node-environment-extensions/error-inspect\");\nfix: |-\n // Removed by OpenNext\n // require(\"./node-environment-extensions/error-inspect\");\n";
|
|
8
|
+
export declare const patchNodeEnvironment: CodePatcher;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getCrossPlatformPathRegex } from "../../../utils/regex.js";
|
|
2
|
+
import { createPatchCode } from "../astCodePatcher.js";
|
|
3
|
+
/**
|
|
4
|
+
* Drops `require("./node-environment-extensions/error-inspect");`
|
|
5
|
+
*
|
|
6
|
+
* This is to avoid pulling babel (~4MB)
|
|
7
|
+
*/
|
|
8
|
+
export const rule = `
|
|
9
|
+
rule:
|
|
10
|
+
pattern: require("./node-environment-extensions/error-inspect");
|
|
11
|
+
fix: |-
|
|
12
|
+
// Removed by OpenNext
|
|
13
|
+
// require("./node-environment-extensions/error-inspect");
|
|
14
|
+
`;
|
|
15
|
+
export const patchNodeEnvironment = {
|
|
16
|
+
name: "patch-node-environment-error-inspect",
|
|
17
|
+
patches: [
|
|
18
|
+
{
|
|
19
|
+
pathFilter: getCrossPlatformPathRegex(String.raw `/next/dist/server/node-environment\.js$`, {
|
|
20
|
+
escape: false,
|
|
21
|
+
}),
|
|
22
|
+
contentFilter: /error-inspect/,
|
|
23
|
+
patchCode: createPatchCode(rule),
|
|
24
|
+
versions: ">=15.0.0",
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
package/dist/build.js
CHANGED
|
@@ -28,10 +28,10 @@ export async function build(openNextConfigPath, nodeExternals) {
|
|
|
28
28
|
// Build Next.js app
|
|
29
29
|
printHeader("Building Next.js app");
|
|
30
30
|
setStandaloneBuildMode(options);
|
|
31
|
+
buildHelper.initOutputDir(options);
|
|
31
32
|
buildNextjsApp(options);
|
|
32
33
|
// Generate deployable bundle
|
|
33
34
|
printHeader("Generating bundle");
|
|
34
|
-
buildHelper.initOutputDir(options);
|
|
35
35
|
// Compile cache.ts
|
|
36
36
|
compileCache(options);
|
|
37
37
|
// Compile middleware
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { NextConfig, PrerenderManifest } from "../../adapters/config/index";
|
|
3
3
|
import { emptyReadableStream, toReadableStream } from "../../utils/stream";
|
|
4
|
+
import { isBinaryContentType } from "../../utils/binary";
|
|
4
5
|
import { getTagsFromValue, hasBeenRevalidated } from "../../utils/cache";
|
|
5
6
|
import { debug } from "../../adapters/logger";
|
|
6
7
|
import { localizePath } from "./i18n";
|
|
@@ -200,6 +201,21 @@ export async function cacheInterceptor(event) {
|
|
|
200
201
|
isBase64Encoded: false,
|
|
201
202
|
};
|
|
202
203
|
}
|
|
204
|
+
case "route": {
|
|
205
|
+
const cacheControl = await computeCacheControl(localizedPath, cachedData.value.body, host, cachedData.value.revalidate, cachedData.lastModified);
|
|
206
|
+
const isBinary = isBinaryContentType(String(cachedData.value.meta?.headers?.["content-type"]));
|
|
207
|
+
return {
|
|
208
|
+
type: "core",
|
|
209
|
+
statusCode: cachedData.value.meta?.status ?? 200,
|
|
210
|
+
body: toReadableStream(cachedData.value.body, isBinary),
|
|
211
|
+
headers: {
|
|
212
|
+
...cacheControl,
|
|
213
|
+
...cachedData.value.meta?.headers,
|
|
214
|
+
vary: VARY_HEADER,
|
|
215
|
+
},
|
|
216
|
+
isBase64Encoded: isBinary,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
203
219
|
default:
|
|
204
220
|
return event;
|
|
205
221
|
}
|
|
@@ -57,9 +57,20 @@ export class OpenNextNodeResponse extends Transform {
|
|
|
57
57
|
this.onEnd = onEnd;
|
|
58
58
|
this.streamCreator = streamCreator;
|
|
59
59
|
this.initialHeaders = initialHeaders;
|
|
60
|
-
if
|
|
60
|
+
// We only set the status code if it is not a NaN and it is a number
|
|
61
|
+
// Only allow status codes between 100 and 599 https://httpwg.org/specs/rfc9110.html#status.codes
|
|
62
|
+
if (statusCode &&
|
|
63
|
+
Number.isInteger(statusCode) &&
|
|
64
|
+
statusCode >= 100 &&
|
|
65
|
+
statusCode <= 599) {
|
|
61
66
|
this.statusCode = statusCode;
|
|
62
67
|
}
|
|
68
|
+
// https://github.com/vercel/next.js/blob/ea08bf2/packages/next/src/server/web/spec-extension/adapters/next-request.ts#L46-L54
|
|
69
|
+
// We want to destroy this response when the original response/request is closed. (i.e when the client disconnects)
|
|
70
|
+
// This is to support `request.signal.onabort` in route handlers
|
|
71
|
+
streamCreator?.abortSignal?.addEventListener("abort", () => {
|
|
72
|
+
this.destroy();
|
|
73
|
+
});
|
|
63
74
|
}
|
|
64
75
|
// Necessary for next 12
|
|
65
76
|
// We might have to implement all the methods here
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Writable } from "node:stream";
|
|
2
2
|
// Response with null body status (101, 204, 205, or 304) cannot have a body.
|
|
3
3
|
const NULL_BODY_STATUSES = new Set([101, 204, 205, 304]);
|
|
4
|
-
const handler = async (handler, converter) => async (request, env, ctx) => {
|
|
4
|
+
const handler = async (handler, converter) => async (request, env, ctx, abortSignal) => {
|
|
5
5
|
globalThis.process = process;
|
|
6
6
|
// Set the environment variables
|
|
7
7
|
// Cloudflare suggests to not override the process.env object but instead apply the values to it
|
|
@@ -38,6 +38,10 @@ const handler = async (handler, converter) => async (request, env, ctx) => {
|
|
|
38
38
|
resolveResponse(response);
|
|
39
39
|
return Writable.fromWeb(writable);
|
|
40
40
|
},
|
|
41
|
+
// This is for passing along the original abort signal from the initial Request you retrieve in your worker
|
|
42
|
+
// Ensures that the response we pass to NextServer is aborted if the request is aborted
|
|
43
|
+
// By doing this `request.signal.onabort` will work in route handlers
|
|
44
|
+
abortSignal: abortSignal,
|
|
41
45
|
};
|
|
42
46
|
ctx.waitUntil(handler(internalEvent, {
|
|
43
47
|
streamCreator,
|
|
@@ -27,6 +27,7 @@ const wrapper = async (handler, converter) => {
|
|
|
27
27
|
req.headers["x-forwarded-proto"] = req.protocol;
|
|
28
28
|
}
|
|
29
29
|
const internalEvent = await converter.convertFrom(req);
|
|
30
|
+
const abortController = new AbortController();
|
|
30
31
|
const streamCreator = {
|
|
31
32
|
writeHeaders: (prelude) => {
|
|
32
33
|
res.setHeader("Set-Cookie", prelude.cookies);
|
|
@@ -35,7 +36,11 @@ const wrapper = async (handler, converter) => {
|
|
|
35
36
|
return res;
|
|
36
37
|
},
|
|
37
38
|
onFinish: () => { },
|
|
39
|
+
abortSignal: abortController.signal,
|
|
38
40
|
};
|
|
41
|
+
res.on("close", () => {
|
|
42
|
+
abortController.abort();
|
|
43
|
+
});
|
|
39
44
|
await handler(internalEvent, { streamCreator });
|
|
40
45
|
});
|
|
41
46
|
const server = app.listen(Number.parseInt(process.env.PORT ?? "3000", 10), () => {
|
|
@@ -3,6 +3,7 @@ import { debug, error } from "../../adapters/logger";
|
|
|
3
3
|
const wrapper = async (handler, converter) => {
|
|
4
4
|
const server = createServer(async (req, res) => {
|
|
5
5
|
const internalEvent = await converter.convertFrom(req);
|
|
6
|
+
const abortController = new AbortController();
|
|
6
7
|
const streamCreator = {
|
|
7
8
|
writeHeaders: (prelude) => {
|
|
8
9
|
res.setHeader("Set-Cookie", prelude.cookies);
|
|
@@ -10,7 +11,11 @@ const wrapper = async (handler, converter) => {
|
|
|
10
11
|
res.flushHeaders();
|
|
11
12
|
return res;
|
|
12
13
|
},
|
|
14
|
+
abortSignal: abortController.signal,
|
|
13
15
|
};
|
|
16
|
+
res.on("close", () => {
|
|
17
|
+
abortController.abort();
|
|
18
|
+
});
|
|
14
19
|
if (internalEvent.rawPath === "/__health") {
|
|
15
20
|
res.writeHead(200, {
|
|
16
21
|
"Content-Type": "text/plain",
|
|
@@ -18,7 +23,9 @@ const wrapper = async (handler, converter) => {
|
|
|
18
23
|
res.end("OK");
|
|
19
24
|
}
|
|
20
25
|
else {
|
|
21
|
-
await handler(internalEvent, {
|
|
26
|
+
await handler(internalEvent, {
|
|
27
|
+
streamCreator,
|
|
28
|
+
});
|
|
22
29
|
}
|
|
23
30
|
});
|
|
24
31
|
await new Promise((resolve) => {
|