cdk-nextjs 0.6.1 → 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 +2467 -2714
- package/.jsii.tabl.json +1 -1
- package/API.md +1725 -1909
- package/CLAUDE.md +2 -1
- package/README.md +429 -130
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +152 -170
- package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
- package/docs/adapter-runtime.md +185 -0
- package/docs/breaking-changes.md +687 -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 +13 -0
- package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +11 -2
- 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/post-deploy.lambda.js +3 -2
- 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 +19 -3
- package/lib/lambdas/post-deploy/prune-s3.js +54 -15
- package/lib/lambdas/post-deploy/prune-s3.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-s3.test.js +255 -0
- 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 +107 -18
- package/lib/nextjs-api.js +349 -39
- package/lib/nextjs-api.test.js +582 -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 +23 -3
- package/lib/nextjs-post-deploy.js +14 -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 +23 -4
- package/lib/nextjs-static-assets.js +29 -6
- package/lib/nextjs-static-assets.test.js +20 -1
- package/lib/root-constructs/nextjs-base-construct.d.ts +105 -45
- package/lib/root-constructs/nextjs-base-construct.js +144 -34
- package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
- package/lib/root-constructs/nextjs-global-containers.js +20 -70
- package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
- package/lib/root-constructs/nextjs-global-functions.js +52 -69
- package/lib/root-constructs/nextjs-regional-containers.d.ts +25 -5
- package/lib/root-constructs/nextjs-regional-containers.js +17 -15
- package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
- package/lib/root-constructs/nextjs-regional-functions.js +8 -25
- 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 +123 -11
- package/lib/utils/base-path.js +276 -39
- package/lib/utils/base-path.test.js +275 -50
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
4
|
+
jest.mock("@aws-sdk/client-s3");
|
|
5
|
+
jest.mock("@aws-sdk/client-dynamodb");
|
|
6
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
7
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
8
|
+
const aws_cache_store_1 = require("./aws-cache-store");
|
|
9
|
+
const use_cache_common_1 = require("./use-cache-common");
|
|
10
|
+
const use_cache_default_handler_1 = require("./use-cache-default-handler");
|
|
11
|
+
const use_cache_remote_handler_1 = require("./use-cache-remote-handler");
|
|
12
|
+
/** The input an automocked SDK command was constructed with. */
|
|
13
|
+
const commandInput = (command, type) => {
|
|
14
|
+
const mock = type;
|
|
15
|
+
return mock.mock.calls[mock.mock.instances.indexOf(command)][0];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* S3 as a map. Every "instance" in these tests is a separate handler over the
|
|
19
|
+
* same map, which is what the cache bucket is to separate Lambda instances.
|
|
20
|
+
*/
|
|
21
|
+
const objects = new Map();
|
|
22
|
+
const s3Send = jest.fn(async (command) => {
|
|
23
|
+
if (command instanceof client_s3_1.PutObjectCommand) {
|
|
24
|
+
const { Key, Body } = commandInput(command, client_s3_1.PutObjectCommand);
|
|
25
|
+
objects.set(Key, Body);
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
if (command instanceof client_s3_1.GetObjectCommand) {
|
|
29
|
+
const { Key } = commandInput(command, client_s3_1.GetObjectCommand);
|
|
30
|
+
const body = objects.get(Key);
|
|
31
|
+
if (body === undefined) {
|
|
32
|
+
throw new client_s3_1.NoSuchKey({ message: "NoSuchKey", $metadata: {} });
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
Body: { transformToString: async () => body },
|
|
36
|
+
ContentType: "application/json; charset=utf-8",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
throw new Error("unexpected S3 command");
|
|
40
|
+
});
|
|
41
|
+
/** The revalidation table's marker rows, as a map. */
|
|
42
|
+
const rows = new Map();
|
|
43
|
+
/** Its revalidation log rows, by sort key. */
|
|
44
|
+
const logRows = new Map();
|
|
45
|
+
const dynamoSend = jest.fn(async (command) => {
|
|
46
|
+
if (command instanceof client_dynamodb_1.UpdateItemCommand) {
|
|
47
|
+
const { Key, ExpressionAttributeValues } = commandInput(command, client_dynamodb_1.UpdateItemCommand);
|
|
48
|
+
const row = rows.get(Key.sk.S) ?? {
|
|
49
|
+
sk: Key.sk,
|
|
50
|
+
};
|
|
51
|
+
for (const [name, value] of Object.entries(ExpressionAttributeValues)) {
|
|
52
|
+
row[name.slice(1)] = value;
|
|
53
|
+
}
|
|
54
|
+
rows.set(Key.sk.S, row);
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
if (command instanceof client_dynamodb_1.BatchGetItemCommand) {
|
|
58
|
+
const { RequestItems } = commandInput(command, client_dynamodb_1.BatchGetItemCommand);
|
|
59
|
+
const [[table, { Keys }]] = Object.entries(RequestItems);
|
|
60
|
+
return {
|
|
61
|
+
Responses: {
|
|
62
|
+
[table]: Keys.map(({ sk }) => rows.get(sk.S)).filter(Boolean),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (command instanceof client_dynamodb_1.PutItemCommand) {
|
|
67
|
+
const { Item } = commandInput(command, client_dynamodb_1.PutItemCommand);
|
|
68
|
+
logRows.set(Item.sk.S, Item);
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
if (command instanceof client_dynamodb_1.QueryCommand) {
|
|
72
|
+
const { ExpressionAttributeValues } = commandInput(command, client_dynamodb_1.QueryCommand);
|
|
73
|
+
const since = ExpressionAttributeValues[":since"].S;
|
|
74
|
+
return {
|
|
75
|
+
Items: Array.from(logRows.keys())
|
|
76
|
+
.filter((sk) => sk >= since)
|
|
77
|
+
.sort()
|
|
78
|
+
.map((sk) => logRows.get(sk)),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
throw new Error("unexpected DynamoDB command");
|
|
82
|
+
});
|
|
83
|
+
client_s3_1.S3Client.mockImplementation(() => ({ send: s3Send }));
|
|
84
|
+
client_dynamodb_1.DynamoDBClient.mockImplementation(() => ({ send: dynamoSend }));
|
|
85
|
+
const s3Calls = (type) => s3Send.mock.calls.filter(([command]) => command instanceof type)
|
|
86
|
+
.length;
|
|
87
|
+
const dynamoCalls = (type) => dynamoSend.mock.calls.filter(([command]) => command instanceof type).length;
|
|
88
|
+
/** One compute instance's view of the shared table. */
|
|
89
|
+
function tagManifest(refreshIntervalMs = 0) {
|
|
90
|
+
return new aws_cache_store_1.TrackedTagMarkers({
|
|
91
|
+
markers: new aws_cache_store_1.TagMarkerTable(new client_dynamodb_1.DynamoDBClient({}), "table", "build"),
|
|
92
|
+
log: new aws_cache_store_1.RevalidationLog(new client_dynamodb_1.DynamoDBClient({}), "table", "build"),
|
|
93
|
+
refreshIntervalMs,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function bucket() {
|
|
97
|
+
return new aws_cache_store_1.CacheBucket(new client_s3_1.S3Client({}), "bucket");
|
|
98
|
+
}
|
|
99
|
+
function remoteInstance(tags = tagManifest()) {
|
|
100
|
+
return (0, use_cache_remote_handler_1.createRemoteUseCacheHandler)({
|
|
101
|
+
bucket: bucket(),
|
|
102
|
+
buildId: "build",
|
|
103
|
+
tags,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function defaultInstance(tags = tagManifest()) {
|
|
107
|
+
return (0, use_cache_default_handler_1.createDefaultUseCacheHandler)({ tags });
|
|
108
|
+
}
|
|
109
|
+
function streamOf(text) {
|
|
110
|
+
return new ReadableStream({
|
|
111
|
+
start(controller) {
|
|
112
|
+
controller.enqueue(new TextEncoder().encode(text));
|
|
113
|
+
controller.close();
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function entry(text, extra = {}) {
|
|
118
|
+
return {
|
|
119
|
+
value: streamOf(text),
|
|
120
|
+
tags: ["posts"],
|
|
121
|
+
stale: 300,
|
|
122
|
+
timestamp: performance.timeOrigin + performance.now(),
|
|
123
|
+
expire: 3600,
|
|
124
|
+
revalidate: 900,
|
|
125
|
+
...extra,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
async function textOf(result) {
|
|
129
|
+
return result
|
|
130
|
+
? new TextDecoder().decode(await (0, use_cache_common_1.readStream)(result.value))
|
|
131
|
+
: undefined;
|
|
132
|
+
}
|
|
133
|
+
/** A request's worth of what Next.js does before reading an entry. */
|
|
134
|
+
async function read(handler, key) {
|
|
135
|
+
await handler.refreshTags();
|
|
136
|
+
return textOf(await handler.get(key, []));
|
|
137
|
+
}
|
|
138
|
+
beforeEach(() => {
|
|
139
|
+
objects.clear();
|
|
140
|
+
rows.clear();
|
|
141
|
+
logRows.clear();
|
|
142
|
+
});
|
|
143
|
+
describe("cacheHandlers.remote", () => {
|
|
144
|
+
it("answers every instance from the entry any one of them stored", async () => {
|
|
145
|
+
const a = remoteInstance();
|
|
146
|
+
const b = remoteInstance();
|
|
147
|
+
await a.set("k", Promise.resolve(entry("from-a")));
|
|
148
|
+
expect(await read(b, "k")).toBe("from-a");
|
|
149
|
+
expect(Array.from(objects.keys())).toEqual([
|
|
150
|
+
expect.stringMatching(/^build\/_use-cache\/[0-9a-f]{64}\.entry$/),
|
|
151
|
+
]);
|
|
152
|
+
});
|
|
153
|
+
it("serves a repeat read from memory", async () => {
|
|
154
|
+
const b = remoteInstance();
|
|
155
|
+
await remoteInstance().set("k", Promise.resolve(entry("v")));
|
|
156
|
+
await read(b, "k");
|
|
157
|
+
s3Send.mockClear();
|
|
158
|
+
expect(await read(b, "k")).toBe("v");
|
|
159
|
+
expect(s3Calls(client_s3_1.GetObjectCommand)).toBe(0);
|
|
160
|
+
});
|
|
161
|
+
it("expires the entry on every instance when a tag is revalidated", async () => {
|
|
162
|
+
const a = remoteInstance();
|
|
163
|
+
const b = remoteInstance();
|
|
164
|
+
await a.set("k", Promise.resolve(entry("old", { timestamp: Date.now() - 1000 })));
|
|
165
|
+
expect(await read(a, "k")).toBe("old");
|
|
166
|
+
expect(await read(b, "k")).toBe("old");
|
|
167
|
+
await a.updateTags(["posts"]);
|
|
168
|
+
expect(await read(a, "k")).toBeUndefined();
|
|
169
|
+
expect(await read(b, "k")).toBeUndefined();
|
|
170
|
+
// A fresh instance reading the stale object from S3 misses too.
|
|
171
|
+
expect(await read(remoteInstance(), "k")).toBeUndefined();
|
|
172
|
+
});
|
|
173
|
+
it("serves a profile-revalidated entry stale, for Next.js to regenerate", async () => {
|
|
174
|
+
const a = remoteInstance();
|
|
175
|
+
await a.set("k", Promise.resolve(entry("old", { timestamp: Date.now() - 1000 })));
|
|
176
|
+
await a.updateTags(["posts"], { expire: 3600 });
|
|
177
|
+
const b = remoteInstance();
|
|
178
|
+
await b.refreshTags();
|
|
179
|
+
const result = await b.get("k", []);
|
|
180
|
+
expect(result?.revalidate).toBe(-1);
|
|
181
|
+
expect(await textOf(result)).toBe("old");
|
|
182
|
+
});
|
|
183
|
+
it("picks up another instance's regenerated entry once its own is stale", async () => {
|
|
184
|
+
const a = remoteInstance();
|
|
185
|
+
const b = remoteInstance();
|
|
186
|
+
const past = performance.timeOrigin + performance.now() - 10_000;
|
|
187
|
+
await a.set("k", Promise.resolve(entry("v1", { timestamp: past, revalidate: 1 })));
|
|
188
|
+
expect(await read(b, "k")).toBe("v1");
|
|
189
|
+
await a.set("k", Promise.resolve(entry("v2")));
|
|
190
|
+
// `b`'s memory copy is past `revalidate`, so S3 is asked for a newer one.
|
|
191
|
+
expect(await read(b, "k")).toBe("v2");
|
|
192
|
+
});
|
|
193
|
+
it("does not serve an entry past its expire", async () => {
|
|
194
|
+
const past = performance.timeOrigin + performance.now() - 10_000;
|
|
195
|
+
await remoteInstance().set("k", Promise.resolve(entry("v", { timestamp: past, revalidate: 1, expire: 2 })));
|
|
196
|
+
expect(await read(remoteInstance(), "k")).toBeUndefined();
|
|
197
|
+
});
|
|
198
|
+
it("makes a get wait for a pending set of the same key", async () => {
|
|
199
|
+
const a = remoteInstance();
|
|
200
|
+
let resolve = () => { };
|
|
201
|
+
const set = a.set("k", new Promise((r) => (resolve = r)));
|
|
202
|
+
const get = a.get("k", []);
|
|
203
|
+
resolve(entry("v"));
|
|
204
|
+
expect(await textOf(await get)).toBe("v");
|
|
205
|
+
await set;
|
|
206
|
+
});
|
|
207
|
+
it("stores nothing from a stream that errors", async () => {
|
|
208
|
+
const a = remoteInstance();
|
|
209
|
+
const failing = new ReadableStream({
|
|
210
|
+
start(controller) {
|
|
211
|
+
controller.enqueue(new Uint8Array([1]));
|
|
212
|
+
controller.error(new Error("render failed"));
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
await a.set("k", Promise.resolve({ ...entry(""), value: failing }));
|
|
216
|
+
expect(objects.size).toBe(0);
|
|
217
|
+
expect(await read(a, "k")).toBeUndefined();
|
|
218
|
+
});
|
|
219
|
+
it("does not store an entry Next.js regenerates on every read", async () => {
|
|
220
|
+
const a = remoteInstance();
|
|
221
|
+
await a.set("k", Promise.resolve(entry("v", { expire: 0 })));
|
|
222
|
+
expect(objects.size).toBe(0);
|
|
223
|
+
expect(await read(a, "k")).toBeUndefined();
|
|
224
|
+
});
|
|
225
|
+
it("never serves an object stored for another key", async () => {
|
|
226
|
+
const a = remoteInstance();
|
|
227
|
+
await a.set("k", Promise.resolve(entry("v")));
|
|
228
|
+
const [key] = Array.from(objects.keys());
|
|
229
|
+
objects.set(key, objects.get(key).replace('"key":"k"', '"key":"other"'));
|
|
230
|
+
const warn = jest.spyOn(console, "warn").mockImplementation(() => { });
|
|
231
|
+
expect(await read(remoteInstance(), "k")).toBeUndefined();
|
|
232
|
+
warn.mockRestore();
|
|
233
|
+
});
|
|
234
|
+
it("keeps working from memory when S3 fails", async () => {
|
|
235
|
+
const error = jest.spyOn(console, "error").mockImplementation(() => { });
|
|
236
|
+
s3Send.mockRejectedValueOnce(new Error("SlowDown"));
|
|
237
|
+
const a = remoteInstance();
|
|
238
|
+
await a.set("k", Promise.resolve(entry("v")));
|
|
239
|
+
expect(await read(a, "k")).toBe("v");
|
|
240
|
+
s3Send.mockRejectedValueOnce(new Error("SlowDown"));
|
|
241
|
+
expect(await read(remoteInstance(), "k")).toBeUndefined();
|
|
242
|
+
error.mockRestore();
|
|
243
|
+
});
|
|
244
|
+
it("is memory-only without a bucket", async () => {
|
|
245
|
+
const a = (0, use_cache_remote_handler_1.createRemoteUseCacheHandler)({
|
|
246
|
+
bucket: null,
|
|
247
|
+
buildId: "build",
|
|
248
|
+
tags: tagManifest(),
|
|
249
|
+
});
|
|
250
|
+
await a.set("k", Promise.resolve(entry("v")));
|
|
251
|
+
expect(await read(a, "k")).toBe("v");
|
|
252
|
+
expect(s3Send).not.toHaveBeenCalled();
|
|
253
|
+
});
|
|
254
|
+
it("reads an S3 entry's tags before trusting it, once per instance", async () => {
|
|
255
|
+
await remoteInstance().set("k", Promise.resolve(entry("v")));
|
|
256
|
+
const b = remoteInstance(tagManifest(60_000));
|
|
257
|
+
dynamoSend.mockClear();
|
|
258
|
+
await read(b, "k");
|
|
259
|
+
await read(b, "k");
|
|
260
|
+
expect(dynamoCalls(client_dynamodb_1.BatchGetItemCommand)).toBe(1);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
describe("cacheHandlers.remote, across a revalidation before an instance started", () => {
|
|
264
|
+
afterEach(() => jest.restoreAllMocks());
|
|
265
|
+
// A stores K1; C revalidates its tag; B starts after C's log row is behind
|
|
266
|
+
// its cursor, stores K2 with the same tag, then reads K1 from S3.
|
|
267
|
+
it("does not serve an older S3 entry as fresh after storing a newer one with its tag", async () => {
|
|
268
|
+
const a = remoteInstance();
|
|
269
|
+
await a.set("k1", Promise.resolve(entry("before", { timestamp: Date.now() - 1000 })));
|
|
270
|
+
await remoteInstance().updateTags(["posts"], { expire: 0 });
|
|
271
|
+
const later = Date.now() + 10_000;
|
|
272
|
+
jest.spyOn(Date, "now").mockReturnValue(later);
|
|
273
|
+
const b = remoteInstance();
|
|
274
|
+
await b.set("k2", Promise.resolve(entry("after", { timestamp: later })));
|
|
275
|
+
expect(await read(b, "k1")).toBeUndefined();
|
|
276
|
+
expect(await read(b, "k2")).toBe("after");
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
describe("cacheHandlers.default", () => {
|
|
280
|
+
it("keeps entries in each instance's memory", async () => {
|
|
281
|
+
const a = defaultInstance();
|
|
282
|
+
const b = defaultInstance();
|
|
283
|
+
await a.set("k", Promise.resolve(entry("v")));
|
|
284
|
+
expect(await read(a, "k")).toBe("v");
|
|
285
|
+
expect(await read(b, "k")).toBeUndefined();
|
|
286
|
+
expect(s3Send).not.toHaveBeenCalled();
|
|
287
|
+
});
|
|
288
|
+
it("expires an entry on an instance that did not run revalidateTag", async () => {
|
|
289
|
+
const a = defaultInstance();
|
|
290
|
+
const b = defaultInstance();
|
|
291
|
+
const created = { timestamp: Date.now() - 1000 };
|
|
292
|
+
await a.set("k", Promise.resolve(entry("a", created)));
|
|
293
|
+
await b.set("k", Promise.resolve(entry("b", created)));
|
|
294
|
+
// Its first read of its own entry reads the tag's marker, once.
|
|
295
|
+
expect(await read(b, "k")).toBe("b");
|
|
296
|
+
// What Next.js does for `revalidateTag`: `updateTags` on every handler of
|
|
297
|
+
// the instance that ran it - here, `a`.
|
|
298
|
+
await a.updateTags(["posts"], { expire: 0 });
|
|
299
|
+
dynamoSend.mockClear();
|
|
300
|
+
expect(await read(a, "k")).toBeUndefined();
|
|
301
|
+
expect(await read(b, "k")).toBeUndefined();
|
|
302
|
+
// `b` learned of it from the log, not by re-reading its tags' markers.
|
|
303
|
+
expect(dynamoCalls(client_dynamodb_1.QueryCommand)).toBeGreaterThan(0);
|
|
304
|
+
expect(dynamoCalls(client_dynamodb_1.BatchGetItemCommand)).toBe(0);
|
|
305
|
+
});
|
|
306
|
+
it("waits for the refresh interval before re-reading tags", async () => {
|
|
307
|
+
const b = defaultInstance(tagManifest(60_000));
|
|
308
|
+
await b.set("k", Promise.resolve(entry("b", { timestamp: Date.now() - 1000 })));
|
|
309
|
+
await read(b, "k");
|
|
310
|
+
await defaultInstance().updateTags(["posts"]);
|
|
311
|
+
dynamoSend.mockClear();
|
|
312
|
+
// Inside the window: still served, and no read spent on it.
|
|
313
|
+
expect(await read(b, "k")).toBe("b");
|
|
314
|
+
expect(dynamoCalls(client_dynamodb_1.BatchGetItemCommand)).toBe(0);
|
|
315
|
+
expect(dynamoCalls(client_dynamodb_1.QueryCommand)).toBe(0);
|
|
316
|
+
});
|
|
317
|
+
it("drops an entry past revalidate, as Next.js's in-memory handler does", async () => {
|
|
318
|
+
const a = defaultInstance();
|
|
319
|
+
const past = performance.timeOrigin + performance.now() - 10_000;
|
|
320
|
+
await a.set("k", Promise.resolve(entry("v", { timestamp: past, revalidate: 1 })));
|
|
321
|
+
expect(await read(a, "k")).toBeUndefined();
|
|
322
|
+
});
|
|
323
|
+
it("reports stale tags as revalidate -1", async () => {
|
|
324
|
+
const a = defaultInstance();
|
|
325
|
+
await a.set("k", Promise.resolve(entry("v", { timestamp: Date.now() - 1000 })));
|
|
326
|
+
await a.updateTags(["posts"], { expire: 3600 });
|
|
327
|
+
const result = await a.get("k", []);
|
|
328
|
+
expect(result?.revalidate).toBe(-1);
|
|
329
|
+
});
|
|
330
|
+
it("answers getExpiration from another instance's revalidatePath", async () => {
|
|
331
|
+
const a = defaultInstance();
|
|
332
|
+
const b = defaultInstance();
|
|
333
|
+
await a.updateTags(["_N_T_/blog/layout"]);
|
|
334
|
+
const expiration = await b.getExpiration(["_N_T_/", "_N_T_/blog/layout"]);
|
|
335
|
+
expect(expiration).toBeGreaterThan(0);
|
|
336
|
+
expect(await b.getExpiration(["_N_T_/other"])).toBe(0);
|
|
337
|
+
});
|
|
338
|
+
it("stores nothing from a stream that errors, and releases the pending get", async () => {
|
|
339
|
+
const a = defaultInstance();
|
|
340
|
+
const failing = new ReadableStream({
|
|
341
|
+
start(controller) {
|
|
342
|
+
controller.error(new Error("render failed"));
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
await a.set("k", Promise.resolve({ ...entry(""), value: failing }));
|
|
346
|
+
expect(await read(a, "k")).toBeUndefined();
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLWhhbmRsZXJzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci91c2UtY2FjaGUtaGFuZGxlcnMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNEQUFzRDtBQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBRXRDLDhEQU9rQztBQUNsQyxrREFLNEI7QUFLNUIsdURBSzJCO0FBQzNCLHlEQUFnRDtBQUNoRCwyRUFBMkU7QUFDM0UseUVBQXlFO0FBRXpFLGdFQUFnRTtBQUNoRSxNQUFNLFlBQVksR0FBRyxDQUFDLE9BQWdCLEVBQUUsSUFBYSxFQUFFLEVBQUU7SUFDdkQsTUFBTSxJQUFJLEdBQUcsSUFBaUIsQ0FBQztJQUMvQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0FBQzFDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLE9BQWdCLEVBQUUsRUFBRTtJQUNoRCxJQUFJLE9BQU8sWUFBWSw0QkFBZ0IsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSw0QkFBZ0IsQ0FBQyxDQUFDO1FBQzlELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUNELElBQUksT0FBTyxZQUFZLDRCQUFnQixF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QzFDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7UUFDMUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6RCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx3RUFBd0UsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN0RixNQUFNLENBQUMsR0FBRyxlQUFlLEVBQUUsQ0FBQztRQUM1QixNQUFNLE9BQU8sR0FBRyxJQUFJLGNBQWMsQ0FBYTtZQUM3QyxLQUFLLENBQUMsVUFBVTtnQkFDZCxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDL0MsQ0FBQztTQUNGLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEUsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzdDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmplc3QubW9jayhcIkBhd3Mtc2RrL2NsaWVudC1zM1wiKTtcbmplc3QubW9jayhcIkBhd3Mtc2RrL2NsaWVudC1keW5hbW9kYlwiKTtcblxuaW1wb3J0IHtcbiAgQXR0cmlidXRlVmFsdWUsXG4gIEJhdGNoR2V0SXRlbUNvbW1hbmQsXG4gIER5bmFtb0RCQ2xpZW50LFxuICBQdXRJdGVtQ29tbWFuZCxcbiAgUXVlcnlDb21tYW5kLFxuICBVcGRhdGVJdGVtQ29tbWFuZCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1keW5hbW9kYlwiO1xuaW1wb3J0IHtcbiAgR2V0T2JqZWN0Q29tbWFuZCxcbiAgTm9TdWNoS2V5LFxuICBQdXRPYmplY3RDb21tYW5kLFxuICBTM0NsaWVudCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuaW1wb3J0IHR5cGUge1xuICBDYWNoZUVudHJ5LFxuICBDYWNoZUhhbmRsZXIsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2xpYi9jYWNoZS1oYW5kbGVycy90eXBlc1wiO1xuaW1wb3J0IHtcbiAgQ2FjaGVCdWNrZXQsXG4gIFJldmFsaWRhdGlvbkxvZyxcbiAgVGFnTWFya2VyVGFibGUsXG4gIFRyYWNrZWRUYWdNYXJrZXJzLFxufSBmcm9tIFwiLi9hd3MtY2FjaGUtc3RvcmVcIjtcbmltcG9ydCB7IHJlYWRTdHJlYW0gfSBmcm9tIFwiLi91c2UtY2FjaGUtY29tbW9uXCI7XG5pbXBvcnQgeyBjcmVhdGVEZWZhdWx0VXNlQ2FjaGVIYW5kbGVyIH0gZnJvbSBcIi4vdXNlLWNhY2hlLWRlZmF1bHQtaGFuZGxlclwiO1xuaW1wb3J0IHsgY3JlYXRlUmVtb3RlVXNlQ2FjaGVIYW5kbGVyIH0gZnJvbSBcIi4vdXNlLWNhY2hlLXJlbW90ZS1oYW5kbGVyXCI7XG5cbi8qKiBUaGUgaW5wdXQgYW4gYXV0b21vY2tlZCBTREsgY29tbWFuZCB3YXMgY29uc3RydWN0ZWQgd2l0aC4gKi9cbmNvbnN0IGNvbW1hbmRJbnB1dCA9IChjb21tYW5kOiB1bmtub3duLCB0eXBlOiB1bmtub3duKSA9PiB7XG4gIGNvbnN0IG1vY2sgPSB0eXBlIGFzIGplc3QuTW9jaztcbiAgcmV0dXJuIG1vY2subW9jay5jYWxsc1ttb2NrLm1vY2suaW5zdGFuY2VzLmluZGV4T2YoY29tbWFuZCldWzBdO1xufTtcblxuLyoqXG4gKiBTMyBhcyBhIG1hcC4gRXZlcnkgXCJpbnN0YW5jZVwiIGluIHRoZXNlIHRlc3RzIGlzIGEgc2VwYXJhdGUgaGFuZGxlciBvdmVyIHRoZVxuICogc2FtZSBtYXAsIHdoaWNoIGlzIHdoYXQgdGhlIGNhY2hlIGJ1Y2tldCBpcyB0byBzZXBhcmF0ZSBMYW1iZGEgaW5zdGFuY2VzLlxuICovXG5jb25zdCBvYmplY3RzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbmNvbnN0IHMzU2VuZCA9IGplc3QuZm4oYXN5bmMgKGNvbW1hbmQ6IHVua25vd24pID0+IHtcbiAgaWYgKGNvbW1hbmQgaW5zdGFuY2VvZiBQdXRPYmplY3RDb21tYW5kKSB7XG4gICAgY29uc3QgeyBLZXksIEJvZHkgfSA9IGNvbW1hbmRJbnB1dChjb21tYW5kLCBQdXRPYmplY3RDb21tYW5kKTtcbiAgICBvYmplY3RzLnNldChLZXksIEJvZHkpO1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBpZiAoY29tbWFuZCBpbnN0YW5jZW9mIEdldE9iamVjdENvbW1hbmQpIHtcbiAgICBjb25zdCB7IEtleSB9ID0gY29tbWFuZElucHV0KGNvbW1hbmQsIEdldE9iamVjdENvbW1hbmQpO1xuICAgIGNvbnN0IGJvZHkgPSBvYmplY3RzLmdldChLZXkpO1xuICAgIGlmIChib2R5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hLZXkoeyBtZXNzYWdlOiBcIk5vU3VjaEtleVwiLCAkbWV0YWRhdGE6IHt9IH0pO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgQm9keTogeyB0cmFuc2Zvcm1Ub1N0cmluZzogYXN5bmMgKCkgPT4gYm9keSB9LFxuICAgICAgQ29udGVudFR5cGU6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiLFxuICAgIH07XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFwidW5leHBlY3RlZCBTMyBjb21tYW5kXCIpO1xufSk7XG5cbi8qKiBUaGUgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MsIGFzIGEgbWFwLiAqL1xuY29uc3Qgcm93cyA9IG5ldyBNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4+KCk7XG4vKiogSXRzIHJldmFsaWRhdGlvbiBsb2cgcm93cywgYnkgc29ydCBrZXkuICovXG5jb25zdCBsb2dSb3dzID0gbmV3IE1hcDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPj4oKTtcbmNvbnN0IGR5bmFtb1NlbmQgPSBqZXN0LmZuKGFzeW5jIChjb21tYW5kOiB1bmtub3duKSA9PiB7XG4gIGlmIChjb21tYW5kIGluc3RhbmNlb2YgVXBkYXRlSXRlbUNvbW1hbmQpIHtcbiAgICBjb25zdCB7IEtleSwgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyB9ID0gY29tbWFuZElucHV0KFxuICAgICAgY29tbWFuZCxcbiAgICAgIFVwZGF0ZUl0ZW1Db21tYW5kLFxuICAgICk7XG4gICAgY29uc3Qgcm93OiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gPSByb3dzLmdldChLZXkuc2suUykgPz8ge1xuICAgICAgc2s6IEtleS5zayxcbiAgICB9O1xuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzKSkge1xuICAgICAgcm93W25hbWUuc2xpY2UoMSldID0gdmFsdWUgYXMgQXR0cmlidXRlVmFsdWU7XG4gICAgfVxuICAgIHJvd3Muc2V0KEtleS5zay5TLCByb3cpO1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBpZiAoY29tbWFuZCBpbnN0YW5jZW9mIEJhdGNoR2V0SXRlbUNvbW1hbmQpIHtcbiAgICBjb25zdCB7IFJlcXVlc3RJdGVtcyB9ID0gY29tbWFuZElucHV0KGNvbW1hbmQsIEJhdGNoR2V0SXRlbUNvbW1hbmQpO1xuICAgIGNvbnN0IFtbdGFibGUsIHsgS2V5cyB9XV0gPSBPYmplY3QuZW50cmllcyhSZXF1ZXN0SXRlbXMpIGFzIFtcbiAgICAgIHN0cmluZyxcbiAgICAgIHsgS2V5czogeyBzazogeyBTOiBzdHJpbmcgfSB9W10gfSxcbiAgICBdW107XG4gICAgcmV0dXJuIHtcbiAgICAgIFJlc3BvbnNlczoge1xuICAgICAgICBbdGFibGVdOiBLZXlzLm1hcCgoeyBzayB9KSA9PiByb3dzLmdldChzay5TKSkuZmlsdGVyKEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIGlmIChjb21tYW5kIGluc3RhbmNlb2YgUHV0SXRlbUNvbW1hbmQpIHtcbiAgICBjb25zdCB7IEl0ZW0gfSA9IGNvbW1hbmRJbnB1dChjb21tYW5kLCBQdXRJdGVtQ29tbWFuZCk7XG4gICAgbG9nUm93cy5zZXQoSXRlbS5zay5TLCBJdGVtKTtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgaWYgKGNvbW1hbmQgaW5zdGFuY2VvZiBRdWVyeUNvbW1hbmQpIHtcbiAgICBjb25zdCB7IEV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMgfSA9IGNvbW1hbmRJbnB1dChjb21tYW5kLCBRdWVyeUNvbW1hbmQpO1xuICAgIGNvbnN0IHNpbmNlID0gRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlc1tcIjpzaW5jZVwiXS5TIGFzIHN0cmluZztcbiAgICByZXR1cm4ge1xuICAgICAgSXRlbXM6IEFycmF5LmZyb20obG9nUm93cy5rZXlzKCkpXG4gICAgICAgIC5maWx0ZXIoKHNrKSA9PiBzayA+PSBzaW5jZSlcbiAgICAgICAgLnNvcnQoKVxuICAgICAgICAubWFwKChzaykgPT4gbG9nUm93cy5nZXQoc2spKSxcbiAgICB9O1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcInVuZXhwZWN0ZWQgRHluYW1vREIgY29tbWFuZFwiKTtcbn0pO1xuXG4oUzNDbGllbnQgYXMgamVzdC5Nb2NrKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gKHsgc2VuZDogczNTZW5kIH0pKTtcbihEeW5hbW9EQkNsaWVudCBhcyBqZXN0Lk1vY2spLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiAoeyBzZW5kOiBkeW5hbW9TZW5kIH0pKTtcblxuY29uc3QgczNDYWxscyA9ICh0eXBlOiB1bmtub3duKSA9PlxuICBzM1NlbmQubW9jay5jYWxscy5maWx0ZXIoKFtjb21tYW5kXSkgPT4gY29tbWFuZCBpbnN0YW5jZW9mICh0eXBlIGFzIG5ldmVyKSlcbiAgICAubGVuZ3RoO1xuY29uc3QgZHluYW1vQ2FsbHMgPSAodHlwZTogdW5rbm93bikgPT5cbiAgZHluYW1vU2VuZC5tb2NrLmNhbGxzLmZpbHRlcihcbiAgICAoW2NvbW1hbmRdKSA9PiBjb21tYW5kIGluc3RhbmNlb2YgKHR5cGUgYXMgbmV2ZXIpLFxuICApLmxlbmd0aDtcblxuLyoqIE9uZSBjb21wdXRlIGluc3RhbmNlJ3MgdmlldyBvZiB0aGUgc2hhcmVkIHRhYmxlLiAqL1xuZnVuY3Rpb24gdGFnTWFuaWZlc3QocmVmcmVzaEludGVydmFsTXMgPSAwKSB7XG4gIHJldHVybiBuZXcgVHJhY2tlZFRhZ01hcmtlcnMoe1xuICAgIG1hcmtlcnM6IG5ldyBUYWdNYXJrZXJUYWJsZShuZXcgRHluYW1vREJDbGllbnQoe30pLCBcInRhYmxlXCIsIFwiYnVpbGRcIiksXG4gICAgbG9nOiBuZXcgUmV2YWxpZGF0aW9uTG9nKG5ldyBEeW5hbW9EQkNsaWVudCh7fSksIFwidGFibGVcIiwgXCJidWlsZFwiKSxcbiAgICByZWZyZXNoSW50ZXJ2YWxNcyxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGJ1Y2tldCgpIHtcbiAgcmV0dXJuIG5ldyBDYWNoZUJ1Y2tldChuZXcgUzNDbGllbnQoe30pLCBcImJ1Y2tldFwiKTtcbn1cblxuZnVuY3Rpb24gcmVtb3RlSW5zdGFuY2UodGFncyA9IHRhZ01hbmlmZXN0KCkpIHtcbiAgcmV0dXJuIGNyZWF0ZVJlbW90ZVVzZUNhY2hlSGFuZGxlcih7XG4gICAgYnVja2V0OiBidWNrZXQoKSxcbiAgICBidWlsZElkOiBcImJ1aWxkXCIsXG4gICAgdGFncyxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRJbnN0YW5jZSh0YWdzID0gdGFnTWFuaWZlc3QoKSkge1xuICByZXR1cm4gY3JlYXRlRGVmYXVsdFVzZUNhY2hlSGFuZGxlcih7IHRhZ3MgfSk7XG59XG5cbmZ1bmN0aW9uIHN0cmVhbU9mKHRleHQ6IHN0cmluZyk6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+IHtcbiAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbSh7XG4gICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgY29udHJvbGxlci5lbnF1ZXVlKG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh0ZXh0KSk7XG4gICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgfSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGVudHJ5KHRleHQ6IHN0cmluZywgZXh0cmE6IFBhcnRpYWw8Q2FjaGVFbnRyeT4gPSB7fSk6IENhY2hlRW50cnkge1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiBzdHJlYW1PZih0ZXh0KSxcbiAgICB0YWdzOiBbXCJwb3N0c1wiXSxcbiAgICBzdGFsZTogMzAwLFxuICAgIHRpbWVzdGFtcDogcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpLFxuICAgIGV4cGlyZTogMzYwMCxcbiAgICByZXZhbGlkYXRlOiA5MDAsXG4gICAgLi4uZXh0cmEsXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRleHRPZihyZXN1bHQ6IENhY2hlRW50cnkgfCB1bmRlZmluZWQpIHtcbiAgcmV0dXJuIHJlc3VsdFxuICAgID8gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGF3YWl0IHJlYWRTdHJlYW0ocmVzdWx0LnZhbHVlKSlcbiAgICA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIEEgcmVxdWVzdCdzIHdvcnRoIG9mIHdoYXQgTmV4dC5qcyBkb2VzIGJlZm9yZSByZWFkaW5nIGFuIGVudHJ5LiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVhZChoYW5kbGVyOiBDYWNoZUhhbmRsZXIsIGtleTogc3RyaW5nKSB7XG4gIGF3YWl0IGhhbmRsZXIucmVmcmVzaFRhZ3MoKTtcbiAgcmV0dXJuIHRleHRPZihhd2FpdCBoYW5kbGVyLmdldChrZXksIFtdKSk7XG59XG5cbmJlZm9yZUVhY2goKCkgPT4ge1xuICBvYmplY3RzLmNsZWFyKCk7XG4gIHJvd3MuY2xlYXIoKTtcbiAgbG9nUm93cy5jbGVhcigpO1xufSk7XG5cbmRlc2NyaWJlKFwiY2FjaGVIYW5kbGVycy5yZW1vdGVcIiwgKCkgPT4ge1xuICBpdChcImFuc3dlcnMgZXZlcnkgaW5zdGFuY2UgZnJvbSB0aGUgZW50cnkgYW55IG9uZSBvZiB0aGVtIHN0b3JlZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHJlbW90ZUluc3RhbmNlKCk7XG4gICAgY29uc3QgYiA9IHJlbW90ZUluc3RhbmNlKCk7XG5cbiAgICBhd2FpdCBhLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwiZnJvbS1hXCIpKSk7XG5cbiAgICBleHBlY3QoYXdhaXQgcmVhZChiLCBcImtcIikpLnRvQmUoXCJmcm9tLWFcIik7XG4gICAgZXhwZWN0KEFycmF5LmZyb20ob2JqZWN0cy5rZXlzKCkpKS50b0VxdWFsKFtcbiAgICAgIGV4cGVjdC5zdHJpbmdNYXRjaGluZygvXmJ1aWxkXFwvX3VzZS1jYWNoZVxcL1swLTlhLWZdezY0fVxcLmVudHJ5JC8pLFxuICAgIF0pO1xuICB9KTtcblxuICBpdChcInNlcnZlcyBhIHJlcGVhdCByZWFkIGZyb20gbWVtb3J5XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBiID0gcmVtb3RlSW5zdGFuY2UoKTtcbiAgICBhd2FpdCByZW1vdGVJbnN0YW5jZSgpLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidlwiKSkpO1xuICAgIGF3YWl0IHJlYWQoYiwgXCJrXCIpO1xuICAgIHMzU2VuZC5tb2NrQ2xlYXIoKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChiLCBcImtcIikpLnRvQmUoXCJ2XCIpO1xuICAgIGV4cGVjdChzM0NhbGxzKEdldE9iamVjdENvbW1hbmQpKS50b0JlKDApO1xuICB9KTtcblxuICBpdChcImV4cGlyZXMgdGhlIGVudHJ5IG9uIGV2ZXJ5IGluc3RhbmNlIHdoZW4gYSB0YWcgaXMgcmV2YWxpZGF0ZWRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSByZW1vdGVJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGIgPSByZW1vdGVJbnN0YW5jZSgpO1xuICAgIGF3YWl0IGEuc2V0KFxuICAgICAgXCJrXCIsXG4gICAgICBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJvbGRcIiwgeyB0aW1lc3RhbXA6IERhdGUubm93KCkgLSAxMDAwIH0pKSxcbiAgICApO1xuICAgIGV4cGVjdChhd2FpdCByZWFkKGEsIFwia1wiKSkudG9CZShcIm9sZFwiKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChiLCBcImtcIikpLnRvQmUoXCJvbGRcIik7XG5cbiAgICBhd2FpdCBhLnVwZGF0ZVRhZ3MoW1wicG9zdHNcIl0pO1xuXG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYSwgXCJrXCIpKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYiwgXCJrXCIpKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgLy8gQSBmcmVzaCBpbnN0YW5jZSByZWFkaW5nIHRoZSBzdGFsZSBvYmplY3QgZnJvbSBTMyBtaXNzZXMgdG9vLlxuICAgIGV4cGVjdChhd2FpdCByZWFkKHJlbW90ZUluc3RhbmNlKCksIFwia1wiKSkudG9CZVVuZGVmaW5lZCgpO1xuICB9KTtcblxuICBpdChcInNlcnZlcyBhIHByb2ZpbGUtcmV2YWxpZGF0ZWQgZW50cnkgc3RhbGUsIGZvciBOZXh0LmpzIHRvIHJlZ2VuZXJhdGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSByZW1vdGVJbnN0YW5jZSgpO1xuICAgIGF3YWl0IGEuc2V0KFxuICAgICAgXCJrXCIsXG4gICAgICBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJvbGRcIiwgeyB0aW1lc3RhbXA6IERhdGUubm93KCkgLSAxMDAwIH0pKSxcbiAgICApO1xuICAgIGF3YWl0IGEudXBkYXRlVGFncyhbXCJwb3N0c1wiXSwgeyBleHBpcmU6IDM2MDAgfSk7XG5cbiAgICBjb25zdCBiID0gcmVtb3RlSW5zdGFuY2UoKTtcbiAgICBhd2FpdCBiLnJlZnJlc2hUYWdzKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYi5nZXQoXCJrXCIsIFtdKTtcbiAgICBleHBlY3QocmVzdWx0Py5yZXZhbGlkYXRlKS50b0JlKC0xKTtcbiAgICBleHBlY3QoYXdhaXQgdGV4dE9mKHJlc3VsdCkpLnRvQmUoXCJvbGRcIik7XG4gIH0pO1xuXG4gIGl0KFwicGlja3MgdXAgYW5vdGhlciBpbnN0YW5jZSdzIHJlZ2VuZXJhdGVkIGVudHJ5IG9uY2UgaXRzIG93biBpcyBzdGFsZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHJlbW90ZUluc3RhbmNlKCk7XG4gICAgY29uc3QgYiA9IHJlbW90ZUluc3RhbmNlKCk7XG4gICAgY29uc3QgcGFzdCA9IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKSAtIDEwXzAwMDtcbiAgICBhd2FpdCBhLnNldChcbiAgICAgIFwia1wiLFxuICAgICAgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidjFcIiwgeyB0aW1lc3RhbXA6IHBhc3QsIHJldmFsaWRhdGU6IDEgfSkpLFxuICAgICk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYiwgXCJrXCIpKS50b0JlKFwidjFcIik7XG5cbiAgICBhd2FpdCBhLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidjJcIikpKTtcbiAgICAvLyBgYmAncyBtZW1vcnkgY29weSBpcyBwYXN0IGByZXZhbGlkYXRlYCwgc28gUzMgaXMgYXNrZWQgZm9yIGEgbmV3ZXIgb25lLlxuICAgIGV4cGVjdChhd2FpdCByZWFkKGIsIFwia1wiKSkudG9CZShcInYyXCIpO1xuICB9KTtcblxuICBpdChcImRvZXMgbm90IHNlcnZlIGFuIGVudHJ5IHBhc3QgaXRzIGV4cGlyZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGFzdCA9IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKSAtIDEwXzAwMDtcbiAgICBhd2FpdCByZW1vdGVJbnN0YW5jZSgpLnNldChcbiAgICAgIFwia1wiLFxuICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICBlbnRyeShcInZcIiwgeyB0aW1lc3RhbXA6IHBhc3QsIHJldmFsaWRhdGU6IDEsIGV4cGlyZTogMiB9KSxcbiAgICAgICksXG4gICAgKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChyZW1vdGVJbnN0YW5jZSgpLCBcImtcIikpLnRvQmVVbmRlZmluZWQoKTtcbiAgfSk7XG5cbiAgaXQoXCJtYWtlcyBhIGdldCB3YWl0IGZvciBhIHBlbmRpbmcgc2V0IG9mIHRoZSBzYW1lIGtleVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHJlbW90ZUluc3RhbmNlKCk7XG4gICAgbGV0IHJlc29sdmU6ICh2YWx1ZTogQ2FjaGVFbnRyeSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICAgIGNvbnN0IHNldCA9IGEuc2V0KFwia1wiLCBuZXcgUHJvbWlzZSgocikgPT4gKHJlc29sdmUgPSByKSkpO1xuICAgIGNvbnN0IGdldCA9IGEuZ2V0KFwia1wiLCBbXSk7XG4gICAgcmVzb2x2ZShlbnRyeShcInZcIikpO1xuICAgIGV4cGVjdChhd2FpdCB0ZXh0T2YoYXdhaXQgZ2V0KSkudG9CZShcInZcIik7XG4gICAgYXdhaXQgc2V0O1xuICB9KTtcblxuICBpdChcInN0b3JlcyBub3RoaW5nIGZyb20gYSBzdHJlYW0gdGhhdCBlcnJvcnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSByZW1vdGVJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGZhaWxpbmcgPSBuZXcgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4oe1xuICAgICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUobmV3IFVpbnQ4QXJyYXkoWzFdKSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZXJyb3IobmV3IEVycm9yKFwicmVuZGVyIGZhaWxlZFwiKSk7XG4gICAgICB9LFxuICAgIH0pO1xuICAgIGF3YWl0IGEuc2V0KFwia1wiLCBQcm9taXNlLnJlc29sdmUoeyAuLi5lbnRyeShcIlwiKSwgdmFsdWU6IGZhaWxpbmcgfSkpO1xuICAgIGV4cGVjdChvYmplY3RzLnNpemUpLnRvQmUoMCk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYSwgXCJrXCIpKS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xuXG4gIGl0KFwiZG9lcyBub3Qgc3RvcmUgYW4gZW50cnkgTmV4dC5qcyByZWdlbmVyYXRlcyBvbiBldmVyeSByZWFkXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gcmVtb3RlSW5zdGFuY2UoKTtcbiAgICBhd2FpdCBhLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidlwiLCB7IGV4cGlyZTogMCB9KSkpO1xuICAgIGV4cGVjdChvYmplY3RzLnNpemUpLnRvQmUoMCk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYSwgXCJrXCIpKS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xuXG4gIGl0KFwibmV2ZXIgc2VydmVzIGFuIG9iamVjdCBzdG9yZWQgZm9yIGFub3RoZXIga2V5XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gcmVtb3RlSW5zdGFuY2UoKTtcbiAgICBhd2FpdCBhLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidlwiKSkpO1xuICAgIGNvbnN0IFtrZXldID0gQXJyYXkuZnJvbShvYmplY3RzLmtleXMoKSk7XG4gICAgb2JqZWN0cy5zZXQoa2V5LCBvYmplY3RzLmdldChrZXkpIS5yZXBsYWNlKCdcImtleVwiOlwia1wiJywgJ1wia2V5XCI6XCJvdGhlclwiJykpO1xuICAgIGNvbnN0IHdhcm4gPSBqZXN0LnNweU9uKGNvbnNvbGUsIFwid2FyblwiKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4ge30pO1xuICAgIGV4cGVjdChhd2FpdCByZWFkKHJlbW90ZUluc3RhbmNlKCksIFwia1wiKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIHdhcm4ubW9ja1Jlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoXCJrZWVwcyB3b3JraW5nIGZyb20gbWVtb3J5IHdoZW4gUzMgZmFpbHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVycm9yID0gamVzdC5zcHlPbihjb25zb2xlLCBcImVycm9yXCIpLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiB7fSk7XG4gICAgczNTZW5kLm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoXCJTbG93RG93blwiKSk7XG4gICAgY29uc3QgYSA9IHJlbW90ZUluc3RhbmNlKCk7XG4gICAgYXdhaXQgYS5zZXQoXCJrXCIsIFByb21pc2UucmVzb2x2ZShlbnRyeShcInZcIikpKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChhLCBcImtcIikpLnRvQmUoXCJ2XCIpO1xuICAgIHMzU2VuZC5tb2NrUmVqZWN0ZWRWYWx1ZU9uY2UobmV3IEVycm9yKFwiU2xvd0Rvd25cIikpO1xuICAgIGV4cGVjdChhd2FpdCByZWFkKHJlbW90ZUluc3RhbmNlKCksIFwia1wiKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIGVycm9yLm1vY2tSZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGl0KFwiaXMgbWVtb3J5LW9ubHkgd2l0aG91dCBhIGJ1Y2tldFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IGNyZWF0ZVJlbW90ZVVzZUNhY2hlSGFuZGxlcih7XG4gICAgICBidWNrZXQ6IG51bGwsXG4gICAgICBidWlsZElkOiBcImJ1aWxkXCIsXG4gICAgICB0YWdzOiB0YWdNYW5pZmVzdCgpLFxuICAgIH0pO1xuICAgIGF3YWl0IGEuc2V0KFwia1wiLCBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJ2XCIpKSk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYSwgXCJrXCIpKS50b0JlKFwidlwiKTtcbiAgICBleHBlY3QoczNTZW5kKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICB9KTtcblxuICBpdChcInJlYWRzIGFuIFMzIGVudHJ5J3MgdGFncyBiZWZvcmUgdHJ1c3RpbmcgaXQsIG9uY2UgcGVyIGluc3RhbmNlXCIsIGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCByZW1vdGVJbnN0YW5jZSgpLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidlwiKSkpO1xuICAgIGNvbnN0IGIgPSByZW1vdGVJbnN0YW5jZSh0YWdNYW5pZmVzdCg2MF8wMDApKTtcbiAgICBkeW5hbW9TZW5kLm1vY2tDbGVhcigpO1xuICAgIGF3YWl0IHJlYWQoYiwgXCJrXCIpO1xuICAgIGF3YWl0IHJlYWQoYiwgXCJrXCIpO1xuICAgIGV4cGVjdChkeW5hbW9DYWxscyhCYXRjaEdldEl0ZW1Db21tYW5kKSkudG9CZSgxKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJjYWNoZUhhbmRsZXJzLnJlbW90ZSwgYWNyb3NzIGEgcmV2YWxpZGF0aW9uIGJlZm9yZSBhbiBpbnN0YW5jZSBzdGFydGVkXCIsICgpID0+IHtcbiAgYWZ0ZXJFYWNoKCgpID0+IGplc3QucmVzdG9yZUFsbE1vY2tzKCkpO1xuXG4gIC8vIEEgc3RvcmVzIEsxOyBDIHJldmFsaWRhdGVzIGl0cyB0YWc7IEIgc3RhcnRzIGFmdGVyIEMncyBsb2cgcm93IGlzIGJlaGluZFxuICAvLyBpdHMgY3Vyc29yLCBzdG9yZXMgSzIgd2l0aCB0aGUgc2FtZSB0YWcsIHRoZW4gcmVhZHMgSzEgZnJvbSBTMy5cbiAgaXQoXCJkb2VzIG5vdCBzZXJ2ZSBhbiBvbGRlciBTMyBlbnRyeSBhcyBmcmVzaCBhZnRlciBzdG9yaW5nIGEgbmV3ZXIgb25lIHdpdGggaXRzIHRhZ1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHJlbW90ZUluc3RhbmNlKCk7XG4gICAgYXdhaXQgYS5zZXQoXG4gICAgICBcImsxXCIsXG4gICAgICBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJiZWZvcmVcIiwgeyB0aW1lc3RhbXA6IERhdGUubm93KCkgLSAxMDAwIH0pKSxcbiAgICApO1xuICAgIGF3YWl0IHJlbW90ZUluc3RhbmNlKCkudXBkYXRlVGFncyhbXCJwb3N0c1wiXSwgeyBleHBpcmU6IDAgfSk7XG5cbiAgICBjb25zdCBsYXRlciA9IERhdGUubm93KCkgKyAxMF8wMDA7XG4gICAgamVzdC5zcHlPbihEYXRlLCBcIm5vd1wiKS5tb2NrUmV0dXJuVmFsdWUobGF0ZXIpO1xuICAgIGNvbnN0IGIgPSByZW1vdGVJbnN0YW5jZSgpO1xuICAgIGF3YWl0IGIuc2V0KFwiazJcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwiYWZ0ZXJcIiwgeyB0aW1lc3RhbXA6IGxhdGVyIH0pKSk7XG5cbiAgICBleHBlY3QoYXdhaXQgcmVhZChiLCBcImsxXCIpKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYiwgXCJrMlwiKSkudG9CZShcImFmdGVyXCIpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcImNhY2hlSGFuZGxlcnMuZGVmYXVsdFwiLCAoKSA9PiB7XG4gIGl0KFwia2VlcHMgZW50cmllcyBpbiBlYWNoIGluc3RhbmNlJ3MgbWVtb3J5XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gZGVmYXVsdEluc3RhbmNlKCk7XG4gICAgY29uc3QgYiA9IGRlZmF1bHRJbnN0YW5jZSgpO1xuICAgIGF3YWl0IGEuc2V0KFwia1wiLCBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJ2XCIpKSk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYSwgXCJrXCIpKS50b0JlKFwidlwiKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChiLCBcImtcIikpLnRvQmVVbmRlZmluZWQoKTtcbiAgICBleHBlY3QoczNTZW5kKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuICB9KTtcblxuICBpdChcImV4cGlyZXMgYW4gZW50cnkgb24gYW4gaW5zdGFuY2UgdGhhdCBkaWQgbm90IHJ1biByZXZhbGlkYXRlVGFnXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gZGVmYXVsdEluc3RhbmNlKCk7XG4gICAgY29uc3QgYiA9IGRlZmF1bHRJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGNyZWF0ZWQgPSB7IHRpbWVzdGFtcDogRGF0ZS5ub3coKSAtIDEwMDAgfTtcbiAgICBhd2FpdCBhLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwiYVwiLCBjcmVhdGVkKSkpO1xuICAgIGF3YWl0IGIuc2V0KFwia1wiLCBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJiXCIsIGNyZWF0ZWQpKSk7XG4gICAgLy8gSXRzIGZpcnN0IHJlYWQgb2YgaXRzIG93biBlbnRyeSByZWFkcyB0aGUgdGFnJ3MgbWFya2VyLCBvbmNlLlxuICAgIGV4cGVjdChhd2FpdCByZWFkKGIsIFwia1wiKSkudG9CZShcImJcIik7XG5cbiAgICAvLyBXaGF0IE5leHQuanMgZG9lcyBmb3IgYHJldmFsaWRhdGVUYWdgOiBgdXBkYXRlVGFnc2Agb24gZXZlcnkgaGFuZGxlciBvZlxuICAgIC8vIHRoZSBpbnN0YW5jZSB0aGF0IHJhbiBpdCAtIGhlcmUsIGBhYC5cbiAgICBhd2FpdCBhLnVwZGF0ZVRhZ3MoW1wicG9zdHNcIl0sIHsgZXhwaXJlOiAwIH0pO1xuICAgIGR5bmFtb1NlbmQubW9ja0NsZWFyKCk7XG5cbiAgICBleHBlY3QoYXdhaXQgcmVhZChhLCBcImtcIikpLnRvQmVVbmRlZmluZWQoKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChiLCBcImtcIikpLnRvQmVVbmRlZmluZWQoKTtcbiAgICAvLyBgYmAgbGVhcm5lZCBvZiBpdCBmcm9tIHRoZSBsb2csIG5vdCBieSByZS1yZWFkaW5nIGl0cyB0YWdzJyBtYXJrZXJzLlxuICAgIGV4cGVjdChkeW5hbW9DYWxscyhRdWVyeUNvbW1hbmQpKS50b0JlR3JlYXRlclRoYW4oMCk7XG4gICAgZXhwZWN0KGR5bmFtb0NhbGxzKEJhdGNoR2V0SXRlbUNvbW1hbmQpKS50b0JlKDApO1xuICB9KTtcblxuICBpdChcIndhaXRzIGZvciB0aGUgcmVmcmVzaCBpbnRlcnZhbCBiZWZvcmUgcmUtcmVhZGluZyB0YWdzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBiID0gZGVmYXVsdEluc3RhbmNlKHRhZ01hbmlmZXN0KDYwXzAwMCkpO1xuICAgIGF3YWl0IGIuc2V0KFxuICAgICAgXCJrXCIsXG4gICAgICBQcm9taXNlLnJlc29sdmUoZW50cnkoXCJiXCIsIHsgdGltZXN0YW1wOiBEYXRlLm5vdygpIC0gMTAwMCB9KSksXG4gICAgKTtcbiAgICBhd2FpdCByZWFkKGIsIFwia1wiKTtcbiAgICBhd2FpdCBkZWZhdWx0SW5zdGFuY2UoKS51cGRhdGVUYWdzKFtcInBvc3RzXCJdKTtcbiAgICBkeW5hbW9TZW5kLm1vY2tDbGVhcigpO1xuXG4gICAgLy8gSW5zaWRlIHRoZSB3aW5kb3c6IHN0aWxsIHNlcnZlZCwgYW5kIG5vIHJlYWQgc3BlbnQgb24gaXQuXG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYiwgXCJrXCIpKS50b0JlKFwiYlwiKTtcbiAgICBleHBlY3QoZHluYW1vQ2FsbHMoQmF0Y2hHZXRJdGVtQ29tbWFuZCkpLnRvQmUoMCk7XG4gICAgZXhwZWN0KGR5bmFtb0NhbGxzKFF1ZXJ5Q29tbWFuZCkpLnRvQmUoMCk7XG4gIH0pO1xuXG4gIGl0KFwiZHJvcHMgYW4gZW50cnkgcGFzdCByZXZhbGlkYXRlLCBhcyBOZXh0LmpzJ3MgaW4tbWVtb3J5IGhhbmRsZXIgZG9lc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IGRlZmF1bHRJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHBhc3QgPSBwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgcGVyZm9ybWFuY2Uubm93KCkgLSAxMF8wMDA7XG4gICAgYXdhaXQgYS5zZXQoXG4gICAgICBcImtcIixcbiAgICAgIFByb21pc2UucmVzb2x2ZShlbnRyeShcInZcIiwgeyB0aW1lc3RhbXA6IHBhc3QsIHJldmFsaWRhdGU6IDEgfSkpLFxuICAgICk7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWQoYSwgXCJrXCIpKS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xuXG4gIGl0KFwicmVwb3J0cyBzdGFsZSB0YWdzIGFzIHJldmFsaWRhdGUgLTFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBkZWZhdWx0SW5zdGFuY2UoKTtcbiAgICBhd2FpdCBhLnNldChcbiAgICAgIFwia1wiLFxuICAgICAgUHJvbWlzZS5yZXNvbHZlKGVudHJ5KFwidlwiLCB7IHRpbWVzdGFtcDogRGF0ZS5ub3coKSAtIDEwMDAgfSkpLFxuICAgICk7XG4gICAgYXdhaXQgYS51cGRhdGVUYWdzKFtcInBvc3RzXCJdLCB7IGV4cGlyZTogMzYwMCB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhLmdldChcImtcIiwgW10pO1xuICAgIGV4cGVjdChyZXN1bHQ/LnJldmFsaWRhdGUpLnRvQmUoLTEpO1xuICB9KTtcblxuICBpdChcImFuc3dlcnMgZ2V0RXhwaXJhdGlvbiBmcm9tIGFub3RoZXIgaW5zdGFuY2UncyByZXZhbGlkYXRlUGF0aFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IGRlZmF1bHRJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGIgPSBkZWZhdWx0SW5zdGFuY2UoKTtcbiAgICBhd2FpdCBhLnVwZGF0ZVRhZ3MoW1wiX05fVF8vYmxvZy9sYXlvdXRcIl0pO1xuICAgIGNvbnN0IGV4cGlyYXRpb24gPSBhd2FpdCBiLmdldEV4cGlyYXRpb24oW1wiX05fVF8vXCIsIFwiX05fVF8vYmxvZy9sYXlvdXRcIl0pO1xuICAgIGV4cGVjdChleHBpcmF0aW9uKS50b0JlR3JlYXRlclRoYW4oMCk7XG4gICAgZXhwZWN0KGF3YWl0IGIuZ2V0RXhwaXJhdGlvbihbXCJfTl9UXy9vdGhlclwiXSkpLnRvQmUoMCk7XG4gIH0pO1xuXG4gIGl0KFwic3RvcmVzIG5vdGhpbmcgZnJvbSBhIHN0cmVhbSB0aGF0IGVycm9ycywgYW5kIHJlbGVhc2VzIHRoZSBwZW5kaW5nIGdldFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IGRlZmF1bHRJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGZhaWxpbmcgPSBuZXcgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4oe1xuICAgICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKG5ldyBFcnJvcihcInJlbmRlciBmYWlsZWRcIikpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgICBhd2FpdCBhLnNldChcImtcIiwgUHJvbWlzZS5yZXNvbHZlKHsgLi4uZW50cnkoXCJcIiksIHZhbHVlOiBmYWlsaW5nIH0pKTtcbiAgICBleHBlY3QoYXdhaXQgcmVhZChhLCBcImtcIikpLnRvQmVVbmRlZmluZWQoKTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CacheHandler } from "next/dist/server/lib/cache-handlers/types";
|
|
2
|
+
import { CacheBucket, TrackedTagMarkers } from "./aws-cache-store";
|
|
3
|
+
export interface RemoteUseCacheHandlerOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The bucket entries are stored in, or `null` for memory only. From
|
|
6
|
+
* `CDK_NEXTJS_CACHE_BUCKET_NAME` by default, and never at build time.
|
|
7
|
+
*/
|
|
8
|
+
bucket?: CacheBucket | null;
|
|
9
|
+
/** Prefixes every S3 key; `CDK_NEXTJS_BUILD_ID` by default. */
|
|
10
|
+
buildId?: string;
|
|
11
|
+
/** Tag state; the process-wide one from the environment by default. */
|
|
12
|
+
tags?: TrackedTagMarkers;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A `'use cache: remote'` handler: S3 for storage, memory in front, and the
|
|
16
|
+
* revalidation table for tags.
|
|
17
|
+
*
|
|
18
|
+
* Unlike the default handler an entry is served until `expire`, not dropped at
|
|
19
|
+
* `revalidate`: a remote read is worth serving stale while Next.js's wrapper
|
|
20
|
+
* regenerates it in the background, which is what `revalidate` is for. A memory
|
|
21
|
+
* copy past `revalidate` is checked against S3 first, since another instance may
|
|
22
|
+
* already have written the regenerated entry.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createRemoteUseCacheHandler(options?: RemoteUseCacheHandlerOptions): CacheHandler;
|
|
25
|
+
declare const _default: CacheHandler;
|
|
26
|
+
export default _default;
|