cdk-nextjs 0.6.2 → 0.7.1

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.
Files changed (263) hide show
  1. package/.jsii +2404 -2723
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1681 -1930
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
  7. package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
  8. package/docs/adapter-runtime.md +185 -0
  9. package/docs/breaking-changes.md +667 -4
  10. package/docs/caching-guide.md +156 -112
  11. package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
  12. package/docs/development-guide.md +1 -1
  13. package/docs/harness-coverage.md +598 -0
  14. package/docs/init-cache-deployment.md +32 -1
  15. package/docs/next-build-output-guide.md +30 -20
  16. package/examples/README.md +5 -1
  17. package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
  18. package/lib/adapter/__fixtures__/app-playground.json +4917 -0
  19. package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
  20. package/lib/adapter/adapter.mjs +1551 -185
  21. package/lib/adapter/adapter.test.js +106 -0
  22. package/lib/adapter/aws-cache-store.d.ts +489 -0
  23. package/lib/adapter/aws-cache-store.js +1004 -0
  24. package/lib/adapter/aws-cache-store.test.d.ts +1 -0
  25. package/lib/adapter/aws-cache-store.test.js +361 -0
  26. package/lib/adapter/build-outputs.d.ts +80 -0
  27. package/lib/adapter/build-outputs.js +857 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +863 -0
  30. package/lib/adapter/cache-handler.d.ts +9 -2
  31. package/lib/adapter/cache-handler.js +72 -96
  32. package/lib/adapter/cache-handler.mjs +18956 -17774
  33. package/lib/adapter/cache-handler.test.js +263 -31
  34. package/lib/adapter/cache-kinds.d.ts +32 -0
  35. package/lib/adapter/cache-kinds.js +35 -0
  36. package/lib/adapter/cache-kinds.test.d.ts +1 -0
  37. package/lib/adapter/cache-kinds.test.js +69 -0
  38. package/lib/adapter/cache-utils.d.ts +90 -0
  39. package/lib/adapter/cache-utils.js +199 -4
  40. package/lib/adapter/cache-utils.test.d.ts +1 -0
  41. package/lib/adapter/cache-utils.test.js +179 -0
  42. package/lib/adapter/function-groups.d.ts +215 -0
  43. package/lib/adapter/function-groups.js +1099 -0
  44. package/lib/adapter/function-groups.test.d.ts +1 -0
  45. package/lib/adapter/function-groups.test.js +743 -0
  46. package/lib/adapter/init-cache.d.ts +6 -0
  47. package/lib/adapter/init-cache.js +245 -0
  48. package/lib/adapter/init-cache.test.d.ts +1 -0
  49. package/lib/adapter/init-cache.test.js +137 -0
  50. package/lib/adapter/local-file-cache-handler.d.ts +23 -0
  51. package/lib/adapter/local-file-cache-handler.js +52 -1
  52. package/lib/adapter/memory-cache-handler.d.ts +26 -17
  53. package/lib/adapter/memory-cache-handler.js +32 -50
  54. package/lib/adapter/memory-cache-handler.test.js +105 -85
  55. package/lib/adapter/s3-cache-handler.d.ts +179 -40
  56. package/lib/adapter/s3-cache-handler.js +807 -277
  57. package/lib/adapter/s3-cache-handler.test.js +1186 -31
  58. package/lib/adapter/use-cache-common.d.ts +90 -0
  59. package/lib/adapter/use-cache-common.js +250 -0
  60. package/lib/adapter/use-cache-common.test.d.ts +1 -0
  61. package/lib/adapter/use-cache-common.test.js +646 -0
  62. package/lib/adapter/use-cache-default-handler.d.ts +24 -0
  63. package/lib/adapter/use-cache-default-handler.js +90 -0
  64. package/lib/adapter/use-cache-default-handler.mjs +38645 -0
  65. package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
  66. package/lib/adapter/use-cache-handlers.test.js +349 -0
  67. package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
  68. package/lib/adapter/use-cache-remote-handler.js +186 -0
  69. package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
  70. package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
  71. package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
  72. package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
  73. package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
  74. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
  75. package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
  76. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
  77. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  78. package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
  81. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
  82. package/lib/index.d.ts +6 -7
  83. package/lib/index.js +2 -4
  84. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  88. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  92. package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
  93. package/lib/lambdas/post-deploy/prune-s3.js +41 -12
  94. package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
  95. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  96. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  103. package/lib/nextjs-api.d.ts +102 -18
  104. package/lib/nextjs-api.js +338 -38
  105. package/lib/nextjs-api.test.js +537 -1
  106. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  107. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  108. package/lib/nextjs-build/nextjs-build.js +684 -327
  109. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  110. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  111. package/lib/nextjs-build/patch-fetch.js +1 -1
  112. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  113. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  114. package/lib/nextjs-cache.d.ts +82 -4
  115. package/lib/nextjs-cache.js +186 -10
  116. package/lib/nextjs-cache.test.js +176 -1
  117. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  118. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  120. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  121. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  122. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  123. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  124. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  125. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  126. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  127. package/lib/nextjs-distribution.d.ts +194 -23
  128. package/lib/nextjs-distribution.js +535 -62
  129. package/lib/nextjs-distribution.test.d.ts +1 -0
  130. package/lib/nextjs-distribution.test.js +697 -0
  131. package/lib/nextjs-post-deploy.d.ts +13 -5
  132. package/lib/nextjs-post-deploy.js +13 -10
  133. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  134. package/lib/nextjs-post-deploy.test.js +34 -0
  135. package/lib/nextjs-static-assets.d.ts +17 -4
  136. package/lib/nextjs-static-assets.js +22 -5
  137. package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
  138. package/lib/root-constructs/nextjs-base-construct.js +139 -47
  139. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  140. package/lib/root-constructs/nextjs-global-containers.js +20 -71
  141. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  142. package/lib/root-constructs/nextjs-global-functions.js +52 -70
  143. package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
  144. package/lib/root-constructs/nextjs-regional-containers.js +8 -15
  145. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  146. package/lib/root-constructs/nextjs-regional-functions.js +8 -26
  147. package/lib/runtime/api-gateway-path.d.ts +34 -0
  148. package/lib/runtime/api-gateway-path.js +71 -0
  149. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  150. package/lib/runtime/api-gateway-path.test.js +65 -0
  151. package/lib/runtime/case-redirect.d.ts +22 -0
  152. package/lib/runtime/case-redirect.js +63 -0
  153. package/lib/runtime/case-redirect.test.d.ts +1 -0
  154. package/lib/runtime/case-redirect.test.js +32 -0
  155. package/lib/runtime/core.d.ts +234 -0
  156. package/lib/runtime/core.js +1216 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1686 -0
  159. package/lib/runtime/deployment-root.d.ts +13 -0
  160. package/lib/runtime/deployment-root.js +29 -0
  161. package/lib/runtime/dispatch.d.ts +331 -0
  162. package/lib/runtime/dispatch.js +751 -0
  163. package/lib/runtime/dispatch.test.d.ts +1 -0
  164. package/lib/runtime/dispatch.test.js +853 -0
  165. package/lib/runtime/entrypoints.d.ts +57 -0
  166. package/lib/runtime/entrypoints.js +115 -0
  167. package/lib/runtime/http/abort-signal.d.ts +6 -0
  168. package/lib/runtime/http/abort-signal.js +19 -0
  169. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  170. package/lib/runtime/http/abort-signal.test.js +49 -0
  171. package/lib/runtime/http/node-server.d.ts +38 -0
  172. package/lib/runtime/http/node-server.js +99 -0
  173. package/lib/runtime/http/node-server.test.d.ts +1 -0
  174. package/lib/runtime/http/node-server.test.js +96 -0
  175. package/lib/runtime/http/node-sink.d.ts +16 -0
  176. package/lib/runtime/http/node-sink.js +48 -0
  177. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  178. package/lib/runtime/http/node-sink.test.js +66 -0
  179. package/lib/runtime/http/request.d.ts +62 -0
  180. package/lib/runtime/http/request.js +134 -0
  181. package/lib/runtime/http/request.test.d.ts +1 -0
  182. package/lib/runtime/http/request.test.js +103 -0
  183. package/lib/runtime/http/response.d.ts +77 -0
  184. package/lib/runtime/http/response.js +229 -0
  185. package/lib/runtime/http/response.test.d.ts +1 -0
  186. package/lib/runtime/http/response.test.js +178 -0
  187. package/lib/runtime/http/sink.d.ts +73 -0
  188. package/lib/runtime/http/sink.js +188 -0
  189. package/lib/runtime/http/sink.test.d.ts +1 -0
  190. package/lib/runtime/http/sink.test.js +257 -0
  191. package/lib/runtime/image-utils.d.ts +78 -0
  192. package/lib/runtime/image-utils.js +129 -0
  193. package/lib/runtime/image-utils.test.d.ts +1 -0
  194. package/lib/runtime/image-utils.test.js +237 -0
  195. package/lib/runtime/image.d.ts +76 -0
  196. package/lib/runtime/image.js +296 -0
  197. package/lib/runtime/image.test.d.ts +1 -0
  198. package/lib/runtime/image.test.js +405 -0
  199. package/lib/runtime/lambda-event.d.ts +4 -0
  200. package/lib/runtime/lambda-event.js +113 -0
  201. package/lib/runtime/lambda-event.test.d.ts +1 -0
  202. package/lib/runtime/lambda-event.test.js +119 -0
  203. package/lib/runtime/lambda.mjs +41600 -0
  204. package/lib/runtime/load-module.d.ts +8 -0
  205. package/lib/runtime/load-module.js +35 -0
  206. package/lib/runtime/manifest.d.ts +215 -0
  207. package/lib/runtime/manifest.js +118 -0
  208. package/lib/runtime/middleware.d.ts +43 -0
  209. package/lib/runtime/middleware.js +113 -0
  210. package/lib/runtime/middleware.test.d.ts +1 -0
  211. package/lib/runtime/middleware.test.js +259 -0
  212. package/lib/runtime/next-modules.d.ts +71 -0
  213. package/lib/runtime/next-modules.js +144 -0
  214. package/lib/runtime/next-modules.test.d.ts +1 -0
  215. package/lib/runtime/next-modules.test.js +34 -0
  216. package/lib/runtime/public-files.d.ts +32 -0
  217. package/lib/runtime/public-files.js +117 -0
  218. package/lib/runtime/public-files.test.d.ts +1 -0
  219. package/lib/runtime/public-files.test.js +97 -0
  220. package/lib/runtime/server.mjs +41593 -0
  221. package/lib/runtime/static-files.d.ts +50 -0
  222. package/lib/runtime/static-files.js +266 -0
  223. package/lib/runtime/static-files.test.d.ts +1 -0
  224. package/lib/runtime/static-files.test.js +118 -0
  225. package/lib/runtime/util.d.ts +28 -0
  226. package/lib/runtime/util.js +79 -0
  227. package/lib/utils/base-path.d.ts +106 -13
  228. package/lib/utils/base-path.js +254 -41
  229. package/lib/utils/base-path.test.js +219 -51
  230. package/lib/utils/get-architecture.d.ts +7 -8
  231. package/lib/utils/get-architecture.js +12 -13
  232. package/lib/utils/zip-directory.d.ts +14 -0
  233. package/lib/utils/zip-directory.js +121 -0
  234. package/lib/utils/zip-directory.test.d.ts +1 -0
  235. package/lib/utils/zip-directory.test.js +99 -0
  236. package/package.json +22 -3
  237. package/scripts/capture-adapter-fixture.mjs +325 -0
  238. package/scripts/e2e-deploy.sh +398 -0
  239. package/scripts/e2e-harness/README.md +707 -0
  240. package/scripts/e2e-harness/app.js +370 -0
  241. package/scripts/e2e-harness/common.sh +249 -0
  242. package/scripts/e2e-harness/screen.mjs +302 -0
  243. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  244. package/scripts/e2e-harness/type-filters.mjs +47 -0
  245. package/scripts/e2e-logs.sh +75 -0
  246. package/scripts/e2e-offline.sh +91 -0
  247. package/scripts/e2e-sweep.sh +370 -0
  248. package/scripts/e2e-warm.sh +114 -0
  249. package/scripts/zero-config-build.mjs +418 -0
  250. package/docs/1k-concurrent-users-executions.png +0 -0
  251. package/docs/plans/adapter-runtime-release.md +0 -362
  252. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  253. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  254. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  255. package/lib/image-optimization/handler-utils.d.ts +0 -34
  256. package/lib/image-optimization/handler-utils.js +0 -83
  257. package/lib/image-optimization/handler-utils.test.js +0 -178
  258. package/lib/nextjs-build/functions.Dockerfile +0 -31
  259. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  260. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  261. package/lib/utils/experimental-flags.d.ts +0 -24
  262. package/lib/utils/experimental-flags.js +0 -30
  263. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createRemoteUseCacheHandler = createRemoteUseCacheHandler;
