cdk-nextjs 0.6.2 → 0.7.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/.jsii +2404 -2723
- package/.jsii.tabl.json +1 -1
- package/API.md +1681 -1930
- package/CLAUDE.md +2 -1
- package/README.md +429 -130
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
- package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
- package/docs/adapter-runtime.md +185 -0
- package/docs/breaking-changes.md +667 -4
- package/docs/caching-guide.md +156 -112
- package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
- package/docs/development-guide.md +1 -1
- package/docs/harness-coverage.md +598 -0
- package/docs/init-cache-deployment.md +32 -1
- package/docs/next-build-output-guide.md +30 -20
- package/examples/README.md +5 -1
- package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
- package/lib/adapter/__fixtures__/app-playground.json +4917 -0
- package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
- package/lib/adapter/adapter.mjs +1548 -185
- package/lib/adapter/adapter.test.js +106 -0
- package/lib/adapter/aws-cache-store.d.ts +489 -0
- package/lib/adapter/aws-cache-store.js +1004 -0
- package/lib/adapter/aws-cache-store.test.d.ts +1 -0
- package/lib/adapter/aws-cache-store.test.js +361 -0
- package/lib/adapter/build-outputs.d.ts +80 -0
- package/lib/adapter/build-outputs.js +852 -0
- package/lib/adapter/build-outputs.test.d.ts +1 -0
- package/lib/adapter/build-outputs.test.js +861 -0
- package/lib/adapter/cache-handler.d.ts +9 -2
- package/lib/adapter/cache-handler.js +72 -96
- package/lib/adapter/cache-handler.mjs +18956 -17774
- package/lib/adapter/cache-handler.test.js +263 -31
- package/lib/adapter/cache-kinds.d.ts +32 -0
- package/lib/adapter/cache-kinds.js +35 -0
- package/lib/adapter/cache-kinds.test.d.ts +1 -0
- package/lib/adapter/cache-kinds.test.js +69 -0
- package/lib/adapter/cache-utils.d.ts +90 -0
- package/lib/adapter/cache-utils.js +199 -4
- package/lib/adapter/cache-utils.test.d.ts +1 -0
- package/lib/adapter/cache-utils.test.js +179 -0
- package/lib/adapter/function-groups.d.ts +215 -0
- package/lib/adapter/function-groups.js +1099 -0
- package/lib/adapter/function-groups.test.d.ts +1 -0
- package/lib/adapter/function-groups.test.js +743 -0
- package/lib/adapter/init-cache.d.ts +6 -0
- package/lib/adapter/init-cache.js +245 -0
- package/lib/adapter/init-cache.test.d.ts +1 -0
- package/lib/adapter/init-cache.test.js +137 -0
- package/lib/adapter/local-file-cache-handler.d.ts +23 -0
- package/lib/adapter/local-file-cache-handler.js +52 -1
- package/lib/adapter/memory-cache-handler.d.ts +26 -17
- package/lib/adapter/memory-cache-handler.js +32 -50
- package/lib/adapter/memory-cache-handler.test.js +105 -85
- package/lib/adapter/s3-cache-handler.d.ts +179 -40
- package/lib/adapter/s3-cache-handler.js +807 -277
- package/lib/adapter/s3-cache-handler.test.js +1186 -31
- package/lib/adapter/use-cache-common.d.ts +90 -0
- package/lib/adapter/use-cache-common.js +250 -0
- package/lib/adapter/use-cache-common.test.d.ts +1 -0
- package/lib/adapter/use-cache-common.test.js +646 -0
- package/lib/adapter/use-cache-default-handler.d.ts +24 -0
- package/lib/adapter/use-cache-default-handler.js +90 -0
- package/lib/adapter/use-cache-default-handler.mjs +38645 -0
- package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
- package/lib/adapter/use-cache-handlers.test.js +349 -0
- package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
- package/lib/adapter/use-cache-remote-handler.js +186 -0
- package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
- package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
- package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
- package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
- package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
- package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
- package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
- package/lib/index.d.ts +6 -7
- package/lib/index.js +2 -4
- package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
- package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
- package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
- package/lib/lambdas/post-deploy/prune-s3.js +41 -12
- package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
- package/lib/nextjs-api.d.ts +102 -18
- package/lib/nextjs-api.js +338 -38
- package/lib/nextjs-api.test.js +537 -1
- package/lib/nextjs-build/global-containers.Dockerfile +15 -10
- package/lib/nextjs-build/nextjs-build.d.ts +339 -63
- package/lib/nextjs-build/nextjs-build.js +684 -327
- package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
- package/lib/nextjs-build/nextjs-build.test.js +412 -0
- package/lib/nextjs-build/patch-fetch.js +1 -1
- package/lib/nextjs-build/patch-fetch.test.js +166 -11
- package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
- package/lib/nextjs-cache.d.ts +82 -4
- package/lib/nextjs-cache.js +186 -10
- package/lib/nextjs-cache.test.js +176 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
- package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
- package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
- package/lib/nextjs-compute/nextjs-containers.js +57 -20
- package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
- package/lib/nextjs-compute/nextjs-functions.js +113 -67
- package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
- package/lib/nextjs-distribution.d.ts +194 -23
- package/lib/nextjs-distribution.js +535 -62
- package/lib/nextjs-distribution.test.d.ts +1 -0
- package/lib/nextjs-distribution.test.js +697 -0
- package/lib/nextjs-post-deploy.d.ts +13 -5
- package/lib/nextjs-post-deploy.js +13 -10
- package/lib/nextjs-post-deploy.test.d.ts +1 -0
- package/lib/nextjs-post-deploy.test.js +34 -0
- package/lib/nextjs-static-assets.d.ts +17 -4
- package/lib/nextjs-static-assets.js +22 -5
- package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
- package/lib/root-constructs/nextjs-base-construct.js +139 -47
- package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
- package/lib/root-constructs/nextjs-global-containers.js +20 -71
- package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
- package/lib/root-constructs/nextjs-global-functions.js +52 -70
- package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
- package/lib/root-constructs/nextjs-regional-containers.js +8 -15
- package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
- package/lib/root-constructs/nextjs-regional-functions.js +8 -26
- package/lib/runtime/api-gateway-path.d.ts +34 -0
- package/lib/runtime/api-gateway-path.js +71 -0
- package/lib/runtime/api-gateway-path.test.d.ts +1 -0
- package/lib/runtime/api-gateway-path.test.js +65 -0
- package/lib/runtime/case-redirect.d.ts +22 -0
- package/lib/runtime/case-redirect.js +63 -0
- package/lib/runtime/case-redirect.test.d.ts +1 -0
- package/lib/runtime/case-redirect.test.js +32 -0
- package/lib/runtime/core.d.ts +234 -0
- package/lib/runtime/core.js +1213 -0
- package/lib/runtime/core.test.d.ts +1 -0
- package/lib/runtime/core.test.js +1678 -0
- package/lib/runtime/deployment-root.d.ts +13 -0
- package/lib/runtime/deployment-root.js +29 -0
- package/lib/runtime/dispatch.d.ts +331 -0
- package/lib/runtime/dispatch.js +751 -0
- package/lib/runtime/dispatch.test.d.ts +1 -0
- package/lib/runtime/dispatch.test.js +853 -0
- package/lib/runtime/entrypoints.d.ts +57 -0
- package/lib/runtime/entrypoints.js +115 -0
- package/lib/runtime/http/abort-signal.d.ts +6 -0
- package/lib/runtime/http/abort-signal.js +19 -0
- package/lib/runtime/http/abort-signal.test.d.ts +1 -0
- package/lib/runtime/http/abort-signal.test.js +49 -0
- package/lib/runtime/http/node-server.d.ts +38 -0
- package/lib/runtime/http/node-server.js +99 -0
- package/lib/runtime/http/node-server.test.d.ts +1 -0
- package/lib/runtime/http/node-server.test.js +96 -0
- package/lib/runtime/http/node-sink.d.ts +16 -0
- package/lib/runtime/http/node-sink.js +48 -0
- package/lib/runtime/http/node-sink.test.d.ts +1 -0
- package/lib/runtime/http/node-sink.test.js +66 -0
- package/lib/runtime/http/request.d.ts +62 -0
- package/lib/runtime/http/request.js +134 -0
- package/lib/runtime/http/request.test.d.ts +1 -0
- package/lib/runtime/http/request.test.js +103 -0
- package/lib/runtime/http/response.d.ts +77 -0
- package/lib/runtime/http/response.js +229 -0
- package/lib/runtime/http/response.test.d.ts +1 -0
- package/lib/runtime/http/response.test.js +178 -0
- package/lib/runtime/http/sink.d.ts +73 -0
- package/lib/runtime/http/sink.js +188 -0
- package/lib/runtime/http/sink.test.d.ts +1 -0
- package/lib/runtime/http/sink.test.js +257 -0
- package/lib/runtime/image-utils.d.ts +78 -0
- package/lib/runtime/image-utils.js +129 -0
- package/lib/runtime/image-utils.test.d.ts +1 -0
- package/lib/runtime/image-utils.test.js +237 -0
- package/lib/runtime/image.d.ts +76 -0
- package/lib/runtime/image.js +296 -0
- package/lib/runtime/image.test.d.ts +1 -0
- package/lib/runtime/image.test.js +405 -0
- package/lib/runtime/lambda-event.d.ts +4 -0
- package/lib/runtime/lambda-event.js +113 -0
- package/lib/runtime/lambda-event.test.d.ts +1 -0
- package/lib/runtime/lambda-event.test.js +119 -0
- package/lib/runtime/lambda.mjs +41595 -0
- package/lib/runtime/load-module.d.ts +8 -0
- package/lib/runtime/load-module.js +35 -0
- package/lib/runtime/manifest.d.ts +215 -0
- package/lib/runtime/manifest.js +118 -0
- package/lib/runtime/middleware.d.ts +43 -0
- package/lib/runtime/middleware.js +113 -0
- package/lib/runtime/middleware.test.d.ts +1 -0
- package/lib/runtime/middleware.test.js +259 -0
- package/lib/runtime/next-modules.d.ts +55 -0
- package/lib/runtime/next-modules.js +124 -0
- package/lib/runtime/next-modules.test.d.ts +1 -0
- package/lib/runtime/next-modules.test.js +34 -0
- package/lib/runtime/public-files.d.ts +32 -0
- package/lib/runtime/public-files.js +117 -0
- package/lib/runtime/public-files.test.d.ts +1 -0
- package/lib/runtime/public-files.test.js +97 -0
- package/lib/runtime/server.mjs +41588 -0
- package/lib/runtime/static-files.d.ts +50 -0
- package/lib/runtime/static-files.js +266 -0
- package/lib/runtime/static-files.test.d.ts +1 -0
- package/lib/runtime/static-files.test.js +118 -0
- package/lib/runtime/util.d.ts +28 -0
- package/lib/runtime/util.js +79 -0
- package/lib/utils/base-path.d.ts +106 -13
- package/lib/utils/base-path.js +254 -41
- package/lib/utils/base-path.test.js +219 -51
- package/lib/utils/get-architecture.d.ts +7 -8
- package/lib/utils/get-architecture.js +12 -13
- package/lib/utils/zip-directory.d.ts +14 -0
- package/lib/utils/zip-directory.js +121 -0
- package/lib/utils/zip-directory.test.d.ts +1 -0
- package/lib/utils/zip-directory.test.js +99 -0
- package/package.json +22 -3
- package/scripts/capture-adapter-fixture.mjs +325 -0
- package/scripts/e2e-deploy.sh +398 -0
- package/scripts/e2e-harness/README.md +707 -0
- package/scripts/e2e-harness/app.js +370 -0
- package/scripts/e2e-harness/common.sh +249 -0
- package/scripts/e2e-harness/screen.mjs +302 -0
- package/scripts/e2e-harness/stage-proxy.mjs +145 -0
- package/scripts/e2e-harness/type-filters.mjs +47 -0
- package/scripts/e2e-logs.sh +75 -0
- package/scripts/e2e-offline.sh +91 -0
- package/scripts/e2e-sweep.sh +370 -0
- package/scripts/e2e-warm.sh +114 -0
- package/scripts/zero-config-build.mjs +418 -0
- package/docs/1k-concurrent-users-executions.png +0 -0
- package/docs/plans/adapter-runtime-release.md +0 -362
- package/docs/plans/phase-0-image-function-opt-in.md +0 -295
- package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
- package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
- package/lib/image-optimization/handler-utils.d.ts +0 -34
- package/lib/image-optimization/handler-utils.js +0 -83
- package/lib/image-optimization/handler-utils.test.js +0 -178
- package/lib/nextjs-build/functions.Dockerfile +0 -31
- package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
- package/lib/nextjs-compute/nextjs-image-function.js +0 -59
- package/lib/utils/experimental-flags.d.ts +0 -24
- package/lib/utils/experimental-flags.js +0 -30
- /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
|
@@ -8,9 +8,32 @@ function sha256(input) {
|
|
|
8
8
|
: Buffer.from(new Uint8Array(input));
|
|
9
9
|
return (0, node_crypto_1.createHash)("sha256").update(buffer).digest("hex");
|
|
10
10
|
}
|
|
11
|
+
class FakeXMLHttpRequest {
|
|
12
|
+
open(_method, _url) { }
|
|
13
|
+
send(_body) { }
|
|
14
|
+
setRequestHeader(_name, _value) { }
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The patch runs in a browser *and* in a web worker, where `window` does not
|
|
18
|
+
* exist — so the stub goes on `globalThis`, which is what both scopes are. Tests
|
|
19
|
+
* that want the main-thread scope also set `globalThis.window`, since real
|
|
20
|
+
* browser code reaches the patched `fetch` through it and `window === globalThis`
|
|
21
|
+
* there.
|
|
22
|
+
*/
|
|
23
|
+
function installScope({ withWindow = true, withXhr = true } = {}) {
|
|
24
|
+
global.location = {
|
|
25
|
+
href: "https://example.com/",
|
|
26
|
+
hostname: "example.com",
|
|
27
|
+
};
|
|
28
|
+
if (withXhr)
|
|
29
|
+
global.XMLHttpRequest = FakeXMLHttpRequest;
|
|
30
|
+
if (withWindow)
|
|
31
|
+
global.window = global;
|
|
32
|
+
}
|
|
11
33
|
describe("patch-fetch", () => {
|
|
12
34
|
let originalFetch;
|
|
13
35
|
let capturedInit;
|
|
36
|
+
const realFetch = global.fetch;
|
|
14
37
|
beforeEach(() => {
|
|
15
38
|
jest.resetModules();
|
|
16
39
|
capturedInit = undefined;
|
|
@@ -18,20 +41,16 @@ describe("patch-fetch", () => {
|
|
|
18
41
|
capturedInit = init;
|
|
19
42
|
return Promise.resolve(new Response("ok"));
|
|
20
43
|
});
|
|
21
|
-
global.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
XMLHttpRequest: class {
|
|
25
|
-
open(_method, _url) { }
|
|
26
|
-
send(_body) { }
|
|
27
|
-
setRequestHeader(_name, _value) { }
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports -- must re-execute against the fresh `window` stub each test
|
|
44
|
+
global.fetch = originalFetch;
|
|
45
|
+
installScope();
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- must re-execute against the fresh global stub each test
|
|
31
47
|
require("./patch-fetch.js");
|
|
32
48
|
});
|
|
33
49
|
afterEach(() => {
|
|
34
50
|
delete global.window;
|
|
51
|
+
delete global.location;
|
|
52
|
+
delete global.XMLHttpRequest;
|
|
53
|
+
global.fetch = realFetch;
|
|
35
54
|
});
|
|
36
55
|
describe("fetch", () => {
|
|
37
56
|
test("hashes URLSearchParams via toString(), not JSON.stringify", async () => {
|
|
@@ -94,6 +113,37 @@ describe("patch-fetch", () => {
|
|
|
94
113
|
const headers = capturedInit.headers;
|
|
95
114
|
expect(headers.get("x-amz-content-sha256")).toBe(sha256(buffer));
|
|
96
115
|
});
|
|
116
|
+
test("hashes a typed array body over the bytes it views", async () => {
|
|
117
|
+
const bytes = new TextEncoder().encode("xxtyped array contents");
|
|
118
|
+
const view = bytes.subarray(2);
|
|
119
|
+
await global.window.fetch("https://example.com/api", {
|
|
120
|
+
method: "POST",
|
|
121
|
+
body: view,
|
|
122
|
+
});
|
|
123
|
+
const headers = capturedInit.headers;
|
|
124
|
+
expect(headers.get("x-amz-content-sha256")).toBe(sha256("typed array contents"));
|
|
125
|
+
});
|
|
126
|
+
test("wraps fetch once when a second patched chunk loads in the same scope", async () => {
|
|
127
|
+
// Every entrypoint chunk carries a copy. Wrapped twice, the outer wrapper
|
|
128
|
+
// re-encoded a FormData body to bytes and the inner one overwrote the
|
|
129
|
+
// right hash with one of those bytes as JSON.
|
|
130
|
+
const patchedOnce = global.fetch;
|
|
131
|
+
const patchedXhr = global.XMLHttpRequest;
|
|
132
|
+
jest.resetModules();
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- the second chunk's copy
|
|
134
|
+
require("./patch-fetch.js");
|
|
135
|
+
expect(global.fetch).toBe(patchedOnce);
|
|
136
|
+
expect(global.XMLHttpRequest).toBe(patchedXhr);
|
|
137
|
+
const formData = new FormData();
|
|
138
|
+
formData.append("field", "value");
|
|
139
|
+
await global.window.fetch("https://example.com/api", {
|
|
140
|
+
method: "POST",
|
|
141
|
+
body: formData,
|
|
142
|
+
});
|
|
143
|
+
expect(originalFetch).toHaveBeenCalledTimes(1);
|
|
144
|
+
const headers = capturedInit.headers;
|
|
145
|
+
expect(headers.get("x-amz-content-sha256")).toBe(sha256(capturedInit.body));
|
|
146
|
+
});
|
|
97
147
|
test("hashes an empty byte array when no body is present", async () => {
|
|
98
148
|
await global.window.fetch("https://example.com/api", {
|
|
99
149
|
method: "POST",
|
|
@@ -101,6 +151,36 @@ describe("patch-fetch", () => {
|
|
|
101
151
|
const headers = capturedInit.headers;
|
|
102
152
|
expect(headers.get("x-amz-content-sha256")).toBe(sha256(new Uint8Array(0)));
|
|
103
153
|
});
|
|
154
|
+
test("hashes a Request's own body when init is omitted", async () => {
|
|
155
|
+
const request = new Request("https://example.com/api", {
|
|
156
|
+
method: "POST",
|
|
157
|
+
body: "request body",
|
|
158
|
+
headers: { "content-type": "text/plain" },
|
|
159
|
+
});
|
|
160
|
+
await global.window.fetch(request);
|
|
161
|
+
const [sentInput] = originalFetch.mock.calls[0];
|
|
162
|
+
expect(sentInput).toBe(request);
|
|
163
|
+
// The body was read from a clone, so the request still has it to send.
|
|
164
|
+
expect(await sentInput.text()).toBe("request body");
|
|
165
|
+
const headers = capturedInit.headers;
|
|
166
|
+
expect(headers.get("x-amz-content-sha256")).toBe(sha256("request body"));
|
|
167
|
+
// `init.headers` replaces the request's own, so they must carry over.
|
|
168
|
+
expect(headers.get("content-type")).toBe("text/plain");
|
|
169
|
+
});
|
|
170
|
+
test("hashes init's body over a Request's own when both are set", async () => {
|
|
171
|
+
const request = new Request("https://example.com/api", {
|
|
172
|
+
method: "POST",
|
|
173
|
+
body: "request body",
|
|
174
|
+
});
|
|
175
|
+
await global.window.fetch(request, { body: "init body" });
|
|
176
|
+
const headers = capturedInit.headers;
|
|
177
|
+
expect(headers.get("x-amz-content-sha256")).toBe(sha256("init body"));
|
|
178
|
+
});
|
|
179
|
+
test("passes a GET Request through without hashing", async () => {
|
|
180
|
+
const request = new Request("https://example.com/api");
|
|
181
|
+
await global.window.fetch(request);
|
|
182
|
+
expect(originalFetch).toHaveBeenCalledWith(request, undefined);
|
|
183
|
+
});
|
|
104
184
|
test("passes through untouched when init is omitted", async () => {
|
|
105
185
|
await global.window.fetch("https://example.com/api");
|
|
106
186
|
expect(originalFetch).toHaveBeenCalledWith("https://example.com/api", undefined);
|
|
@@ -155,6 +235,35 @@ describe("patch-fetch", () => {
|
|
|
155
235
|
await xhr.send("should not be hashed");
|
|
156
236
|
expect(setRequestHeader).not.toHaveBeenCalled();
|
|
157
237
|
});
|
|
238
|
+
test("hashes the bytes of a typed-array or Blob body, not their JSON", async () => {
|
|
239
|
+
const bytes = new Uint8Array([1, 2, 3, 250]);
|
|
240
|
+
for (const body of [bytes, new Blob([bytes])]) {
|
|
241
|
+
const setRequestHeader = jest.fn();
|
|
242
|
+
const xhr = new global.window.XMLHttpRequest();
|
|
243
|
+
xhr.setRequestHeader = setRequestHeader;
|
|
244
|
+
xhr.open("POST", "https://example.com/api");
|
|
245
|
+
await xhr.send(body);
|
|
246
|
+
expect(setRequestHeader).toHaveBeenCalledWith("x-amz-content-sha256", sha256(bytes));
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
test("sends a FormData body as the encoding it hashed, with its boundary", async () => {
|
|
250
|
+
const send = jest.spyOn(FakeXMLHttpRequest.prototype, "send");
|
|
251
|
+
const setRequestHeader = jest.fn();
|
|
252
|
+
const form = new FormData();
|
|
253
|
+
form.append("name", "value");
|
|
254
|
+
form.append("file", new Blob(["file-bytes"]), "a.txt");
|
|
255
|
+
const xhr = new global.window.XMLHttpRequest();
|
|
256
|
+
xhr.setRequestHeader = setRequestHeader;
|
|
257
|
+
xhr.open("POST", "https://example.com/api");
|
|
258
|
+
await xhr.send(form);
|
|
259
|
+
const sent = send.mock.calls[0][0];
|
|
260
|
+
expect(sent).toBeInstanceOf(Uint8Array);
|
|
261
|
+
expect(setRequestHeader).toHaveBeenCalledWith("x-amz-content-sha256", sha256(sent));
|
|
262
|
+
const contentType = setRequestHeader.mock.calls.find(([name]) => name === "content-type")?.[1];
|
|
263
|
+
expect(contentType).toMatch(/^multipart\/form-data; boundary=/);
|
|
264
|
+
expect(Buffer.from(sent).toString()).toContain(contentType.split("boundary=")[1]);
|
|
265
|
+
send.mockRestore();
|
|
266
|
+
});
|
|
158
267
|
test("does not hash when there is no body", async () => {
|
|
159
268
|
const setRequestHeader = jest.fn();
|
|
160
269
|
const xhr = new global.window.XMLHttpRequest();
|
|
@@ -165,4 +274,50 @@ describe("patch-fetch", () => {
|
|
|
165
274
|
});
|
|
166
275
|
});
|
|
167
276
|
});
|
|
168
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0Y2gtZmV0Y2gudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZXh0anMtYnVpbGQvcGF0Y2gtZmV0Y2gudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNEQUFzRDtBQUN0RCw2Q0FBeUM7QUFFekMsU0FBUyxNQUFNLENBQUMsS0FBd0M7SUFDdEQsTUFBTSxNQUFNLEdBQ1YsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN2QixDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDcEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUN6QyxPQUFPLElBQUEsd0JBQVUsRUFBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixJQUFJLGFBQXdCLENBQUM7SUFDN0IsSUFBSSxZQUFxQyxDQUFDO0lBRTFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEIsWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUV6QixhQUFhLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQWUsRUFBRSxJQUFrQixFQUFFLEVBQUU7WUFDOUQsWUFBWSxHQUFHLElBQUksQ0FBQztZQUNwQixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVGLE1BQWMsQ0FBQyxNQUFNLEdBQUc7WUFDdkIsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLHNCQUFzQixFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUU7WUFDbkUsS0FBSyxFQUFFLGFBQWE7WUFDcEIsY0FBYyxFQUFFO2dCQUNkLElBQUksQ0FBQyxPQUFlLEVBQUUsSUFBWSxJQUFHLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxLQUFlLElBQUcsQ0FBQztnQkFDeEIsZ0JBQWdCLENBQUMsS0FBYSxFQUFFLE1BQWMsSUFBRyxDQUFDO2FBQ25EO1NBQ0YsQ0FBQztRQUVGLDhIQUE4SDtRQUM5SCxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUM5QixDQUFDLENBQUMsQ0FBQztJQUVILFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYixPQUFRLE1BQWMsQ0FBQyxNQUFNLENBQUM7SUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRTtRQUNyQixJQUFJLENBQUMsMkRBQTJELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDM0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBRXZELE1BQU8sTUFBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUU7Z0JBQzVELE1BQU0sRUFBRSxNQUFNO2dCQUNkLElBQUksRUFBRSxNQUFNO2FBQ2IsQ0FBQyxDQUFDO1lBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7WUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDOUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUMxQixDQUFDO1lBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDNUMsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRTtnQkFDNUQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSSxFQUFFLGVBQWU7YUFDdEIsQ0FBQyxDQUFDO1lBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7WUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQywyRUFBMkUsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMzRixNQUFNLFFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2xDLFFBQVEsQ0FBQyxNQUFNLENBQ2IsTUFBTSxFQUNOLElBQUksSUFBSSxDQUFDLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFDbkQsVUFBVSxDQUNYLENBQUM7WUFFRixNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsUUFBUTthQUNmLENBQUMsQ0FBQztZQUVILDBGQUEwRjtZQUMxRixNQUFNLFNBQVMsR0FBRyxZQUFhLENBQUMsSUFBa0IsQ0FBQztZQUNuRCxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRTdDLE1BQU0sT0FBTyxHQUFHLFlBQWEsQ0FBQyxPQUFrQixDQUFDO1lBQ2pELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFFLENBQUM7WUFDakQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFFcEUsb0VBQW9FO1lBQ3BFLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFO2dCQUNqRCxPQUFPLEVBQUUsRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFO2FBQ3pDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hELE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFTLENBQUM7WUFDOUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbkMsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHVDQUF1QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3ZELE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUVqRSxNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQztZQUVILE1BQU0sT0FBTyxHQUFHLFlBQWEsQ0FBQyxPQUFrQixDQUFDO1lBQ2pELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzlDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUNqQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsK0NBQStDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDL0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFFeEUsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRTtnQkFDNUQsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsSUFBSSxFQUFFLE1BQU07YUFDYixDQUFDLENBQUM7WUFFSCxNQUFNLE9BQU8sR0FBRyxZQUFhLENBQUMsT0FBa0IsQ0FBQztZQUNqRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ25FLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3BFLE1BQU8sTUFBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUU7Z0JBQzVELE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7WUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDOUMsTUFBTSxDQUFDLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQzFCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQywrQ0FBK0MsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMvRCxNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFFOUQsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLG9CQUFvQixDQUN4Qyx5QkFBeUIsRUFDekIsU0FBUyxDQUNWLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx5REFBeUQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN6RSxNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsS0FBSztnQkFDYixJQUFJLEVBQUUsc0JBQXNCO2FBQzdCLENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxZQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDaEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsMERBQTBELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDMUUsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsRUFBRTtnQkFDakUsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSSxFQUFFLHNCQUFzQjthQUM3QixDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsWUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO1FBQzlCLElBQUksQ0FBQywyREFBMkQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMzRSxNQUFNLE1BQU0sR0FBRyxJQUFJLGVBQWUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDdkQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFFbkMsTUFBTSxHQUFHLEdBQUcsSUFBSyxNQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hELEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztZQUN4QyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUV2QixNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxvQkFBb0IsQ0FDM0Msc0JBQXNCLEVBQ3RCLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FDMUIsQ0FBQztZQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FDL0Msc0JBQXNCLEVBQ3RCLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FDYixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDNUMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFFbkMsTUFBTSxHQUFHLEdBQUcsSUFBSyxNQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hELEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztZQUN4QyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUVoQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxvQkFBb0IsQ0FDM0Msc0JBQXNCLEVBQ3RCLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FDeEIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHdDQUF3QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3hELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBRW5DLE1BQU0sR0FBRyxHQUFHLElBQUssTUFBYyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4RCxHQUFHLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7WUFDeEMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUseUJBQXlCLENBQUMsQ0FBQztZQUMzQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUV2QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN6RCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUVuQyxNQUFNLEdBQUcsR0FBRyxJQUFLLE1BQWMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEQsR0FBRyxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDhCQUE4QixDQUFDLENBQUM7WUFDakQsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFFdkMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUNBQXFDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDckQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFFbkMsTUFBTSxHQUFHLEdBQUcsSUFBSyxNQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hELEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztZQUN4QyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBRWpCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuXG5mdW5jdGlvbiBzaGEyNTYoaW5wdXQ6IHN0cmluZyB8IEFycmF5QnVmZmVyIHwgVWludDhBcnJheSkge1xuICBjb25zdCBidWZmZXIgPVxuICAgIHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIlxuICAgICAgPyBCdWZmZXIuZnJvbShpbnB1dClcbiAgICAgIDogQnVmZmVyLmZyb20obmV3IFVpbnQ4QXJyYXkoaW5wdXQpKTtcbiAgcmV0dXJuIGNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KFwiaGV4XCIpO1xufVxuXG5kZXNjcmliZShcInBhdGNoLWZldGNoXCIsICgpID0+IHtcbiAgbGV0IG9yaWdpbmFsRmV0Y2g6IGplc3QuTW9jaztcbiAgbGV0IGNhcHR1cmVkSW5pdDogUmVxdWVzdEluaXQgfCB1bmRlZmluZWQ7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgamVzdC5yZXNldE1vZHVsZXMoKTtcbiAgICBjYXB0dXJlZEluaXQgPSB1bmRlZmluZWQ7XG5cbiAgICBvcmlnaW5hbEZldGNoID0gamVzdC5mbigoX2lucHV0OiB1bmtub3duLCBpbml0PzogUmVxdWVzdEluaXQpID0+IHtcbiAgICAgIGNhcHR1cmVkSW5pdCA9IGluaXQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXNwb25zZShcIm9rXCIpKTtcbiAgICB9KTtcblxuICAgIChnbG9iYWwgYXMgYW55KS53aW5kb3cgPSB7XG4gICAgICBsb2NhdGlvbjogeyBocmVmOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vXCIsIGhvc3RuYW1lOiBcImV4YW1wbGUuY29tXCIgfSxcbiAgICAgIGZldGNoOiBvcmlnaW5hbEZldGNoLFxuICAgICAgWE1MSHR0cFJlcXVlc3Q6IGNsYXNzIHtcbiAgICAgICAgb3BlbihfbWV0aG9kOiBzdHJpbmcsIF91cmw6IHN0cmluZykge31cbiAgICAgICAgc2VuZChfYm9keT86IHVua25vd24pIHt9XG4gICAgICAgIHNldFJlcXVlc3RIZWFkZXIoX25hbWU6IHN0cmluZywgX3ZhbHVlOiBzdHJpbmcpIHt9XG4gICAgICB9LFxuICAgIH07XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAtLSBtdXN0IHJlLWV4ZWN1dGUgYWdhaW5zdCB0aGUgZnJlc2ggYHdpbmRvd2Agc3R1YiBlYWNoIHRlc3RcbiAgICByZXF1aXJlKFwiLi9wYXRjaC1mZXRjaC5qc1wiKTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBkZWxldGUgKGdsb2JhbCBhcyBhbnkpLndpbmRvdztcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJmZXRjaFwiLCAoKSA9PiB7XG4gICAgdGVzdChcImhhc2hlcyBVUkxTZWFyY2hQYXJhbXMgdmlhIHRvU3RyaW5nKCksIG5vdCBKU09OLnN0cmluZ2lmeVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHsgYTogXCIxXCIsIGI6IFwiMlwiIH0pO1xuXG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBwYXJhbXMsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoXG4gICAgICAgIHNoYTI1NihwYXJhbXMudG9TdHJpbmcoKSksXG4gICAgICApO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLm5vdC50b0JlKHNoYTI1NihcInt9XCIpKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYXNoZXMgYSBwbGFpbiBzdHJpbmcgYm9keVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBcInJhdyB0ZXh0IGJvZHlcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShzaGEyNTYoXCJyYXcgdGV4dCBib2R5XCIpKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYXNoZXMgYSBGb3JtRGF0YSBib2R5IG92ZXIgaXRzIGV4YWN0IGVuY29kZWQgYnl0ZXMgYW5kIHNldHMgY29udGVudC10eXBlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICBmb3JtRGF0YS5hcHBlbmQoXCJmaWVsZFwiLCBcInZhbHVlXCIpO1xuICAgICAgZm9ybURhdGEuYXBwZW5kKFxuICAgICAgICBcImZpbGVcIixcbiAgICAgICAgbmV3IEJsb2IoW1wiZmlsZSBjb250ZW50c1wiXSwgeyB0eXBlOiBcInRleHQvcGxhaW5cIiB9KSxcbiAgICAgICAgXCJmaWxlLnR4dFwiLFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keTogZm9ybURhdGEsXG4gICAgICB9KTtcblxuICAgICAgLy8gdGhlIGJvZHkgc2VudCB0byB0aGUgcmVhbCBmZXRjaCBtdXN0IGJlIHRoZSByZS1lbmNvZGVkIGJ5dGVzLCBub3QgdGhlIG9yaWdpbmFsIEZvcm1EYXRhXG4gICAgICBjb25zdCBzZW50Qnl0ZXMgPSBjYXB0dXJlZEluaXQhLmJvZHkgYXMgVWludDhBcnJheTtcbiAgICAgIGV4cGVjdChzZW50Qnl0ZXMpLnRvQmVJbnN0YW5jZU9mKFVpbnQ4QXJyYXkpO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBjb25zdCBjb250ZW50VHlwZSA9IGhlYWRlcnMuZ2V0KFwiY29udGVudC10eXBlXCIpITtcbiAgICAgIGV4cGVjdChjb250ZW50VHlwZSkudG9NYXRjaCgvXm11bHRpcGFydFxcL2Zvcm0tZGF0YTsgYm91bmRhcnk9Lyk7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShzaGEyNTYoc2VudEJ5dGVzKSk7XG5cbiAgICAgIC8vIHRoZSBoYXNoZWQvc2VudCBieXRlcyBtdXN0IHJvdW5kLXRyaXAgYmFjayB0byB0aGUgb3JpZ2luYWwgZmllbGRzXG4gICAgICBjb25zdCByb3VuZFRyaXBwZWQgPSBhd2FpdCBuZXcgUmVzcG9uc2Uoc2VudEJ5dGVzLCB7XG4gICAgICAgIGhlYWRlcnM6IHsgXCJjb250ZW50LXR5cGVcIjogY29udGVudFR5cGUgfSxcbiAgICAgIH0pLmZvcm1EYXRhKCk7XG4gICAgICBleHBlY3Qocm91bmRUcmlwcGVkLmdldChcImZpZWxkXCIpKS50b0JlKFwidmFsdWVcIik7XG4gICAgICBjb25zdCBmaWxlID0gcm91bmRUcmlwcGVkLmdldChcImZpbGVcIikgYXMgRmlsZTtcbiAgICAgIGV4cGVjdChmaWxlLm5hbWUpLnRvQmUoXCJmaWxlLnR4dFwiKTtcbiAgICAgIGV4cGVjdChhd2FpdCBmaWxlLnRleHQoKSkudG9CZShcImZpbGUgY29udGVudHNcIik7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFzaGVzIGEgQmxvYiBib2R5IG92ZXIgaXRzIHJhdyBieXRlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW1wiYmxvYiBjb250ZW50c1wiXSwgeyB0eXBlOiBcInRleHQvcGxhaW5cIiB9KTtcblxuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keTogYmxvYixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShcbiAgICAgICAgc2hhMjU2KGF3YWl0IGJsb2IuYXJyYXlCdWZmZXIoKSksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImhhc2hlcyBhbiBBcnJheUJ1ZmZlciBib2R5IG92ZXIgaXRzIHJhdyBieXRlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWZmZXIgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJhcnJheSBidWZmZXIgY29udGVudHNcIikuYnVmZmVyO1xuXG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUFVUXCIsXG4gICAgICAgIGJvZHk6IGJ1ZmZlcixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShzaGEyNTYoYnVmZmVyKSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFzaGVzIGFuIGVtcHR5IGJ5dGUgYXJyYXkgd2hlbiBubyBib2R5IGlzIHByZXNlbnRcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShcbiAgICAgICAgc2hhMjU2KG5ldyBVaW50OEFycmF5KDApKSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwicGFzc2VzIHRocm91Z2ggdW50b3VjaGVkIHdoZW4gaW5pdCBpcyBvbWl0dGVkXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IChnbG9iYWwgYXMgYW55KS53aW5kb3cuZmV0Y2goXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcblxuICAgICAgZXhwZWN0KG9yaWdpbmFsRmV0Y2gpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICBcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwicGFzc2VzIHRocm91Z2ggd2l0aG91dCBoYXNoaW5nIGZvciBub24tUFVUL1BPU1QgbWV0aG9kc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgIGJvZHk6IFwic2hvdWxkIG5vdCBiZSBoYXNoZWRcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY2FwdHVyZWRJbml0IS5oZWFkZXJzKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwicGFzc2VzIHRocm91Z2ggd2l0aG91dCBoYXNoaW5nIGZvciBjcm9zcy1vcmlnaW4gcmVxdWVzdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vb3RoZXItb3JpZ2luLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBcInNob3VsZCBub3QgYmUgaGFzaGVkXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNhcHR1cmVkSW5pdCEuaGVhZGVycykudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlhNTEh0dHBSZXF1ZXN0XCIsICgpID0+IHtcbiAgICB0ZXN0KFwiaGFzaGVzIFVSTFNlYXJjaFBhcmFtcyB2aWEgdG9TdHJpbmcoKSwgbm90IEpTT04uc3RyaW5naWZ5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyBhOiBcIjFcIiwgYjogXCIyXCIgfSk7XG4gICAgICBjb25zdCBzZXRSZXF1ZXN0SGVhZGVyID0gamVzdC5mbigpO1xuXG4gICAgICBjb25zdCB4aHIgPSBuZXcgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIgPSBzZXRSZXF1ZXN0SGVhZGVyO1xuICAgICAgeGhyLm9wZW4oXCJQT1NUXCIsIFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIik7XG4gICAgICBhd2FpdCB4aHIuc2VuZChwYXJhbXMpO1xuXG4gICAgICBleHBlY3Qoc2V0UmVxdWVzdEhlYWRlcikudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgIFwieC1hbXotY29udGVudC1zaGEyNTZcIixcbiAgICAgICAgc2hhMjU2KHBhcmFtcy50b1N0cmluZygpKSxcbiAgICAgICk7XG4gICAgICBleHBlY3Qoc2V0UmVxdWVzdEhlYWRlcikubm90LnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICBcIngtYW16LWNvbnRlbnQtc2hhMjU2XCIsXG4gICAgICAgIHNoYTI1NihcInt9XCIpLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYXNoZXMgYSBwbGFpbiBzdHJpbmcgYm9keVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzZXRSZXF1ZXN0SGVhZGVyID0gamVzdC5mbigpO1xuXG4gICAgICBjb25zdCB4aHIgPSBuZXcgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIgPSBzZXRSZXF1ZXN0SGVhZGVyO1xuICAgICAgeGhyLm9wZW4oXCJQVVRcIiwgXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcbiAgICAgIGF3YWl0IHhoci5zZW5kKFwicmF3IHRleHQgYm9keVwiKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICBcIngtYW16LWNvbnRlbnQtc2hhMjU2XCIsXG4gICAgICAgIHNoYTI1NihcInJhdyB0ZXh0IGJvZHlcIiksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImRvZXMgbm90IGhhc2ggZm9yIG5vbi1QVVQvUE9TVCBtZXRob2RzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNldFJlcXVlc3RIZWFkZXIgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyAoZ2xvYmFsIGFzIGFueSkud2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlciA9IHNldFJlcXVlc3RIZWFkZXI7XG4gICAgICB4aHIub3BlbihcIkdFVFwiLCBcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIpO1xuICAgICAgYXdhaXQgeGhyLnNlbmQoXCJzaG91bGQgbm90IGJlIGhhc2hlZFwiKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZG9lcyBub3QgaGFzaCBmb3IgY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNldFJlcXVlc3RIZWFkZXIgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyAoZ2xvYmFsIGFzIGFueSkud2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlciA9IHNldFJlcXVlc3RIZWFkZXI7XG4gICAgICB4aHIub3BlbihcIlBPU1RcIiwgXCJodHRwczovL290aGVyLW9yaWdpbi5jb20vYXBpXCIpO1xuICAgICAgYXdhaXQgeGhyLnNlbmQoXCJzaG91bGQgbm90IGJlIGhhc2hlZFwiKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZG9lcyBub3QgaGFzaCB3aGVuIHRoZXJlIGlzIG5vIGJvZHlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2V0UmVxdWVzdEhlYWRlciA9IGplc3QuZm4oKTtcblxuICAgICAgY29uc3QgeGhyID0gbmV3IChnbG9iYWwgYXMgYW55KS53aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyID0gc2V0UmVxdWVzdEhlYWRlcjtcbiAgICAgIHhoci5vcGVuKFwiUE9TVFwiLCBcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIpO1xuICAgICAgYXdhaXQgeGhyLnNlbmQoKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|
|
277
|
+
/**
|
|
278
|
+
* Turbopack's web-worker bootstrap is `static/chunks/turbopack-worker-*.js`,
|
|
279
|
+
* which `patchFetchInClientJs`'s `turbopack-` selector matches — so this file is
|
|
280
|
+
* prepended to a script that runs off the main thread. Reading `window` there
|
|
281
|
+
* threw before the worker's own module could run, which took out every
|
|
282
|
+
* `new Worker(new URL(…))` app (`worker-module-url`, `worker-relay-compiler`).
|
|
283
|
+
*/
|
|
284
|
+
describe("patch-fetch in a worker scope", () => {
|
|
285
|
+
let originalFetch;
|
|
286
|
+
let capturedInit;
|
|
287
|
+
const realFetch = global.fetch;
|
|
288
|
+
beforeEach(() => {
|
|
289
|
+
jest.resetModules();
|
|
290
|
+
capturedInit = undefined;
|
|
291
|
+
originalFetch = jest.fn((_input, init) => {
|
|
292
|
+
capturedInit = init;
|
|
293
|
+
return Promise.resolve(new Response("ok"));
|
|
294
|
+
});
|
|
295
|
+
global.fetch = originalFetch;
|
|
296
|
+
// No `window`, and no `XMLHttpRequest`: the narrowest scope the patch can
|
|
297
|
+
// land in.
|
|
298
|
+
installScope({ withWindow: false, withXhr: false });
|
|
299
|
+
});
|
|
300
|
+
afterEach(() => {
|
|
301
|
+
delete global.window;
|
|
302
|
+
delete global.location;
|
|
303
|
+
global.fetch = realFetch;
|
|
304
|
+
});
|
|
305
|
+
test("loads without a window and still signs a same-origin POST", async () => {
|
|
306
|
+
expect(() => {
|
|
307
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- the point of the test is that requiring it does not throw
|
|
308
|
+
require("./patch-fetch.js");
|
|
309
|
+
}).not.toThrow();
|
|
310
|
+
await global.fetch("https://example.com/api", {
|
|
311
|
+
method: "POST",
|
|
312
|
+
body: "worker body",
|
|
313
|
+
});
|
|
314
|
+
const headers = capturedInit.headers;
|
|
315
|
+
expect(headers.get("x-amz-content-sha256")).toBe(sha256("worker body"));
|
|
316
|
+
});
|
|
317
|
+
test("leaves XMLHttpRequest alone when the scope has none", () => {
|
|
318
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- re-executed against this scope
|
|
319
|
+
require("./patch-fetch.js");
|
|
320
|
+
expect(global.XMLHttpRequest).toBeUndefined();
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0Y2gtZmV0Y2gudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZXh0anMtYnVpbGQvcGF0Y2gtZmV0Y2gudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNEQUFzRDtBQUN0RCw2Q0FBeUM7QUFFekMsU0FBUyxNQUFNLENBQUMsS0FBd0M7SUFDdEQsTUFBTSxNQUFNLEdBQ1YsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN2QixDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDcEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUN6QyxPQUFPLElBQUEsd0JBQVUsRUFBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRCxNQUFNLGtCQUFrQjtJQUN0QixJQUFJLENBQUMsT0FBZSxFQUFFLElBQVksSUFBRyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxLQUFlLElBQUcsQ0FBQztJQUN4QixnQkFBZ0IsQ0FBQyxLQUFhLEVBQUUsTUFBYyxJQUFHLENBQUM7Q0FDbkQ7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxFQUFFLFVBQVUsR0FBRyxJQUFJLEVBQUUsT0FBTyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUU7SUFDN0QsTUFBYyxDQUFDLFFBQVEsR0FBRztRQUN6QixJQUFJLEVBQUUsc0JBQXNCO1FBQzVCLFFBQVEsRUFBRSxhQUFhO0tBQ3hCLENBQUM7SUFDRixJQUFJLE9BQU87UUFBRyxNQUFjLENBQUMsY0FBYyxHQUFHLGtCQUFrQixDQUFDO0lBQ2pFLElBQUksVUFBVTtRQUFHLE1BQWMsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBQ2xELENBQUM7QUFFRCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixJQUFJLGFBQXdCLENBQUM7SUFDN0IsSUFBSSxZQUFxQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFFL0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixZQUFZLEdBQUcsU0FBUyxDQUFDO1FBRXpCLGFBQWEsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBZSxFQUFFLElBQWtCLEVBQUUsRUFBRTtZQUM5RCxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBQ0YsTUFBYyxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUM7UUFFdEMsWUFBWSxFQUFFLENBQUM7UUFFZiw0SEFBNEg7UUFDNUgsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsT0FBUSxNQUFjLENBQUMsTUFBTSxDQUFDO1FBQzlCLE9BQVEsTUFBYyxDQUFDLFFBQVEsQ0FBQztRQUNoQyxPQUFRLE1BQWMsQ0FBQyxjQUFjLENBQUM7UUFDdEMsTUFBTSxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7SUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRTtRQUNyQixJQUFJLENBQUMsMkRBQTJELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDM0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBRXZELE1BQU8sTUFBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUU7Z0JBQzVELE1BQU0sRUFBRSxNQUFNO2dCQUNkLElBQUksRUFBRSxNQUFNO2FBQ2IsQ0FBQyxDQUFDO1lBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7WUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDOUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUMxQixDQUFDO1lBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDNUMsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRTtnQkFDNUQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSSxFQUFFLGVBQWU7YUFDdEIsQ0FBQyxDQUFDO1lBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7WUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQywyRUFBMkUsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMzRixNQUFNLFFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2xDLFFBQVEsQ0FBQyxNQUFNLENBQ2IsTUFBTSxFQUNOLElBQUksSUFBSSxDQUFDLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFDbkQsVUFBVSxDQUNYLENBQUM7WUFFRixNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsUUFBUTthQUNmLENBQUMsQ0FBQztZQUVILDBGQUEwRjtZQUMxRixNQUFNLFNBQVMsR0FBRyxZQUFhLENBQUMsSUFBa0IsQ0FBQztZQUNuRCxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRTdDLE1BQU0sT0FBTyxHQUFHLFlBQWEsQ0FBQyxPQUFrQixDQUFDO1lBQ2pELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFFLENBQUM7WUFDakQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFFcEUsb0VBQW9FO1lBQ3BFLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFO2dCQUNqRCxPQUFPLEVBQUUsRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFO2FBQ3pDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hELE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFTLENBQUM7WUFDOUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbkMsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHVDQUF1QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3ZELE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUVqRSxNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQztZQUVILE1BQU0sT0FBTyxHQUFHLFlBQWEsQ0FBQyxPQUFrQixDQUFDO1lBQ2pELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzlDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUNqQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsK0NBQStDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDL0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFFeEUsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRTtnQkFDNUQsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsSUFBSSxFQUFFLE1BQU07YUFDYixDQUFDLENBQUM7WUFFSCxNQUFNLE9BQU8sR0FBRyxZQUFhLENBQUMsT0FBa0IsQ0FBQztZQUNqRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ25FLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLG1EQUFtRCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ25FLE1BQU0sS0FBSyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDakUsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUUvQixNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQztZQUVILE1BQU0sT0FBTyxHQUFHLFlBQWEsQ0FBQyxPQUFrQixDQUFDO1lBQ2pELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzlDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUMvQixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsc0VBQXNFLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDdEYsMEVBQTBFO1lBQzFFLHNFQUFzRTtZQUN0RSw4Q0FBOEM7WUFDOUMsTUFBTSxXQUFXLEdBQUksTUFBYyxDQUFDLEtBQUssQ0FBQztZQUMxQyxNQUFNLFVBQVUsR0FBSSxNQUFjLENBQUMsY0FBYyxDQUFDO1lBQ2xELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQiw0RkFBNEY7WUFDNUYsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDNUIsTUFBTSxDQUFFLE1BQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDaEQsTUFBTSxDQUFFLE1BQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFeEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNoQyxRQUFRLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsQyxNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUM1RCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsUUFBUTthQUNmLENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQyxNQUFNLE9BQU8sR0FBRyxZQUFhLENBQUMsT0FBa0IsQ0FBQztZQUNqRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUM5QyxNQUFNLENBQUMsWUFBYSxDQUFDLElBQWtCLENBQUMsQ0FDekMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3BFLE1BQU8sTUFBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUU7Z0JBQzVELE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7WUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDOUMsTUFBTSxDQUFDLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQzFCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxrREFBa0QsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNsRSxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRTtnQkFDckQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUU7YUFDMUMsQ0FBQyxDQUFDO1lBRUgsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU1QyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNoQyx1RUFBdUU7WUFDdkUsTUFBTSxDQUFDLE1BQU8sU0FBcUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNqRSxNQUFNLE9BQU8sR0FBRyxZQUFhLENBQUMsT0FBa0IsQ0FBQztZQUNqRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1lBQ3pFLHNFQUFzRTtZQUN0RSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQywyREFBMkQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMzRSxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRTtnQkFDckQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSSxFQUFFLGNBQWM7YUFDckIsQ0FBQyxDQUFDO1lBRUgsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUVuRSxNQUFNLE9BQU8sR0FBRyxZQUFhLENBQUMsT0FBa0IsQ0FBQztZQUNqRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLDhDQUE4QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlELE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFFdkQsTUFBTyxNQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU1QyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLCtDQUErQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQy9ELE1BQU8sTUFBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUU5RCxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsb0JBQW9CLENBQ3hDLHlCQUF5QixFQUN6QixTQUFTLENBQ1YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHlEQUF5RCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3pFLE1BQU8sTUFBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUU7Z0JBQzVELE1BQU0sRUFBRSxLQUFLO2dCQUNiLElBQUksRUFBRSxzQkFBc0I7YUFDN0IsQ0FBQyxDQUFDO1lBRUgsTUFBTSxDQUFDLFlBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNoRCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQywwREFBMEQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMxRSxNQUFPLE1BQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDhCQUE4QixFQUFFO2dCQUNqRSxNQUFNLEVBQUUsTUFBTTtnQkFDZCxJQUFJLEVBQUUsc0JBQXNCO2FBQzdCLENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxZQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDaEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLEVBQUU7UUFDOUIsSUFBSSxDQUFDLDJEQUEyRCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzNFLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBZSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUVuQyxNQUFNLEdBQUcsR0FBRyxJQUFLLE1BQWMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEQsR0FBRyxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlCQUF5QixDQUFDLENBQUM7WUFDNUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXZCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLG9CQUFvQixDQUMzQyxzQkFBc0IsRUFDdEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUMxQixDQUFDO1lBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUMvQyxzQkFBc0IsRUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUNiLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLElBQUksRUFBRTtZQUM1QyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUVuQyxNQUFNLEdBQUcsR0FBRyxJQUFLLE1BQWMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEQsR0FBRyxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLHlCQUF5QixDQUFDLENBQUM7WUFDM0MsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRWhDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLG9CQUFvQixDQUMzQyxzQkFBc0IsRUFDdEIsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUN4QixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsd0NBQXdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDeEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFFbkMsTUFBTSxHQUFHLEdBQUcsSUFBSyxNQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hELEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztZQUN4QyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBRXZDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHlDQUF5QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3pELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBRW5DLE1BQU0sR0FBRyxHQUFHLElBQUssTUFBYyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4RCxHQUFHLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7WUFDeEMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsOEJBQThCLENBQUMsQ0FBQztZQUNqRCxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUV2QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxnRUFBZ0UsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNoRixNQUFNLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDN0MsS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxHQUFHLEdBQUcsSUFBSyxNQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN4RCxHQUFHLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7Z0JBQ3hDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlCQUF5QixDQUFDLENBQUM7Z0JBQzVDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFckIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsb0JBQW9CLENBQzNDLHNCQUFzQixFQUN0QixNQUFNLENBQUMsS0FBSyxDQUFDLENBQ2QsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxvRUFBb0UsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNwRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM5RCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUV2RCxNQUFNLEdBQUcsR0FBRyxJQUFLLE1BQWMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEQsR0FBRyxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlCQUF5QixDQUFDLENBQUM7WUFDNUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXJCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBZSxDQUFDO1lBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsb0JBQW9CLENBQzNDLHNCQUFzQixFQUN0QixNQUFNLENBQUMsSUFBSSxDQUFDLENBQ2IsQ0FBQztZQUNGLE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUNsRCxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksS0FBSyxjQUFjLENBQ3BDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNQLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUMsa0NBQWtDLENBQUMsQ0FBQztZQUNoRSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FDNUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDbEMsQ0FBQztZQUNGLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNyRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUVuQyxNQUFNLEdBQUcsR0FBRyxJQUFLLE1BQWMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEQsR0FBRyxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlCQUF5QixDQUFDLENBQUM7WUFDNUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFakIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUg7Ozs7OztHQU1HO0FBQ0gsUUFBUSxDQUFDLCtCQUErQixFQUFFLEdBQUcsRUFBRTtJQUM3QyxJQUFJLGFBQXdCLENBQUM7SUFDN0IsSUFBSSxZQUFxQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFFL0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixZQUFZLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLGFBQWEsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBZSxFQUFFLElBQWtCLEVBQUUsRUFBRTtZQUM5RCxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBQ0YsTUFBYyxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUM7UUFDdEMsMEVBQTBFO1FBQzFFLFdBQVc7UUFDWCxZQUFZLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3RELENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNiLE9BQVEsTUFBYyxDQUFDLE1BQU0sQ0FBQztRQUM5QixPQUFRLE1BQWMsQ0FBQyxRQUFRLENBQUM7UUFDaEMsTUFBTSxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7SUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsMkRBQTJELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDM0UsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNWLDhIQUE4SDtZQUM5SCxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFakIsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFO1lBQzVDLE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLGFBQWE7U0FDcEIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxPQUFPLEdBQUcsWUFBYSxDQUFDLE9BQWtCLENBQUM7UUFDakQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUMxRSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxxREFBcUQsRUFBRSxHQUFHLEVBQUU7UUFDL0QsbUdBQW1HO1FBQ25HLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRTVCLE1BQU0sQ0FBRSxNQUFjLENBQUMsY0FBYyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDekQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuXG5mdW5jdGlvbiBzaGEyNTYoaW5wdXQ6IHN0cmluZyB8IEFycmF5QnVmZmVyIHwgVWludDhBcnJheSkge1xuICBjb25zdCBidWZmZXIgPVxuICAgIHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIlxuICAgICAgPyBCdWZmZXIuZnJvbShpbnB1dClcbiAgICAgIDogQnVmZmVyLmZyb20obmV3IFVpbnQ4QXJyYXkoaW5wdXQpKTtcbiAgcmV0dXJuIGNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KFwiaGV4XCIpO1xufVxuXG5jbGFzcyBGYWtlWE1MSHR0cFJlcXVlc3Qge1xuICBvcGVuKF9tZXRob2Q6IHN0cmluZywgX3VybDogc3RyaW5nKSB7fVxuICBzZW5kKF9ib2R5PzogdW5rbm93bikge31cbiAgc2V0UmVxdWVzdEhlYWRlcihfbmFtZTogc3RyaW5nLCBfdmFsdWU6IHN0cmluZykge31cbn1cblxuLyoqXG4gKiBUaGUgcGF0Y2ggcnVucyBpbiBhIGJyb3dzZXIgKmFuZCogaW4gYSB3ZWIgd29ya2VyLCB3aGVyZSBgd2luZG93YCBkb2VzIG5vdFxuICogZXhpc3Qg4oCUIHNvIHRoZSBzdHViIGdvZXMgb24gYGdsb2JhbFRoaXNgLCB3aGljaCBpcyB3aGF0IGJvdGggc2NvcGVzIGFyZS4gVGVzdHNcbiAqIHRoYXQgd2FudCB0aGUgbWFpbi10aHJlYWQgc2NvcGUgYWxzbyBzZXQgYGdsb2JhbFRoaXMud2luZG93YCwgc2luY2UgcmVhbFxuICogYnJvd3NlciBjb2RlIHJlYWNoZXMgdGhlIHBhdGNoZWQgYGZldGNoYCB0aHJvdWdoIGl0IGFuZCBgd2luZG93ID09PSBnbG9iYWxUaGlzYFxuICogdGhlcmUuXG4gKi9cbmZ1bmN0aW9uIGluc3RhbGxTY29wZSh7IHdpdGhXaW5kb3cgPSB0cnVlLCB3aXRoWGhyID0gdHJ1ZSB9ID0ge30pIHtcbiAgKGdsb2JhbCBhcyBhbnkpLmxvY2F0aW9uID0ge1xuICAgIGhyZWY6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9cIixcbiAgICBob3N0bmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICB9O1xuICBpZiAod2l0aFhocikgKGdsb2JhbCBhcyBhbnkpLlhNTEh0dHBSZXF1ZXN0ID0gRmFrZVhNTEh0dHBSZXF1ZXN0O1xuICBpZiAod2l0aFdpbmRvdykgKGdsb2JhbCBhcyBhbnkpLndpbmRvdyA9IGdsb2JhbDtcbn1cblxuZGVzY3JpYmUoXCJwYXRjaC1mZXRjaFwiLCAoKSA9PiB7XG4gIGxldCBvcmlnaW5hbEZldGNoOiBqZXN0Lk1vY2s7XG4gIGxldCBjYXB0dXJlZEluaXQ6IFJlcXVlc3RJbml0IHwgdW5kZWZpbmVkO1xuICBjb25zdCByZWFsRmV0Y2ggPSBnbG9iYWwuZmV0Y2g7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgamVzdC5yZXNldE1vZHVsZXMoKTtcbiAgICBjYXB0dXJlZEluaXQgPSB1bmRlZmluZWQ7XG5cbiAgICBvcmlnaW5hbEZldGNoID0gamVzdC5mbigoX2lucHV0OiB1bmtub3duLCBpbml0PzogUmVxdWVzdEluaXQpID0+IHtcbiAgICAgIGNhcHR1cmVkSW5pdCA9IGluaXQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXNwb25zZShcIm9rXCIpKTtcbiAgICB9KTtcbiAgICAoZ2xvYmFsIGFzIGFueSkuZmV0Y2ggPSBvcmlnaW5hbEZldGNoO1xuXG4gICAgaW5zdGFsbFNjb3BlKCk7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAtLSBtdXN0IHJlLWV4ZWN1dGUgYWdhaW5zdCB0aGUgZnJlc2ggZ2xvYmFsIHN0dWIgZWFjaCB0ZXN0XG4gICAgcmVxdWlyZShcIi4vcGF0Y2gtZmV0Y2guanNcIik7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgZGVsZXRlIChnbG9iYWwgYXMgYW55KS53aW5kb3c7XG4gICAgZGVsZXRlIChnbG9iYWwgYXMgYW55KS5sb2NhdGlvbjtcbiAgICBkZWxldGUgKGdsb2JhbCBhcyBhbnkpLlhNTEh0dHBSZXF1ZXN0O1xuICAgIGdsb2JhbC5mZXRjaCA9IHJlYWxGZXRjaDtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJmZXRjaFwiLCAoKSA9PiB7XG4gICAgdGVzdChcImhhc2hlcyBVUkxTZWFyY2hQYXJhbXMgdmlhIHRvU3RyaW5nKCksIG5vdCBKU09OLnN0cmluZ2lmeVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHsgYTogXCIxXCIsIGI6IFwiMlwiIH0pO1xuXG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBwYXJhbXMsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoXG4gICAgICAgIHNoYTI1NihwYXJhbXMudG9TdHJpbmcoKSksXG4gICAgICApO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLm5vdC50b0JlKHNoYTI1NihcInt9XCIpKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYXNoZXMgYSBwbGFpbiBzdHJpbmcgYm9keVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBcInJhdyB0ZXh0IGJvZHlcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShzaGEyNTYoXCJyYXcgdGV4dCBib2R5XCIpKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYXNoZXMgYSBGb3JtRGF0YSBib2R5IG92ZXIgaXRzIGV4YWN0IGVuY29kZWQgYnl0ZXMgYW5kIHNldHMgY29udGVudC10eXBlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICBmb3JtRGF0YS5hcHBlbmQoXCJmaWVsZFwiLCBcInZhbHVlXCIpO1xuICAgICAgZm9ybURhdGEuYXBwZW5kKFxuICAgICAgICBcImZpbGVcIixcbiAgICAgICAgbmV3IEJsb2IoW1wiZmlsZSBjb250ZW50c1wiXSwgeyB0eXBlOiBcInRleHQvcGxhaW5cIiB9KSxcbiAgICAgICAgXCJmaWxlLnR4dFwiLFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keTogZm9ybURhdGEsXG4gICAgICB9KTtcblxuICAgICAgLy8gdGhlIGJvZHkgc2VudCB0byB0aGUgcmVhbCBmZXRjaCBtdXN0IGJlIHRoZSByZS1lbmNvZGVkIGJ5dGVzLCBub3QgdGhlIG9yaWdpbmFsIEZvcm1EYXRhXG4gICAgICBjb25zdCBzZW50Qnl0ZXMgPSBjYXB0dXJlZEluaXQhLmJvZHkgYXMgVWludDhBcnJheTtcbiAgICAgIGV4cGVjdChzZW50Qnl0ZXMpLnRvQmVJbnN0YW5jZU9mKFVpbnQ4QXJyYXkpO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBjb25zdCBjb250ZW50VHlwZSA9IGhlYWRlcnMuZ2V0KFwiY29udGVudC10eXBlXCIpITtcbiAgICAgIGV4cGVjdChjb250ZW50VHlwZSkudG9NYXRjaCgvXm11bHRpcGFydFxcL2Zvcm0tZGF0YTsgYm91bmRhcnk9Lyk7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShzaGEyNTYoc2VudEJ5dGVzKSk7XG5cbiAgICAgIC8vIHRoZSBoYXNoZWQvc2VudCBieXRlcyBtdXN0IHJvdW5kLXRyaXAgYmFjayB0byB0aGUgb3JpZ2luYWwgZmllbGRzXG4gICAgICBjb25zdCByb3VuZFRyaXBwZWQgPSBhd2FpdCBuZXcgUmVzcG9uc2Uoc2VudEJ5dGVzLCB7XG4gICAgICAgIGhlYWRlcnM6IHsgXCJjb250ZW50LXR5cGVcIjogY29udGVudFR5cGUgfSxcbiAgICAgIH0pLmZvcm1EYXRhKCk7XG4gICAgICBleHBlY3Qocm91bmRUcmlwcGVkLmdldChcImZpZWxkXCIpKS50b0JlKFwidmFsdWVcIik7XG4gICAgICBjb25zdCBmaWxlID0gcm91bmRUcmlwcGVkLmdldChcImZpbGVcIikgYXMgRmlsZTtcbiAgICAgIGV4cGVjdChmaWxlLm5hbWUpLnRvQmUoXCJmaWxlLnR4dFwiKTtcbiAgICAgIGV4cGVjdChhd2FpdCBmaWxlLnRleHQoKSkudG9CZShcImZpbGUgY29udGVudHNcIik7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFzaGVzIGEgQmxvYiBib2R5IG92ZXIgaXRzIHJhdyBieXRlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW1wiYmxvYiBjb250ZW50c1wiXSwgeyB0eXBlOiBcInRleHQvcGxhaW5cIiB9KTtcblxuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keTogYmxvYixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShcbiAgICAgICAgc2hhMjU2KGF3YWl0IGJsb2IuYXJyYXlCdWZmZXIoKSksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImhhc2hlcyBhbiBBcnJheUJ1ZmZlciBib2R5IG92ZXIgaXRzIHJhdyBieXRlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWZmZXIgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoXCJhcnJheSBidWZmZXIgY29udGVudHNcIikuYnVmZmVyO1xuXG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUFVUXCIsXG4gICAgICAgIGJvZHk6IGJ1ZmZlcixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgICBleHBlY3QoaGVhZGVycy5nZXQoXCJ4LWFtei1jb250ZW50LXNoYTI1NlwiKSkudG9CZShzaGEyNTYoYnVmZmVyKSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFzaGVzIGEgdHlwZWQgYXJyYXkgYm9keSBvdmVyIHRoZSBieXRlcyBpdCB2aWV3c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBieXRlcyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcInh4dHlwZWQgYXJyYXkgY29udGVudHNcIik7XG4gICAgICBjb25zdCB2aWV3ID0gYnl0ZXMuc3ViYXJyYXkoMik7XG5cbiAgICAgIGF3YWl0IChnbG9iYWwgYXMgYW55KS53aW5kb3cuZmV0Y2goXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiLCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGJvZHk6IHZpZXcsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoXG4gICAgICAgIHNoYTI1NihcInR5cGVkIGFycmF5IGNvbnRlbnRzXCIpLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJ3cmFwcyBmZXRjaCBvbmNlIHdoZW4gYSBzZWNvbmQgcGF0Y2hlZCBjaHVuayBsb2FkcyBpbiB0aGUgc2FtZSBzY29wZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBFdmVyeSBlbnRyeXBvaW50IGNodW5rIGNhcnJpZXMgYSBjb3B5LiBXcmFwcGVkIHR3aWNlLCB0aGUgb3V0ZXIgd3JhcHBlclxuICAgICAgLy8gcmUtZW5jb2RlZCBhIEZvcm1EYXRhIGJvZHkgdG8gYnl0ZXMgYW5kIHRoZSBpbm5lciBvbmUgb3Zlcndyb3RlIHRoZVxuICAgICAgLy8gcmlnaHQgaGFzaCB3aXRoIG9uZSBvZiB0aG9zZSBieXRlcyBhcyBKU09OLlxuICAgICAgY29uc3QgcGF0Y2hlZE9uY2UgPSAoZ2xvYmFsIGFzIGFueSkuZmV0Y2g7XG4gICAgICBjb25zdCBwYXRjaGVkWGhyID0gKGdsb2JhbCBhcyBhbnkpLlhNTEh0dHBSZXF1ZXN0O1xuICAgICAgamVzdC5yZXNldE1vZHVsZXMoKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzIC0tIHRoZSBzZWNvbmQgY2h1bmsncyBjb3B5XG4gICAgICByZXF1aXJlKFwiLi9wYXRjaC1mZXRjaC5qc1wiKTtcbiAgICAgIGV4cGVjdCgoZ2xvYmFsIGFzIGFueSkuZmV0Y2gpLnRvQmUocGF0Y2hlZE9uY2UpO1xuICAgICAgZXhwZWN0KChnbG9iYWwgYXMgYW55KS5YTUxIdHRwUmVxdWVzdCkudG9CZShwYXRjaGVkWGhyKTtcblxuICAgICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgIGZvcm1EYXRhLmFwcGVuZChcImZpZWxkXCIsIFwidmFsdWVcIik7XG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBmb3JtRGF0YSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qob3JpZ2luYWxGZXRjaCkudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoXG4gICAgICAgIHNoYTI1NihjYXB0dXJlZEluaXQhLmJvZHkgYXMgVWludDhBcnJheSksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImhhc2hlcyBhbiBlbXB0eSBieXRlIGFycmF5IHdoZW4gbm8gYm9keSBpcyBwcmVzZW50XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IChnbG9iYWwgYXMgYW55KS53aW5kb3cuZmV0Y2goXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiLCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoXG4gICAgICAgIHNoYTI1NihuZXcgVWludDhBcnJheSgwKSksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImhhc2hlcyBhIFJlcXVlc3QncyBvd24gYm9keSB3aGVuIGluaXQgaXMgb21pdHRlZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFJlcXVlc3QoXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiLCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGJvZHk6IFwicmVxdWVzdCBib2R5XCIsXG4gICAgICAgIGhlYWRlcnM6IHsgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L3BsYWluXCIgfSxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKHJlcXVlc3QpO1xuXG4gICAgICBjb25zdCBbc2VudElucHV0XSA9IG9yaWdpbmFsRmV0Y2gubW9jay5jYWxsc1swXTtcbiAgICAgIGV4cGVjdChzZW50SW5wdXQpLnRvQmUocmVxdWVzdCk7XG4gICAgICAvLyBUaGUgYm9keSB3YXMgcmVhZCBmcm9tIGEgY2xvbmUsIHNvIHRoZSByZXF1ZXN0IHN0aWxsIGhhcyBpdCB0byBzZW5kLlxuICAgICAgZXhwZWN0KGF3YWl0IChzZW50SW5wdXQgYXMgUmVxdWVzdCkudGV4dCgpKS50b0JlKFwicmVxdWVzdCBib2R5XCIpO1xuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoc2hhMjU2KFwicmVxdWVzdCBib2R5XCIpKTtcbiAgICAgIC8vIGBpbml0LmhlYWRlcnNgIHJlcGxhY2VzIHRoZSByZXF1ZXN0J3Mgb3duLCBzbyB0aGV5IG11c3QgY2Fycnkgb3Zlci5cbiAgICAgIGV4cGVjdChoZWFkZXJzLmdldChcImNvbnRlbnQtdHlwZVwiKSkudG9CZShcInRleHQvcGxhaW5cIik7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFzaGVzIGluaXQncyBib2R5IG92ZXIgYSBSZXF1ZXN0J3Mgb3duIHdoZW4gYm90aCBhcmUgc2V0XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keTogXCJyZXF1ZXN0IGJvZHlcIixcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKHJlcXVlc3QsIHsgYm9keTogXCJpbml0IGJvZHlcIiB9KTtcblxuICAgICAgY29uc3QgaGVhZGVycyA9IGNhcHR1cmVkSW5pdCEuaGVhZGVycyBhcyBIZWFkZXJzO1xuICAgICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoc2hhMjU2KFwiaW5pdCBib2R5XCIpKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJwYXNzZXMgYSBHRVQgUmVxdWVzdCB0aHJvdWdoIHdpdGhvdXQgaGFzaGluZ1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFJlcXVlc3QoXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcblxuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChyZXF1ZXN0KTtcblxuICAgICAgZXhwZWN0KG9yaWdpbmFsRmV0Y2gpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHJlcXVlc3QsIHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwicGFzc2VzIHRocm91Z2ggdW50b3VjaGVkIHdoZW4gaW5pdCBpcyBvbWl0dGVkXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IChnbG9iYWwgYXMgYW55KS53aW5kb3cuZmV0Y2goXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcblxuICAgICAgZXhwZWN0KG9yaWdpbmFsRmV0Y2gpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICBcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwicGFzc2VzIHRocm91Z2ggd2l0aG91dCBoYXNoaW5nIGZvciBub24tUFVUL1BPU1QgbWV0aG9kc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCAoZ2xvYmFsIGFzIGFueSkud2luZG93LmZldGNoKFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgIGJvZHk6IFwic2hvdWxkIG5vdCBiZSBoYXNoZWRcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY2FwdHVyZWRJbml0IS5oZWFkZXJzKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwicGFzc2VzIHRocm91Z2ggd2l0aG91dCBoYXNoaW5nIGZvciBjcm9zcy1vcmlnaW4gcmVxdWVzdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5mZXRjaChcImh0dHBzOi8vb3RoZXItb3JpZ2luLmNvbS9hcGlcIiwge1xuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBcInNob3VsZCBub3QgYmUgaGFzaGVkXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNhcHR1cmVkSW5pdCEuaGVhZGVycykudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlhNTEh0dHBSZXF1ZXN0XCIsICgpID0+IHtcbiAgICB0ZXN0KFwiaGFzaGVzIFVSTFNlYXJjaFBhcmFtcyB2aWEgdG9TdHJpbmcoKSwgbm90IEpTT04uc3RyaW5naWZ5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyBhOiBcIjFcIiwgYjogXCIyXCIgfSk7XG4gICAgICBjb25zdCBzZXRSZXF1ZXN0SGVhZGVyID0gamVzdC5mbigpO1xuXG4gICAgICBjb25zdCB4aHIgPSBuZXcgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIgPSBzZXRSZXF1ZXN0SGVhZGVyO1xuICAgICAgeGhyLm9wZW4oXCJQT1NUXCIsIFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGlcIik7XG4gICAgICBhd2FpdCB4aHIuc2VuZChwYXJhbXMpO1xuXG4gICAgICBleHBlY3Qoc2V0UmVxdWVzdEhlYWRlcikudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgIFwieC1hbXotY29udGVudC1zaGEyNTZcIixcbiAgICAgICAgc2hhMjU2KHBhcmFtcy50b1N0cmluZygpKSxcbiAgICAgICk7XG4gICAgICBleHBlY3Qoc2V0UmVxdWVzdEhlYWRlcikubm90LnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICBcIngtYW16LWNvbnRlbnQtc2hhMjU2XCIsXG4gICAgICAgIHNoYTI1NihcInt9XCIpLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJoYXNoZXMgYSBwbGFpbiBzdHJpbmcgYm9keVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzZXRSZXF1ZXN0SGVhZGVyID0gamVzdC5mbigpO1xuXG4gICAgICBjb25zdCB4aHIgPSBuZXcgKGdsb2JhbCBhcyBhbnkpLndpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIgPSBzZXRSZXF1ZXN0SGVhZGVyO1xuICAgICAgeGhyLm9wZW4oXCJQVVRcIiwgXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcbiAgICAgIGF3YWl0IHhoci5zZW5kKFwicmF3IHRleHQgYm9keVwiKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICBcIngtYW16LWNvbnRlbnQtc2hhMjU2XCIsXG4gICAgICAgIHNoYTI1NihcInJhdyB0ZXh0IGJvZHlcIiksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImRvZXMgbm90IGhhc2ggZm9yIG5vbi1QVVQvUE9TVCBtZXRob2RzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNldFJlcXVlc3RIZWFkZXIgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyAoZ2xvYmFsIGFzIGFueSkud2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlciA9IHNldFJlcXVlc3RIZWFkZXI7XG4gICAgICB4aHIub3BlbihcIkdFVFwiLCBcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIpO1xuICAgICAgYXdhaXQgeGhyLnNlbmQoXCJzaG91bGQgbm90IGJlIGhhc2hlZFwiKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZG9lcyBub3QgaGFzaCBmb3IgY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNldFJlcXVlc3RIZWFkZXIgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyAoZ2xvYmFsIGFzIGFueSkud2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlciA9IHNldFJlcXVlc3RIZWFkZXI7XG4gICAgICB4aHIub3BlbihcIlBPU1RcIiwgXCJodHRwczovL290aGVyLW9yaWdpbi5jb20vYXBpXCIpO1xuICAgICAgYXdhaXQgeGhyLnNlbmQoXCJzaG91bGQgbm90IGJlIGhhc2hlZFwiKTtcblxuICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFzaGVzIHRoZSBieXRlcyBvZiBhIHR5cGVkLWFycmF5IG9yIEJsb2IgYm9keSwgbm90IHRoZWlyIEpTT05cIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShbMSwgMiwgMywgMjUwXSk7XG4gICAgICBmb3IgKGNvbnN0IGJvZHkgb2YgW2J5dGVzLCBuZXcgQmxvYihbYnl0ZXNdKV0pIHtcbiAgICAgICAgY29uc3Qgc2V0UmVxdWVzdEhlYWRlciA9IGplc3QuZm4oKTtcbiAgICAgICAgY29uc3QgeGhyID0gbmV3IChnbG9iYWwgYXMgYW55KS53aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIgPSBzZXRSZXF1ZXN0SGVhZGVyO1xuICAgICAgICB4aHIub3BlbihcIlBPU1RcIiwgXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcbiAgICAgICAgYXdhaXQgeGhyLnNlbmQoYm9keSk7XG5cbiAgICAgICAgZXhwZWN0KHNldFJlcXVlc3RIZWFkZXIpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICAgIFwieC1hbXotY29udGVudC1zaGEyNTZcIixcbiAgICAgICAgICBzaGEyNTYoYnl0ZXMpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGVzdChcInNlbmRzIGEgRm9ybURhdGEgYm9keSBhcyB0aGUgZW5jb2RpbmcgaXQgaGFzaGVkLCB3aXRoIGl0cyBib3VuZGFyeVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzZW5kID0gamVzdC5zcHlPbihGYWtlWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLCBcInNlbmRcIik7XG4gICAgICBjb25zdCBzZXRSZXF1ZXN0SGVhZGVyID0gamVzdC5mbigpO1xuICAgICAgY29uc3QgZm9ybSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgZm9ybS5hcHBlbmQoXCJuYW1lXCIsIFwidmFsdWVcIik7XG4gICAgICBmb3JtLmFwcGVuZChcImZpbGVcIiwgbmV3IEJsb2IoW1wiZmlsZS1ieXRlc1wiXSksIFwiYS50eHRcIik7XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyAoZ2xvYmFsIGFzIGFueSkud2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlciA9IHNldFJlcXVlc3RIZWFkZXI7XG4gICAgICB4aHIub3BlbihcIlBPU1RcIiwgXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcbiAgICAgIGF3YWl0IHhoci5zZW5kKGZvcm0pO1xuXG4gICAgICBjb25zdCBzZW50ID0gc2VuZC5tb2NrLmNhbGxzWzBdWzBdIGFzIFVpbnQ4QXJyYXk7XG4gICAgICBleHBlY3Qoc2VudCkudG9CZUluc3RhbmNlT2YoVWludDhBcnJheSk7XG4gICAgICBleHBlY3Qoc2V0UmVxdWVzdEhlYWRlcikudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgIFwieC1hbXotY29udGVudC1zaGEyNTZcIixcbiAgICAgICAgc2hhMjU2KHNlbnQpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gc2V0UmVxdWVzdEhlYWRlci5tb2NrLmNhbGxzLmZpbmQoXG4gICAgICAgIChbbmFtZV0pID0+IG5hbWUgPT09IFwiY29udGVudC10eXBlXCIsXG4gICAgICApPy5bMV07XG4gICAgICBleHBlY3QoY29udGVudFR5cGUpLnRvTWF0Y2goL15tdWx0aXBhcnRcXC9mb3JtLWRhdGE7IGJvdW5kYXJ5PS8pO1xuICAgICAgZXhwZWN0KEJ1ZmZlci5mcm9tKHNlbnQpLnRvU3RyaW5nKCkpLnRvQ29udGFpbihcbiAgICAgICAgY29udGVudFR5cGUuc3BsaXQoXCJib3VuZGFyeT1cIilbMV0sXG4gICAgICApO1xuICAgICAgc2VuZC5tb2NrUmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImRvZXMgbm90IGhhc2ggd2hlbiB0aGVyZSBpcyBubyBib2R5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNldFJlcXVlc3RIZWFkZXIgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyAoZ2xvYmFsIGFzIGFueSkud2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlciA9IHNldFJlcXVlc3RIZWFkZXI7XG4gICAgICB4aHIub3BlbihcIlBPU1RcIiwgXCJodHRwczovL2V4YW1wbGUuY29tL2FwaVwiKTtcbiAgICAgIGF3YWl0IHhoci5zZW5kKCk7XG5cbiAgICAgIGV4cGVjdChzZXRSZXF1ZXN0SGVhZGVyKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vKipcbiAqIFR1cmJvcGFjaydzIHdlYi13b3JrZXIgYm9vdHN0cmFwIGlzIGBzdGF0aWMvY2h1bmtzL3R1cmJvcGFjay13b3JrZXItKi5qc2AsXG4gKiB3aGljaCBgcGF0Y2hGZXRjaEluQ2xpZW50SnNgJ3MgYHR1cmJvcGFjay1gIHNlbGVjdG9yIG1hdGNoZXMg4oCUIHNvIHRoaXMgZmlsZSBpc1xuICogcHJlcGVuZGVkIHRvIGEgc2NyaXB0IHRoYXQgcnVucyBvZmYgdGhlIG1haW4gdGhyZWFkLiBSZWFkaW5nIGB3aW5kb3dgIHRoZXJlXG4gKiB0aHJldyBiZWZvcmUgdGhlIHdvcmtlcidzIG93biBtb2R1bGUgY291bGQgcnVuLCB3aGljaCB0b29rIG91dCBldmVyeVxuICogYG5ldyBXb3JrZXIobmV3IFVSTCjigKYpKWAgYXBwIChgd29ya2VyLW1vZHVsZS11cmxgLCBgd29ya2VyLXJlbGF5LWNvbXBpbGVyYCkuXG4gKi9cbmRlc2NyaWJlKFwicGF0Y2gtZmV0Y2ggaW4gYSB3b3JrZXIgc2NvcGVcIiwgKCkgPT4ge1xuICBsZXQgb3JpZ2luYWxGZXRjaDogamVzdC5Nb2NrO1xuICBsZXQgY2FwdHVyZWRJbml0OiBSZXF1ZXN0SW5pdCB8IHVuZGVmaW5lZDtcbiAgY29uc3QgcmVhbEZldGNoID0gZ2xvYmFsLmZldGNoO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGplc3QucmVzZXRNb2R1bGVzKCk7XG4gICAgY2FwdHVyZWRJbml0ID0gdW5kZWZpbmVkO1xuICAgIG9yaWdpbmFsRmV0Y2ggPSBqZXN0LmZuKChfaW5wdXQ6IHVua25vd24sIGluaXQ/OiBSZXF1ZXN0SW5pdCkgPT4ge1xuICAgICAgY2FwdHVyZWRJbml0ID0gaW5pdDtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3BvbnNlKFwib2tcIikpO1xuICAgIH0pO1xuICAgIChnbG9iYWwgYXMgYW55KS5mZXRjaCA9IG9yaWdpbmFsRmV0Y2g7XG4gICAgLy8gTm8gYHdpbmRvd2AsIGFuZCBubyBgWE1MSHR0cFJlcXVlc3RgOiB0aGUgbmFycm93ZXN0IHNjb3BlIHRoZSBwYXRjaCBjYW5cbiAgICAvLyBsYW5kIGluLlxuICAgIGluc3RhbGxTY29wZSh7IHdpdGhXaW5kb3c6IGZhbHNlLCB3aXRoWGhyOiBmYWxzZSB9KTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBkZWxldGUgKGdsb2JhbCBhcyBhbnkpLndpbmRvdztcbiAgICBkZWxldGUgKGdsb2JhbCBhcyBhbnkpLmxvY2F0aW9uO1xuICAgIGdsb2JhbC5mZXRjaCA9IHJlYWxGZXRjaDtcbiAgfSk7XG5cbiAgdGVzdChcImxvYWRzIHdpdGhvdXQgYSB3aW5kb3cgYW5kIHN0aWxsIHNpZ25zIGEgc2FtZS1vcmlnaW4gUE9TVFwiLCBhc3luYyAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzIC0tIHRoZSBwb2ludCBvZiB0aGUgdGVzdCBpcyB0aGF0IHJlcXVpcmluZyBpdCBkb2VzIG5vdCB0aHJvd1xuICAgICAgcmVxdWlyZShcIi4vcGF0Y2gtZmV0Y2guanNcIik7XG4gICAgfSkubm90LnRvVGhyb3coKTtcblxuICAgIGF3YWl0IGdsb2JhbC5mZXRjaChcImh0dHBzOi8vZXhhbXBsZS5jb20vYXBpXCIsIHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICBib2R5OiBcIndvcmtlciBib2R5XCIsXG4gICAgfSk7XG5cbiAgICBjb25zdCBoZWFkZXJzID0gY2FwdHVyZWRJbml0IS5oZWFkZXJzIGFzIEhlYWRlcnM7XG4gICAgZXhwZWN0KGhlYWRlcnMuZ2V0KFwieC1hbXotY29udGVudC1zaGEyNTZcIikpLnRvQmUoc2hhMjU2KFwid29ya2VyIGJvZHlcIikpO1xuICB9KTtcblxuICB0ZXN0KFwibGVhdmVzIFhNTEh0dHBSZXF1ZXN0IGFsb25lIHdoZW4gdGhlIHNjb3BlIGhhcyBub25lXCIsICgpID0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAtLSByZS1leGVjdXRlZCBhZ2FpbnN0IHRoaXMgc2NvcGVcbiAgICByZXF1aXJlKFwiLi9wYXRjaC1mZXRjaC5qc1wiKTtcblxuICAgIGV4cGVjdCgoZ2xvYmFsIGFzIGFueSkuWE1MSHR0cFJlcXVlc3QpLnRvQmVVbmRlZmluZWQoKTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# ~~ Generated by cdk-nextjs ~~
|
|
2
|
+
# cdk-nextjs rewrites any Dockerfile carrying the line above, so that an
|
|
3
|
+
# upgrade does not leave a stale one behind. To own this file yourself, delete
|
|
4
|
+
# that line and cdk-nextjs will leave the rest of it alone.
|
|
2
5
|
# Modified from: https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
|
|
3
6
|
|
|
4
7
|
# Production image, copy all the files and run next
|
|
@@ -14,13 +17,17 @@ ENV NODE_ENV=production
|
|
|
14
17
|
RUN addgroup --system --gid 1001 nodejs
|
|
15
18
|
RUN adduser --system --uid 1001 nextjs
|
|
16
19
|
|
|
17
|
-
ARG
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
COPY --chown=nextjs:nodejs .next/
|
|
22
|
-
#
|
|
23
|
-
|
|
20
|
+
ARG RELATIVE_PROJECT_DIR
|
|
21
|
+
# The deployment root cdk-nextjs staged during `next build`: the traced assets of
|
|
22
|
+
# every built output, keyed by repo-root-relative path, plus cdk-nextjs's own
|
|
23
|
+
# request-handling server under cdk-nextjs-runtime/. Replaces `.next/standalone`.
|
|
24
|
+
COPY --chown=nextjs:nodejs .next/cdk-nextjs-adapter/app ./
|
|
25
|
+
# There is no CloudFront in front of this deployment type, so the server answers
|
|
26
|
+
# every static request itself: the manifest lists `.next/static`, the runtime
|
|
27
|
+
# lists `public` when it starts, and it serves both off disk. (Image optimization
|
|
28
|
+
# reads its sources from here too, through the runtime's in-process routing.)
|
|
29
|
+
COPY --chown=nextjs:nodejs .next/static ./$RELATIVE_PROJECT_DIR/.next/static
|
|
30
|
+
COPY --chown=nextjs:nodejs public ./$RELATIVE_PROJECT_DIR/public
|
|
24
31
|
|
|
25
32
|
USER nextjs
|
|
26
33
|
|
|
@@ -28,8 +35,8 @@ EXPOSE 3000
|
|
|
28
35
|
|
|
29
36
|
ENV PORT=3000
|
|
30
37
|
|
|
31
|
-
#
|
|
32
|
-
#
|
|
38
|
+
# cdk-nextjs's own server, staged above. It invokes the entrypoints `next build`
|
|
39
|
+
# produced in-process; there is no `next start` and no server.js.
|
|
33
40
|
# CMD will be overwritten by ECS Task Definition
|
|
34
41
|
ENV HOSTNAME="0.0.0.0"
|
|
35
|
-
CMD ["node" "server.
|
|
42
|
+
CMD ["node", "cdk-nextjs-runtime/server.mjs"]
|
package/lib/nextjs-cache.d.ts
CHANGED
|
@@ -11,8 +11,12 @@ export interface NextjsCacheProps {
|
|
|
11
11
|
readonly buildId: string;
|
|
12
12
|
/**
|
|
13
13
|
* Bring your own S3 bucket for cache storage. When provided, cdk-nextjs
|
|
14
|
-
* will skip creating a new bucket.
|
|
15
|
-
*
|
|
14
|
+
* will skip creating a new bucket.
|
|
15
|
+
*
|
|
16
|
+
* The bucket must be dedicated to this one deployment. Don't share it with
|
|
17
|
+
* another deployment (another branch, stage, or app): every deploy's
|
|
18
|
+
* post-deploy step deletes every object under a top-level prefix other than
|
|
19
|
+
* the current `buildId/`, which includes every other deployment's cache.
|
|
16
20
|
*/
|
|
17
21
|
readonly cacheBucket?: IBucket;
|
|
18
22
|
/**
|
|
@@ -24,8 +28,16 @@ export interface NextjsCacheProps {
|
|
|
24
28
|
/**
|
|
25
29
|
* Bring your own DynamoDB table for revalidation metadata. When provided,
|
|
26
30
|
* cdk-nextjs will skip creating a new table. The table must have `pk` (String)
|
|
27
|
-
* as partition key and `sk` (String) as sort key.
|
|
28
|
-
* `
|
|
31
|
+
* as partition key and `sk` (String) as sort key.
|
|
32
|
+
* Enabling TTL on its `ttl` attribute is recommended: each tag revalidation
|
|
33
|
+
* writes a revalidation log row that expires through it after 15 minutes.
|
|
34
|
+
* Without TTL those rows are kept until a deploy replaces their build, whose
|
|
35
|
+
* post-deploy step deletes them.
|
|
36
|
+
*
|
|
37
|
+
* The table must be dedicated to this one deployment. Don't share it with
|
|
38
|
+
* another deployment (another branch, stage, or app): every deploy's
|
|
39
|
+
* post-deploy step deletes the entries of the build it last recorded in the
|
|
40
|
+
* table, which with a shared table is another deployment's live build.
|
|
29
41
|
*/
|
|
30
42
|
readonly revalidationTable?: ITableV2;
|
|
31
43
|
}
|
|
@@ -46,10 +58,76 @@ export declare class NextjsCache extends Construct {
|
|
|
46
58
|
/**
|
|
47
59
|
* Creates DynamoDB table for revalidation metadata
|
|
48
60
|
* Schema: pk (buildId or "METADATA"), sk (tag#cacheKey or "CURRENT_BUILD"), createdAt, revalidatedAt
|
|
61
|
+
*
|
|
62
|
+
* Also the `'use cache'` revalidation log (pk "<buildId>#log",
|
|
63
|
+
* sk "<epoch-ms>#<tag>"), whose rows expire through the `ttl` attribute.
|
|
49
64
|
*/
|
|
50
65
|
private createRevalidationTable;
|
|
51
66
|
/**
|
|
52
67
|
* Deploy pre-built cache files from .next/cdk-nextjs-init-cache to S3
|
|
53
68
|
*/
|
|
54
69
|
private createDeployment;
|
|
70
|
+
/**
|
|
71
|
+
* `/tmp` and memory for `BucketDeployment`'s unzip Lambda, scaled to the init
|
|
72
|
+
* cache it has to unpack.
|
|
73
|
+
*
|
|
74
|
+
* That Lambda downloads the asset zip into `/tmp` and then extracts it
|
|
75
|
+
* alongside, so it needs room for both at once. CDK defaults it to 512 MiB of
|
|
76
|
+
* ephemeral storage and 128 MB of memory — fine for a small app, and a hard
|
|
77
|
+
* failure for one whose prerendered payloads are large. A fixture with 60
|
|
78
|
+
* statically generated pages carrying ~1 MB of RSC each produced a 664 MiB
|
|
79
|
+
* seed directory and the handler died on
|
|
80
|
+
* `OSError: [Errno 28] No space left on device` inside `zip.extractall`.
|
|
81
|
+
* Worse, `cdk deploy --hotswap` invokes the custom resource directly with a
|
|
82
|
+
* placeholder response URL, so the `Status: FAILED` it sends goes nowhere: the
|
|
83
|
+
* CLI prints "Contents of AWS::S3::Bucket … hotswapped!", exits 0, and the app
|
|
84
|
+
* comes up serving a *partially* seeded cache. Every route whose entry did not
|
|
85
|
+
* make it is then a miss that re-renders — which, for a
|
|
86
|
+
* `cacheComponents: true` app, means a postponed shell where the prerender
|
|
87
|
+
* should have been.
|
|
88
|
+
*
|
|
89
|
+
* The zip's compressed size is not known at synth time (CDK archives the asset
|
|
90
|
+
* later), so the worst case — an incompressible payload — is what gets
|
|
91
|
+
* budgeted: twice the directory, plus headroom, rounded up to a
|
|
92
|
+
* {@link storageStep}. Memory is only raised past
|
|
93
|
+
* CDK's default for caches big enough that 128 MB's slice of a vCPU would make
|
|
94
|
+
* the unzip and upload race the custom resource's 15-minute timeout; small
|
|
95
|
+
* apps keep the cheaper default and their existing template.
|
|
96
|
+
*
|
|
97
|
+
* Above the 10 GiB ephemeral-storage ceiling there is nothing left to ask for,
|
|
98
|
+
* so this warns and lets the deployment fail loudly rather than pretend.
|
|
99
|
+
* `overrides.bucketDeploymentProps` wins over everything here, including
|
|
100
|
+
* `useEfs: true`, which is the supported way out.
|
|
101
|
+
*/
|
|
102
|
+
private sizeDeploymentLambda;
|
|
103
|
+
/**
|
|
104
|
+
* Stage the init cache under a `buildId` directory, so that the objects land
|
|
105
|
+
* at `<buildId>/<key>` without a `destinationKeyPrefix`.
|
|
106
|
+
*
|
|
107
|
+
* The keys have to carry the build ID — that is how the runtime cache handler
|
|
108
|
+
* and the post-deploy pruner namespace one deployment's entries from the next
|
|
109
|
+
* (`src/adapter/s3-cache-handler.ts`). Asking `BucketDeployment` for it, as
|
|
110
|
+
* this used to, is what costs: it unconditionally tags the *destination
|
|
111
|
+
* bucket* with `aws-cdk:cr-owned:<destinationKeyPrefix>:<hash>`, so a prefix
|
|
112
|
+
* that changes per build makes the bucket's `Tags` change per build.
|
|
113
|
+
* `AWS::S3::Bucket` `Tags` are not hotswappable, so `cdk deploy
|
|
114
|
+
* --hotswap-fallback` rejected the diff and fell back to a full CloudFormation
|
|
115
|
+
* deployment every single time — measured at 19 of 22 deploys in one harness
|
|
116
|
+
* run, ~110s each against a ~52s hotswap.
|
|
117
|
+
*
|
|
118
|
+
* Putting the build ID in the asset's own paths instead leaves the S3 keys
|
|
119
|
+
* byte-identical and the tag key constant (`aws-cdk:cr-owned:<hash>`, derived
|
|
120
|
+
* from the construct path). Nothing else read the prefix: `prune` is already
|
|
121
|
+
* `false`, and the two handler branches that do scope work to it — emptying
|
|
122
|
+
* the prefix on delete, and deleting the old prefix when the destination
|
|
123
|
+
* changes — are both gated on `retainOnDelete`, which `BucketDeployment`
|
|
124
|
+
* defaults to `true`.
|
|
125
|
+
*
|
|
126
|
+
* A copy rather than the directory itself because the build ID is only known
|
|
127
|
+
* *after* `next build`, so the adapter cannot write into a nested directory in
|
|
128
|
+
* the first place, and because `.next/cdk-nextjs-init-cache` has to stay where
|
|
129
|
+
* it is for the local cache handler to read it (`CDK_NEXTJS_INIT_CACHE_DIR`).
|
|
130
|
+
* CDK is about to read every byte of this to zip it regardless.
|
|
131
|
+
*/
|
|
132
|
+
private createStagingDirectory;
|
|
55
133
|
}
|