@opennextjs/aws 3.8.2 → 3.8.4
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/core/routing/routeMatcher.js +2 -2
- package/dist/core/routing/util.js +2 -0
- package/dist/overrides/converters/aws-apigw-v2.js +4 -2
- package/dist/overrides/converters/aws-cloudfront.js +2 -1
- package/dist/overrides/converters/edge.js +5 -3
- package/dist/overrides/originResolver/pattern-env.js +49 -19
- package/dist/overrides/wrappers/cloudflare-node.js +43 -6
- package/package.json +1 -1
|
@@ -63,8 +63,8 @@ function getStaticAPIRoutes() {
|
|
|
63
63
|
.map(createRouteDefinition);
|
|
64
64
|
// We filter out both static API and page routes from the app paths manifest
|
|
65
65
|
const appPathsStaticAPIRoutes = Object.values(AppPathRoutesManifest)
|
|
66
|
-
.filter((route) => route.startsWith("/api/") ||
|
|
67
|
-
|
|
66
|
+
.filter((route) => (route.startsWith("/api/") || route === "/api") &&
|
|
67
|
+
!dynamicRoutePages.has(route))
|
|
68
68
|
.map(createRouteDefinition);
|
|
69
69
|
return [...pagesStaticAPIRoutes, ...appPathsStaticAPIRoutes];
|
|
70
70
|
}
|
|
@@ -126,6 +126,8 @@ export function convertToQueryString(query) {
|
|
|
126
126
|
* @__PURE__
|
|
127
127
|
*/
|
|
128
128
|
export function convertToQuery(querystring) {
|
|
129
|
+
if (!querystring)
|
|
130
|
+
return {};
|
|
129
131
|
const query = new URLSearchParams(querystring);
|
|
130
132
|
const queryObject = {};
|
|
131
133
|
for (const key of query.keys()) {
|
|
@@ -47,8 +47,10 @@ function normalizeAPIGatewayProxyEventV2Headers(event) {
|
|
|
47
47
|
if (Array.isArray(cookies)) {
|
|
48
48
|
headers.cookie = cookies.join("; ");
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
if (rawHeaders) {
|
|
51
|
+
for (const [key, value] of Object.entries(rawHeaders)) {
|
|
52
|
+
headers[key.toLowerCase()] = value;
|
|
53
|
+
}
|
|
52
54
|
}
|
|
53
55
|
return headers;
|
|
54
56
|
}
|
|
@@ -48,9 +48,10 @@ const cloudfrontReadOnlyHeaders = [
|
|
|
48
48
|
function normalizeCloudFrontRequestEventHeaders(rawHeaders) {
|
|
49
49
|
const headers = {};
|
|
50
50
|
for (const [key, values] of Object.entries(rawHeaders)) {
|
|
51
|
+
const lowerKey = key.toLowerCase();
|
|
51
52
|
for (const { value } of values) {
|
|
52
53
|
if (value) {
|
|
53
|
-
headers[
|
|
54
|
+
headers[lowerKey] = value;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
}
|
|
@@ -9,8 +9,6 @@ const converter = {
|
|
|
9
9
|
const url = new URL(event.url);
|
|
10
10
|
const searchParams = url.searchParams;
|
|
11
11
|
const query = getQueryFromSearchParams(searchParams);
|
|
12
|
-
// Transform body into Buffer
|
|
13
|
-
const body = await event.arrayBuffer();
|
|
14
12
|
const headers = {};
|
|
15
13
|
event.headers.forEach((value, key) => {
|
|
16
14
|
headers[key] = value;
|
|
@@ -18,6 +16,10 @@ const converter = {
|
|
|
18
16
|
const rawPath = url.pathname;
|
|
19
17
|
const method = event.method;
|
|
20
18
|
const shouldHaveBody = method !== "GET" && method !== "HEAD";
|
|
19
|
+
// Only read body for methods that should have one
|
|
20
|
+
const body = shouldHaveBody
|
|
21
|
+
? Buffer.from(await event.arrayBuffer())
|
|
22
|
+
: undefined;
|
|
21
23
|
const cookieHeader = event.headers.get("cookie");
|
|
22
24
|
const cookies = cookieHeader
|
|
23
25
|
? cookieParser.parse(cookieHeader)
|
|
@@ -27,7 +29,7 @@ const converter = {
|
|
|
27
29
|
method,
|
|
28
30
|
rawPath,
|
|
29
31
|
url: event.url,
|
|
30
|
-
body
|
|
32
|
+
body,
|
|
31
33
|
headers,
|
|
32
34
|
remoteAddress: event.headers.get("x-forwarded-for") ?? "::1",
|
|
33
35
|
query,
|
|
@@ -1,31 +1,61 @@
|
|
|
1
1
|
import { debug, error } from "../../adapters/logger";
|
|
2
|
+
// Cache parsed origins and compiled patterns at module level
|
|
3
|
+
let cachedOrigins;
|
|
4
|
+
const cachedPatterns = [];
|
|
5
|
+
let initialized = false;
|
|
6
|
+
/**
|
|
7
|
+
* Initializes the cached values on the first execution
|
|
8
|
+
*/
|
|
9
|
+
function initializeOnce() {
|
|
10
|
+
if (initialized)
|
|
11
|
+
return;
|
|
12
|
+
// Parse origin JSON once
|
|
13
|
+
cachedOrigins = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}");
|
|
14
|
+
// Pre-compile all regex patterns
|
|
15
|
+
const functions = globalThis.openNextConfig.functions ?? {};
|
|
16
|
+
for (const key in functions) {
|
|
17
|
+
if (key !== "default") {
|
|
18
|
+
const value = functions[key];
|
|
19
|
+
const regexes = [];
|
|
20
|
+
for (const pattern of value.patterns) {
|
|
21
|
+
// Convert cloudfront pattern to regex
|
|
22
|
+
const regexPattern = `/${pattern
|
|
23
|
+
.replace(/\*\*/g, "(.*)")
|
|
24
|
+
.replace(/\*/g, "([^/]*)")
|
|
25
|
+
.replace(/\//g, "\\/")
|
|
26
|
+
.replace(/\?/g, ".")}`;
|
|
27
|
+
regexes.push(new RegExp(regexPattern));
|
|
28
|
+
}
|
|
29
|
+
cachedPatterns.push({
|
|
30
|
+
key,
|
|
31
|
+
patterns: value.patterns,
|
|
32
|
+
regexes,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
initialized = true;
|
|
37
|
+
}
|
|
2
38
|
const envLoader = {
|
|
3
39
|
name: "env",
|
|
4
40
|
resolve: async (_path) => {
|
|
5
41
|
try {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.replace(/\*/g, "([^/]*)")
|
|
15
|
-
.replace(/\//g, "\\/")
|
|
16
|
-
.replace(/\?/g, ".")}`).test(_path);
|
|
17
|
-
})) {
|
|
18
|
-
debug("Using origin", key, value.patterns);
|
|
19
|
-
return origin[key];
|
|
42
|
+
initializeOnce();
|
|
43
|
+
// Test against pre-compiled patterns
|
|
44
|
+
for (const { key, patterns, regexes } of cachedPatterns) {
|
|
45
|
+
for (const regex of regexes) {
|
|
46
|
+
if (regex.test(_path)) {
|
|
47
|
+
debug("Using origin", key, patterns);
|
|
48
|
+
return cachedOrigins[key];
|
|
49
|
+
}
|
|
20
50
|
}
|
|
21
51
|
}
|
|
22
|
-
if (_path.startsWith("/_next/image") &&
|
|
52
|
+
if (_path.startsWith("/_next/image") && cachedOrigins.imageOptimizer) {
|
|
23
53
|
debug("Using origin", "imageOptimizer", _path);
|
|
24
|
-
return
|
|
54
|
+
return cachedOrigins.imageOptimizer;
|
|
25
55
|
}
|
|
26
|
-
if (
|
|
27
|
-
debug("Using default origin",
|
|
28
|
-
return
|
|
56
|
+
if (cachedOrigins.default) {
|
|
57
|
+
debug("Using default origin", cachedOrigins.default, _path);
|
|
58
|
+
return cachedOrigins.default;
|
|
29
59
|
}
|
|
30
60
|
return false;
|
|
31
61
|
}
|
|
@@ -25,18 +25,55 @@ const handler = async (handler, converter) => async (request, env, ctx, abortSig
|
|
|
25
25
|
if (url.hostname === "localhost") {
|
|
26
26
|
responseHeaders.set("Content-Encoding", "identity");
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// Optimize: skip ReadableStream creation for null body statuses
|
|
29
|
+
if (NULL_BODY_STATUSES.has(statusCode)) {
|
|
30
|
+
const response = new Response(null, {
|
|
31
|
+
status: statusCode,
|
|
32
|
+
headers: responseHeaders,
|
|
33
|
+
});
|
|
34
|
+
resolveResponse(response);
|
|
35
|
+
// Return a no-op Writable that discards all data
|
|
36
|
+
return new Writable({
|
|
37
|
+
write(chunk, encoding, callback) {
|
|
38
|
+
callback();
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
let controller;
|
|
43
|
+
const readable = new ReadableStream({
|
|
44
|
+
start(c) {
|
|
45
|
+
controller = c;
|
|
31
46
|
},
|
|
32
47
|
});
|
|
33
|
-
const
|
|
34
|
-
const response = new Response(body, {
|
|
48
|
+
const response = new Response(readable, {
|
|
35
49
|
status: statusCode,
|
|
36
50
|
headers: responseHeaders,
|
|
37
51
|
});
|
|
38
52
|
resolveResponse(response);
|
|
39
|
-
return Writable
|
|
53
|
+
return new Writable({
|
|
54
|
+
write(chunk, encoding, callback) {
|
|
55
|
+
controller.enqueue(chunk);
|
|
56
|
+
callback();
|
|
57
|
+
},
|
|
58
|
+
final(callback) {
|
|
59
|
+
controller.close();
|
|
60
|
+
callback();
|
|
61
|
+
},
|
|
62
|
+
destroy(error, callback) {
|
|
63
|
+
if (error) {
|
|
64
|
+
controller.error(error);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
try {
|
|
68
|
+
controller.close();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Ignore "This ReadableStream is closed" error
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
callback(error);
|
|
75
|
+
},
|
|
76
|
+
});
|
|
40
77
|
},
|
|
41
78
|
// This is for passing along the original abort signal from the initial Request you retrieve in your worker
|
|
42
79
|
// Ensures that the response we pass to NextServer is aborted if the request is aborted
|