7
+ /*
8
+ The `cacheHandlers.remote` handler, for `'use cache: remote'`.
9
+ See: https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheHandlers
10
+
11
+ Entries are stored in the cache bucket, so every instance reads what any
12
+ instance wrote, with a bounded in-memory tier in front. Tags go through the
13
+ revalidation table's marker rows, shared with plain `'use cache'` and with the
14
+ incremental cache. Without this, Next.js maps `remote` to its in-memory
15
+ default handler, and `'use cache: remote'` is no more shared than
16
+ `'use cache'`.
17
+ */
18
+ /* eslint-disable import/no-extraneous-dependencies */
19
+ const node_crypto_1 = require("node:crypto");
20
+ const client_s3_1 = require("@aws-sdk/client-s3");
21
+ const debug_1 = __importDefault(require("debug"));
22
+ const aws_cache_store_1 = require("./aws-cache-store");
23
+ const cache_utils_1 = require("./cache-utils");
24
+ const use_cache_common_1 = require("./use-cache-common");
25
+ function bucketFromEnv() {
26
+ if ((0, use_cache_common_1.isBuildPhase)()) {
27
+ // No credentials, and nothing a build-time entry could be read back by:
28
+ // prerenders keep what they need in their own resume data cache.
29
+ return null;
30
+ }
31
+ const { bucketName, region } = (0, aws_cache_store_1.resolveAwsCacheConfig)();
32
+ if (!bucketName) {
33
+ console.warn("CDK_NEXTJS_CACHE_BUCKET_NAME environment variable not set, 'use cache: remote' entries are local to each instance");
34
+ return null;
35
+ }
36
+ return new aws_cache_store_1.CacheBucket(new client_s3_1.S3Client({ region }), bucketName);
37
+ }
38
+ /** Whether `stored` is past `revalidate`, so a fresher copy may exist. */
39
+ function isPastRevalidate(stored, at) {
40
+ return at > stored.timestamp + stored.revalidate * 1000;
41
+ }
42
+ /** Whether `stored` is past `expire`, and may no longer be served at all. */
43
+ function isPastExpire(stored, at) {
44
+ return at > stored.timestamp + stored.expire * 1000;
45
+ }
46
+ /**
47
+ * A `'use cache: remote'` handler: S3 for storage, memory in front, and the
48
+ * revalidation table for tags.
49
+ *
50
+ * Unlike the default handler an entry is served until `expire`, not dropped at
51
+ * `revalidate`: a remote read is worth serving stale while Next.js's wrapper
52
+ * regenerates it in the background, which is what `revalidate` is for. A memory
53
+ * copy past `revalidate` is checked against S3 first, since another instance may
54
+ * already have written the regenerated entry.
55
+ */
56
+ function createRemoteUseCacheHandler(options = {}) {
57
+ const bucket = options.bucket === undefined ? bucketFromEnv() : options.bucket;
58
+ const buildId = options.buildId ?? (0, aws_cache_store_1.resolveAwsCacheConfig)().buildId;
59
+ const tags = options.tags ?? (0, use_cache_common_1.sharedTagManifest)();
60
+ const memory = new use_cache_common_1.EntryLru((0, use_cache_common_1.numberFromEnv)("CDK_NEXTJS_USE_CACHE_MEMORY_BYTES", use_cache_common_1.DEFAULT_MEMORY_BYTES));
61
+ const pending = new use_cache_common_1.PendingSets();
62
+ const debug = (0, debug_1.default)("cdk-nextjs:cache-handler:use-cache:remote");
63
+ const s3Key = (cacheKey) => (0, aws_cache_store_1.useCacheS3Key)(buildId, (0, node_crypto_1.createHash)("sha256").update(cacheKey).digest("hex"));
64
+ async function readFromS3(cacheKey) {
65
+ if (!bucket) {
66
+ return undefined;
67
+ }
68
+ const key = s3Key(cacheKey);
69
+ try {
70
+ const object = await bucket.get(key);
71
+ if (!object) {
72
+ debug(`S3 MISS ${cacheKey}`);
73
+ return undefined;
74
+ }
75
+ const parsed = (0, cache_utils_1.parseCacheValue)(object);
76
+ if (parsed.key !== cacheKey) {
77
+ // A hash collision, or an object that is not ours: never serve it.
78
+ console.warn(`'use cache: remote' entry ${key} is for another key`);
79
+ return undefined;
80
+ }
81
+ return {
82
+ tags: parsed.tags,
83
+ stale: parsed.stale,
84
+ timestamp: parsed.timestamp,
85
+ expire: parsed.expire,
86
+ revalidate: parsed.revalidate,
87
+ value: new Uint8Array(parsed.value),
88
+ };
89
+ }
90
+ catch (error) {
91
+ console.error(`Error reading 'use cache: remote' entry ${key} from S3:`, error);
92
+ return undefined;
93
+ }
94
+ }
95
+ async function writeToS3(cacheKey, stored) {
96
+ if (!bucket) {
97
+ return;
98
+ }
99
+ const key = s3Key(cacheKey);
100
+ const serialized = {
101
+ ...stored,
102
+ key: cacheKey,
103
+ value: Buffer.from(stored.value),
104
+ };
105
+ try {
106
+ await bucket.putJson(key, (0, cache_utils_1.serializeCacheValue)(serialized));
107
+ debug(`S3 SET ${cacheKey} (${key})`);
108
+ }
109
+ catch (error) {
110
+ // The entry is still in memory here; other instances just miss.
111
+ console.error(`Error writing 'use cache: remote' entry ${key} to S3:`, error);
112
+ }
113
+ }
114
+ return {
115
+ async get(cacheKey) {
116
+ await pending.wait(cacheKey);
117
+ const at = (0, use_cache_common_1.now)();
118
+ let stored = memory.get(cacheKey);
119
+ if (stored) {
120
+ await tags.ensure(stored.tags);
121
+ }
122
+ // Past `revalidate`, or stale or expired by tag: another instance may
123
+ // already have written the regenerated entry, and serving that beats
124
+ // regenerating it here too. An expired entry S3 has nothing newer for is
125
+ // dropped below.
126
+ if (!stored ||
127
+ isPastRevalidate(stored, at) ||
128
+ tags.state(stored.tags, stored.timestamp) !== "fresh") {
129
+ const fromS3 = await readFromS3(cacheKey);
130
+ if (fromS3 && (!stored || fromS3.timestamp > stored.timestamp)) {
131
+ stored = fromS3;
132
+ // An entry written by another instance: its tags may have been
133
+ // revalidated at any time since, so they are read before judging it.
134
+ await tags.ensure(stored.tags);
135
+ memory.set(cacheKey, stored);
136
+ }
137
+ }
138
+ if (!stored) {
139
+ debug(`MISS ${cacheKey}`);
140
+ return undefined;
141
+ }
142
+ if (isPastExpire(stored, at)) {
143
+ debug(`EXPIRED ${cacheKey}`);
144
+ memory.delete(cacheKey);
145
+ return undefined;
146
+ }
147
+ const state = tags.state(stored.tags, stored.timestamp);
148
+ if (state === "expired") {
149
+ debug(`EXPIRED BY TAG ${cacheKey}`);
150
+ memory.delete(cacheKey);
151
+ return undefined;
152
+ }
153
+ debug(`HIT ${cacheKey}${state === "stale" ? " (stale tag)" : ""}`);
154
+ // `revalidate: -1` makes the wrapper serve the entry and regenerate it in
155
+ // the background, the built-in handler's answer to a stale tag.
156
+ return (0, use_cache_common_1.cacheEntryOf)(stored, state === "stale" ? -1 : stored.revalidate);
157
+ },
158
+ async set(cacheKey, pendingEntry) {
159
+ const done = pending.begin(cacheKey);
160
+ let stored;
161
+ try {
162
+ stored = await (0, use_cache_common_1.storedEntryOf)(pendingEntry);
163
+ }
164
+ catch (error) {
165
+ // The stream errored: store nothing rather than a partial entry.
166
+ debug(`SET FAILED ${cacheKey}`, error);
167
+ done();
168
+ return;
169
+ }
170
+ if ((0, use_cache_common_1.isDynamicEntry)(stored)) {
171
+ debug(`SKIP dynamic entry ${cacheKey}`);
172
+ done();
173
+ return;
174
+ }
175
+ memory.set(cacheKey, stored);
176
+ tags.track(stored.tags);
177
+ // A `get` waiting on this `set` can be answered from memory now; only
178
+ // other instances need the S3 copy.
179
+ done();
180
+ await writeToS3(cacheKey, stored);
181
+ },
182
+ ...(0, use_cache_common_1.tagMethods)(tags),
183
+ };
184
+ }
185
+ exports.default = (0, use_cache_common_1.lazyHandler)(() => createRemoteUseCacheHandler());
186
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLXJlbW90ZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvdXNlLWNhY2hlLXJlbW90ZS1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBaUdBLGtFQXlKQztBQTFQRDs7Ozs7Ozs7OztFQVVFO0FBQ0Ysc0RBQXNEO0FBQ3RELDZDQUF5QztBQUN6QyxrREFBOEM7QUFDOUMsa0RBQTZCO0FBSzdCLHVEQUsyQjtBQUMzQiwrQ0FBcUU7QUFDckUseURBYzRCO0FBcUI1QixTQUFTLGFBQWE7SUFDcEIsSUFBSSxJQUFBLCtCQUFZLEdBQUUsRUFBRSxDQUFDO1FBQ25CLHdFQUF3RTtRQUN4RSxpRUFBaUU7UUFDakUsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFBLHVDQUFxQixHQUFFLENBQUM7SUFDdkQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLE9BQU8sQ0FBQyxJQUFJLENBQ1YsbUhBQW1ILENBQ3BILENBQUM7UUFDRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPLElBQUksNkJBQVcsQ0FBQyxJQUFJLG9CQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFFRCwwRUFBMEU7QUFDMUUsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFtQixFQUFFLEVBQVU7SUFDdkQsT0FBTyxFQUFFLEdBQUcsTUFBTSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztBQUMxRCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLFNBQVMsWUFBWSxDQUFDLE1BQW1CLEVBQUUsRUFBVTtJQUNuRCxPQUFPLEVBQUUsR0FBRyxNQUFNLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFD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ciwgZm9yIGAndXNlIGNhY2hlOiByZW1vdGUnYC5cbiAgU2VlOiBodHRwczovL25leHRqcy5vcmcvZG9jcy9hcHAvYXBpLXJlZmVyZW5jZS9jb25maWcvbmV4dC1jb25maWctanMvY2FjaGVIYW5kbGVyc1xuXG4gIEVudHJpZXMgYXJlIHN0b3JlZCBpbiB0aGUgY2FjaGUgYnVja2V0LCBzbyBldmVyeSBpbnN0YW5jZSByZWFkcyB3aGF0IGFueVxuICBpbnN0YW5jZSB3cm90ZSwgd2l0aCBhIGJvdW5kZWQgaW4tbWVtb3J5IHRpZXIgaW4gZnJvbnQuIFRhZ3MgZ28gdGhyb3VnaCB0aGVcbiAgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MsIHNoYXJlZCB3aXRoIHBsYWluIGAndXNlIGNhY2hlJ2AgYW5kIHdpdGggdGhlXG4gIGluY3JlbWVudGFsIGNhY2hlLiBXaXRob3V0IHRoaXMsIE5leHQuanMgbWFwcyBgcmVtb3RlYCB0byBpdHMgaW4tbWVtb3J5XG4gIGRlZmF1bHQgaGFuZGxlciwgYW5kIGAndXNlIGNhY2hlOiByZW1vdGUnYCBpcyBubyBtb3JlIHNoYXJlZCB0aGFuXG4gIGAndXNlIGNhY2hlJ2AuXG4qL1xuLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBTM0NsaWVudCB9IGZyb20gXCJAYXdzLXNkay9jbGllbnQtczNcIjtcbmltcG9ydCBnZXREZWJ1ZyBmcm9tIFwiZGVidWdcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ2FjaGVFbnRyeSxcbiAgQ2FjaGVIYW5kbGVyLFxufSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9saWIvY2FjaGUtaGFuZGxlcnMvdHlwZXNcIjtcbmltcG9ydCB7XG4gIENhY2hlQnVja2V0LFxuICByZXNvbHZlQXdzQ2FjaGVDb25maWcsXG4gIFRyYWNrZWRUYWdNYXJrZXJzLFxuICB1c2VDYWNoZVMzS2V5LFxufSBmcm9tIFwiLi9hd3MtY2FjaGUtc3RvcmVcIjtcbmltcG9ydCB7IHBhcnNlQ2FjaGVWYWx1ZSwgc2VyaWFsaXplQ2FjaGVWYWx1ZSB9IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5pbXBvcnQge1xuICBjYWNoZUVudHJ5T2YsXG4gIERFRkFVTFRfTUVNT1JZX0JZVEVTLFxuICBFbnRyeUxydSxcbiAgaXNCdWlsZFBoYXNlLFxuICBpc0R5bmFtaWNFbnRyeSxcbiAgbGF6eUhhbmRsZXIsXG4gIG5vdyxcbiAgbnVtYmVyRnJvbUVudixcbiAgUGVuZGluZ1NldHMsXG4gIHNoYXJlZFRhZ01hbmlmZXN0LFxuICBTdG9yZWRFbnRyeSxcbiAgc3RvcmVkRW50cnlPZixcbiAgdGFnTWV0aG9kcyxcbn0gZnJvbSBcIi4vdXNlLWNhY2hlLWNvbW1vblwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlbW90ZVVzZUNhY2hlSGFuZGxlck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGJ1Y2tldCBlbnRyaWVzIGFyZSBzdG9yZWQgaW4sIG9yIGBudWxsYCBmb3IgbWVtb3J5IG9ubHkuIEZyb21cbiAgICogYENES19ORVhUSlNfQ0FDSEVfQlVDS0VUX05BTUVgIGJ5IGRlZmF1bHQsIGFuZCBuZXZlciBhdCBidWlsZCB0aW1lLlxuICAgKi9cbiAgYnVja2V0PzogQ2FjaGVCdWNrZXQgfCBudWxsO1xuICAvKiogUHJlZml4ZXMgZXZlcnkgUzMga2V5OyBgQ0RLX05FWFRKU19CVUlMRF9JRGAgYnkgZGVmYXVsdC4gKi9cbiAgYnVpbGRJZD86IHN0cmluZztcbiAgLyoqIFRhZyBzdGF0ZTsgdGhlIHByb2Nlc3Mtd2lkZSBvbmUgZnJvbSB0aGUgZW52aXJvbm1lbnQgYnkgZGVmYXVsdC4gKi9cbiAgdGFncz86IFRyYWNrZWRUYWdNYXJrZXJzO1xufVxuXG4vKiogV2hhdCBpcyB3cml0dGVuIHRvIFMzIGZvciBvbmUgZW50cnkuICovXG5pbnRlcmZhY2UgU2VyaWFsaXplZEVudHJ5IGV4dGVuZHMgT21pdDxTdG9yZWRFbnRyeSwgXCJ2YWx1ZVwiPiB7XG4gIC8qKiBUaGUgZnVsbCBjYWNoZSBrZXksIGNoZWNrZWQgb24gcmVhZDsgdGhlIG9iamVjdCBrZXkgaXMgb25seSBpdHMgaGFzaC4gKi9cbiAga2V5OiBzdHJpbmc7XG4gIHZhbHVlOiBCdWZmZXI7XG59XG5cbmZ1bmN0aW9uIGJ1Y2tldEZyb21FbnYoKTogQ2FjaGVCdWNrZXQgfCBudWxsIHtcbiAgaWYgKGlzQnVpbGRQaGFzZSgpKSB7XG4gICAgLy8gTm8gY3JlZGVudGlhbHMsIGFuZCBub3RoaW5nIGEgYnVpbGQtdGltZSBlbnRyeSBjb3VsZCBiZSByZWFkIGJhY2sgYnk6XG4gICAgLy8gcHJlcmVuZGVycyBrZWVwIHdoYXQgdGhleSBuZWVkIGluIHRoZWlyIG93biByZXN1bWUgZGF0YSBjYWNoZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCB7IGJ1Y2tldE5hbWUsIHJlZ2lvbiB9ID0gcmVzb2x2ZUF3c0NhY2hlQ29uZmlnKCk7XG4gIGlmICghYnVja2V0TmFtZSkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIFwiQ0RLX05FWFRKU19DQUNIRV9CVUNLRVRfTkFNRSBlbnZpcm9ubWVudCB2YXJpYWJsZSBub3Qgc2V0LCAndXNlIGNhY2hlOiByZW1vdGUnIGVudHJpZXMgYXJlIGxvY2FsIHRvIGVhY2ggaW5zdGFuY2VcIixcbiAgICApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBuZXcgQ2FjaGVCdWNrZXQobmV3IFMzQ2xpZW50KHsgcmVnaW9uIH0pLCBidWNrZXROYW1lKTtcbn1cblxuLyoqIFdoZXRoZXIgYHN0b3JlZGAgaXMgcGFzdCBgcmV2YWxpZGF0ZWAsIHNvIGEgZnJlc2hlciBjb3B5IG1heSBleGlzdC4gKi9cbmZ1bmN0aW9uIGlzUGFzdFJldmFsaWRhdGUoc3RvcmVkOiBTdG9yZWRFbnRyeSwgYXQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gYXQgPiBzdG9yZWQudGltZXN0YW1wICsgc3RvcmVkLnJldmFsaWRhdGUgKiAxMDAwO1xufVxuXG4vKiogV2hldGhlciBgc3RvcmVkYCBpcyBwYXN0IGBleHBpcmVgLCBhbmQgbWF5IG5vIGxvbmdlciBiZSBzZXJ2ZWQgYXQgYWxsLiAqL1xuZnVuY3Rpb24gaXNQYXN0RXhwaXJlKHN0b3JlZDogU3RvcmVkRW50cnksIGF0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGF0ID4gc3RvcmVkLnRpbWVzdGFtcCArIHN0b3JlZC5leHBpcmUgKiAxMDAwO1xufVxuXG4vKipcbiAqIEEgYCd1c2UgY2FjaGU6IHJlbW90ZSdgIGhhbmRsZXI6IFMzIGZvciBzdG9yYWdlLCBtZW1vcnkgaW4gZnJvbnQsIGFuZCB0aGVcbiAqIHJldmFsaWRhdGlvbiB0YWJsZSBmb3IgdGFncy5cbiAqXG4gKiBVbmxpa2UgdGhlIGRlZmF1bHQgaGFuZGxlciBhbiBlbnRyeSBpcyBzZXJ2ZWQgdW50aWwgYGV4cGlyZWAsIG5vdCBkcm9wcGVkIGF0XG4gKiBgcmV2YWxpZGF0ZWA6IGEgcmVtb3RlIHJlYWQgaXMgd29ydGggc2VydmluZyBzdGFsZSB3aGlsZSBOZXh0LmpzJ3Mgd3JhcHBlclxuICogcmVnZW5lcmF0ZXMgaXQgaW4gdGhlIGJhY2tncm91bmQsIHdoaWNoIGlzIHdoYXQgYHJldmFsaWRhdGVgIGlzIGZvci4gQSBtZW1vcnlcbiAqIGNvcHkgcGFzdCBgcmV2YWxpZGF0ZWAgaXMgY2hlY2tlZCBhZ2FpbnN0IFMzIGZpcnN0LCBzaW5jZSBhbm90aGVyIGluc3RhbmNlIG1heVxuICogYWxyZWFkeSBoYXZlIHdyaXR0ZW4gdGhlIHJlZ2VuZXJhdGVkIGVudHJ5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVtb3RlVXNlQ2FjaGVIYW5kbGVyKFxuICBvcHRpb25zOiBSZW1vdGVVc2VDYWNoZUhhbmRsZXJPcHRpb25zID0ge30sXG4pOiBDYWNoZUhhbmRsZXIge1xuICBjb25zdCBidWNrZXQgPVxuICAgIG9wdGlvbnMuYnVja2V0ID09PSB1bmRlZmluZWQgPyBidWNrZXRGcm9tRW52KCkgOiBvcHRpb25zLmJ1Y2tldDtcbiAgY29uc3QgYnVpbGRJZCA9IG9wdGlvbnMuYnVpbGRJZCA/PyByZXNvbHZlQXdzQ2FjaGVDb25maWcoKS5idWlsZElkO1xuICBjb25zdCB0YWdzID0gb3B0aW9ucy50YWdzID8/IHNoYXJlZFRhZ01hbmlmZXN0KCk7XG4gIGNvbnN0IG1lbW9yeSA9IG5ldyBFbnRyeUxydShcbiAgICBudW1iZXJGcm9tRW52KFwiQ0RLX05FWFRKU19VU0VfQ0FDSEVfTUVNT1JZX0JZVEVTXCIsIERFRkFVTFRfTUVNT1JZX0JZVEVTKSxcbiAgKTtcbiAgY29uc3QgcGVuZGluZyA9IG5ldyBQZW5kaW5nU2V0cygpO1xuICBjb25zdCBkZWJ1ZyA9IGdldERlYnVnKFwiY2RrLW5leHRqczpjYWNoZS1oYW5kbGVyOnVzZS1jYWNoZTpyZW1vdGVcIik7XG5cbiAgY29uc3QgczNLZXkgPSAoY2FjaGVLZXk6IHN0cmluZykgPT5cbiAgICB1c2VDYWNoZVMzS2V5KGJ1aWxkSWQsIGNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNhY2hlS2V5KS5kaWdlc3QoXCJoZXhcIikpO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlYWRGcm9tUzMoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxTdG9yZWRFbnRyeSB8IHVuZGVmaW5lZD4ge1xuICAgIGlmICghYnVja2V0KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBrZXkgPSBzM0tleShjYWNoZUtleSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG9iamVjdCA9IGF3YWl0IGJ1Y2tldC5nZXQoa2V5KTtcbiAgICAgIGlmICghb2JqZWN0KSB7XG4gICAgICAgIGRlYnVnKGBTMyBNSVNTICR7Y2FjaGVLZXl9YCk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBwYXJzZWQgPSBwYXJzZUNhY2hlVmFsdWUob2JqZWN0KSBhcyBTZXJpYWxpemVkRW50cnk7XG4gICAgICBpZiAocGFyc2VkLmtleSAhPT0gY2FjaGVLZXkpIHtcbiAgICAgICAgLy8gQSBoYXNoIGNvbGxpc2lvbiwgb3IgYW4gb2JqZWN0IHRoYXQgaXMgbm90IG91cnM6IG5ldmVyIHNlcnZlIGl0LlxuICAgICAgICBjb25zb2xlLndhcm4oYCd1c2UgY2FjaGU6IHJlbW90ZScgZW50cnkgJHtrZXl9IGlzIGZvciBhbm90aGVyIGtleWApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGFnczogcGFyc2VkLnRhZ3MsXG4gICAgICAgIHN0YWxlOiBwYXJzZWQuc3RhbGUsXG4gICAgICAgIHRpbWVzdGFtcDogcGFyc2VkLnRpbWVzdGFtcCxcbiAgICAgICAgZXhwaXJlOiBwYXJzZWQuZXhwaXJlLFxuICAgICAgICByZXZhbGlkYXRlOiBwYXJzZWQucmV2YWxpZGF0ZSxcbiAgICAgICAgdmFsdWU6IG5ldyBVaW50OEFycmF5KHBhcnNlZC52YWx1ZSksXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBgRXJyb3IgcmVhZGluZyAndXNlIGNhY2hlOiByZW1vdGUnIGVudHJ5ICR7a2V5fSBmcm9tIFMzOmAsXG4gICAgICAgIGVycm9yLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gd3JpdGVUb1MzKGNhY2hlS2V5OiBzdHJpbmcsIHN0b3JlZDogU3RvcmVkRW50cnkpIHtcbiAgICBpZiAoIWJ1Y2tldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBrZXkgPSBzM0tleShjYWNoZUtleSk7XG4gICAgY29uc3Qgc2VyaWFsaXplZDogU2VyaWFsaXplZEVudHJ5ID0ge1xuICAgICAgLi4uc3RvcmVkLFxuICAgICAga2V5OiBjYWNoZUtleSxcbiAgICAgIHZhbHVlOiBCdWZmZXIuZnJvbShzdG9yZWQudmFsdWUpLFxuICAgIH07XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGJ1Y2tldC5wdXRKc29uKGtleSwgc2VyaWFsaXplQ2FjaGVWYWx1ZShzZXJpYWxpemVkKSk7XG4gICAgICBkZWJ1ZyhgUzMgU0VUICR7Y2FjaGVLZXl9ICgke2tleX0pYCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFRoZSBlbnRyeSBpcyBzdGlsbCBpbiBtZW1vcnkgaGVyZTsgb3RoZXIgaW5zdGFuY2VzIGp1c3QgbWlzcy5cbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBFcnJvciB3cml0aW5nICd1c2UgY2FjaGU6IHJlbW90ZScgZW50cnkgJHtrZXl9IHRvIFMzOmAsXG4gICAgICAgIGVycm9yLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldChjYWNoZUtleTogc3RyaW5nKTogUHJvbWlzZTxDYWNoZUVudHJ5IHwgdW5kZWZpbmVkPiB7XG4gICAgICBhd2FpdCBwZW5kaW5nLndhaXQoY2FjaGVLZXkpO1xuICAgICAgY29uc3QgYXQgPSBub3coKTtcblxuICAgICAgbGV0IHN0b3JlZCA9IG1lbW9yeS5nZXQoY2FjaGVLZXkpO1xuICAgICAgaWYgKHN0b3JlZCkge1xuICAgICAgICBhd2FpdCB0YWdzLmVuc3VyZShzdG9yZWQudGFncyk7XG4gICAgICB9XG5cbiAgICAgIC8vIFBhc3QgYHJldmFsaWRhdGVgLCBvciBzdGFsZSBvciBleHBpcmVkIGJ5IHRhZzogYW5vdGhlciBpbnN0YW5jZSBtYXlcbiAgICAgIC8vIGFscmVhZHkgaGF2ZSB3cml0dGVuIHRoZSByZWdlbmVyYXRlZCBlbnRyeSwgYW5kIHNlcnZpbmcgdGhhdCBiZWF0c1xuICAgICAgLy8gcmVnZW5lcmF0aW5nIGl0IGhlcmUgdG9vLiBBbiBleHBpcmVkIGVudHJ5IFMzIGhhcyBub3RoaW5nIG5ld2VyIGZvciBpc1xuICAgICAgLy8gZHJvcHBlZCBiZWxvdy5cbiAgICAgIGlmIChcbiAgICAgICAgIXN0b3JlZCB8fFxuICAgICAgICBpc1Bhc3RSZXZhbGlkYXRlKHN0b3JlZCwgYXQpIHx8XG4gICAgICAgIHRhZ3Muc3RhdGUoc3RvcmVkLnRhZ3MsIHN0b3JlZC50aW1lc3RhbXApICE9PSBcImZyZXNoXCJcbiAgICAgICkge1xuICAgICAgICBjb25zdCBmcm9tUzMgPSBhd2FpdCByZWFkRnJvbVMzKGNhY2hlS2V5KTtcbiAgICAgICAgaWYgKGZyb21TMyAmJiAoIXN0b3JlZCB8fCBmcm9tUzMudGltZXN0YW1wID4gc3RvcmVkLnRpbWVzdGFtcCkpIHtcbiAgICAgICAgICBzdG9yZWQgPSBmcm9tUzM7XG4gICAgICAgICAgLy8gQW4gZW50cnkgd3JpdHRlbiBieSBhbm90aGVyIGluc3RhbmNlOiBpdHMgdGFncyBtYXkgaGF2ZSBiZWVuXG4gICAgICAgICAgLy8gcmV2YWxpZGF0ZWQgYXQgYW55IHRpbWUgc2luY2UsIHNvIHRoZXkgYXJlIHJlYWQgYmVmb3JlIGp1ZGdpbmcgaXQuXG4gICAgICAgICAgYXdhaXQgdGFncy5lbnN1cmUoc3RvcmVkLnRhZ3MpO1xuICAgICAgICAgIG1lbW9yeS5zZXQoY2FjaGVLZXksIHN0b3JlZCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFzdG9yZWQpIHtcbiAgICAgICAgZGVidWcoYE1JU1MgJHtjYWNoZUtleX1gKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChpc1Bhc3RFeHBpcmUoc3RvcmVkLCBhdCkpIHtcbiAgICAgICAgZGVidWcoYEVYUElSRUQgJHtjYWNoZUtleX1gKTtcbiAgICAgICAgbWVtb3J5LmRlbGV0ZShjYWNoZUtleSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0ZSA9IHRhZ3Muc3RhdGUoc3RvcmVkLnRhZ3MsIHN0b3JlZC50aW1lc3RhbXApO1xuICAgICAgaWYgKHN0YXRlID09PSBcImV4cGlyZWRcIikge1xuICAgICAgICBkZWJ1ZyhgRVhQSVJFRCBCWSBUQUcgJHtjYWNoZUtleX1gKTtcbiAgICAgICAgbWVtb3J5LmRlbGV0ZShjYWNoZUtleSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBkZWJ1ZyhgSElUICR7Y2FjaGVLZXl9JHtzdGF0ZSA9PT0gXCJzdGFsZVwiID8gXCIgKHN0YWxlIHRhZylcIiA6IFwiXCJ9YCk7XG4gICAgICAvLyBgcmV2YWxpZGF0ZTogLTFgIG1ha2VzIHRoZSB3cmFwcGVyIHNlcnZlIHRoZSBlbnRyeSBhbmQgcmVnZW5lcmF0ZSBpdCBpblxuICAgICAgLy8gdGhlIGJhY2tncm91bmQsIHRoZSBidWlsdC1pbiBoYW5kbGVyJ3MgYW5zd2VyIHRvIGEgc3RhbGUgdGFnLlxuICAgICAgcmV0dXJuIGNhY2hlRW50cnlPZihzdG9yZWQsIHN0YXRlID09PSBcInN0YWxlXCIgPyAtMSA6IHN0b3JlZC5yZXZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgc2V0KFxuICAgICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICAgIHBlbmRpbmdFbnRyeTogUHJvbWlzZTxDYWNoZUVudHJ5PixcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IGRvbmUgPSBwZW5kaW5nLmJlZ2luKGNhY2hlS2V5KTtcbiAgICAgIGxldCBzdG9yZWQ6IFN0b3JlZEVudHJ5O1xuICAgICAgdHJ5IHtcbiAgICAgICAgc3RvcmVkID0gYXdhaXQgc3RvcmVkRW50cnlPZihwZW5kaW5nRW50cnkpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gVGhlIHN0cmVhbSBlcnJvcmVkOiBzdG9yZSBub3RoaW5nIHJhdGhlciB0aGFuIGEgcGFydGlhbCBlbnRyeS5cbiAgICAgICAgZGVidWcoYFNFVCBGQUlMRUQgJHtjYWNoZUtleX1gLCBlcnJvcik7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGlzRHluYW1pY0VudHJ5KHN0b3JlZCkpIHtcbiAgICAgICAgZGVidWcoYFNLSVAgZHluYW1pYyBlbnRyeSAke2NhY2hlS2V5fWApO1xuICAgICAgICBkb25lKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG1lbW9yeS5zZXQoY2FjaGVLZXksIHN0b3JlZCk7XG4gICAgICB0YWdzLnRyYWNrKHN0b3JlZC50YWdzKTtcbiAgICAgIC8vIEEgYGdldGAgd2FpdGluZyBvbiB0aGlzIGBzZXRgIGNhbiBiZSBhbnN3ZXJlZCBmcm9tIG1lbW9yeSBub3c7IG9ubHlcbiAgICAgIC8vIG90aGVyIGluc3RhbmNlcyBuZWVkIHRoZSBTMyBjb3B5LlxuICAgICAgZG9uZSgpO1xuICAgICAgYXdhaXQgd3JpdGVUb1MzKGNhY2hlS2V5LCBzdG9yZWQpO1xuICAgIH0sXG5cbiAgICAuLi50YWdNZXRob2RzKHRhZ3MpLFxuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBsYXp5SGFuZGxlcigoKSA9PiBjcmVhdGVSZW1vdGVVc2VDYWNoZUhhbmRsZXIoKSk7XG4iXX0=