@opennextjs/aws 3.2.0 → 3.2.2
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/README.md +15 -1
- package/dist/adapters/cache.d.ts +1 -23
- package/dist/adapters/cache.js +22 -18
- package/dist/adapters/config/index.js +1 -1
- package/dist/adapters/config/util.js +2 -2
- package/dist/adapters/dynamo-provider.js +3 -5
- package/dist/adapters/edge-adapter.d.ts +0 -3
- package/dist/adapters/edge-adapter.js +43 -38
- package/dist/adapters/image-optimization-adapter.js +4 -4
- package/dist/adapters/logger.d.ts +0 -3
- package/dist/adapters/logger.js +3 -5
- package/dist/adapters/middleware.js +42 -18
- package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +0 -3
- package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +0 -3
- package/dist/adapters/revalidate.js +2 -2
- package/dist/adapters/server-adapter.d.ts +0 -3
- package/dist/adapters/server-adapter.js +3 -1
- package/dist/adapters/util.js +2 -2
- package/dist/build/bundleNextServer.d.ts +3 -1
- package/dist/build/bundleNextServer.js +3 -3
- package/dist/build/compileConfig.js +3 -3
- package/dist/build/copyTracedFiles.js +16 -27
- package/dist/build/createAssets.js +35 -26
- package/dist/build/createImageOptimizationBundle.js +4 -1
- package/dist/build/createMiddleware.d.ts +4 -4
- package/dist/build/createMiddleware.js +16 -19
- package/dist/build/createRevalidationBundle.js +1 -1
- package/dist/build/createServerBundle.js +34 -45
- package/dist/build/createWarmerBundle.js +1 -1
- package/dist/build/edge/createEdgeBundle.d.ts +9 -7
- package/dist/build/edge/createEdgeBundle.js +19 -14
- package/dist/build/generateOutput.js +7 -13
- package/dist/build/helper.d.ts +22 -4
- package/dist/build/helper.js +26 -12
- package/dist/build/installDeps.js +12 -2
- package/dist/build/patch/patchedAsyncStorage.js +1 -1
- package/dist/build/utils.js +3 -2
- package/dist/build/validateConfig.js +1 -0
- package/dist/core/createGenericHandler.d.ts +2 -4
- package/dist/core/createGenericHandler.js +6 -7
- package/dist/core/createMainHandler.d.ts +0 -17
- package/dist/core/createMainHandler.js +10 -9
- package/dist/core/edgeFunctionHandler.d.ts +1 -51
- package/dist/core/patchAsyncStorage.js +5 -6
- package/dist/core/requestHandler.js +98 -89
- package/dist/core/require-hooks.js +8 -7
- package/dist/core/resolve.d.ts +13 -7
- package/dist/core/resolve.js +29 -35
- package/dist/core/routing/cacheInterceptor.js +12 -13
- package/dist/core/routing/i18n/accept-header.js +3 -2
- package/dist/core/routing/matcher.d.ts +2 -4
- package/dist/core/routing/matcher.js +29 -31
- package/dist/core/routing/middleware.js +22 -18
- package/dist/core/routing/util.d.ts +0 -13
- package/dist/core/routing/util.js +32 -91
- package/dist/core/routingHandler.d.ts +2 -0
- package/dist/core/routingHandler.js +30 -12
- package/dist/core/util.js +5 -3
- package/dist/helpers/withSST.d.ts +1 -1
- package/dist/http/openNextResponse.d.ts +5 -9
- package/dist/http/openNextResponse.js +29 -31
- package/dist/http/request.d.ts +0 -3
- package/dist/http/request.js +4 -2
- package/dist/http/util.d.ts +1 -1
- package/dist/http/util.js +8 -12
- package/dist/minimize-js.js +19 -19
- package/dist/overrides/converters/aws-apigw-v1.d.ts +2 -2
- package/dist/overrides/converters/aws-apigw-v1.js +2 -1
- package/dist/overrides/converters/aws-apigw-v2.d.ts +2 -2
- package/dist/overrides/converters/aws-apigw-v2.js +6 -7
- package/dist/overrides/converters/aws-cloudfront.d.ts +2 -2
- package/dist/overrides/converters/aws-cloudfront.js +11 -30
- package/dist/overrides/converters/dummy.d.ts +1 -1
- package/dist/overrides/converters/edge.d.ts +5 -1
- package/dist/overrides/converters/edge.js +16 -17
- package/dist/overrides/converters/node.d.ts +1 -1
- package/dist/overrides/converters/node.js +1 -1
- package/dist/overrides/converters/sqs-revalidate.d.ts +1 -1
- package/dist/overrides/imageLoader/dummy.d.ts +1 -1
- package/dist/overrides/imageLoader/host.d.ts +1 -1
- package/dist/overrides/imageLoader/s3.d.ts +1 -1
- package/dist/overrides/imageLoader/s3.js +1 -1
- package/dist/overrides/incrementalCache/dummy.d.ts +1 -1
- package/dist/overrides/incrementalCache/s3-lite.d.ts +1 -1
- package/dist/overrides/incrementalCache/s3-lite.js +15 -19
- package/dist/overrides/incrementalCache/s3.d.ts +1 -1
- package/dist/overrides/incrementalCache/s3.js +1 -1
- package/dist/overrides/originResolver/dummy.d.ts +1 -1
- package/dist/overrides/originResolver/pattern-env.d.ts +1 -1
- package/dist/overrides/originResolver/pattern-env.js +10 -11
- package/dist/overrides/proxyExternalRequest/dummy.d.ts +3 -0
- package/dist/overrides/proxyExternalRequest/dummy.js +7 -0
- package/dist/overrides/proxyExternalRequest/fetch.d.ts +3 -0
- package/dist/overrides/proxyExternalRequest/fetch.js +25 -0
- package/dist/overrides/proxyExternalRequest/node.d.ts +3 -0
- package/dist/overrides/proxyExternalRequest/node.js +67 -0
- package/dist/overrides/queue/dummy.d.ts +1 -1
- package/dist/overrides/queue/sqs-lite.d.ts +1 -1
- package/dist/overrides/queue/sqs-lite.js +7 -9
- package/dist/overrides/queue/sqs.d.ts +1 -1
- package/dist/overrides/queue/sqs.js +1 -1
- package/dist/overrides/tagCache/constants.js +2 -2
- package/dist/overrides/tagCache/dummy.d.ts +1 -1
- package/dist/overrides/tagCache/dynamodb-lite.d.ts +1 -1
- package/dist/overrides/tagCache/dynamodb-lite.js +10 -12
- package/dist/overrides/tagCache/dynamodb.d.ts +1 -1
- package/dist/overrides/tagCache/dynamodb.js +2 -2
- package/dist/overrides/warmer/aws-lambda.d.ts +1 -1
- package/dist/overrides/warmer/dummy.d.ts +1 -1
- package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +2 -2
- package/dist/overrides/wrappers/aws-lambda.d.ts +2 -2
- package/dist/overrides/wrappers/cloudflare.d.ts +2 -1
- package/dist/overrides/wrappers/cloudflare.js +21 -3
- package/dist/overrides/wrappers/dummy.d.ts +2 -2
- package/dist/overrides/wrappers/node.d.ts +2 -2
- package/dist/overrides/wrappers/node.js +3 -3
- package/dist/plugins/edge.d.ts +3 -2
- package/dist/plugins/edge.js +33 -34
- package/dist/plugins/replacement.d.ts +1 -1
- package/dist/plugins/replacement.js +5 -6
- package/dist/plugins/resolve.d.ts +3 -1
- package/dist/plugins/resolve.js +4 -1
- package/dist/types/aws-lambda.d.ts +2 -5
- package/dist/types/cache.d.ts +0 -2
- package/dist/types/global.d.ts +188 -0
- package/dist/types/next-types.d.ts +1 -3
- package/dist/types/open-next.d.ts +24 -45
- package/dist/types/overrides.d.ts +87 -0
- package/dist/utils/promise.d.ts +3 -0
- package/dist/utils/promise.js +44 -0
- package/dist/utils/stream.d.ts +0 -1
- package/package.json +2 -2
- package/dist/adapters/plugins/without-routing/requestHandler.d.ts +0 -2
- package/dist/adapters/plugins/without-routing/requestHandler.js +0 -10
- package/dist/overrides/incrementalCache/types.d.ts +0 -34
- package/dist/overrides/queue/types.d.ts +0 -12
- package/dist/overrides/tagCache/types.d.ts +0 -11
- package/dist/overrides/tagCache/types.js +0 -1
- /package/dist/{overrides/incrementalCache/types.js → types/global.js} +0 -0
- /package/dist/{overrides/queue/types.js → types/overrides.js} +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { Converter
|
|
2
|
-
declare const _default: Converter
|
|
1
|
+
import type { Converter } from "../../types/overrides";
|
|
2
|
+
declare const _default: Converter;
|
|
3
3
|
export default _default;
|
|
@@ -32,21 +32,19 @@ function normalizeAPIGatewayProxyEventV2Body(event) {
|
|
|
32
32
|
if (Buffer.isBuffer(body)) {
|
|
33
33
|
return body;
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
if (typeof body === "string") {
|
|
36
36
|
return Buffer.from(body, isBase64Encoded ? "base64" : "utf8");
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
if (typeof body === "object") {
|
|
39
39
|
return Buffer.from(JSON.stringify(body));
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
return Buffer.from("", "utf8");
|
|
43
|
-
}
|
|
41
|
+
return Buffer.from("", "utf8");
|
|
44
42
|
}
|
|
45
43
|
function normalizeAPIGatewayProxyEventV2Headers(event) {
|
|
46
44
|
const { headers: rawHeaders, cookies } = event;
|
|
47
45
|
const headers = {};
|
|
48
46
|
if (Array.isArray(cookies)) {
|
|
49
|
-
headers
|
|
47
|
+
headers.cookie = cookies.join("; ");
|
|
50
48
|
}
|
|
51
49
|
for (const [key, value] of Object.entries(rawHeaders || {})) {
|
|
52
50
|
headers[key.toLowerCase()] = value;
|
|
@@ -66,7 +64,8 @@ async function convertFromAPIGatewayProxyEventV2(event) {
|
|
|
66
64
|
query: removeUndefinedFromQuery(convertToQuery(rawQueryString)),
|
|
67
65
|
cookies: event.cookies?.reduce((acc, cur) => {
|
|
68
66
|
const [key, value] = cur.split("=");
|
|
69
|
-
|
|
67
|
+
acc[key] = value;
|
|
68
|
+
return acc;
|
|
70
69
|
}, {}) ?? {},
|
|
71
70
|
};
|
|
72
71
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { Converter
|
|
2
|
-
declare const _default: Converter
|
|
1
|
+
import type { Converter } from "../../types/overrides";
|
|
2
|
+
declare const _default: Converter;
|
|
3
3
|
export default _default;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { parseCookies } from "../../http/util";
|
|
2
2
|
import { fromReadableStream } from "../../utils/stream";
|
|
3
3
|
import { debug } from "../../adapters/logger";
|
|
4
|
-
import {
|
|
5
|
-
const
|
|
4
|
+
import { convertToQuery, convertToQueryString, } from "../../core/routing/util";
|
|
5
|
+
const cloudfrontBlacklistedHeaders = [
|
|
6
6
|
// Disallowed headers, see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-function-restrictions-all.html#function-restrictions-disallowed-headers
|
|
7
7
|
"connection",
|
|
8
8
|
"expect",
|
|
@@ -67,8 +67,9 @@ async function convertFromCloudFrontRequestEvent(event) {
|
|
|
67
67
|
remoteAddress: clientIp,
|
|
68
68
|
query: convertToQuery(querystring),
|
|
69
69
|
cookies: headers.cookie?.reduce((acc, cur) => {
|
|
70
|
-
const { key, value } = cur;
|
|
71
|
-
|
|
70
|
+
const { key = "", value } = cur;
|
|
71
|
+
acc[key] = value;
|
|
72
|
+
return acc;
|
|
72
73
|
}, {}) ?? {},
|
|
73
74
|
};
|
|
74
75
|
}
|
|
@@ -76,18 +77,15 @@ function convertToCloudfrontHeaders(headers, directResponse) {
|
|
|
76
77
|
const cloudfrontHeaders = {};
|
|
77
78
|
Object.entries(headers)
|
|
78
79
|
.map(([key, value]) => [key.toLowerCase(), value])
|
|
79
|
-
.filter(([key]) => !
|
|
80
|
+
.filter(([key]) => !cloudfrontBlacklistedHeaders.some((header) => typeof header === "string" ? header === key : header.test(key)) &&
|
|
80
81
|
// Only remove read-only headers when directly responding in lambda@edge
|
|
81
82
|
(directResponse ? !cloudfrontReadOnlyHeaders.includes(key) : true))
|
|
82
83
|
.forEach(([key, value]) => {
|
|
83
84
|
if (key === "set-cookie") {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
value: cookie,
|
|
89
|
-
}));
|
|
90
|
-
}
|
|
85
|
+
cloudfrontHeaders[key] = parseCookies(`${value}`).map((cookie) => ({
|
|
86
|
+
key,
|
|
87
|
+
value: cookie,
|
|
88
|
+
}));
|
|
91
89
|
return;
|
|
92
90
|
}
|
|
93
91
|
cloudfrontHeaders[key] = [
|
|
@@ -104,25 +102,8 @@ async function convertToCloudFrontRequestResult(result, originalRequest) {
|
|
|
104
102
|
const { method, clientIp, origin } = originalRequest.Records[0].cf.request;
|
|
105
103
|
const responseHeaders = result.internalEvent.headers;
|
|
106
104
|
// Handle external rewrite
|
|
107
|
-
if (result.isExternalRewrite) {
|
|
108
|
-
const serverResponse = createServerResponse(result.internalEvent, {});
|
|
109
|
-
await proxyRequest(result.internalEvent, serverResponse);
|
|
110
|
-
const externalResult = convertRes(serverResponse);
|
|
111
|
-
const body = await fromReadableStream(externalResult.body, externalResult.isBase64Encoded);
|
|
112
|
-
const cloudfrontResult = {
|
|
113
|
-
status: externalResult.statusCode.toString(),
|
|
114
|
-
statusDescription: "OK",
|
|
115
|
-
headers: convertToCloudfrontHeaders(externalResult.headers, true),
|
|
116
|
-
bodyEncoding: externalResult.isBase64Encoded
|
|
117
|
-
? "base64"
|
|
118
|
-
: "text",
|
|
119
|
-
body,
|
|
120
|
-
};
|
|
121
|
-
debug("externalResult", cloudfrontResult);
|
|
122
|
-
return cloudfrontResult;
|
|
123
|
-
}
|
|
124
105
|
let customOrigin = origin?.custom;
|
|
125
|
-
let host = responseHeaders
|
|
106
|
+
let host = responseHeaders.host ?? responseHeaders.Host;
|
|
126
107
|
if (result.origin) {
|
|
127
108
|
customOrigin = {
|
|
128
109
|
...customOrigin,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InternalEvent, InternalResult } from "../../types/open-next";
|
|
2
|
+
import type { Converter } from "../../types/overrides";
|
|
2
3
|
import type { MiddlewareOutputEvent } from "../../core/routingHandler";
|
|
4
|
+
declare global {
|
|
5
|
+
var __dangerous_ON_edge_converter_returns_request: boolean | undefined;
|
|
6
|
+
}
|
|
3
7
|
declare const converter: Converter<InternalEvent, InternalResult | ({
|
|
4
8
|
type: "middleware";
|
|
5
9
|
} & MiddlewareOutputEvent)>;
|
|
@@ -5,7 +5,7 @@ const converter = {
|
|
|
5
5
|
const searchParams = new URL(event.url).searchParams;
|
|
6
6
|
const query = {};
|
|
7
7
|
for (const [key, value] of searchParams.entries()) {
|
|
8
|
-
if (query
|
|
8
|
+
if (key in query) {
|
|
9
9
|
if (Array.isArray(query[key])) {
|
|
10
10
|
query[key].push(value);
|
|
11
11
|
}
|
|
@@ -26,19 +26,17 @@ const converter = {
|
|
|
26
26
|
const rawPath = new URL(event.url).pathname;
|
|
27
27
|
const method = event.method;
|
|
28
28
|
const shouldHaveBody = method !== "GET" && method !== "HEAD";
|
|
29
|
+
const cookies = Object.fromEntries(parseCookies(event.headers.get("cookie")).map((cookie) => cookie.split("=")));
|
|
29
30
|
return {
|
|
30
31
|
type: "core",
|
|
31
32
|
method,
|
|
32
33
|
rawPath,
|
|
33
34
|
url: event.url,
|
|
34
35
|
body: shouldHaveBody ? Buffer.from(body) : undefined,
|
|
35
|
-
headers
|
|
36
|
+
headers,
|
|
36
37
|
remoteAddress: event.headers.get("x-forwarded-for") ?? "::1",
|
|
37
38
|
query,
|
|
38
|
-
cookies
|
|
39
|
-
const [key, value] = cookie.split("=");
|
|
40
|
-
return [key, value];
|
|
41
|
-
}) ?? []),
|
|
39
|
+
cookies,
|
|
42
40
|
};
|
|
43
41
|
},
|
|
44
42
|
convertTo: async (result) => {
|
|
@@ -52,7 +50,7 @@ const converter = {
|
|
|
52
50
|
url = `https://${result.internalEvent.headers.host}${url}`;
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
|
-
const
|
|
53
|
+
const request = new Request(url, {
|
|
56
54
|
body: result.internalEvent.body,
|
|
57
55
|
method: result.internalEvent.method,
|
|
58
56
|
headers: {
|
|
@@ -60,28 +58,29 @@ const converter = {
|
|
|
60
58
|
"x-forwarded-host": result.internalEvent.headers.host,
|
|
61
59
|
},
|
|
62
60
|
});
|
|
61
|
+
if (globalThis.__dangerous_ON_edge_converter_returns_request === true) {
|
|
62
|
+
return request;
|
|
63
|
+
}
|
|
63
64
|
const cfCache = (result.isISR ||
|
|
64
65
|
result.internalEvent.rawPath.startsWith("/_next/image")) &&
|
|
65
66
|
process.env.DISABLE_CACHE !== "true"
|
|
66
67
|
? { cacheEverything: true }
|
|
67
68
|
: {};
|
|
68
|
-
return fetch(
|
|
69
|
+
return fetch(request, {
|
|
69
70
|
// This is a hack to make sure that the response is cached by Cloudflare
|
|
70
71
|
// See https://developers.cloudflare.com/workers/examples/cache-using-fetch/#caching-html-resources
|
|
71
72
|
// @ts-expect-error - This is a Cloudflare specific option
|
|
72
73
|
cf: cfCache,
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
headers.set(key, Array.isArray(value) ? value.join(",") : value);
|
|
79
|
-
}
|
|
80
|
-
return new Response(result.body, {
|
|
81
|
-
status: result.statusCode,
|
|
82
|
-
headers: headers,
|
|
83
|
-
});
|
|
76
|
+
const headers = new Headers();
|
|
77
|
+
for (const [key, value] of Object.entries(result.headers)) {
|
|
78
|
+
headers.set(key, Array.isArray(value) ? value.join(",") : value);
|
|
84
79
|
}
|
|
80
|
+
return new Response(result.body, {
|
|
81
|
+
status: result.statusCode,
|
|
82
|
+
headers: headers,
|
|
83
|
+
});
|
|
85
84
|
},
|
|
86
85
|
name: "edge",
|
|
87
86
|
};
|
|
@@ -28,7 +28,7 @@ const converter = {
|
|
|
28
28
|
req.socket.remoteAddress ??
|
|
29
29
|
"::1",
|
|
30
30
|
query,
|
|
31
|
-
cookies: Object.fromEntries(parseCookies(req.headers
|
|
31
|
+
cookies: Object.fromEntries(parseCookies(req.headers.cookie)?.map((cookie) => {
|
|
32
32
|
const [key, value] = cookie.split("=");
|
|
33
33
|
return [key, value];
|
|
34
34
|
}) ?? []),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Converter } from "../../types/
|
|
1
|
+
import type { Converter } from "../../types/overrides";
|
|
2
2
|
import type { RevalidateEvent } from "../../adapters/revalidate";
|
|
3
3
|
declare const converter: Converter<RevalidateEvent, RevalidateEvent>;
|
|
4
4
|
export default converter;
|
|
@@ -16,7 +16,7 @@ const s3Loader = {
|
|
|
16
16
|
const response = await s3Client.send(new GetObjectCommand({
|
|
17
17
|
Bucket: BUCKET_NAME,
|
|
18
18
|
Key: keyPrefix
|
|
19
|
-
? keyPrefix
|
|
19
|
+
? `${keyPrefix}/${key.replace(/^\//, "")}`
|
|
20
20
|
: key.replace(/^\//, ""),
|
|
21
21
|
}));
|
|
22
22
|
const body = response.Body;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { AwsClient } from "aws4fetch";
|
|
3
|
-
import path from "path";
|
|
4
4
|
import { IgnorableError, RecoverableError } from "../../utils/error";
|
|
5
5
|
import { customFetchClient } from "../../utils/fetch";
|
|
6
6
|
import { parseNumberFromEnv } from "../../adapters/util";
|
|
@@ -10,16 +10,14 @@ const getAwsClient = () => {
|
|
|
10
10
|
if (awsClient) {
|
|
11
11
|
return awsClient;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return awsClient;
|
|
22
|
-
}
|
|
13
|
+
awsClient = new AwsClient({
|
|
14
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
15
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
16
|
+
sessionToken: process.env.AWS_SESSION_TOKEN,
|
|
17
|
+
region: CACHE_BUCKET_REGION,
|
|
18
|
+
retries: parseNumberFromEnv(process.env.AWS_SDK_S3_MAX_ATTEMPTS),
|
|
19
|
+
});
|
|
20
|
+
return awsClient;
|
|
23
21
|
};
|
|
24
22
|
const awsFetch = async (key, options) => {
|
|
25
23
|
const { CACHE_BUCKET_REGION, CACHE_BUCKET_NAME } = process.env;
|
|
@@ -39,16 +37,14 @@ const incrementalCache = {
|
|
|
39
37
|
if (result.status === 404) {
|
|
40
38
|
throw new IgnorableError("Not found");
|
|
41
39
|
}
|
|
42
|
-
|
|
40
|
+
if (result.status !== 200) {
|
|
43
41
|
throw new RecoverableError(`Failed to get cache: ${result.status}`);
|
|
44
42
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
}
|
|
43
|
+
const cacheData = await result.json();
|
|
44
|
+
return {
|
|
45
|
+
value: cacheData,
|
|
46
|
+
lastModified: new Date(result.headers.get("last-modified") ?? "").getTime(),
|
|
47
|
+
};
|
|
52
48
|
},
|
|
53
49
|
async set(key, value, isFetch) {
|
|
54
50
|
const response = await awsFetch(buildS3Key(key, isFetch ? "fetch" : "cache"), {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
|
|
2
|
-
import path from "path";
|
|
3
3
|
import { awsLogger } from "../../adapters/logger";
|
|
4
4
|
import { parseNumberFromEnv } from "../../adapters/util";
|
|
5
5
|
const { CACHE_BUCKET_REGION, CACHE_BUCKET_KEY_PREFIX, NEXT_BUILD_ID, CACHE_BUCKET_NAME, } = process.env;
|
|
@@ -9,24 +9,23 @@ const envLoader = {
|
|
|
9
9
|
// Convert cloudfront pattern to regex
|
|
10
10
|
return new RegExp(
|
|
11
11
|
// transform glob pattern to regex
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.replace(/\?/g, ".")).test(_path);
|
|
12
|
+
`/${pattern
|
|
13
|
+
.replace(/\*\*/g, "(.*)")
|
|
14
|
+
.replace(/\*/g, "([^/]*)")
|
|
15
|
+
.replace(/\//g, "\\/")
|
|
16
|
+
.replace(/\?/g, ".")}`).test(_path);
|
|
18
17
|
})) {
|
|
19
18
|
debug("Using origin", key, value.patterns);
|
|
20
19
|
return origin[key];
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
|
-
if (_path.startsWith("/_next/image") && origin
|
|
22
|
+
if (_path.startsWith("/_next/image") && origin.imageOptimizer) {
|
|
24
23
|
debug("Using origin", "imageOptimizer", _path);
|
|
25
|
-
return origin
|
|
24
|
+
return origin.imageOptimizer;
|
|
26
25
|
}
|
|
27
|
-
if (origin
|
|
28
|
-
debug("Using default origin", origin
|
|
29
|
-
return origin
|
|
26
|
+
if (origin.default) {
|
|
27
|
+
debug("Using default origin", origin.default, _path);
|
|
28
|
+
return origin.default;
|
|
30
29
|
}
|
|
31
30
|
return false;
|
|
32
31
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { emptyReadableStream } from "../../utils/stream";
|
|
2
|
+
const fetchProxy = {
|
|
3
|
+
name: "fetch-proxy",
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
proxy: async (internalEvent) => {
|
|
6
|
+
const { url, headers, method, body } = internalEvent;
|
|
7
|
+
const response = await fetch(url, {
|
|
8
|
+
method,
|
|
9
|
+
headers,
|
|
10
|
+
body,
|
|
11
|
+
});
|
|
12
|
+
const responseHeaders = {};
|
|
13
|
+
response.headers.forEach((value, key) => {
|
|
14
|
+
responseHeaders[key] = value;
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
type: "core",
|
|
18
|
+
headers: responseHeaders,
|
|
19
|
+
statusCode: response.status,
|
|
20
|
+
isBase64Encoded: true,
|
|
21
|
+
body: response.body ?? emptyReadableStream(),
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
export default fetchProxy;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { debug, error } from "node:console";
|
|
2
|
+
import { request } from "node:https";
|
|
3
|
+
import { Readable } from "node:stream";
|
|
4
|
+
import { isBinaryContentType } from "../../adapters/binary";
|
|
5
|
+
function filterHeadersForProxy(headers) {
|
|
6
|
+
const filteredHeaders = {};
|
|
7
|
+
const disallowedHeaders = [
|
|
8
|
+
"host",
|
|
9
|
+
"connection",
|
|
10
|
+
"via",
|
|
11
|
+
"x-cache",
|
|
12
|
+
"transfer-encoding",
|
|
13
|
+
"content-encoding",
|
|
14
|
+
"content-length",
|
|
15
|
+
];
|
|
16
|
+
Object.entries(headers)
|
|
17
|
+
.filter(([key, _]) => {
|
|
18
|
+
const lowerKey = key.toLowerCase();
|
|
19
|
+
return !(disallowedHeaders.includes(lowerKey) || lowerKey.startsWith("x-amz"));
|
|
20
|
+
})
|
|
21
|
+
.forEach(([key, value]) => {
|
|
22
|
+
filteredHeaders[key] = value?.toString() ?? "";
|
|
23
|
+
});
|
|
24
|
+
return filteredHeaders;
|
|
25
|
+
}
|
|
26
|
+
const nodeProxy = {
|
|
27
|
+
name: "node-proxy",
|
|
28
|
+
proxy: (internalEvent) => {
|
|
29
|
+
const { url, headers, method, body } = internalEvent;
|
|
30
|
+
debug("proxyRequest", url);
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
const filteredHeaders = filterHeadersForProxy(headers);
|
|
33
|
+
debug("filteredHeaders", filteredHeaders);
|
|
34
|
+
const req = request(url, {
|
|
35
|
+
headers: filteredHeaders,
|
|
36
|
+
method,
|
|
37
|
+
rejectUnauthorized: false,
|
|
38
|
+
}, (_res) => {
|
|
39
|
+
const nodeReadableStream = _res.headers["content-encoding"] === "br"
|
|
40
|
+
? _res.pipe(require("node:zlib").createBrotliDecompress())
|
|
41
|
+
: _res.headers["content-encoding"] === "gzip"
|
|
42
|
+
? _res.pipe(require("node:zlib").createGunzip())
|
|
43
|
+
: _res;
|
|
44
|
+
const isBase64Encoded = isBinaryContentType(headers["content-type"]) ||
|
|
45
|
+
!!headers["content-encoding"];
|
|
46
|
+
const result = {
|
|
47
|
+
type: "core",
|
|
48
|
+
headers: filterHeadersForProxy(_res.headers),
|
|
49
|
+
statusCode: _res.statusCode ?? 200,
|
|
50
|
+
// TODO: check base64 encoding
|
|
51
|
+
isBase64Encoded,
|
|
52
|
+
body: Readable.toWeb(nodeReadableStream),
|
|
53
|
+
};
|
|
54
|
+
resolve(result);
|
|
55
|
+
_res.on("error", (e) => {
|
|
56
|
+
error("proxyRequest error", e);
|
|
57
|
+
reject(e);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
if (body && method !== "GET" && method !== "HEAD") {
|
|
61
|
+
req.write(body);
|
|
62
|
+
}
|
|
63
|
+
req.end();
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
export default nodeProxy;
|
|
@@ -7,15 +7,13 @@ const getAwsClient = () => {
|
|
|
7
7
|
if (awsClient) {
|
|
8
8
|
return awsClient;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return awsClient;
|
|
18
|
-
}
|
|
10
|
+
awsClient = new AwsClient({
|
|
11
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
12
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
13
|
+
sessionToken: process.env.AWS_SESSION_TOKEN,
|
|
14
|
+
region: process.env.REVALIDATION_QUEUE_REGION,
|
|
15
|
+
});
|
|
16
|
+
return awsClient;
|
|
19
17
|
};
|
|
20
18
|
const awsFetch = (body) => {
|
|
21
19
|
const { REVALIDATION_QUEUE_REGION } = process.env;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
|
|
2
2
|
import { awsLogger } from "../../adapters/logger";
|
|
3
3
|
// Expected environment variables
|
|
4
4
|
const { REVALIDATION_QUEUE_REGION, REVALIDATION_QUEUE_URL } = process.env;
|
|
@@ -7,10 +7,10 @@ const DEFAULT_DYNAMO_BATCH_WRITE_COMMAND_CONCURRENCY = 4;
|
|
|
7
7
|
export const getDynamoBatchWriteCommandConcurrency = () => {
|
|
8
8
|
const dynamoBatchWriteCommandConcurrencyFromEnv = process.env.DYNAMO_BATCH_WRITE_COMMAND_CONCURRENCY;
|
|
9
9
|
const parsedDynamoBatchWriteCommandConcurrencyFromEnv = dynamoBatchWriteCommandConcurrencyFromEnv
|
|
10
|
-
? parseInt(dynamoBatchWriteCommandConcurrencyFromEnv)
|
|
10
|
+
? Number.parseInt(dynamoBatchWriteCommandConcurrencyFromEnv)
|
|
11
11
|
: undefined;
|
|
12
12
|
if (parsedDynamoBatchWriteCommandConcurrencyFromEnv &&
|
|
13
|
-
!isNaN(parsedDynamoBatchWriteCommandConcurrencyFromEnv)) {
|
|
13
|
+
!Number.isNaN(parsedDynamoBatchWriteCommandConcurrencyFromEnv)) {
|
|
14
14
|
return parsedDynamoBatchWriteCommandConcurrencyFromEnv;
|
|
15
15
|
}
|
|
16
16
|
return DEFAULT_DYNAMO_BATCH_WRITE_COMMAND_CONCURRENCY;
|