cdk-nextjs 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +1548 -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 +852 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +861 -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 +1213 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1678 -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 +41595 -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 +55 -0
  213. package/lib/runtime/next-modules.js +124 -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 +41588 -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
@@ -5,8 +5,98 @@ import type { SetIncrementalFetchCacheContext, SetIncrementalResponseCacheContex
5
5
  export declare function serializeCacheValue(value: any): string;
6
6
  /**
7
7
  * Parse cache value with custom handling for Map and Buffer objects
8
+ *
9
+ * Buffers are read back from base64 when that is how they were written, and from
10
+ * an array of per-byte integers when they were not. That array is the format
11
+ * `Buffer.toJSON()` produces and the one this code used to write, and it is
12
+ * ruinous for a page with a large payload: a 1 MiB prerender became ~3 MiB of
13
+ * JSON text, an 11.6 MiB cache entry once html and the per-segment copies are
14
+ * counted, and — because `JSON.parse`'s reviver runs for *every array element* —
15
+ * upwards of three million reviver calls to read one page. Measured against a
16
+ * deployment: 4.8s of Lambda time to answer a 1 MiB segment prefetch, against
17
+ * 45ms for a small one from the same cache. base64 is 4/3 the bytes rather than
18
+ * ~3x, and `Buffer.from(str, "base64")` is one native call.
8
19
  */
9
20
  export declare function parseCacheValue(jsonString: string): any;
21
+ /**
22
+ * The cache key a prerendered route's seeded entry has to be written under.
23
+ *
24
+ * `ctx.outputs.prerenders[].pathname` is the *URL* the page is served at, so it
25
+ * carries the app's `basePath`. The key the server later looks entries up under
26
+ * is the route, which does not — Next.js strips `basePath` before routing, so the
27
+ * cache handler never sees it at request time. Seeding `/prod/ssg/1` verbatim
28
+ * therefore writes `<buildId>/prod/ssg/1.json` while the server asks for
29
+ * `<buildId>/ssg/1.json`: every build-time prerender is a MISS that re-renders on
30
+ * first request, and the page is only "static" from the second visit onwards.
31
+ */
32
+ export declare function prerenderPathToCacheKey(pathname: string, basePath: string): string;
33
+ /** The outputs one route contributes to `ctx.outputs.prerenders`. */
34
+ export interface PrerenderVariants<T> {
35
+ /** The HTML render. Its pathname is the route, with no suffix. */
36
+ html?: T;
37
+ /** The flight payload, built as `<route>.rsc` — but see {@link groupPrerenders}. */
38
+ rsc?: T;
39
+ /** Per-segment flight payloads, under `<route>.segments/`. */
40
+ segments: T[];
41
+ /** A Pages Router route's `pageData`, built as its `/_next/data/` route. */
42
+ data?: T;
43
+ }
44
+ /**
45
+ * Collect `ctx.outputs.prerenders` into one entry per route.
46
+ *
47
+ * Next.js emits up to three shapes per prerendered App Router route — `/blog/hello`,
48
+ * `/blog/hello.rsc`, and `/blog/hello.segments/*.segment.rsc` — and a cache entry
49
+ * needs all of them together, so they have to be grouped by route before anything
50
+ * can be seeded. A Pages Router route emits two: the HTML, and its `pageData` at
51
+ * the route's `/_next/data/<buildId>/<page>.json` pathname
52
+ * ({@link PAGES_DATA_PATHNAME}). That one is not a suffix of the page's own
53
+ * pathname, so it is matched rather than stripped.
54
+ *
55
+ * The one case that is not a suffix strip is the **root route**, which cannot be
56
+ * named `/.rsc`: its payloads are emitted under `/index.rsc` and
57
+ * `/index.segments/` while its HTML stays at `/` (or at the `basePath`, e.g.
58
+ * `/prod` and `/prod/index.rsc`). Reconstructing names by concatenation therefore
59
+ * silently loses the home page's `rscData` — and with a `basePath` also its
60
+ * `segmentData`, because `/prod` and `/prod/index` group apart. That is not a
61
+ * cosmetic gap: `app-page-runtime.js` answers an RSC request for an entry with no
62
+ * `rscData` by checking `cachedData.html.contentType`, and under `cacheComponents`
63
+ * sends an empty `404`. Every client-side navigation to `/` breaks.
64
+ *
65
+ * The remap is conditional rather than unconditional so that an app with a real
66
+ * page at `app/index/page.tsx` — whose HTML prerender genuinely is `/index` — keeps
67
+ * its own group.
68
+ */
69
+ export declare function groupPrerenders<T extends {
70
+ pathname: string;
71
+ }>(prerenders: T[]): Map<string, PrerenderVariants<T>>;
72
+ /** See {@link NON_CACHEABLE_APP_PAGE_HEADERS}. */
73
+ export declare function appPageCacheHeaders<T>(initialHeaders: Record<string, T>): Record<string, T>;
74
+ /**
75
+ * The tags a cache value's render was tagged with, as Next.js records them: in
76
+ * its `x-next-cache-tags` header, comma separated, including the implicit
77
+ * `_N_T_/…` path chain `revalidatePath` uses. One parser for the build's tag
78
+ * manifest and the runtime's mapping rows, which have to agree.
79
+ *
80
+ * `value` is `unknown` because it arrives both as a stored entry read back from
81
+ * S3 and as the `IncrementalCacheValue` union; only some members have headers.
82
+ */
83
+ export declare function headerTags(value: unknown): string[];
84
+ /**
85
+ * Name of the file the adapter writes into the init cache directory mapping each
86
+ * cache tag to the cache keys of the build-time prerenders carrying it.
87
+ *
88
+ * It rides to S3 with the rest of the init cache, and `S3CacheHandler`'s
89
+ * `revalidateTag` reads it alongside the `tag#cacheKey` rows a runtime `set`
90
+ * writes. Without it `revalidateTag` knows a prerender is stale (see
91
+ * `checkIfRevalidated`) but not which CloudFront paths to invalidate, so the CDN
92
+ * keeps serving the old response until its TTL expires - a year, for a
93
+ * prerender.
94
+ *
95
+ * The leading underscore keeps it clear of cache keys, which are route paths.
96
+ */
97
+ export declare const INIT_CACHE_TAG_MANIFEST = "_cdk-nextjs-tag-manifest.json";
98
+ /** Contents of {@link INIT_CACHE_TAG_MANIFEST}: tag -> init cache keys. */
99
+ export type InitCacheTagManifest = Record<string, string[]>;
10
100
  /**
11
101
  * Helper to safely extract tags from context
12
102
  */
@@ -1,8 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INIT_CACHE_TAG_MANIFEST = void 0;
3
4
  exports.serializeCacheValue = serializeCacheValue;
4
5
  exports.parseCacheValue = parseCacheValue;
6
+ exports.prerenderPathToCacheKey = prerenderPathToCacheKey;
7
+ exports.groupPrerenders = groupPrerenders;
8
+ exports.appPageCacheHeaders = appPageCacheHeaders;
9
+ exports.headerTags = headerTags;
5
10
  exports.getTags = getTags;
11
+ const base_path_1 = require("../utils/base-path");
6
12
  /**
7
13
  * Pre-process value to convert Buffers and Maps before JSON.stringify
8
14
  * This is necessary because Buffer.toJSON() is called before replacer functions
@@ -12,11 +18,13 @@ function preprocessValue(value) {
12
18
  if (value == null) {
13
19
  return value;
14
20
  }
15
- // Convert Buffer to our custom format
21
+ // Convert Buffer to our custom format. base64, not the array of per-byte
22
+ // integers this used to write (and that `Buffer.toJSON()` writes) — see
23
+ // {@link parseCacheValue} for why that mattered so much.
16
24
  if (Buffer.isBuffer(value)) {
17
25
  return {
18
26
  __type: "Buffer",
19
- data: Array.from(value),
27
+ base64: value.toString("base64"),
20
28
  };
21
29
  }
22
30
  // Convert Map to our custom format
@@ -56,6 +64,17 @@ function serializeCacheValue(value) {
56
64
  }
57
65
  /**
58
66
  * Parse cache value with custom handling for Map and Buffer objects
67
+ *
68
+ * Buffers are read back from base64 when that is how they were written, and from
69
+ * an array of per-byte integers when they were not. That array is the format
70
+ * `Buffer.toJSON()` produces and the one this code used to write, and it is
71
+ * ruinous for a page with a large payload: a 1 MiB prerender became ~3 MiB of
72
+ * JSON text, an 11.6 MiB cache entry once html and the per-segment copies are
73
+ * counted, and — because `JSON.parse`'s reviver runs for *every array element* —
74
+ * upwards of three million reviver calls to read one page. Measured against a
75
+ * deployment: 4.8s of Lambda time to answer a 1 MiB segment prefetch, against
76
+ * 45ms for a small one from the same cache. base64 is 4/3 the bytes rather than
77
+ * ~3x, and `Buffer.from(str, "base64")` is one native call.
59
78
  */
60
79
  function parseCacheValue(jsonString) {
61
80
  return JSON.parse(jsonString, (_key, val) => {
@@ -65,7 +84,9 @@ function parseCacheValue(jsonString) {
65
84
  }
66
85
  // Restore Buffer objects that were serialized with __type marker (our custom format)
67
86
  if (val && typeof val === "object" && val.__type === "Buffer") {
68
- return Buffer.from(val.data);
87
+ return typeof val.base64 === "string"
88
+ ? Buffer.from(val.base64, "base64")
89
+ : Buffer.from(val.data);
69
90
  }
70
91
  // Restore Buffer objects that were serialized with Node.js default Buffer.toJSON() format
71
92
  // This handles legacy cache entries or runtime-generated entries
@@ -78,10 +99,184 @@ function parseCacheValue(jsonString) {
78
99
  return val;
79
100
  });
80
101
  }
102
+ /**
103
+ * The cache key a prerendered route's seeded entry has to be written under.
104
+ *
105
+ * `ctx.outputs.prerenders[].pathname` is the *URL* the page is served at, so it
106
+ * carries the app's `basePath`. The key the server later looks entries up under
107
+ * is the route, which does not — Next.js strips `basePath` before routing, so the
108
+ * cache handler never sees it at request time. Seeding `/prod/ssg/1` verbatim
109
+ * therefore writes `<buildId>/prod/ssg/1.json` while the server asks for
110
+ * `<buildId>/ssg/1.json`: every build-time prerender is a MISS that re-renders on
111
+ * first request, and the page is only "static" from the second visit onwards.
112
+ */
113
+ function prerenderPathToCacheKey(pathname, basePath) {
114
+ // Matching on a path boundary so a sibling route like `/production` is not
115
+ // read as basePath `/prod` plus `uction`.
116
+ const route = ((0, base_path_1.hasPathPrefix)(pathname, basePath)
117
+ ? pathname.slice(basePath.length)
118
+ : pathname)
119
+ // Leading slashes would make an S3 key with an empty first segment.
120
+ .replace(/^\/+/, "");
121
+ return route === "" ? "index" : route;
122
+ }
123
+ const INDEX_SUFFIX = "/index";
124
+ /**
125
+ * A Pages Router data route: `/_next/data/<buildId>/<page>.json`, optionally
126
+ * behind a `basePath` (`normalizePathname` in Next.js's `build-complete` prefixes
127
+ * every output pathname, this one included).
128
+ *
129
+ * Capture 1 is that prefix and capture 2 the page path without its `.json`, so
130
+ * `/prod/_next/data/abc123/blog/hello.json` recomposes to `/prod/blog/hello`.
131
+ */
132
+ const PAGES_DATA_PATHNAME = /^(.*)\/_next\/data\/[^/]+\/(.+)\.json$/;
133
+ /**
134
+ * Collect `ctx.outputs.prerenders` into one entry per route.
135
+ *
136
+ * Next.js emits up to three shapes per prerendered App Router route — `/blog/hello`,
137
+ * `/blog/hello.rsc`, and `/blog/hello.segments/*.segment.rsc` — and a cache entry
138
+ * needs all of them together, so they have to be grouped by route before anything
139
+ * can be seeded. A Pages Router route emits two: the HTML, and its `pageData` at
140
+ * the route's `/_next/data/<buildId>/<page>.json` pathname
141
+ * ({@link PAGES_DATA_PATHNAME}). That one is not a suffix of the page's own
142
+ * pathname, so it is matched rather than stripped.
143
+ *
144
+ * The one case that is not a suffix strip is the **root route**, which cannot be
145
+ * named `/.rsc`: its payloads are emitted under `/index.rsc` and
146
+ * `/index.segments/` while its HTML stays at `/` (or at the `basePath`, e.g.
147
+ * `/prod` and `/prod/index.rsc`). Reconstructing names by concatenation therefore
148
+ * silently loses the home page's `rscData` — and with a `basePath` also its
149
+ * `segmentData`, because `/prod` and `/prod/index` group apart. That is not a
150
+ * cosmetic gap: `app-page-runtime.js` answers an RSC request for an entry with no
151
+ * `rscData` by checking `cachedData.html.contentType`, and under `cacheComponents`
152
+ * sends an empty `404`. Every client-side navigation to `/` breaks.
153
+ *
154
+ * The remap is conditional rather than unconditional so that an app with a real
155
+ * page at `app/index/page.tsx` — whose HTML prerender genuinely is `/index` — keeps
156
+ * its own group.
157
+ */
158
+ function groupPrerenders(prerenders) {
159
+ const htmlPathnames = new Set(prerenders
160
+ .map((p) => p.pathname)
161
+ .filter((p) => !p.endsWith(".rsc") &&
162
+ !p.includes(".segments/") &&
163
+ !PAGES_DATA_PATHNAME.test(p)));
164
+ const groups = new Map();
165
+ const variantsFor = (base) => {
166
+ let variants = groups.get(base);
167
+ if (!variants) {
168
+ variants = { segments: [] };
169
+ groups.set(base, variants);
170
+ }
171
+ return variants;
172
+ };
173
+ /** `/index.rsc` belongs to `/`, `/prod/index.rsc` to `/prod`. */
174
+ const routeOf = (base) => {
175
+ if (base.endsWith(INDEX_SUFFIX) && !htmlPathnames.has(base)) {
176
+ const parent = base.slice(0, -INDEX_SUFFIX.length) || "/";
177
+ if (htmlPathnames.has(parent)) {
178
+ return parent;
179
+ }
180
+ }
181
+ return base;
182
+ };
183
+ for (const prerender of prerenders) {
184
+ const { pathname } = prerender;
185
+ const dataRoute = PAGES_DATA_PATHNAME.exec(pathname);
186
+ if (dataRoute) {
187
+ variantsFor(routeOf(`${dataRoute[1]}/${dataRoute[2]}`)).data = prerender;
188
+ }
189
+ else if (pathname.includes(".segments/")) {
190
+ variantsFor(routeOf(pathname.split(".segments/")[0])).segments.push(prerender);
191
+ }
192
+ else if (pathname.endsWith(".rsc")) {
193
+ variantsFor(routeOf(pathname.slice(0, -".rsc".length))).rsc = prerender;
194
+ }
195
+ else {
196
+ variantsFor(pathname).html = prerender;
197
+ }
198
+ }
199
+ return groups;
200
+ }
201
+ /**
202
+ * Headers that must not be seeded into an `APP_PAGE` cache entry, even though the
203
+ * adapter output lists them in `fallback.initialHeaders`.
204
+ *
205
+ * `initialHeaders` describes how a platform should serve the prerendered *file*
206
+ * straight off a CDN. A cache entry is a different thing: `app-page-runtime.js`
207
+ * `appendHeader`s `cachedData.headers` onto the response and *then* serves the
208
+ * variant the request actually asked for, so anything presentational in there is
209
+ * either wrong or doubled. At request time Next.js stores only what the render
210
+ * put in `metadata.headers` — `x-nextjs-stale-time`, `x-next-cache-tags`, and
211
+ * whatever the app set through `headers()`/`cookies()` — and never these four.
212
+ *
213
+ * `content-type` is the one that actually breaks. `send-payload.js` sets the type
214
+ * only when the response does not already have one
215
+ * (`if (!res.getHeader('Content-Type') && result.contentType)`), so a seeded
216
+ * `text/html; charset=utf-8` makes every RSC request to a prerendered page answer
217
+ * the flight payload labeled as HTML. The client router rejects that, and so does
218
+ * Next.js itself: `createRedirectRenderResult` checks the content type of the
219
+ * sub-response it fetches to stream an action `redirect()`, and on a mismatch
220
+ * cancels the body and returns an empty result.
221
+ *
222
+ * `vary`, `x-nextjs-prerender`, and `x-nextjs-postponed` are all set by the
223
+ * entrypoint itself, so seeding them only produces two of each.
224
+ *
225
+ * `APP_ROUTE` entries are deliberately *not* filtered: a route handler's
226
+ * `content-type` is part of its cached response, and `app-route.js` replays those
227
+ * headers verbatim.
228
+ */
229
+ const NON_CACHEABLE_APP_PAGE_HEADERS = new Set([
230
+ "content-type",
231
+ "vary",
232
+ "x-nextjs-prerender",
233
+ "x-nextjs-postponed",
234
+ ]);
235
+ /** See {@link NON_CACHEABLE_APP_PAGE_HEADERS}. */
236
+ function appPageCacheHeaders(initialHeaders) {
237
+ const headers = {};
238
+ for (const [name, value] of Object.entries(initialHeaders)) {
239
+ if (!NON_CACHEABLE_APP_PAGE_HEADERS.has(name.toLowerCase())) {
240
+ headers[name] = value;
241
+ }
242
+ }
243
+ return headers;
244
+ }
245
+ /** `NEXT_CACHE_TAGS_HEADER`, inlined so this file imports no Next.js internals. */
246
+ const NEXT_CACHE_TAGS_HEADER = "x-next-cache-tags";
247
+ /**
248
+ * The tags a cache value's render was tagged with, as Next.js records them: in
249
+ * its `x-next-cache-tags` header, comma separated, including the implicit
250
+ * `_N_T_/…` path chain `revalidatePath` uses. One parser for the build's tag
251
+ * manifest and the runtime's mapping rows, which have to agree.
252
+ *
253
+ * `value` is `unknown` because it arrives both as a stored entry read back from
254
+ * S3 and as the `IncrementalCacheValue` union; only some members have headers.
255
+ */
256
+ function headerTags(value) {
257
+ const headers = value
258
+ ?.headers;
259
+ const header = headers?.[NEXT_CACHE_TAGS_HEADER];
260
+ return typeof header === "string" ? header.split(",").filter(Boolean) : [];
261
+ }
262
+ /**
263
+ * Name of the file the adapter writes into the init cache directory mapping each
264
+ * cache tag to the cache keys of the build-time prerenders carrying it.
265
+ *
266
+ * It rides to S3 with the rest of the init cache, and `S3CacheHandler`'s
267
+ * `revalidateTag` reads it alongside the `tag#cacheKey` rows a runtime `set`
268
+ * writes. Without it `revalidateTag` knows a prerender is stale (see
269
+ * `checkIfRevalidated`) but not which CloudFront paths to invalidate, so the CDN
270
+ * keeps serving the old response until its TTL expires - a year, for a
271
+ * prerender.
272
+ *
273
+ * The leading underscore keeps it clear of cache keys, which are route paths.
274
+ */
275
+ exports.INIT_CACHE_TAG_MANIFEST = "_cdk-nextjs-tag-manifest.json";
81
276
  /**
82
277
  * Helper to safely extract tags from context
83
278
  */
84
279
  function getTags(ctx) {
85
280
  return "tags" in ctx ? ctx.tags : undefined;
86
281
  }
87
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9jYWNoZS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTJEQSxrREFLQztBQUtELDBDQXNCQztBQUtELDBCQUlDO0FBNUZEOzs7R0FHRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQVU7SUFDakMsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHNDQUFzQztJQUN0QyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMzQixPQUFPO1lBQ0wsTUFBTSxFQUFFLFFBQVE7WUFDaEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1NBQ3hCLENBQUM7SUFDSixDQUFDO0lBRUQsbUNBQW1DO0lBQ25DLElBQUksS0FBSyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sT0FBTyxHQUF3QixFQUFFLENBQUM7UUFDeEMsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUNELE9BQU87WUFDTCxNQUFNLEVBQUUsS0FBSztZQUNiLElBQUksRUFBRSxPQUFPO1NBQ2QsQ0FBQztJQUNKLENBQUM7SUFFRCw2QkFBNkI7SUFDN0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsOEJBQThCO0lBQzlCLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDOUIsTUFBTSxTQUFTLEdBQXdCLEVBQUUsQ0FBQztRQUMxQyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9DLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxLQUFVO0lBQzVDLGdFQUFnRTtJQUNoRSxpREFBaUQ7SUFDakQsTUFBTSxTQUFTLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixlQUFlLENBQUMsVUFBa0I7SUFDaEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUMxQyw4REFBOEQ7UUFDOUQsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDM0QsT0FBTyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFDRCxxRkFBcUY7UUFDckYsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixDQUFDO1FBQ0QsMEZBQTBGO1FBQzFGLGlFQUFpRTtRQUNqRSxJQUNFLEdBQUc7WUFDSCxPQUFPLEdBQUcsS0FBSyxRQUFRO1lBQ3ZCLEdBQUcsQ0FBQyxJQUFJLEtBQUssUUFBUTtZQUNyQixLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFDdkIsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixPQUFPLENBQ3JCLEdBQXlFO0lBRXpFLE9BQU8sTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBTaGFyZWQgY2FjaGUgdXRpbGl0eSBmdW5jdGlvbnNcbiovXG5pbXBvcnQgdHlwZSB7XG4gIFNldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQsXG4gIFNldEluY3JlbWVudGFsUmVzcG9uc2VDYWNoZUNvbnRleHQsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5cbi8qKlxuICogUHJlLXByb2Nlc3MgdmFsdWUgdG8gY29udmVydCBCdWZmZXJzIGFuZCBNYXBzIGJlZm9yZSBKU09OLnN0cmluZ2lmeVxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBCdWZmZXIudG9KU09OKCkgaXMgY2FsbGVkIGJlZm9yZSByZXBsYWNlciBmdW5jdGlvbnNcbiAqL1xuZnVuY3Rpb24gcHJlcHJvY2Vzc1ZhbHVlKHZhbHVlOiBhbnkpOiBhbnkge1xuICAvLyBIYW5kbGUgbnVsbC91bmRlZmluZWRcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvLyBDb252ZXJ0IEJ1ZmZlciB0byBvdXIgY3VzdG9tIGZvcm1hdFxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6IFwiQnVmZmVyXCIsXG4gICAgICBkYXRhOiBBcnJheS5mcm9tKHZhbHVlKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gQ29udmVydCBNYXAgdG8gb3VyIGN1c3RvbSBmb3JtYXRcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgY29uc3QgZW50cmllczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsXSBvZiB2YWx1ZS5lbnRyaWVzKCkpIHtcbiAgICAgIGVudHJpZXNba2V5XSA9IHByZXByb2Nlc3NWYWx1ZSh2YWwpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiBcIk1hcFwiLFxuICAgICAgZGF0YTogZW50cmllcyxcbiAgICB9O1xuICB9XG5cbiAgLy8gUmVjdXJzaXZlbHkgcHJvY2VzcyBhcnJheXNcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLm1hcCgoaXRlbSkgPT4gcHJlcHJvY2Vzc1ZhbHVlKGl0ZW0pKTtcbiAgfVxuXG4gIC8vIFJlY3Vyc2l2ZWx5IHByb2Nlc3Mgb2JqZWN0c1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgcHJvY2Vzc2VkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWxdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgcHJvY2Vzc2VkW2tleV0gPSBwcmVwcm9jZXNzVmFsdWUodmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3NlZDtcbiAgfVxuXG4gIC8vIFJldHVybiBwcmltaXRpdmVzIGFzLWlzXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBTZXJpYWxpemUgY2FjaGUgdmFsdWUgd2l0aCBjdXN0b20gaGFuZGxpbmcgZm9yIE1hcCBhbmQgQnVmZmVyIG9iamVjdHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZUNhY2hlVmFsdWUodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gIC8vIFByZS1wcm9jZXNzIHRvIGNvbnZlcnQgQnVmZmVycyBhbmQgTWFwcyBiZWZvcmUgSlNPTi5zdHJpbmdpZnlcbiAgLy8gVGhpcyBlbnN1cmVzIEJ1ZmZlci50b0pTT04oKSBkb2Vzbid0IGludGVyZmVyZVxuICBjb25zdCBwcm9jZXNzZWQgPSBwcmVwcm9jZXNzVmFsdWUodmFsdWUpO1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocHJvY2Vzc2VkKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBjYWNoZSB2YWx1ZSB3aXRoIGN1c3RvbSBoYW5kbGluZyBmb3IgTWFwIGFuZCBCdWZmZXIgb2JqZWN0c1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDYWNoZVZhbHVlKGpzb25TdHJpbmc6IHN0cmluZyk6IGFueSB7XG4gIHJldHVybiBKU09OLnBhcnNlKGpzb25TdHJpbmcsIChfa2V5LCB2YWwpID0+IHtcbiAgICAvLyBSZXN0b3JlIE1hcCBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlclxuICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiB2YWwuX190eXBlID09PSBcIk1hcFwiKSB7XG4gICAgICByZXR1cm4gbmV3IE1hcChPYmplY3QuZW50cmllcyh2YWwuZGF0YSkpO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIEJ1ZmZlciBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlciAob3VyIGN1c3RvbSBmb3JtYXQpXG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmIHZhbC5fX3R5cGUgPT09IFwiQnVmZmVyXCIpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWwuZGF0YSk7XG4gICAgfVxuICAgIC8vIFJlc3RvcmUgQnVmZmVyIG9iamVjdHMgdGhhdCB3ZXJlIHNlcmlhbGl6ZWQgd2l0aCBOb2RlLmpzIGRlZmF1bHQgQnVmZmVyLnRvSlNPTigpIGZvcm1hdFxuICAgIC8vIFRoaXMgaGFuZGxlcyBsZWdhY3kgY2FjaGUgZW50cmllcyBvciBydW50aW1lLWdlbmVyYXRlZCBlbnRyaWVzXG4gICAgaWYgKFxuICAgICAgdmFsICYmXG4gICAgICB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmXG4gICAgICB2YWwudHlwZSA9PT0gXCJCdWZmZXJcIiAmJlxuICAgICAgQXJyYXkuaXNBcnJheSh2YWwuZGF0YSlcbiAgICApIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWwuZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB2YWw7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBzYWZlbHkgZXh0cmFjdCB0YWdzIGZyb20gY29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGFncyhcbiAgY3R4OiBTZXRJbmNyZW1lbnRhbEZldGNoQ2FjaGVDb250ZXh0IHwgU2V0SW5jcmVtZW50YWxSZXNwb25zZUNhY2hlQ29udGV4dCxcbik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIFwidGFnc1wiIGluIGN0eCA/IGN0eC50YWdzIDogdW5kZWZpbmVkO1xufVxuIl19
282
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9jYWNoZS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE4REEsa0RBS0M7QUFnQkQsMENBd0JDO0FBYUQsMERBY0M7QUFtREQsMENBb0RDO0FBc0NELGtEQVVDO0FBY0QsZ0NBS0M7QUF1QkQsMEJBSUM7QUFwVUQsa0RBQW1EO0FBRW5EOzs7R0FHRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQVU7SUFDakMsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHlFQUF5RTtJQUN6RSx3RUFBd0U7SUFDeEUseURBQXlEO0lBQ3pELElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzNCLE9BQU87WUFDTCxNQUFNLEVBQUUsUUFBUTtZQUNoQixNQUFNLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7U0FDakMsQ0FBQztJQUNKLENBQUM7SUFFRCxtQ0FBbUM7SUFDbkMsSUFBSSxLQUFLLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDekIsTUFBTSxPQUFPLEdBQXdCLEVBQUUsQ0FBQztRQUN4QyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTztZQUNMLE1BQU0sRUFBRSxLQUFLO1lBQ2IsSUFBSSxFQUFFLE9BQU87U0FDZCxDQUFDO0lBQ0osQ0FBQztJQUVELDZCQUE2QjtJQUM3QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixPQUFPLEtBQUss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T0FBTyxDQUNyQixHQUF5RTtJQUV6RSxPQUFPLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgU2hhcmVkIGNhY2hlIHV0aWxpdHkgZnVuY3Rpb25zXG4qL1xuaW1wb3J0IHR5cGUge1xuICBTZXRJbmNyZW1lbnRhbEZldGNoQ2FjaGVDb250ZXh0LFxuICBTZXRJbmNyZW1lbnRhbFJlc3BvbnNlQ2FjaGVDb250ZXh0LFxufSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZVwiO1xuaW1wb3J0IHsgaGFzUGF0aFByZWZpeCB9IGZyb20gXCIuLi91dGlscy9iYXNlLXBhdGhcIjtcblxuLyoqXG4gKiBQcmUtcHJvY2VzcyB2YWx1ZSB0byBjb252ZXJ0IEJ1ZmZlcnMgYW5kIE1hcHMgYmVmb3JlIEpTT04uc3RyaW5naWZ5XG4gKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIEJ1ZmZlci50b0pTT04oKSBpcyBjYWxsZWQgYmVmb3JlIHJlcGxhY2VyIGZ1bmN0aW9uc1xuICovXG5mdW5jdGlvbiBwcmVwcm9jZXNzVmFsdWUodmFsdWU6IGFueSk6IGFueSB7XG4gIC8vIEhhbmRsZSBudWxsL3VuZGVmaW5lZFxuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgQnVmZmVyIHRvIG91ciBjdXN0b20gZm9ybWF0LiBiYXNlNjQsIG5vdCB0aGUgYXJyYXkgb2YgcGVyLWJ5dGVcbiAgLy8gaW50ZWdlcnMgdGhpcyB1c2VkIHRvIHdyaXRlIChhbmQgdGhhdCBgQnVmZmVyLnRvSlNPTigpYCB3cml0ZXMpIOKAlCBzZWVcbiAgLy8ge0BsaW5rIHBhcnNlQ2FjaGVWYWx1ZX0gZm9yIHdoeSB0aGF0IG1hdHRlcmVkIHNvIG11Y2guXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogXCJCdWZmZXJcIixcbiAgICAgIGJhc2U2NDogdmFsdWUudG9TdHJpbmcoXCJiYXNlNjRcIiksXG4gICAgfTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgTWFwIHRvIG91ciBjdXN0b20gZm9ybWF0XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkge1xuICAgIGNvbnN0IGVudHJpZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbF0gb2YgdmFsdWUuZW50cmllcygpKSB7XG4gICAgICBlbnRyaWVzW2tleV0gPSBwcmVwcm9jZXNzVmFsdWUodmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogXCJNYXBcIixcbiAgICAgIGRhdGE6IGVudHJpZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJlY3Vyc2l2ZWx5IHByb2Nlc3MgYXJyYXlzXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5tYXAoKGl0ZW0pID0+IHByZXByb2Nlc3NWYWx1ZShpdGVtKSk7XG4gIH1cblxuICAvLyBSZWN1cnNpdmVseSBwcm9jZXNzIG9iamVjdHNcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IHByb2Nlc3NlZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgIHByb2Nlc3NlZFtrZXldID0gcHJlcHJvY2Vzc1ZhbHVlKHZhbCk7XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzZWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gcHJpbWl0aXZlcyBhcy1pc1xuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogU2VyaWFsaXplIGNhY2hlIHZhbHVlIHdpdGggY3VzdG9tIGhhbmRsaW5nIGZvciBNYXAgYW5kIEJ1ZmZlciBvYmplY3RzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVDYWNoZVZhbHVlKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAvLyBQcmUtcHJvY2VzcyB0byBjb252ZXJ0IEJ1ZmZlcnMgYW5kIE1hcHMgYmVmb3JlIEpTT04uc3RyaW5naWZ5XG4gIC8vIFRoaXMgZW5zdXJlcyBCdWZmZXIudG9KU09OKCkgZG9lc24ndCBpbnRlcmZlcmVcbiAgY29uc3QgcHJvY2Vzc2VkID0gcHJlcHJvY2Vzc1ZhbHVlKHZhbHVlKTtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHByb2Nlc3NlZCk7XG59XG5cbi8qKlxuICogUGFyc2UgY2FjaGUgdmFsdWUgd2l0aCBjdXN0b20gaGFuZGxpbmcgZm9yIE1hcCBhbmQgQnVmZmVyIG9iamVjdHNcbiAqXG4gKiBCdWZmZXJzIGFyZSByZWFkIGJhY2sgZnJvbSBiYXNlNjQgd2hlbiB0aGF0IGlzIGhvdyB0aGV5IHdlcmUgd3JpdHRlbiwgYW5kIGZyb21cbiAqIGFuIGFycmF5IG9mIHBlci1ieXRlIGludGVnZXJzIHdoZW4gdGhleSB3ZXJlIG5vdC4gVGhhdCBhcnJheSBpcyB0aGUgZm9ybWF0XG4gKiBgQnVmZmVyLnRvSlNPTigpYCBwcm9kdWNlcyBhbmQgdGhlIG9uZSB0aGlzIGNvZGUgdXNlZCB0byB3cml0ZSwgYW5kIGl0IGlzXG4gKiBydWlub3VzIGZvciBhIHBhZ2Ugd2l0aCBhIGxhcmdlIHBheWxvYWQ6IGEgMSBNaUIgcHJlcmVuZGVyIGJlY2FtZSB+MyBNaUIgb2ZcbiAqIEpTT04gdGV4dCwgYW4gMTEuNiBNaUIgY2FjaGUgZW50cnkgb25jZSBodG1sIGFuZCB0aGUgcGVyLXNlZ21lbnQgY29waWVzIGFyZVxuICogY291bnRlZCwgYW5kIOKAlCBiZWNhdXNlIGBKU09OLnBhcnNlYCdzIHJldml2ZXIgcnVucyBmb3IgKmV2ZXJ5IGFycmF5IGVsZW1lbnQqIOKAlFxuICogdXB3YXJkcyBvZiB0aHJlZSBtaWxsaW9uIHJldml2ZXIgY2FsbHMgdG8gcmVhZCBvbmUgcGFnZS4gTWVhc3VyZWQgYWdhaW5zdCBhXG4gKiBkZXBsb3ltZW50OiA0LjhzIG9mIExhbWJkYSB0aW1lIHRvIGFuc3dlciBhIDEgTWlCIHNlZ21lbnQgcHJlZmV0Y2gsIGFnYWluc3RcbiAqIDQ1bXMgZm9yIGEgc21hbGwgb25lIGZyb20gdGhlIHNhbWUgY2FjaGUuIGJhc2U2NCBpcyA0LzMgdGhlIGJ5dGVzIHJhdGhlciB0aGFuXG4gKiB+M3gsIGFuZCBgQnVmZmVyLmZyb20oc3RyLCBcImJhc2U2NFwiKWAgaXMgb25lIG5hdGl2ZSBjYWxsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDYWNoZVZhbHVlKGpzb25TdHJpbmc6IHN0cmluZyk6IGFueSB7XG4gIHJldHVybiBKU09OLnBhcnNlKGpzb25TdHJpbmcsIChfa2V5LCB2YWwpID0+IHtcbiAgICAvLyBSZXN0b3JlIE1hcCBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlclxuICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiB2YWwuX190eXBlID09PSBcIk1hcFwiKSB7XG4gICAgICByZXR1cm4gbmV3IE1hcChPYmplY3QuZW50cmllcyh2YWwuZGF0YSkpO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIEJ1ZmZlciBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlciAob3VyIGN1c3RvbSBmb3JtYXQpXG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmIHZhbC5fX3R5cGUgPT09IFwiQnVmZmVyXCIpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsLmJhc2U2NCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IEJ1ZmZlci5mcm9tKHZhbC5iYXNlNjQsIFwiYmFzZTY0XCIpXG4gICAgICAgIDogQnVmZmVyLmZyb20odmFsLmRhdGEpO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIEJ1ZmZlciBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggTm9kZS5qcyBkZWZhdWx0IEJ1ZmZlci50b0pTT04oKSBmb3JtYXRcbiAgICAvLyBUaGlzIGhhbmRsZXMgbGVnYWN5IGNhY2hlIGVudHJpZXMgb3IgcnVudGltZS1nZW5lcmF0ZWQgZW50cmllc1xuICAgIGlmIChcbiAgICAgIHZhbCAmJlxuICAgICAgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgdmFsLnR5cGUgPT09IFwiQnVmZmVyXCIgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkodmFsLmRhdGEpXG4gICAgKSB7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsLmRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsO1xuICB9KTtcbn1cblxuLyoqXG4gKiBUaGUgY2FjaGUga2V5IGEgcHJlcmVuZGVyZWQgcm91dGUncyBzZWVkZWQgZW50cnkgaGFzIHRvIGJlIHdyaXR0ZW4gdW5kZXIuXG4gKlxuICogYGN0eC5vdXRwdXRzLnByZXJlbmRlcnNbXS5wYXRobmFtZWAgaXMgdGhlICpVUkwqIHRoZSBwYWdlIGlzIHNlcnZlZCBhdCwgc28gaXRcbiAqIGNhcnJpZXMgdGhlIGFwcCdzIGBiYXNlUGF0aGAuIFRoZSBrZXkgdGhlIHNlcnZlciBsYXRlciBsb29rcyBlbnRyaWVzIHVwIHVuZGVyXG4gKiBpcyB0aGUgcm91dGUsIHdoaWNoIGRvZXMgbm90IOKAlCBOZXh0LmpzIHN0cmlwcyBgYmFzZVBhdGhgIGJlZm9yZSByb3V0aW5nLCBzbyB0aGVcbiAqIGNhY2hlIGhhbmRsZXIgbmV2ZXIgc2VlcyBpdCBhdCByZXF1ZXN0IHRpbWUuIFNlZWRpbmcgYC9wcm9kL3NzZy8xYCB2ZXJiYXRpbVxuICogdGhlcmVmb3JlIHdyaXRlcyBgPGJ1aWxkSWQ+L3Byb2Qvc3NnLzEuanNvbmAgd2hpbGUgdGhlIHNlcnZlciBhc2tzIGZvclxuICogYDxidWlsZElkPi9zc2cvMS5qc29uYDogZXZlcnkgYnVpbGQtdGltZSBwcmVyZW5kZXIgaXMgYSBNSVNTIHRoYXQgcmUtcmVuZGVycyBvblxuICogZmlyc3QgcmVxdWVzdCwgYW5kIHRoZSBwYWdlIGlzIG9ubHkgXCJzdGF0aWNcIiBmcm9tIHRoZSBzZWNvbmQgdmlzaXQgb253YXJkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFxuICBwYXRobmFtZTogc3RyaW5nLFxuICBiYXNlUGF0aDogc3RyaW5nLFxuKTogc3RyaW5nIHtcbiAgLy8gTWF0Y2hpbmcgb24gYSBwYXRoIGJvdW5kYXJ5IHNvIGEgc2libGluZyByb3V0ZSBsaWtlIGAvcHJvZHVjdGlvbmAgaXMgbm90XG4gIC8vIHJlYWQgYXMgYmFzZVBhdGggYC9wcm9kYCBwbHVzIGB1Y3Rpb25gLlxuICBjb25zdCByb3V0ZSA9IChcbiAgICBoYXNQYXRoUHJlZml4KHBhdGhuYW1lLCBiYXNlUGF0aClcbiAgICAgID8gcGF0aG5hbWUuc2xpY2UoYmFzZVBhdGgubGVuZ3RoKVxuICAgICAgOiBwYXRobmFtZVxuICApXG4gICAgLy8gTGVhZGluZyBzbGFzaGVzIHdvdWxkIG1ha2UgYW4gUzMga2V5IHdpdGggYW4gZW1wdHkgZmlyc3Qgc2VnbWVudC5cbiAgICAucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgcmV0dXJuIHJvdXRlID09PSBcIlwiID8gXCJpbmRleFwiIDogcm91dGU7XG59XG5cbi8qKiBUaGUgb3V0cHV0cyBvbmUgcm91dGUgY29udHJpYnV0ZXMgdG8gYGN0eC5vdXRwdXRzLnByZXJlbmRlcnNgLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVyZW5kZXJWYXJpYW50czxUPiB7XG4gIC8qKiBUaGUgSFRNTCByZW5kZXIuIEl0cyBwYXRobmFtZSBpcyB0aGUgcm91dGUsIHdpdGggbm8gc3VmZml4LiAqL1xuICBodG1sPzogVDtcbiAgLyoqIFRoZSBmbGlnaHQgcGF5bG9hZCwgYnVpbHQgYXMgYDxyb3V0ZT4ucnNjYCDigJQgYnV0IHNlZSB7QGxpbmsgZ3JvdXBQcmVyZW5kZXJzfS4gKi9cbiAgcnNjPzogVDtcbiAgLyoqIFBlci1zZWdtZW50IGZsaWdodCBwYXlsb2FkcywgdW5kZXIgYDxyb3V0ZT4uc2VnbWVudHMvYC4gKi9cbiAgc2VnbWVudHM6IFRbXTtcbiAgLyoqIEEgUGFnZXMgUm91dGVyIHJvdXRlJ3MgYHBhZ2VEYXRhYCwgYnVpbHQgYXMgaXRzIGAvX25leHQvZGF0YS9gIHJvdXRlLiAqL1xuICBkYXRhPzogVDtcbn1cblxuY29uc3QgSU5ERVhfU1VGRklYID0gXCIvaW5kZXhcIjtcblxuLyoqXG4gKiBBIFBhZ2VzIFJvdXRlciBkYXRhIHJvdXRlOiBgL19uZXh0L2RhdGEvPGJ1aWxkSWQ+LzxwYWdlPi5qc29uYCwgb3B0aW9uYWxseVxuICogYmVoaW5kIGEgYGJhc2VQYXRoYCAoYG5vcm1hbGl6ZVBhdGhuYW1lYCBpbiBOZXh0LmpzJ3MgYGJ1aWxkLWNvbXBsZXRlYCBwcmVmaXhlc1xuICogZXZlcnkgb3V0cHV0IHBhdGhuYW1lLCB0aGlzIG9uZSBpbmNsdWRlZCkuXG4gKlxuICogQ2FwdHVyZSAxIGlzIHRoYXQgcHJlZml4IGFuZCBjYXB0dXJlIDIgdGhlIHBhZ2UgcGF0aCB3aXRob3V0IGl0cyBgLmpzb25gLCBzb1xuICogYC9wcm9kL19uZXh0L2RhdGEvYWJjMTIzL2Jsb2cvaGVsbG8uanNvbmAgcmVjb21wb3NlcyB0byBgL3Byb2QvYmxvZy9oZWxsb2AuXG4gKi9cbmNvbnN0IFBBR0VTX0RBVEFfUEFUSE5BTUUgPSAvXiguKilcXC9fbmV4dFxcL2RhdGFcXC9bXi9dK1xcLyguKylcXC5qc29uJC87XG5cbi8qKlxuICogQ29sbGVjdCBgY3R4Lm91dHB1dHMucHJlcmVuZGVyc2AgaW50byBvbmUgZW50cnkgcGVyIHJvdXRlLlxuICpcbiAqIE5leHQuanMgZW1pdHMgdXAgdG8gdGhyZWUgc2hhcGVzIHBlciBwcmVyZW5kZXJlZCBBcHAgUm91dGVyIHJvdXRlIOKAlCBgL2Jsb2cvaGVsbG9gLFxuICogYC9ibG9nL2hlbGxvLnJzY2AsIGFuZCBgL2Jsb2cvaGVsbG8uc2VnbWVudHMvKi5zZWdtZW50LnJzY2Ag4oCUIGFuZCBhIGNhY2hlIGVudHJ5XG4gKiBuZWVkcyBhbGwgb2YgdGhlbSB0b2dldGhlciwgc28gdGhleSBoYXZlIHRvIGJlIGdyb3VwZWQgYnkgcm91dGUgYmVmb3JlIGFueXRoaW5nXG4gKiBjYW4gYmUgc2VlZGVkLiBBIFBhZ2VzIFJvdXRlciByb3V0ZSBlbWl0cyB0d286IHRoZSBIVE1MLCBhbmQgaXRzIGBwYWdlRGF0YWAgYXRcbiAqIHRoZSByb3V0ZSdzIGAvX25leHQvZGF0YS88YnVpbGRJZD4vPHBhZ2U+Lmpzb25gIHBhdGhuYW1lXG4gKiAoe0BsaW5rIFBBR0VTX0RBVEFfUEFUSE5BTUV9KS4gVGhhdCBvbmUgaXMgbm90IGEgc3VmZml4IG9mIHRoZSBwYWdlJ3Mgb3duXG4gKiBwYXRobmFtZSwgc28gaXQgaXMgbWF0Y2hlZCByYXRoZXIgdGhhbiBzdHJpcHBlZC5cbiAqXG4gKiBUaGUgb25lIGNhc2UgdGhhdCBpcyBub3QgYSBzdWZmaXggc3RyaXAgaXMgdGhlICoqcm9vdCByb3V0ZSoqLCB3aGljaCBjYW5ub3QgYmVcbiAqIG5hbWVkIGAvLnJzY2A6IGl0cyBwYXlsb2FkcyBhcmUgZW1pdHRlZCB1bmRlciBgL2luZGV4LnJzY2AgYW5kXG4gKiBgL2luZGV4LnNlZ21lbnRzL2Agd2hpbGUgaXRzIEhUTUwgc3RheXMgYXQgYC9gIChvciBhdCB0aGUgYGJhc2VQYXRoYCwgZS5nLlxuICogYC9wcm9kYCBhbmQgYC9wcm9kL2luZGV4LnJzY2ApLiBSZWNvbnN0cnVjdGluZyBuYW1lcyBieSBjb25jYXRlbmF0aW9uIHRoZXJlZm9yZVxuICogc2lsZW50bHkgbG9zZXMgdGhlIGhvbWUgcGFnZSdzIGByc2NEYXRhYCDigJQgYW5kIHdpdGggYSBgYmFzZVBhdGhgIGFsc28gaXRzXG4gKiBgc2VnbWVudERhdGFgLCBiZWNhdXNlIGAvcHJvZGAgYW5kIGAvcHJvZC9pbmRleGAgZ3JvdXAgYXBhcnQuIFRoYXQgaXMgbm90IGFcbiAqIGNvc21ldGljIGdhcDogYGFwcC1wYWdlLXJ1bnRpbWUuanNgIGFuc3dlcnMgYW4gUlNDIHJlcXVlc3QgZm9yIGFuIGVudHJ5IHdpdGggbm9cbiAqIGByc2NEYXRhYCBieSBjaGVja2luZyBgY2FjaGVkRGF0YS5odG1sLmNvbnRlbnRUeXBlYCwgYW5kIHVuZGVyIGBjYWNoZUNvbXBvbmVudHNgXG4gKiBzZW5kcyBhbiBlbXB0eSBgNDA0YC4gRXZlcnkgY2xpZW50LXNpZGUgbmF2aWdhdGlvbiB0byBgL2AgYnJlYWtzLlxuICpcbiAqIFRoZSByZW1hcCBpcyBjb25kaXRpb25hbCByYXRoZXIgdGhhbiB1bmNvbmRpdGlvbmFsIHNvIHRoYXQgYW4gYXBwIHdpdGggYSByZWFsXG4gKiBwYWdlIGF0IGBhcHAvaW5kZXgvcGFnZS50c3hgIOKAlCB3aG9zZSBIVE1MIHByZXJlbmRlciBnZW51aW5lbHkgaXMgYC9pbmRleGAg4oCUIGtlZXBzXG4gKiBpdHMgb3duIGdyb3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBQcmVyZW5kZXJzPFQgZXh0ZW5kcyB7IHBhdGhuYW1lOiBzdHJpbmcgfT4oXG4gIHByZXJlbmRlcnM6IFRbXSxcbik6IE1hcDxzdHJpbmcsIFByZXJlbmRlclZhcmlhbnRzPFQ+PiB7XG4gIGNvbnN0IGh0bWxQYXRobmFtZXMgPSBuZXcgU2V0KFxuICAgIHByZXJlbmRlcnNcbiAgICAgIC5tYXAoKHApID0+IHAucGF0aG5hbWUpXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAocCkgPT5cbiAgICAgICAgICAhcC5lbmRzV2l0aChcIi5yc2NcIikgJiZcbiAgICAgICAgICAhcC5pbmNsdWRlcyhcIi5zZWdtZW50cy9cIikgJiZcbiAgICAgICAgICAhUEFHRVNfREFUQV9QQVRITkFNRS50ZXN0KHApLFxuICAgICAgKSxcbiAgKTtcbiAgY29uc3QgZ3JvdXBzID0gbmV3IE1hcDxzdHJpbmcsIFByZXJlbmRlclZhcmlhbnRzPFQ+PigpO1xuXG4gIGNvbnN0IHZhcmlhbnRzRm9yID0gKGJhc2U6IHN0cmluZyk6IFByZXJlbmRlclZhcmlhbnRzPFQ+ID0+IHtcbiAgICBsZXQgdmFyaWFudHMgPSBncm91cHMuZ2V0KGJhc2UpO1xuICAgIGlmICghdmFyaWFudHMpIHtcbiAgICAgIHZhcmlhbnRzID0geyBzZWdtZW50czogW10gfTtcbiAgICAgIGdyb3Vwcy5zZXQoYmFzZSwgdmFyaWFudHMpO1xuICAgIH1cbiAgICByZXR1cm4gdmFyaWFudHM7XG4gIH07XG5cbiAgLyoqIGAvaW5kZXgucnNjYCBiZWxvbmdzIHRvIGAvYCwgYC9wcm9kL2luZGV4LnJzY2AgdG8gYC9wcm9kYC4gKi9cbiAgY29uc3Qgcm91dGVPZiA9IChiYXNlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgIGlmIChiYXNlLmVuZHNXaXRoKElOREVYX1NVRkZJWCkgJiYgIWh0bWxQYXRobmFtZXMuaGFzKGJhc2UpKSB7XG4gICAgICBjb25zdCBwYXJlbnQgPSBiYXNlLnNsaWNlKDAsIC1JTkRFWF9TVUZGSVgubGVuZ3RoKSB8fCBcIi9cIjtcbiAgICAgIGlmIChodG1sUGF0aG5hbWVzLmhhcyhwYXJlbnQpKSB7XG4gICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBiYXNlO1xuICB9O1xuXG4gIGZvciAoY29uc3QgcHJlcmVuZGVyIG9mIHByZXJlbmRlcnMpIHtcbiAgICBjb25zdCB7IHBhdGhuYW1lIH0gPSBwcmVyZW5kZXI7XG4gICAgY29uc3QgZGF0YVJvdXRlID0gUEFHRVNfREFUQV9QQVRITkFNRS5leGVjKHBhdGhuYW1lKTtcbiAgICBpZiAoZGF0YVJvdXRlKSB7XG4gICAgICB2YXJpYW50c0Zvcihyb3V0ZU9mKGAke2RhdGFSb3V0ZVsxXX0vJHtkYXRhUm91dGVbMl19YCkpLmRhdGEgPSBwcmVyZW5kZXI7XG4gICAgfSBlbHNlIGlmIChwYXRobmFtZS5pbmNsdWRlcyhcIi5zZWdtZW50cy9cIikpIHtcbiAgICAgIHZhcmlhbnRzRm9yKHJvdXRlT2YocGF0aG5hbWUuc3BsaXQoXCIuc2VnbWVudHMvXCIpWzBdKSkuc2VnbWVudHMucHVzaChcbiAgICAgICAgcHJlcmVuZGVyLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHBhdGhuYW1lLmVuZHNXaXRoKFwiLnJzY1wiKSkge1xuICAgICAgdmFyaWFudHNGb3Iocm91dGVPZihwYXRobmFtZS5zbGljZSgwLCAtXCIucnNjXCIubGVuZ3RoKSkpLnJzYyA9IHByZXJlbmRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyaWFudHNGb3IocGF0aG5hbWUpLmh0bWwgPSBwcmVyZW5kZXI7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdyb3Vwcztcbn1cblxuLyoqXG4gKiBIZWFkZXJzIHRoYXQgbXVzdCBub3QgYmUgc2VlZGVkIGludG8gYW4gYEFQUF9QQUdFYCBjYWNoZSBlbnRyeSwgZXZlbiB0aG91Z2ggdGhlXG4gKiBhZGFwdGVyIG91dHB1dCBsaXN0cyB0aGVtIGluIGBmYWxsYmFjay5pbml0aWFsSGVhZGVyc2AuXG4gKlxuICogYGluaXRpYWxIZWFkZXJzYCBkZXNjcmliZXMgaG93IGEgcGxhdGZvcm0gc2hvdWxkIHNlcnZlIHRoZSBwcmVyZW5kZXJlZCAqZmlsZSpcbiAqIHN0cmFpZ2h0IG9mZiBhIENETi4gQSBjYWNoZSBlbnRyeSBpcyBhIGRpZmZlcmVudCB0aGluZzogYGFwcC1wYWdlLXJ1bnRpbWUuanNgXG4gKiBgYXBwZW5kSGVhZGVyYHMgYGNhY2hlZERhdGEuaGVhZGVyc2Agb250byB0aGUgcmVzcG9uc2UgYW5kICp0aGVuKiBzZXJ2ZXMgdGhlXG4gKiB2YXJpYW50IHRoZSByZXF1ZXN0IGFjdHVhbGx5IGFza2VkIGZvciwgc28gYW55dGhpbmcgcHJlc2VudGF0aW9uYWwgaW4gdGhlcmUgaXNcbiAqIGVpdGhlciB3cm9uZyBvciBkb3VibGVkLiBBdCByZXF1ZXN0IHRpbWUgTmV4dC5qcyBzdG9yZXMgb25seSB3aGF0IHRoZSByZW5kZXJcbiAqIHB1dCBpbiBgbWV0YWRhdGEuaGVhZGVyc2Ag4oCUIGB4LW5leHRqcy1zdGFsZS10aW1lYCwgYHgtbmV4dC1jYWNoZS10YWdzYCwgYW5kXG4gKiB3aGF0ZXZlciB0aGUgYXBwIHNldCB0aHJvdWdoIGBoZWFkZXJzKClgL2Bjb29raWVzKClgIOKAlCBhbmQgbmV2ZXIgdGhlc2UgZm91ci5cbiAqXG4gKiBgY29udGVudC10eXBlYCBpcyB0aGUgb25lIHRoYXQgYWN0dWFsbHkgYnJlYWtzLiBgc2VuZC1wYXlsb2FkLmpzYCBzZXRzIHRoZSB0eXBlXG4gKiBvbmx5IHdoZW4gdGhlIHJlc3BvbnNlIGRvZXMgbm90IGFscmVhZHkgaGF2ZSBvbmVcbiAqIChgaWYgKCFyZXMuZ2V0SGVhZGVyKCdDb250ZW50LVR5cGUnKSAmJiByZXN1bHQuY29udGVudFR5cGUpYCksIHNvIGEgc2VlZGVkXG4gKiBgdGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04YCBtYWtlcyBldmVyeSBSU0MgcmVxdWVzdCB0byBhIHByZXJlbmRlcmVkIHBhZ2UgYW5zd2VyXG4gKiB0aGUgZmxpZ2h0IHBheWxvYWQgbGFiZWxlZCBhcyBIVE1MLiBUaGUgY2xpZW50IHJvdXRlciByZWplY3RzIHRoYXQsIGFuZCBzbyBkb2VzXG4gKiBOZXh0LmpzIGl0c2VsZjogYGNyZWF0ZVJlZGlyZWN0UmVuZGVyUmVzdWx0YCBjaGVja3MgdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGVcbiAqIHN1Yi1yZXNwb25zZSBpdCBmZXRjaGVzIHRvIHN0cmVhbSBhbiBhY3Rpb24gYHJlZGlyZWN0KClgLCBhbmQgb24gYSBtaXNtYXRjaFxuICogY2FuY2VscyB0aGUgYm9keSBhbmQgcmV0dXJucyBhbiBlbXB0eSByZXN1bHQuXG4gKlxuICogYHZhcnlgLCBgeC1uZXh0anMtcHJlcmVuZGVyYCwgYW5kIGB4LW5leHRqcy1wb3N0cG9uZWRgIGFyZSBhbGwgc2V0IGJ5IHRoZVxuICogZW50cnlwb2ludCBpdHNlbGYsIHNvIHNlZWRpbmcgdGhlbSBvbmx5IHByb2R1Y2VzIHR3byBvZiBlYWNoLlxuICpcbiAqIGBBUFBfUk9VVEVgIGVudHJpZXMgYXJlIGRlbGliZXJhdGVseSAqbm90KiBmaWx0ZXJlZDogYSByb3V0ZSBoYW5kbGVyJ3NcbiAqIGBjb250ZW50LXR5cGVgIGlzIHBhcnQgb2YgaXRzIGNhY2hlZCByZXNwb25zZSwgYW5kIGBhcHAtcm91dGUuanNgIHJlcGxheXMgdGhvc2VcbiAqIGhlYWRlcnMgdmVyYmF0aW0uXG4gKi9cbmNvbnN0IE5PTl9DQUNIRUFCTEVfQVBQX1BBR0VfSEVBREVSUyA9IG5ldyBTZXQoW1xuICBcImNvbnRlbnQtdHlwZVwiLFxuICBcInZhcnlcIixcbiAgXCJ4LW5leHRqcy1wcmVyZW5kZXJcIixcbiAgXCJ4LW5leHRqcy1wb3N0cG9uZWRcIixcbl0pO1xuXG4vKiogU2VlIHtAbGluayBOT05fQ0FDSEVBQkxFX0FQUF9QQUdFX0hFQURFUlN9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcFBhZ2VDYWNoZUhlYWRlcnM8VD4oXG4gIGluaXRpYWxIZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBUPixcbik6IFJlY29yZDxzdHJpbmcsIFQ+IHtcbiAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgVD4gPSB7fTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGluaXRpYWxIZWFkZXJzKSkge1xuICAgIGlmICghTk9OX0NBQ0hFQUJMRV9BUFBfUEFHRV9IRUFERVJTLmhhcyhuYW1lLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICBoZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBoZWFkZXJzO1xufVxuXG4vKiogYE5FWFRfQ0FDSEVfVEFHU19IRUFERVJgLCBpbmxpbmVkIHNvIHRoaXMgZmlsZSBpbXBvcnRzIG5vIE5leHQuanMgaW50ZXJuYWxzLiAqL1xuY29uc3QgTkVYVF9DQUNIRV9UQUdTX0hFQURFUiA9IFwieC1uZXh0LWNhY2hlLXRhZ3NcIjtcblxuLyoqXG4gKiBUaGUgdGFncyBhIGNhY2hlIHZhbHVlJ3MgcmVuZGVyIHdhcyB0YWdnZWQgd2l0aCwgYXMgTmV4dC5qcyByZWNvcmRzIHRoZW06IGluXG4gKiBpdHMgYHgtbmV4dC1jYWNoZS10YWdzYCBoZWFkZXIsIGNvbW1hIHNlcGFyYXRlZCwgaW5jbHVkaW5nIHRoZSBpbXBsaWNpdFxuICogYF9OX1RfL+KApmAgcGF0aCBjaGFpbiBgcmV2YWxpZGF0ZVBhdGhgIHVzZXMuIE9uZSBwYXJzZXIgZm9yIHRoZSBidWlsZCdzIHRhZ1xuICogbWFuaWZlc3QgYW5kIHRoZSBydW50aW1lJ3MgbWFwcGluZyByb3dzLCB3aGljaCBoYXZlIHRvIGFncmVlLlxuICpcbiAqIGB2YWx1ZWAgaXMgYHVua25vd25gIGJlY2F1c2UgaXQgYXJyaXZlcyBib3RoIGFzIGEgc3RvcmVkIGVudHJ5IHJlYWQgYmFjayBmcm9tXG4gKiBTMyBhbmQgYXMgdGhlIGBJbmNyZW1lbnRhbENhY2hlVmFsdWVgIHVuaW9uOyBvbmx5IHNvbWUgbWVtYmVycyBoYXZlIGhlYWRlcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoZWFkZXJUYWdzKHZhbHVlOiB1bmtub3duKTogc3RyaW5nW10ge1xuICBjb25zdCBoZWFkZXJzID0gKHZhbHVlIGFzIHsgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0gfCBudWxsKVxuICAgID8uaGVhZGVycztcbiAgY29uc3QgaGVhZGVyID0gaGVhZGVycz8uW05FWFRfQ0FDSEVfVEFHU19IRUFERVJdO1xuICByZXR1cm4gdHlwZW9mIGhlYWRlciA9PT0gXCJzdHJpbmdcIiA/IGhlYWRlci5zcGxpdChcIixcIikuZmlsdGVyKEJvb2xlYW4pIDogW107XG59XG5cbi8qKlxuICogTmFtZSBvZiB0aGUgZmlsZSB0aGUgYWRhcHRlciB3cml0ZXMgaW50byB0aGUgaW5pdCBjYWNoZSBkaXJlY3RvcnkgbWFwcGluZyBlYWNoXG4gKiBjYWNoZSB0YWcgdG8gdGhlIGNhY2hlIGtleXMgb2YgdGhlIGJ1aWxkLXRpbWUgcHJlcmVuZGVycyBjYXJyeWluZyBpdC5cbiAqXG4gKiBJdCByaWRlcyB0byBTMyB3aXRoIHRoZSByZXN0IG9mIHRoZSBpbml0IGNhY2hlLCBhbmQgYFMzQ2FjaGVIYW5kbGVyYCdzXG4gKiBgcmV2YWxpZGF0ZVRhZ2AgcmVhZHMgaXQgYWxvbmdzaWRlIHRoZSBgdGFnI2NhY2hlS2V5YCByb3dzIGEgcnVudGltZSBgc2V0YFxuICogd3JpdGVzLiBXaXRob3V0IGl0IGByZXZhbGlkYXRlVGFnYCBrbm93cyBhIHByZXJlbmRlciBpcyBzdGFsZSAoc2VlXG4gKiBgY2hlY2tJZlJldmFsaWRhdGVkYCkgYnV0IG5vdCB3aGljaCBDbG91ZEZyb250IHBhdGhzIHRvIGludmFsaWRhdGUsIHNvIHRoZSBDRE5cbiAqIGtlZXBzIHNlcnZpbmcgdGhlIG9sZCByZXNwb25zZSB1bnRpbCBpdHMgVFRMIGV4cGlyZXMgLSBhIHllYXIsIGZvciBhXG4gKiBwcmVyZW5kZXIuXG4gKlxuICogVGhlIGxlYWRpbmcgdW5kZXJzY29yZSBrZWVwcyBpdCBjbGVhciBvZiBjYWNoZSBrZXlzLCB3aGljaCBhcmUgcm91dGUgcGF0aHMuXG4gKi9cbmV4cG9ydCBjb25zdCBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVCA9IFwiX2Nkay1uZXh0anMtdGFnLW1hbmlmZXN0Lmpzb25cIjtcblxuLyoqIENvbnRlbnRzIG9mIHtAbGluayBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVH06IHRhZyAtPiBpbml0IGNhY2hlIGtleXMuICovXG5leHBvcnQgdHlwZSBJbml0Q2FjaGVUYWdNYW5pZmVzdCA9IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPjtcblxuLyoqXG4gKiBIZWxwZXIgdG8gc2FmZWx5IGV4dHJhY3QgdGFncyBmcm9tIGNvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRhZ3MoXG4gIGN0eDogU2V0SW5jcmVtZW50YWxGZXRjaENhY2hlQ29udGV4dCB8IFNldEluY3JlbWVudGFsUmVzcG9uc2VDYWNoZUNvbnRleHQsXG4pOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBcInRhZ3NcIiBpbiBjdHggPyBjdHgudGFncyA6IHVuZGVmaW5lZDtcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cache_utils_1 = require("./cache-utils");
4
+ describe("prerenderPathToCacheKey", () => {
5
+ it("drops the leading slash", () => {
6
+ expect((0, cache_utils_1.prerenderPathToCacheKey)("/ssg/1", "")).toBe("ssg/1");
7
+ });
8
+ it("maps the root route to index", () => {
9
+ expect((0, cache_utils_1.prerenderPathToCacheKey)("/", "")).toBe("index");
10
+ });
11
+ /**
12
+ * The regression that made every prerender a MISS on a deployment with a
13
+ * `basePath`: the seed wrote `prod/ssg/1.json` while the server, which sees the
14
+ * path only after Next.js has stripped `basePath`, asked for `ssg/1.json`.
15
+ */
16
+ it("strips the app's basePath", () => {
17
+ expect((0, cache_utils_1.prerenderPathToCacheKey)("/prod/ssg/1", "/prod")).toBe("ssg/1");
18
+ });
19
+ it("maps the basePath root to index", () => {
20
+ expect((0, cache_utils_1.prerenderPathToCacheKey)("/prod", "/prod")).toBe("index");
21
+ });
22
+ it("only strips basePath on a path boundary", () => {
23
+ expect((0, cache_utils_1.prerenderPathToCacheKey)("/production/1", "/prod")).toBe("production/1");
24
+ });
25
+ });
26
+ describe("groupPrerenders", () => {
27
+ const at = (...pathnames) => pathnames.map((pathname) => ({
28
+ pathname,
29
+ }));
30
+ it("groups a route's html, rsc and segment outputs together", () => {
31
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/blog/hello", "/blog/hello.rsc", "/blog/hello.segments/$c$.segment.rsc", "/blog/hello.segments/$c$/__PAGE__.segment.rsc"));
32
+ expect(groups.size).toBe(1);
33
+ const variants = groups.get("/blog/hello");
34
+ expect(variants?.html?.pathname).toBe("/blog/hello");
35
+ expect(variants?.rsc?.pathname).toBe("/blog/hello.rsc");
36
+ expect(variants?.segments).toHaveLength(2);
37
+ });
38
+ /**
39
+ * The regression: the root route's HTML is emitted as `/` but its flight payload
40
+ * as `/index.rsc`, so grouping by a reconstructed `${route}.rsc` left `/` with no
41
+ * `rscData` and every client-side navigation to the home page 404'd.
42
+ */
43
+ it("gives the root route the /index.rsc payload", () => {
44
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/", "/index.rsc", "/index.segments/$c$.segment.rsc"));
45
+ expect(Array.from(groups.keys())).toEqual(["/"]);
46
+ expect(groups.get("/")?.rsc?.pathname).toBe("/index.rsc");
47
+ expect(groups.get("/")?.segments).toHaveLength(1);
48
+ });
49
+ /** With a `basePath` the split is `/prod` vs `/prod/index`. */
50
+ it("gives the basePath root its /index.rsc payload", () => {
51
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/prod", "/prod/index.rsc", "/prod/index.segments/$c$.segment.rsc"));
52
+ expect(Array.from(groups.keys())).toEqual(["/prod"]);
53
+ expect(groups.get("/prod")?.rsc?.pathname).toBe("/prod/index.rsc");
54
+ expect(groups.get("/prod")?.segments).toHaveLength(1);
55
+ });
56
+ /** An app with a real `app/index/page.tsx` keeps its own group. */
57
+ it("leaves a genuine /index route alone", () => {
58
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/", "/index", "/index.rsc"));
59
+ expect(Array.from(groups.keys()).sort()).toEqual(["/", "/index"]);
60
+ expect(groups.get("/")?.rsc).toBeUndefined();
61
+ expect(groups.get("/index")?.rsc?.pathname).toBe("/index.rsc");
62
+ });
63
+ /** `/nested/index.rsc` with no `/nested` HTML is its own route, not a remap. */
64
+ it("only remaps when the parent really is a prerendered route", () => {
65
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/nested/index.rsc"));
66
+ expect(Array.from(groups.keys())).toEqual(["/nested/index"]);
67
+ });
68
+ it("keeps segments whose route has no other output", () => {
69
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/ppr.segments/$c$.segment.rsc"));
70
+ expect(groups.get("/ppr")?.segments).toHaveLength(1);
71
+ expect(groups.get("/ppr")?.html).toBeUndefined();
72
+ });
73
+ /**
74
+ * A Pages Router route's `pageData` lives at a pathname of its own rather than
75
+ * at a suffix of the page's, so an unmatched one would become a group named
76
+ * `/_next/data/...` - which gets no cache kind, and so silently drops the data
77
+ * every seeded entry needs.
78
+ */
79
+ it("attaches a Pages Router route's /_next/data output", () => {
80
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/blog/hello", "/_next/data/build-abc123/blog/hello.json"));
81
+ expect(Array.from(groups.keys())).toEqual(["/blog/hello"]);
82
+ expect(groups.get("/blog/hello")?.data?.pathname).toBe("/_next/data/build-abc123/blog/hello.json");
83
+ });
84
+ /** The `fallback: true` template, whose data route has no file behind it. */
85
+ it("attaches the data output of a dynamic route's fallback template", () => {
86
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/[slug]", "/_next/data/build-abc123/[slug].json"));
87
+ expect(Array.from(groups.keys())).toEqual(["/[slug]"]);
88
+ expect(groups.get("/[slug]")?.data?.pathname).toBe("/_next/data/build-abc123/[slug].json");
89
+ });
90
+ /** `/index.json` is the root page's data route, the same remap as `/index.rsc`. */
91
+ it("gives the root route its /index.json data output", () => {
92
+ const groups = (0, cache_utils_1.groupPrerenders)(at("/prod", "/prod/_next/data/build-abc123/index.json"));
93
+ expect(Array.from(groups.keys())).toEqual(["/prod"]);
94
+ expect(groups.get("/prod")?.data?.pathname).toBe("/prod/_next/data/build-abc123/index.json");
95
+ });
96
+ });
97
+ describe("appPageCacheHeaders", () => {
98
+ /** Exactly what `onBuildComplete` is handed for a prerendered app page. */
99
+ const initialHeaders = {
100
+ vary: "rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch",
101
+ "content-type": "text/html; charset=utf-8",
102
+ "x-nextjs-stale-time": "300",
103
+ "x-nextjs-prerender": "1",
104
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/page,_N_T_/,_N_T_/index",
105
+ };
106
+ /**
107
+ * The regression: a seeded `content-type: text/html` survives into the response
108
+ * and `send-payload.js` will not overwrite it, so an RSC request to a
109
+ * prerendered page gets the flight payload labeled as HTML.
110
+ */
111
+ it("drops content-type, which would mislabel every RSC response", () => {
112
+ expect((0, cache_utils_1.appPageCacheHeaders)(initialHeaders)).not.toHaveProperty("content-type");
113
+ });
114
+ it("keeps the headers a render would really have stored", () => {
115
+ expect((0, cache_utils_1.appPageCacheHeaders)(initialHeaders)).toEqual({
116
+ "x-nextjs-stale-time": "300",
117
+ "x-next-cache-tags": "_N_T_/layout,_N_T_/page,_N_T_/,_N_T_/index",
118
+ });
119
+ });
120
+ it("drops the headers the entrypoint sets itself, which would double up", () => {
121
+ const headers = (0, cache_utils_1.appPageCacheHeaders)({
122
+ ...initialHeaders,
123
+ "x-nextjs-postponed": "1",
124
+ });
125
+ expect(Object.keys(headers)).not.toContain("vary");
126
+ expect(Object.keys(headers)).not.toContain("x-nextjs-prerender");
127
+ expect(Object.keys(headers)).not.toContain("x-nextjs-postponed");
128
+ });
129
+ it("matches case-insensitively", () => {
130
+ expect((0, cache_utils_1.appPageCacheHeaders)({ "Content-Type": "text/html" })).toEqual({});
131
+ });
132
+ it("passes through anything the app set itself", () => {
133
+ expect((0, cache_utils_1.appPageCacheHeaders)({ "x-custom": "1", "set-cookie": "a=b" })).toEqual({ "x-custom": "1", "set-cookie": "a=b" });
134
+ });
135
+ });
136
+ describe("serializeCacheValue / parseCacheValue", () => {
137
+ it("round-trips a Buffer", () => {
138
+ const value = { rscData: Buffer.from("hello, cache") };
139
+ const restored = (0, cache_utils_1.parseCacheValue)((0, cache_utils_1.serializeCacheValue)(value));
140
+ expect(Buffer.isBuffer(restored.rscData)).toBe(true);
141
+ expect(restored.rscData.toString()).toBe("hello, cache");
142
+ });
143
+ it("round-trips bytes that are not valid UTF-8", () => {
144
+ const value = Buffer.from([0x00, 0xff, 0xfe, 0x80, 0x7f]);
145
+ const restored = (0, cache_utils_1.parseCacheValue)((0, cache_utils_1.serializeCacheValue)({ value })).value;
146
+ expect(restored.equals(value)).toBe(true);
147
+ });
148
+ it("round-trips a Map, including Buffers inside it", () => {
149
+ const value = new Map([["/_index", Buffer.from("segment")]]);
150
+ const restored = (0, cache_utils_1.parseCacheValue)((0, cache_utils_1.serializeCacheValue)({ value })).value;
151
+ expect(restored).toBeInstanceOf(Map);
152
+ expect(restored.get("/_index").toString()).toBe("segment");
153
+ });
154
+ /**
155
+ * base64, not the array of per-byte integers `Buffer.toJSON()` produces: that
156
+ * array is ~3 bytes of JSON per byte of payload *and* makes `JSON.parse`'s
157
+ * reviver run once per element, which cost 4.8s of Lambda time to answer a
158
+ * single 1 MiB segment prefetch on a real deployment.
159
+ */
160
+ it("writes a Buffer as base64 rather than an array of bytes", () => {
161
+ const json = (0, cache_utils_1.serializeCacheValue)({ rscData: Buffer.from("hello") });
162
+ expect(JSON.parse(json).rscData).toEqual({
163
+ __type: "Buffer",
164
+ base64: "aGVsbG8=",
165
+ });
166
+ // Comfortably under the ~5 bytes per payload byte an integer array costs.
167
+ expect(json.length).toBeLessThan(60);
168
+ });
169
+ it("still reads the integer-array format an older build wrote", () => {
170
+ const legacy = JSON.stringify({
171
+ ours: { __type: "Buffer", data: [104, 105] },
172
+ nodes: { type: "Buffer", data: [104, 105] },
173
+ });
174
+ const restored = (0, cache_utils_1.parseCacheValue)(legacy);
175
+ expect(restored.ours.toString()).toBe("hi");
176
+ expect(restored.nodes.toString()).toBe("hi");
177
+ });
178
+ });
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL2NhY2hlLXV0aWxzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQ0FNdUI7QUFFdkIsUUFBUSxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRTtJQUN2QyxFQUFFLENBQUMseUJBQXlCLEVBQUUsR0FBRyxFQUFFO1FBQ2pDLE1BQU0sQ0FBQyxJQUFBLHFDQUF1QixFQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4QkFBOEIsRUFBRSxHQUFHLEVBQUU7UUFDdEMsTUFBTSxDQUFDLElBQUEscUNBQXVCLEVBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0lBRUg7Ozs7T0FJRztJQUNILEVBQUUsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7UUFDbkMsTUFBTSxDQUFDLElBQUEscUNBQXVCLEVBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUN6QyxNQUFNLENBQUMsSUFBQSxxQ0FBdUIsRUFBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO1FBQ2pELE1BQU0sQ0FBQyxJQUFBLHFDQUF1QixFQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDNUQsY0FBYyxD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bnRlbnQiOlsiaW1wb3J0IHtcbiAgYXBwUGFnZUNhY2hlSGVhZGVycyxcbiAgZ3JvdXBQcmVyZW5kZXJzLFxuICBwYXJzZUNhY2hlVmFsdWUsXG4gIHByZXJlbmRlclBhdGhUb0NhY2hlS2V5LFxuICBzZXJpYWxpemVDYWNoZVZhbHVlLFxufSBmcm9tIFwiLi9jYWNoZS11dGlsc1wiO1xuXG5kZXNjcmliZShcInByZXJlbmRlclBhdGhUb0NhY2hlS2V5XCIsICgpID0+IHtcbiAgaXQoXCJkcm9wcyB0aGUgbGVhZGluZyBzbGFzaFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFwiL3NzZy8xXCIsIFwiXCIpKS50b0JlKFwic3NnLzFcIik7XG4gIH0pO1xuXG4gIGl0KFwibWFwcyB0aGUgcm9vdCByb3V0ZSB0byBpbmRleFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFwiL1wiLCBcIlwiKSkudG9CZShcImluZGV4XCIpO1xuICB9KTtcblxuICAvKipcbiAgICogVGhlIHJlZ3Jlc3Npb24gdGhhdCBtYWRlIGV2ZXJ5IHByZXJlbmRlciBhIE1JU1Mgb24gYSBkZXBsb3ltZW50IHdpdGggYVxuICAgKiBgYmFzZVBhdGhgOiB0aGUgc2VlZCB3cm90ZSBgcHJvZC9zc2cvMS5qc29uYCB3aGlsZSB0aGUgc2VydmVyLCB3aGljaCBzZWVzIHRoZVxuICAgKiBwYXRoIG9ubHkgYWZ0ZXIgTmV4dC5qcyBoYXMgc3RyaXBwZWQgYGJhc2VQYXRoYCwgYXNrZWQgZm9yIGBzc2cvMS5qc29uYC5cbiAgICovXG4gIGl0KFwic3RyaXBzIHRoZSBhcHAncyBiYXNlUGF0aFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFwiL3Byb2Qvc3NnLzFcIiwgXCIvcHJvZFwiKSkudG9CZShcInNzZy8xXCIpO1xuICB9KTtcblxuICBpdChcIm1hcHMgdGhlIGJhc2VQYXRoIHJvb3QgdG8gaW5kZXhcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChwcmVyZW5kZXJQYXRoVG9DYWNoZUtleShcIi9wcm9kXCIsIFwiL3Byb2RcIikpLnRvQmUoXCJpbmRleFwiKTtcbiAgfSk7XG5cbiAgaXQoXCJvbmx5IHN0cmlwcyBiYXNlUGF0aCBvbiBhIHBhdGggYm91bmRhcnlcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChwcmVyZW5kZXJQYXRoVG9DYWNoZUtleShcIi9wcm9kdWN0aW9uLzFcIiwgXCIvcHJvZFwiKSkudG9CZShcbiAgICAgIFwicHJvZHVjdGlvbi8xXCIsXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJncm91cFByZXJlbmRlcnNcIiwgKCkgPT4ge1xuICBjb25zdCBhdCA9ICguLi5wYXRobmFtZXM6IHN0cmluZ1tdKSA9PlxuICAgIHBhdGhuYW1lcy5tYXAoKHBhdGhuYW1lKSA9PiAoe1xuICAgICAgcGF0aG5hbWUsXG4gICAgfSkpO1xuXG4gIGl0KFwiZ3JvdXBzIGEgcm91dGUncyBodG1sLCByc2MgYW5kIHNlZ21lbnQgb3V0cHV0cyB0b2dldGhlclwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXG4gICAgICAgIFwiL2Jsb2cvaGVsbG9cIixcbiAgICAgICAgXCIvYmxvZy9oZWxsby5yc2NcIixcbiAgICAgICAgXCIvYmxvZy9oZWxsby5zZWdtZW50cy8kYyQuc2VnbWVudC5yc2NcIixcbiAgICAgICAgXCIvYmxvZy9oZWxsby5zZWdtZW50cy8kYyQvX19QQUdFX18uc2VnbWVudC5yc2NcIixcbiAgICAgICksXG4gICAgKTtcbiAgICBleHBlY3QoZ3JvdXBzLnNpemUpLnRvQmUoMSk7XG4gICAgY29uc3QgdmFyaWFudHMgPSBncm91cHMuZ2V0KFwiL2Jsb2cvaGVsbG9cIik7XG4gICAgZXhwZWN0KHZhcmlhbnRzPy5odG1sPy5wYXRobmFtZSkudG9CZShcIi9ibG9nL2hlbGxvXCIpO1xuICAgIGV4cGVjdCh2YXJpYW50cz8ucnNjPy5wYXRobmFtZSkudG9CZShcIi9ibG9nL2hlbGxvLnJzY1wiKTtcbiAgICBleHBlY3QodmFyaWFudHM/LnNlZ21lbnRzKS50b0hhdmVMZW5ndGgoMik7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVncmVzc2lvbjogdGhlIHJvb3Qgcm91dGUncyBIVE1MIGlzIGVtaXR0ZWQgYXMgYC9gIGJ1dCBpdHMgZmxpZ2h0IHBheWxvYWRcbiAgICogYXMgYC9pbmRleC5yc2NgLCBzbyBncm91cGluZyBieSBhIHJlY29uc3RydWN0ZWQgYCR7cm91dGV9LnJzY2AgbGVmdCBgL2Agd2l0aCBub1xuICAgKiBgcnNjRGF0YWAgYW5kIGV2ZXJ5IGNsaWVudC1zaWRlIG5hdmlnYXRpb24gdG8gdGhlIGhvbWUgcGFnZSA0MDQnZC5cbiAgICovXG4gIGl0KFwiZ2l2ZXMgdGhlIHJvb3Qgcm91dGUgdGhlIC9pbmRleC5yc2MgcGF5bG9hZFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvXCIsIFwiL2luZGV4LnJzY1wiLCBcIi9pbmRleC5zZWdtZW50cy8kYyQuc2VnbWVudC5yc2NcIiksXG4gICAgKTtcbiAgICBleHBlY3QoQXJyYXkuZnJvbShncm91cHMua2V5cygpKSkudG9FcXVhbChbXCIvXCJdKTtcbiAgICBleHBlY3QoZ3JvdXBzLmdldChcIi9cIik/LnJzYz8ucGF0aG5hbWUpLnRvQmUoXCIvaW5kZXgucnNjXCIpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL1wiKT8uc2VnbWVudHMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgfSk7XG5cbiAgLyoqIFdpdGggYSBgYmFzZVBhdGhgIHRoZSBzcGxpdCBpcyBgL3Byb2RgIHZzIGAvcHJvZC9pbmRleGAuICovXG4gIGl0KFwiZ2l2ZXMgdGhlIGJhc2VQYXRoIHJvb3QgaXRzIC9pbmRleC5yc2MgcGF5bG9hZFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvcHJvZFwiLCBcIi9wcm9kL2luZGV4LnJzY1wiLCBcIi9wcm9kL2luZGV4LnNlZ21lbnRzLyRjJC5zZWdtZW50LnJzY1wiKSxcbiAgICApO1xuICAgIGV4cGVjdChBcnJheS5mcm9tKGdyb3Vwcy5rZXlzKCkpKS50b0VxdWFsKFtcIi9wcm9kXCJdKTtcbiAgICBleHBlY3QoZ3JvdXBzLmdldChcIi9wcm9kXCIpPy5yc2M/LnBhdGhuYW1lKS50b0JlKFwiL3Byb2QvaW5kZXgucnNjXCIpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL3Byb2RcIik/LnNlZ21lbnRzKS50b0hhdmVMZW5ndGgoMSk7XG4gIH0pO1xuXG4gIC8qKiBBbiBhcHAgd2l0aCBhIHJlYWwgYGFwcC9pbmRleC9wYWdlLnRzeGAga2VlcHMgaXRzIG93biBncm91cC4gKi9cbiAgaXQoXCJsZWF2ZXMgYSBnZW51aW5lIC9pbmRleCByb3V0ZSBhbG9uZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKGF0KFwiL1wiLCBcIi9pbmRleFwiLCBcIi9pbmRleC5yc2NcIikpO1xuICAgIGV4cGVjdChBcnJheS5mcm9tKGdyb3Vwcy5rZXlzKCkpLnNvcnQoKSkudG9FcXVhbChbXCIvXCIsIFwiL2luZGV4XCJdKTtcbiAgICBleHBlY3QoZ3JvdXBzLmdldChcIi9cIik/LnJzYykudG9CZVVuZGVmaW5lZCgpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL2luZGV4XCIpPy5yc2M/LnBhdGhuYW1lKS50b0JlKFwiL2luZGV4LnJzY1wiKTtcbiAgfSk7XG5cbiAgLyoqIGAvbmVzdGVkL2luZGV4LnJzY2Agd2l0aCBubyBgL25lc3RlZGAgSFRNTCBpcyBpdHMgb3duIHJvdXRlLCBub3QgYSByZW1hcC4gKi9cbiAgaXQoXCJvbmx5IHJlbWFwcyB3aGVuIHRoZSBwYXJlbnQgcmVhbGx5IGlzIGEgcHJlcmVuZGVyZWQgcm91dGVcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGdyb3VwcyA9IGdyb3VwUHJlcmVuZGVycyhhdChcIi9uZXN0ZWQvaW5kZXgucnNjXCIpKTtcbiAgICBleHBlY3QoQXJyYXkuZnJvbShncm91cHMua2V5cygpKSkudG9FcXVhbChbXCIvbmVzdGVkL2luZGV4XCJdKTtcbiAgfSk7XG5cbiAgaXQoXCJrZWVwcyBzZWdtZW50cyB3aG9zZSByb3V0ZSBoYXMgbm8gb3RoZXIgb3V0cHV0XCIsICgpID0+IHtcbiAgICBjb25zdCBncm91cHMgPSBncm91cFByZXJlbmRlcnMoYXQoXCIvcHByLnNlZ21lbnRzLyRjJC5zZWdtZW50LnJzY1wiKSk7XG4gICAgZXhwZWN0KGdyb3Vwcy5nZXQoXCIvcHByXCIpPy5zZWdtZW50cykudG9IYXZlTGVuZ3RoKDEpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL3BwclwiKT8uaHRtbCkudG9CZVVuZGVmaW5lZCgpO1xuICB9KTtcblxuICAvKipcbiAgICogQSBQYWdlcyBSb3V0ZXIgcm91dGUncyBgcGFnZURhdGFgIGxpdmVzIGF0IGEgcGF0aG5hbWUgb2YgaXRzIG93biByYXRoZXIgdGhhblxuICAgKiBhdCBhIHN1ZmZpeCBvZiB0aGUgcGFnZSdzLCBzbyBhbiB1bm1hdGNoZWQgb25lIHdvdWxkIGJlY29tZSBhIGdyb3VwIG5hbWVkXG4gICAqIGAvX25leHQvZGF0YS8uLi5gIC0gd2hpY2ggZ2V0cyBubyBjYWNoZSBraW5kLCBhbmQgc28gc2lsZW50bHkgZHJvcHMgdGhlIGRhdGFcbiAgICogZXZlcnkgc2VlZGVkIGVudHJ5IG5lZWRzLlxuICAgKi9cbiAgaXQoXCJhdHRhY2hlcyBhIFBhZ2VzIFJvdXRlciByb3V0ZSdzIC9fbmV4dC9kYXRhIG91dHB1dFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvYmxvZy9oZWxsb1wiLCBcIi9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9ibG9nL2hlbGxvLmpzb25cIiksXG4gICAgKTtcbiAgICBleHBlY3QoQXJyYXkuZnJvbShncm91cHMua2V5cygpKSkudG9FcXVhbChbXCIvYmxvZy9oZWxsb1wiXSk7XG4gICAgZXhwZWN0KGdyb3Vwcy5nZXQoXCIvYmxvZy9oZWxsb1wiKT8uZGF0YT8ucGF0aG5hbWUpLnRvQmUoXG4gICAgICBcIi9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9ibG9nL2hlbGxvLmpzb25cIixcbiAgICApO1xuICB9KTtcblxuICAvKiogVGhlIGBmYWxsYmFjazogdHJ1ZWAgdGVtcGxhdGUsIHdob3NlIGRhdGEgcm91dGUgaGFzIG5vIGZpbGUgYmVoaW5kIGl0LiAqL1xuICBpdChcImF0dGFjaGVzIHRoZSBkYXRhIG91dHB1dCBvZiBhIGR5bmFtaWMgcm91dGUncyBmYWxsYmFjayB0ZW1wbGF0ZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvW3NsdWddXCIsIFwiL19uZXh0L2RhdGEvYnVpbGQtYWJjMTIzL1tzbHVnXS5qc29uXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KEFycmF5LmZyb20oZ3JvdXBzLmtleXMoKSkpLnRvRXF1YWwoW1wiL1tzbHVnXVwiXSk7XG4gICAgZXhwZWN0KGdyb3Vwcy5nZXQoXCIvW3NsdWddXCIpPy5kYXRhPy5wYXRobmFtZSkudG9CZShcbiAgICAgIFwiL19uZXh0L2RhdGEvYnVpbGQtYWJjMTIzL1tzbHVnXS5qc29uXCIsXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqIGAvaW5kZXguanNvbmAgaXMgdGhlIHJvb3QgcGFnZSdzIGRhdGEgcm91dGUsIHRoZSBzYW1lIHJlbWFwIGFzIGAvaW5kZXgucnNjYC4gKi9cbiAgaXQoXCJnaXZlcyB0aGUgcm9vdCByb3V0ZSBpdHMgL2luZGV4Lmpzb24gZGF0YSBvdXRwdXRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGdyb3VwcyA9IGdyb3VwUHJlcmVuZGVycyhcbiAgICAgIGF0KFwiL3Byb2RcIiwgXCIvcHJvZC9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9pbmRleC5qc29uXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KEFycmF5LmZyb20oZ3JvdXBzLmtleXMoKSkpLnRvRXF1YWwoW1wiL3Byb2RcIl0pO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL3Byb2RcIik/LmRhdGE/LnBhdGhuYW1lKS50b0JlKFxuICAgICAgXCIvcHJvZC9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9pbmRleC5qc29uXCIsXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJhcHBQYWdlQ2FjaGVIZWFkZXJzXCIsICgpID0+IHtcbiAgLyoqIEV4YWN0bHkgd2hhdCBgb25CdWlsZENvbXBsZXRlYCBpcyBoYW5kZWQgZm9yIGEgcHJlcmVuZGVyZWQgYXBwIHBhZ2UuICovXG4gIGNvbnN0IGluaXRpYWxIZWFkZXJzID0ge1xuICAgIHZhcnk6IFwicnNjLCBuZXh0LXJvdXRlci1zdGF0ZS10cmVlLCBuZXh0LXJvdXRlci1wcmVmZXRjaCwgbmV4dC1yb3V0ZXItc2VnbWVudC1wcmVmZXRjaFwiLFxuICAgIFwiY29udGVudC10eXBlXCI6IFwidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgXCJ4LW5leHRqcy1zdGFsZS10aW1lXCI6IFwiMzAwXCIsXG4gICAgXCJ4LW5leHRqcy1wcmVyZW5kZXJcIjogXCIxXCIsXG4gICAgXCJ4LW5leHQtY2FjaGUtdGFnc1wiOiBcIl9OX1RfL2xheW91dCxfTl9UXy9wYWdlLF9OX1RfLyxfTl9UXy9pbmRleFwiLFxuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcmVncmVzc2lvbjogYSBzZWVkZWQgYGNvbnRlbnQtdHlwZTogdGV4dC9odG1sYCBzdXJ2aXZlcyBpbnRvIHRoZSByZXNwb25zZVxuICAgKiBhbmQgYHNlbmQtcGF5bG9hZC5qc2Agd2lsbCBub3Qgb3ZlcndyaXRlIGl0LCBzbyBhbiBSU0MgcmVxdWVzdCB0byBhXG4gICAqIHByZXJlbmRlcmVkIHBhZ2UgZ2V0cyB0aGUgZmxpZ2h0IHBheWxvYWQgbGFiZWxlZCBhcyBIVE1MLlxuICAgKi9cbiAgaXQoXCJkcm9wcyBjb250ZW50LXR5cGUsIHdoaWNoIHdvdWxkIG1pc2xhYmVsIGV2ZXJ5IFJTQyByZXNwb25zZVwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KGFwcFBhZ2VDYWNoZUhlYWRlcnMoaW5pdGlhbEhlYWRlcnMpKS5ub3QudG9IYXZlUHJvcGVydHkoXG4gICAgICBcImNvbnRlbnQtdHlwZVwiLFxuICAgICk7XG4gIH0pO1xuXG4gIGl0KFwia2VlcHMgdGhlIGhlYWRlcnMgYSByZW5kZXIgd291bGQgcmVhbGx5IGhhdmUgc3RvcmVkXCIsICgpID0+IHtcbiAgICBleHBlY3QoYXBwUGFnZUNhY2hlSGVhZGVycyhpbml0aWFsSGVhZGVycykpLnRvRXF1YWwoe1xuICAgICAgXCJ4LW5leHRqcy1zdGFsZS10aW1lXCI6IFwiMzAwXCIsXG4gICAgICBcIngtbmV4dC1jYWNoZS10YWdzXCI6IFwiX05fVF8vbGF5b3V0LF9OX1RfL3BhZ2UsX05fVF8vLF9OX1RfL2luZGV4XCIsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwiZHJvcHMgdGhlIGhlYWRlcnMgdGhlIGVudHJ5cG9pbnQgc2V0cyBpdHNlbGYsIHdoaWNoIHdvdWxkIGRvdWJsZSB1cFwiLCAoKSA9PiB7XG4gICAgY29uc3QgaGVhZGVycyA9IGFwcFBhZ2VDYWNoZUhlYWRlcnMoe1xuICAgICAgLi4uaW5pdGlhbEhlYWRlcnMsXG4gICAgICBcIngtbmV4dGpzLXBvc3Rwb25lZFwiOiBcIjFcIixcbiAgICB9KTtcbiAgICBleHBlY3QoT2JqZWN0LmtleXMoaGVhZGVycykpLm5vdC50b0NvbnRhaW4oXCJ2YXJ5XCIpO1xuICAgIGV4cGVjdChPYmplY3Qua2V5cyhoZWFkZXJzKSkubm90LnRvQ29udGFpbihcIngtbmV4dGpzLXByZXJlbmRlclwiKTtcbiAgICBleHBlY3QoT2JqZWN0LmtleXMoaGVhZGVycykpLm5vdC50b0NvbnRhaW4oXCJ4LW5leHRqcy1wb3N0cG9uZWRcIik7XG4gIH0pO1xuXG4gIGl0KFwibWF0Y2hlcyBjYXNlLWluc2Vuc2l0aXZlbHlcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChhcHBQYWdlQ2FjaGVIZWFkZXJzKHsgXCJDb250ZW50LVR5cGVcIjogXCJ0ZXh0L2h0bWxcIiB9KSkudG9FcXVhbCh7fSk7XG4gIH0pO1xuXG4gIGl0KFwicGFzc2VzIHRocm91Z2ggYW55dGhpbmcgdGhlIGFwcCBzZXQgaXRzZWxmXCIsICgpID0+IHtcbiAgICBleHBlY3QoXG4gICAgICBhcHBQYWdlQ2FjaGVIZWFkZXJzKHsgXCJ4LWN1c3RvbVwiOiBcIjFcIiwgXCJzZXQtY29va2llXCI6IFwiYT1iXCIgfSksXG4gICAgKS50b0VxdWFsKHsgXCJ4LWN1c3RvbVwiOiBcIjFcIiwgXCJzZXQtY29va2llXCI6IFwiYT1iXCIgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwic2VyaWFsaXplQ2FjaGVWYWx1ZSAvIHBhcnNlQ2FjaGVWYWx1ZVwiLCAoKSA9PiB7XG4gIGl0KFwicm91bmQtdHJpcHMgYSBCdWZmZXJcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0geyByc2NEYXRhOiBCdWZmZXIuZnJvbShcImhlbGxvLCBjYWNoZVwiKSB9O1xuXG4gICAgY29uc3QgcmVzdG9yZWQgPSBwYXJzZUNhY2hlVmFsdWUoc2VyaWFsaXplQ2FjaGVWYWx1ZSh2YWx1ZSkpO1xuXG4gICAgZXhwZWN0KEJ1ZmZlci5pc0J1ZmZlcihyZXN0b3JlZC5yc2NEYXRhKSkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdG9yZWQucnNjRGF0YS50b1N0cmluZygpKS50b0JlKFwiaGVsbG8sIGNhY2hlXCIpO1xuICB9KTtcblxuICBpdChcInJvdW5kLXRyaXBzIGJ5dGVzIHRoYXQgYXJlIG5vdCB2YWxpZCBVVEYtOFwiLCAoKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBCdWZmZXIuZnJvbShbMHgwMCwgMHhmZiwgMHhmZSwgMHg4MCwgMHg3Zl0pO1xuXG4gICAgY29uc3QgcmVzdG9yZWQgPSBwYXJzZUNhY2hlVmFsdWUoc2VyaWFsaXplQ2FjaGVWYWx1ZSh7IHZhbHVlIH0pKS52YWx1ZTtcblxuICAgIGV4cGVjdChyZXN0b3JlZC5lcXVhbHModmFsdWUpKS50b0JlKHRydWUpO1xuICB9KTtcblxuICBpdChcInJvdW5kLXRyaXBzIGEgTWFwLCBpbmNsdWRpbmcgQnVmZmVycyBpbnNpZGUgaXRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gbmV3IE1hcChbW1wiL19pbmRleFwiLCBCdWZmZXIuZnJvbShcInNlZ21lbnRcIildXSk7XG5cbiAgICBjb25zdCByZXN0b3JlZCA9IHBhcnNlQ2FjaGVWYWx1ZShzZXJpYWxpemVDYWNoZVZhbHVlKHsgdmFsdWUgfSkpLnZhbHVlO1xuXG4gICAgZXhwZWN0KHJlc3RvcmVkKS50b0JlSW5zdGFuY2VPZihNYXApO1xuICAgIGV4cGVjdChyZXN0b3JlZC5nZXQoXCIvX2luZGV4XCIpLnRvU3RyaW5nKCkpLnRvQmUoXCJzZWdtZW50XCIpO1xuICB9KTtcblxuICAvKipcbiAgICogYmFzZTY0LCBub3QgdGhlIGFycmF5IG9mIHBlci1ieXRlIGludGVnZXJzIGBCdWZmZXIudG9KU09OKClgIHByb2R1Y2VzOiB0aGF0XG4gICAqIGFycmF5IGlzIH4zIGJ5dGVzIG9mIEpTT04gcGVyIGJ5dGUgb2YgcGF5bG9hZCAqYW5kKiBtYWtlcyBgSlNPTi5wYXJzZWAnc1xuICAgKiByZXZpdmVyIHJ1biBvbmNlIHBlciBlbGVtZW50LCB3aGljaCBjb3N0IDQuOHMgb2YgTGFtYmRhIHRpbWUgdG8gYW5zd2VyIGFcbiAgICogc2luZ2xlIDEgTWlCIHNlZ21lbnQgcHJlZmV0Y2ggb24gYSByZWFsIGRlcGxveW1lbnQuXG4gICAqL1xuICBpdChcIndyaXRlcyBhIEJ1ZmZlciBhcyBiYXNlNjQgcmF0aGVyIHRoYW4gYW4gYXJyYXkgb2YgYnl0ZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGpzb24gPSBzZXJpYWxpemVDYWNoZVZhbHVlKHsgcnNjRGF0YTogQnVmZmVyLmZyb20oXCJoZWxsb1wiKSB9KTtcblxuICAgIGV4cGVjdChKU09OLnBhcnNlKGpzb24pLnJzY0RhdGEpLnRvRXF1YWwoe1xuICAgICAgX190eXBlOiBcIkJ1ZmZlclwiLFxuICAgICAgYmFzZTY0OiBcImFHVnNiRzg9XCIsXG4gICAgfSk7XG4gICAgLy8gQ29tZm9ydGFibHkgdW5kZXIgdGhlIH41IGJ5dGVzIHBlciBwYXlsb2FkIGJ5dGUgYW4gaW50ZWdlciBhcnJheSBjb3N0cy5cbiAgICBleHBlY3QoanNvbi5sZW5ndGgpLnRvQmVMZXNzVGhhbig2MCk7XG4gIH0pO1xuXG4gIGl0KFwic3RpbGwgcmVhZHMgdGhlIGludGVnZXItYXJyYXkgZm9ybWF0IGFuIG9sZGVyIGJ1aWxkIHdyb3RlXCIsICgpID0+IHtcbiAgICBjb25zdCBsZWdhY3kgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBvdXJzOiB7IF9fdHlwZTogXCJCdWZmZXJcIiwgZGF0YTogWzEwNCwgMTA1XSB9LFxuICAgICAgbm9kZXM6IHsgdHlwZTogXCJCdWZmZXJcIiwgZGF0YTogWzEwNCwgMTA1XSB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzdG9yZWQgPSBwYXJzZUNhY2hlVmFsdWUobGVnYWN5KTtcblxuICAgIGV4cGVjdChyZXN0b3JlZC5vdXJzLnRvU3RyaW5nKCkpLnRvQmUoXCJoaVwiKTtcbiAgICBleHBlY3QocmVzdG9yZWQubm9kZXMudG9TdHJpbmcoKSkudG9CZShcImhpXCIpO1xuICB9KTtcbn0pO1xuIl19