cdk-nextjs 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/.jsii +2467 -2714
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1725 -1909
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +152 -170
  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 +687 -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 +13 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +11 -2
  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/post-deploy.lambda.js +3 -2
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  88. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  92. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  93. package/lib/lambdas/post-deploy/prune-s3.d.ts +19 -3
  94. package/lib/lambdas/post-deploy/prune-s3.js +54 -15
  95. package/lib/lambdas/post-deploy/prune-s3.test.d.ts +1 -0
  96. package/lib/lambdas/post-deploy/prune-s3.test.js +255 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  103. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  104. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  105. package/lib/nextjs-api.d.ts +107 -18
  106. package/lib/nextjs-api.js +349 -39
  107. package/lib/nextjs-api.test.js +582 -1
  108. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  109. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  110. package/lib/nextjs-build/nextjs-build.js +684 -327
  111. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  112. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  113. package/lib/nextjs-build/patch-fetch.js +1 -1
  114. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  115. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  116. package/lib/nextjs-cache.d.ts +82 -4
  117. package/lib/nextjs-cache.js +186 -10
  118. package/lib/nextjs-cache.test.js +176 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  120. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  121. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  122. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  123. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  124. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  125. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  126. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  127. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  128. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  129. package/lib/nextjs-distribution.d.ts +194 -23
  130. package/lib/nextjs-distribution.js +535 -62
  131. package/lib/nextjs-distribution.test.d.ts +1 -0
  132. package/lib/nextjs-distribution.test.js +697 -0
  133. package/lib/nextjs-post-deploy.d.ts +23 -3
  134. package/lib/nextjs-post-deploy.js +14 -10
  135. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  136. package/lib/nextjs-post-deploy.test.js +34 -0
  137. package/lib/nextjs-static-assets.d.ts +23 -4
  138. package/lib/nextjs-static-assets.js +29 -6
  139. package/lib/nextjs-static-assets.test.js +20 -1
  140. package/lib/root-constructs/nextjs-base-construct.d.ts +105 -45
  141. package/lib/root-constructs/nextjs-base-construct.js +144 -34
  142. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  143. package/lib/root-constructs/nextjs-global-containers.js +20 -70
  144. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  145. package/lib/root-constructs/nextjs-global-functions.js +52 -69
  146. package/lib/root-constructs/nextjs-regional-containers.d.ts +25 -5
  147. package/lib/root-constructs/nextjs-regional-containers.js +17 -15
  148. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  149. package/lib/root-constructs/nextjs-regional-functions.js +8 -25
  150. package/lib/runtime/api-gateway-path.d.ts +34 -0
  151. package/lib/runtime/api-gateway-path.js +71 -0
  152. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  153. package/lib/runtime/api-gateway-path.test.js +65 -0
  154. package/lib/runtime/case-redirect.d.ts +22 -0
  155. package/lib/runtime/case-redirect.js +63 -0
  156. package/lib/runtime/case-redirect.test.d.ts +1 -0
  157. package/lib/runtime/case-redirect.test.js +32 -0
  158. package/lib/runtime/core.d.ts +234 -0
  159. package/lib/runtime/core.js +1213 -0
  160. package/lib/runtime/core.test.d.ts +1 -0
  161. package/lib/runtime/core.test.js +1678 -0
  162. package/lib/runtime/deployment-root.d.ts +13 -0
  163. package/lib/runtime/deployment-root.js +29 -0
  164. package/lib/runtime/dispatch.d.ts +331 -0
  165. package/lib/runtime/dispatch.js +751 -0
  166. package/lib/runtime/dispatch.test.d.ts +1 -0
  167. package/lib/runtime/dispatch.test.js +853 -0
  168. package/lib/runtime/entrypoints.d.ts +57 -0
  169. package/lib/runtime/entrypoints.js +115 -0
  170. package/lib/runtime/http/abort-signal.d.ts +6 -0
  171. package/lib/runtime/http/abort-signal.js +19 -0
  172. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  173. package/lib/runtime/http/abort-signal.test.js +49 -0
  174. package/lib/runtime/http/node-server.d.ts +38 -0
  175. package/lib/runtime/http/node-server.js +99 -0
  176. package/lib/runtime/http/node-server.test.d.ts +1 -0
  177. package/lib/runtime/http/node-server.test.js +96 -0
  178. package/lib/runtime/http/node-sink.d.ts +16 -0
  179. package/lib/runtime/http/node-sink.js +48 -0
  180. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  181. package/lib/runtime/http/node-sink.test.js +66 -0
  182. package/lib/runtime/http/request.d.ts +62 -0
  183. package/lib/runtime/http/request.js +134 -0
  184. package/lib/runtime/http/request.test.d.ts +1 -0
  185. package/lib/runtime/http/request.test.js +103 -0
  186. package/lib/runtime/http/response.d.ts +77 -0
  187. package/lib/runtime/http/response.js +229 -0
  188. package/lib/runtime/http/response.test.d.ts +1 -0
  189. package/lib/runtime/http/response.test.js +178 -0
  190. package/lib/runtime/http/sink.d.ts +73 -0
  191. package/lib/runtime/http/sink.js +188 -0
  192. package/lib/runtime/http/sink.test.d.ts +1 -0
  193. package/lib/runtime/http/sink.test.js +257 -0
  194. package/lib/runtime/image-utils.d.ts +78 -0
  195. package/lib/runtime/image-utils.js +129 -0
  196. package/lib/runtime/image-utils.test.d.ts +1 -0
  197. package/lib/runtime/image-utils.test.js +237 -0
  198. package/lib/runtime/image.d.ts +76 -0
  199. package/lib/runtime/image.js +296 -0
  200. package/lib/runtime/image.test.d.ts +1 -0
  201. package/lib/runtime/image.test.js +405 -0
  202. package/lib/runtime/lambda-event.d.ts +4 -0
  203. package/lib/runtime/lambda-event.js +113 -0
  204. package/lib/runtime/lambda-event.test.d.ts +1 -0
  205. package/lib/runtime/lambda-event.test.js +119 -0
  206. package/lib/runtime/lambda.mjs +41595 -0
  207. package/lib/runtime/load-module.d.ts +8 -0
  208. package/lib/runtime/load-module.js +35 -0
  209. package/lib/runtime/manifest.d.ts +215 -0
  210. package/lib/runtime/manifest.js +118 -0
  211. package/lib/runtime/middleware.d.ts +43 -0
  212. package/lib/runtime/middleware.js +113 -0
  213. package/lib/runtime/middleware.test.d.ts +1 -0
  214. package/lib/runtime/middleware.test.js +259 -0
  215. package/lib/runtime/next-modules.d.ts +55 -0
  216. package/lib/runtime/next-modules.js +124 -0
  217. package/lib/runtime/next-modules.test.d.ts +1 -0
  218. package/lib/runtime/next-modules.test.js +34 -0
  219. package/lib/runtime/public-files.d.ts +32 -0
  220. package/lib/runtime/public-files.js +117 -0
  221. package/lib/runtime/public-files.test.d.ts +1 -0
  222. package/lib/runtime/public-files.test.js +97 -0
  223. package/lib/runtime/server.mjs +41588 -0
  224. package/lib/runtime/static-files.d.ts +50 -0
  225. package/lib/runtime/static-files.js +266 -0
  226. package/lib/runtime/static-files.test.d.ts +1 -0
  227. package/lib/runtime/static-files.test.js +118 -0
  228. package/lib/runtime/util.d.ts +28 -0
  229. package/lib/runtime/util.js +79 -0
  230. package/lib/utils/base-path.d.ts +123 -11
  231. package/lib/utils/base-path.js +276 -39
  232. package/lib/utils/base-path.test.js +275 -50
  233. package/lib/utils/get-architecture.d.ts +7 -8
  234. package/lib/utils/get-architecture.js +12 -13
  235. package/lib/utils/zip-directory.d.ts +14 -0
  236. package/lib/utils/zip-directory.js +121 -0
  237. package/lib/utils/zip-directory.test.d.ts +1 -0
  238. package/lib/utils/zip-directory.test.js +99 -0
  239. package/package.json +22 -3
  240. package/scripts/capture-adapter-fixture.mjs +325 -0
  241. package/scripts/e2e-deploy.sh +398 -0
  242. package/scripts/e2e-harness/README.md +707 -0
  243. package/scripts/e2e-harness/app.js +370 -0
  244. package/scripts/e2e-harness/common.sh +249 -0
  245. package/scripts/e2e-harness/screen.mjs +302 -0
  246. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  247. package/scripts/e2e-harness/type-filters.mjs +47 -0
  248. package/scripts/e2e-logs.sh +75 -0
  249. package/scripts/e2e-offline.sh +91 -0
  250. package/scripts/e2e-sweep.sh +370 -0
  251. package/scripts/e2e-warm.sh +114 -0
  252. package/scripts/zero-config-build.mjs +418 -0
  253. package/docs/1k-concurrent-users-executions.png +0 -0
  254. package/docs/plans/adapter-runtime-release.md +0 -362
  255. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  256. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  257. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  258. package/lib/image-optimization/handler-utils.d.ts +0 -34
  259. package/lib/image-optimization/handler-utils.js +0 -83
  260. package/lib/image-optimization/handler-utils.test.js +0 -178
  261. package/lib/nextjs-build/functions.Dockerfile +0 -31
  262. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  263. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  264. package/lib/utils/experimental-flags.d.ts +0 -24
  265. package/lib/utils/experimental-flags.js +0 -30
  266. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -0,0 +1,6 @@
1
+ import type { BuildCompleteContext } from "./build-outputs";
2
+ /**
3
+ * Write a `<cacheKey>.json` per prerendered route under `cacheDir`, plus
4
+ * {@link INIT_CACHE_TAG_MANIFEST} when any entry carries tags.
5
+ */
6
+ export declare function writeInitCache(ctx: Pick<BuildCompleteContext, "config" | "outputs">, cacheDir: string): Promise<void>;
@@ -0,0 +1,245 @@
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.writeInitCache = writeInitCache;
7
+ /* eslint-disable import/no-extraneous-dependencies */
8
+ /**
9
+ * The init cache: one response-cache entry per prerendered route, written by
10
+ * `onBuildComplete` and seeded into S3 at deploy, so a fresh
11
+ * deployment starts with what `next build` rendered instead of a cold cache.
12
+ *
13
+ * Separate from `adapter.mts` only so it can be tested without loading the
14
+ * adapter itself (which resolves cdk-nextjs's own handlers off `import.meta`).
15
+ */
16
+ const node_fs_1 = require("node:fs");
17
+ const promises_1 = require("node:fs/promises");
18
+ const node_path_1 = require("node:path");
19
+ const debug_1 = __importDefault(require("debug"));
20
+ const cache_kinds_1 = require("./cache-kinds");
21
+ const cache_utils_1 = require("./cache-utils");
22
+ const debug = (0, debug_1.default)("cdk-nextjs:adapter");
23
+ /**
24
+ * Write a `<cacheKey>.json` per prerendered route under `cacheDir`, plus
25
+ * {@link INIT_CACHE_TAG_MANIFEST} when any entry carries tags.
26
+ */
27
+ async function writeInitCache(ctx, cacheDir) {
28
+ // Ensure cache directory exists
29
+ await (0, promises_1.mkdir)(cacheDir, { recursive: true });
30
+ debug(`Init cache directory: ${cacheDir}`);
31
+ // One entry per route, with its HTML, `.rsc` and segment outputs together
32
+ const prerenderGroups = (0, cache_utils_1.groupPrerenders)(ctx.outputs.prerenders);
33
+ debug(`Prerender groups: ${prerenderGroups.size} groups`);
34
+ const cacheKindOf = (0, cache_kinds_1.cacheKindResolver)(ctx.outputs);
35
+ // Tag -> cache keys, standing in for the mapping rows a runtime `set` writes.
36
+ // See `INIT_CACHE_TAG_MANIFEST`.
37
+ const tagManifest = {};
38
+ // Process each group and create cache entries
39
+ for (const [basePath, variants] of prerenderGroups) {
40
+ try {
41
+ // A dynamic route template — `/[lang]/[slug]` — is not a dead entry: with
42
+ // PPR it is the route's *fallback shell*, and the server looks it up in
43
+ // the cache under exactly that key. `app-page-runtime` reads
44
+ // `prerenderManifest.dynamicRoutes[route].fallback` (the literal template
45
+ // string) and calls `handleResponse({ cacheKey, isFallback: true })`; the
46
+ // Pages Router does the same with `srcPage` for an ISR fallback. Skipping
47
+ // these groups made every such lookup a MISS, so the shell was rendered
48
+ // per request instead of resumed from the build - visible in
49
+ // `test/e2e/app-dir/sub-shell-generation`, where a `'use cache'` root
50
+ // layout reported `(runtime)` where next start reports `(buildtime)`.
51
+ //
52
+ // A Pages Router template is seeded for the same reason: in production
53
+ // its fill function only returns what the cache already holds, so with
54
+ // nothing seeded there is no `fallback: true` shell to serve and
55
+ // `router.isFallback` is never true (`test/e2e/fallback-route-params`).
56
+ // Nothing extra is needed to keep non-PPR templates out: a route with no
57
+ // shell emits no prerender output.
58
+ const kind = cacheKindOf(variants);
59
+ if (!kind) {
60
+ debug(`SKIP: No route kind found for ${basePath}`);
61
+ continue;
62
+ }
63
+ debug(`Processing ${basePath} (${kind})`);
64
+ const { html: htmlPrerender, rsc: rscPrerender, segments: segmentPrerenders, data: dataPrerender, } = variants;
65
+ if (!htmlPrerender && !rscPrerender && !dataPrerender) {
66
+ debug(`SKIP: No prerender files found for ${basePath}`);
67
+ continue; // Skip if we don't have the main files
68
+ }
69
+ // Create cache entry with the appropriate structure based on kind
70
+ let cacheEntry;
71
+ if (kind === "APP_PAGE" /* CachedRouteKind.APP_PAGE */) {
72
+ // Read HTML file
73
+ const html = await readPrerenderAsText(htmlPrerender);
74
+ if (!html) {
75
+ debug(`SKIP: No HTML content for APP_PAGE ${basePath}`);
76
+ continue; // Skip if no HTML content
77
+ }
78
+ // Read RSC data
79
+ const rscData = await readPrerenderAsBuffer(rscPrerender);
80
+ // Read segment data
81
+ const segmentData = await getSegmentData(segmentPrerenders);
82
+ // Extract headers from the HTML or RSC prerender
83
+ const headers = (0, cache_utils_1.appPageCacheHeaders)(htmlPrerender?.fallback?.initialHeaders ||
84
+ rscPrerender?.fallback?.initialHeaders ||
85
+ {});
86
+ cacheEntry = {
87
+ lastModified: Date.now(),
88
+ value: {
89
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
90
+ html,
91
+ rscData,
92
+ headers,
93
+ segmentData: segmentData,
94
+ // postponedState from fallback appears to be the React postponed state
95
+ // which matches what the cache expects for postponed
96
+ postponed: htmlPrerender?.fallback?.postponedState,
97
+ // initialStatus from prerender is the HTTP status of the prerendered page
98
+ status: htmlPrerender?.fallback?.initialStatus,
99
+ },
100
+ };
101
+ }
102
+ else if (kind === "APP_ROUTE" /* CachedRouteKind.APP_ROUTE */) {
103
+ const body = await readPrerenderAsBuffer(htmlPrerender);
104
+ if (!body) {
105
+ debug(`SKIP: No body content for APP_ROUTE ${basePath}`);
106
+ continue; // Skip if no content
107
+ }
108
+ // Extract headers
109
+ const headers = htmlPrerender?.fallback?.initialHeaders || {};
110
+ cacheEntry = {
111
+ lastModified: Date.now(),
112
+ value: {
113
+ kind: "APP_ROUTE" /* CachedRouteKind.APP_ROUTE */,
114
+ body,
115
+ headers,
116
+ status: htmlPrerender?.fallback?.initialStatus || 200,
117
+ },
118
+ };
119
+ }
120
+ else if (kind === "PAGES" /* CachedRouteKind.PAGES */) {
121
+ // A build-time `notFound: true`. Next.js reports the route as
122
+ // prerendered and hands us a prerender whose `filePath` is
123
+ // `pages/404.html` and whose `initialStatus` is 404 - but it writes
124
+ // *no* output for it (no `first.html`, `.json` or `.meta`), because a
125
+ // Pages Router `notFound` is represented in the cache as an entry
126
+ // whose `value` is `null` (`pages-handler.ts`, "isNotFound in
127
+ // metadata"), and `FileSystemCache.set` keeps a null value in its LRU
128
+ // only, never on disk. So `next start` misses, re-runs
129
+ // `getStaticProps`, and answers 404 from `render404()`.
130
+ //
131
+ // Seeding it as an ordinary `PAGES` entry made that a 200: the entry
132
+ // is a HIT carrying the 404 page's HTML, and the pages handler never
133
+ // reads `value.status` on the HIT path, so the status stayed 200 while
134
+ // the body said "404 page". Skipping it restores the miss, and with it
135
+ // `next start`'s status. Costs one render per revalidate window, which
136
+ // is what `next start` pays too.
137
+ const initialStatus = htmlPrerender?.fallback?.initialStatus;
138
+ if (initialStatus !== undefined && initialStatus !== 200) {
139
+ debug(`SKIP: PAGES ${basePath} prerendered with status ${initialStatus} (build-time notFound)`);
140
+ continue;
141
+ }
142
+ const html = await readPrerenderAsText(htmlPrerender);
143
+ if (!html) {
144
+ debug(`SKIP: No HTML content for PAGES ${basePath}`);
145
+ continue;
146
+ }
147
+ // `getStaticProps`' result, which the entrypoint answers
148
+ // `/_next/data/<buildId>/<page>.json` with and the client router reads
149
+ // on a navigation. A route's *fallback* template has no data file -
150
+ // there are no params to run `getStaticProps` with yet - and
151
+ // `FileSystemCache` skips the read for one too (`if (!ctx.isFallback)`),
152
+ // leaving `pageData` an empty object.
153
+ const pageDataJson = await readPrerenderAsText(dataPrerender);
154
+ cacheEntry = {
155
+ lastModified: Date.now(),
156
+ value: {
157
+ kind: "PAGES" /* CachedRouteKind.PAGES */,
158
+ html,
159
+ pageData: pageDataJson ? JSON.parse(pageDataJson) : {},
160
+ // Both `undefined`, which is what `FileSystemCache` hands back for
161
+ // a `PAGES` entry: it reads a `.meta` sidecar for the App Router
162
+ // kinds only, and `sendRenderResult` supplies the content type.
163
+ // Seeding `fallback.initialHeaders` instead would put
164
+ // `content-type: text/html` on the JSON data responses served from
165
+ // this same entry.
166
+ headers: undefined,
167
+ status: undefined,
168
+ },
169
+ };
170
+ }
171
+ else {
172
+ // Skip unsupported kinds
173
+ debug(`SKIP: Unsupported route kind ${kind} for ${basePath}`);
174
+ continue;
175
+ }
176
+ // Write cache entry to file, under the route rather than the URL it is
177
+ // served at - see `prerenderPathToCacheKey`.
178
+ const cacheKey = (0, cache_utils_1.prerenderPathToCacheKey)(basePath, ctx.config.basePath || "");
179
+ const cacheFilePath = (0, node_path_1.join)(cacheDir, `${cacheKey}.json`);
180
+ // Ensure parent directory exists
181
+ await (0, promises_1.mkdir)((0, node_path_1.join)(cacheDir, cacheKey.split("/").slice(0, -1).join("/")), {
182
+ recursive: true,
183
+ });
184
+ await (0, promises_1.writeFile)(cacheFilePath, (0, cache_utils_1.serializeCacheValue)(cacheEntry));
185
+ for (const tag of (0, cache_utils_1.headerTags)(cacheEntry.value)) {
186
+ (tagManifest[tag] ??= []).push(cacheKey);
187
+ }
188
+ debug(`Created cache entry: ${cacheFilePath}`);
189
+ }
190
+ catch (error) {
191
+ console.error(`Error processing prerender group ${basePath}:`, error);
192
+ }
193
+ }
194
+ const taggedKeys = Object.keys(tagManifest).length;
195
+ if (taggedKeys > 0) {
196
+ await (0, promises_1.writeFile)((0, node_path_1.join)(cacheDir, cache_utils_1.INIT_CACHE_TAG_MANIFEST), JSON.stringify(tagManifest));
197
+ debug(`Wrote ${cache_utils_1.INIT_CACHE_TAG_MANIFEST} with ${taggedKeys} tags`);
198
+ }
199
+ }
200
+ /**
201
+ * Read file content from a prerender as UTF-8 string
202
+ */
203
+ async function readPrerenderAsText(prerender) {
204
+ if (prerender?.fallback &&
205
+ "filePath" in prerender.fallback &&
206
+ prerender.fallback.filePath &&
207
+ (0, node_fs_1.existsSync)(prerender.fallback.filePath)) {
208
+ return (0, promises_1.readFile)(prerender.fallback.filePath, "utf-8");
209
+ }
210
+ return undefined;
211
+ }
212
+ /**
213
+ * Read file content from a prerender as Buffer
214
+ */
215
+ async function readPrerenderAsBuffer(prerender) {
216
+ if (prerender?.fallback &&
217
+ "filePath" in prerender.fallback &&
218
+ prerender.fallback.filePath &&
219
+ (0, node_fs_1.existsSync)(prerender.fallback.filePath)) {
220
+ return (0, promises_1.readFile)(prerender.fallback.filePath);
221
+ }
222
+ return undefined;
223
+ }
224
+ /**
225
+ * Read segment data from segment prerenders
226
+ */
227
+ async function getSegmentData(segmentPrerenders) {
228
+ const segmentData = new Map();
229
+ for (const segmentPrerender of segmentPrerenders) {
230
+ if (segmentPrerender.fallback &&
231
+ "filePath" in segmentPrerender.fallback &&
232
+ segmentPrerender.fallback.filePath &&
233
+ (0, node_fs_1.existsSync)(segmentPrerender.fallback.filePath)) {
234
+ const segmentContent = await (0, promises_1.readFile)(segmentPrerender.fallback.filePath);
235
+ // Extract segment name from pathname
236
+ const segmentName = "/" +
237
+ segmentPrerender.pathname
238
+ .split(".segments/")[1]
239
+ .replace(/\.segment\.rsc$/, "");
240
+ segmentData.set(segmentName, segmentContent);
241
+ }
242
+ }
243
+ return segmentData;
244
+ }
245
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC1jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL2luaXQtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFpQ0Esd0NBcU5DO0FBdFBELHNEQUFzRDtBQUN0RDs7Ozs7OztHQU9HO0FBQ0gscUNBQXFDO0FBQ3JDLCtDQUE4RDtBQUM5RCx5Q0FBaUM7QUFDakMsa0RBQTZCO0FBSTdCLCtDQUFrRDtBQUNsRCwrQ0FRdUI7QUFFdkIsTUFBTSxLQUFLLEdBQUcsSUFBQSxlQUFRLEVBQUMsb0JBQW9CLENBQUMsQ0FBQztBQUU3Qzs7O0dBR0c7QUFDSSxLQUFLLFVBQVUsY0FBYyxDQUNsQyxHQUFxRCxFQUNyRCxRQUFnQjtJQUVoQixnQ0FBZ0M7SUFDaEMsTUFBTSxJQUFBLGdCQUFLLEVBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDM0MsS0FBSyxDQUFDLHlCQUF5QixRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBRTNDLDBFQUEwRTtJQUMxRSxNQUFNLGVBQWUsR0FBRyxJQUFBLDZCQUFlLEVBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoRSxLQUFLLENBQUMscUJBQXFCLGVBQWUsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDO0lBRTFELE1BQU0sV0FBVyxHQUFHLElBQUEsK0JBQWlCLEVBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRW5ELDhFQUE4RTtJQUM5RSxpQ0FBaUM7SUFDakMsTUFBTSxXQUFXLEdBQXlCLEVBQUUsQ0FBQztJQUU3Qyw4Q0FBOEM7SUFDOUMsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQztZQUNILDBFQUEwRTtZQUMxRSx3RUFBd0U7WUFDeEUsNkRBQTZEO1lBQzdELDBFQUEwRTtZQUMxRSwwRUFBMEU7WUFD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ZW91cy1kZXBlbmRlbmNpZXMgKi9cbi8qKlxuICogVGhlIGluaXQgY2FjaGU6IG9uZSByZXNwb25zZS1jYWNoZSBlbnRyeSBwZXIgcHJlcmVuZGVyZWQgcm91dGUsIHdyaXR0ZW4gYnlcbiAqIGBvbkJ1aWxkQ29tcGxldGVgIGFuZCBzZWVkZWQgaW50byBTMyBhdCBkZXBsb3ksIHNvIGEgZnJlc2hcbiAqIGRlcGxveW1lbnQgc3RhcnRzIHdpdGggd2hhdCBgbmV4dCBidWlsZGAgcmVuZGVyZWQgaW5zdGVhZCBvZiBhIGNvbGQgY2FjaGUuXG4gKlxuICogU2VwYXJhdGUgZnJvbSBgYWRhcHRlci5tdHNgIG9ubHkgc28gaXQgY2FuIGJlIHRlc3RlZCB3aXRob3V0IGxvYWRpbmcgdGhlXG4gKiBhZGFwdGVyIGl0c2VsZiAod2hpY2ggcmVzb2x2ZXMgY2RrLW5leHRqcydzIG93biBoYW5kbGVycyBvZmYgYGltcG9ydC5tZXRhYCkuXG4gKi9cbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgbWtkaXIsIHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCBnZXREZWJ1ZyBmcm9tIFwiZGVidWdcIjtcbmltcG9ydCB7IENhY2hlSGFuZGxlclZhbHVlIH0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvbGliL2luY3JlbWVudGFsLWNhY2hlXCI7XG5pbXBvcnQgeyBDYWNoZWRSb3V0ZUtpbmQgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZS9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBCdWlsZENvbXBsZXRlQ29udGV4dCB9IGZyb20gXCIuL2J1aWxkLW91dHB1dHNcIjtcbmltcG9ydCB7IGNhY2hlS2luZFJlc29sdmVyIH0gZnJvbSBcIi4vY2FjaGUta2luZHNcIjtcbmltcG9ydCB7XG4gIGFwcFBhZ2VDYWNoZUhlYWRlcnMsXG4gIGdyb3VwUHJlcmVuZGVycyxcbiAgaGVhZGVyVGFncyxcbiAgSU5JVF9DQUNIRV9UQUdfTUFOSUZFU1QsXG4gIEluaXRDYWNoZVRhZ01hbmlmZXN0LFxuICBwcmVyZW5kZXJQYXRoVG9DYWNoZUtleSxcbiAgc2VyaWFsaXplQ2FjaGVWYWx1ZSxcbn0gZnJvbSBcIi4vY2FjaGUtdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBnZXREZWJ1ZyhcImNkay1uZXh0anM6YWRhcHRlclwiKTtcblxuLyoqXG4gKiBXcml0ZSBhIGA8Y2FjaGVLZXk+Lmpzb25gIHBlciBwcmVyZW5kZXJlZCByb3V0ZSB1bmRlciBgY2FjaGVEaXJgLCBwbHVzXG4gKiB7QGxpbmsgSU5JVF9DQUNIRV9UQUdfTUFOSUZFU1R9IHdoZW4gYW55IGVudHJ5IGNhcnJpZXMgdGFncy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlSW5pdENhY2hlKFxuICBjdHg6IFBpY2s8QnVpbGRDb21wbGV0ZUNvbnRleHQsIFwiY29uZmlnXCIgfCBcIm91dHB1dHNcIj4sXG4gIGNhY2hlRGlyOiBzdHJpbmcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgLy8gRW5zdXJlIGNhY2hlIGRpcmVjdG9yeSBleGlzdHNcbiAgYXdhaXQgbWtkaXIoY2FjaGVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBkZWJ1ZyhgSW5pdCBjYWNoZSBkaXJlY3Rvcnk6ICR7Y2FjaGVEaXJ9YCk7XG5cbiAgLy8gT25lIGVudHJ5IHBlciByb3V0ZSwgd2l0aCBpdHMgSFRNTCwgYC5yc2NgIGFuZCBzZWdtZW50IG91dHB1dHMgdG9nZXRoZXJcbiAgY29uc3QgcHJlcmVuZGVyR3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKGN0eC5vdXRwdXRzLnByZXJlbmRlcnMpO1xuICBkZWJ1ZyhgUHJlcmVuZGVyIGdyb3VwczogJHtwcmVyZW5kZXJHcm91cHMuc2l6ZX0gZ3JvdXBzYCk7XG5cbiAgY29uc3QgY2FjaGVLaW5kT2YgPSBjYWNoZUtpbmRSZXNvbHZlcihjdHgub3V0cHV0cyk7XG5cbiAgLy8gVGFnIC0+IGNhY2hlIGtleXMsIHN0YW5kaW5nIGluIGZvciB0aGUgbWFwcGluZyByb3dzIGEgcnVudGltZSBgc2V0YCB3cml0ZXMuXG4gIC8vIFNlZSBgSU5JVF9DQUNIRV9UQUdfTUFOSUZFU1RgLlxuICBjb25zdCB0YWdNYW5pZmVzdDogSW5pdENhY2hlVGFnTWFuaWZlc3QgPSB7fTtcblxuICAvLyBQcm9jZXNzIGVhY2ggZ3JvdXAgYW5kIGNyZWF0ZSBjYWNoZSBlbnRyaWVzXG4gIGZvciAoY29uc3QgW2Jhc2VQYXRoLCB2YXJpYW50c10gb2YgcHJlcmVuZGVyR3JvdXBzKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEEgZHluYW1pYyByb3V0ZSB0ZW1wbGF0ZSDigJQgYC9bbGFuZ10vW3NsdWddYCDigJQgaXMgbm90IGEgZGVhZCBlbnRyeTogd2l0aFxuICAgICAgLy8gUFBSIGl0IGlzIHRoZSByb3V0ZSdzICpmYWxsYmFjayBzaGVsbCosIGFuZCB0aGUgc2VydmVyIGxvb2tzIGl0IHVwIGluXG4gICAgICAvLyB0aGUgY2FjaGUgdW5kZXIgZXhhY3RseSB0aGF0IGtleS4gYGFwcC1wYWdlLXJ1bnRpbWVgIHJlYWRzXG4gICAgICAvLyBgcHJlcmVuZGVyTWFuaWZlc3QuZHluYW1pY1JvdXRlc1tyb3V0ZV0uZmFsbGJhY2tgICh0aGUgbGl0ZXJhbCB0ZW1wbGF0ZVxuICAgICAgLy8gc3RyaW5nKSBhbmQgY2FsbHMgYGhhbmRsZVJlc3BvbnNlKHsgY2FjaGVLZXksIGlzRmFsbGJhY2s6IHRydWUgfSlgOyB0aGVcbiAgICAgIC8vIFBhZ2VzIFJvdXRlciBkb2VzIHRoZSBzYW1lIHdpdGggYHNyY1BhZ2VgIGZvciBhbiBJU1IgZmFsbGJhY2suIFNraXBwaW5nXG4gICAgICAvLyB0aGVzZSBncm91cHMgbWFkZSBldmVyeSBzdWNoIGxvb2t1cCBhIE1JU1MsIHNvIHRoZSBzaGVsbCB3YXMgcmVuZGVyZWRcbiAgICAgIC8vIHBlciByZXF1ZXN0IGluc3RlYWQgb2YgcmVzdW1lZCBmcm9tIHRoZSBidWlsZCAtIHZpc2libGUgaW5cbiAgICAgIC8vIGB0ZXN0L2UyZS9hcHAtZGlyL3N1Yi1zaGVsbC1nZW5lcmF0aW9uYCwgd2hlcmUgYSBgJ3VzZSBjYWNoZSdgIHJvb3RcbiAgICAgIC8vIGxheW91dCByZXBvcnRlZCBgKHJ1bnRpbWUpYCB3aGVyZSBuZXh0IHN0YXJ0IHJlcG9ydHMgYChidWlsZHRpbWUpYC5cbiAgICAgIC8vXG4gICAgICAvLyBBIFBhZ2VzIFJvdXRlciB0ZW1wbGF0ZSBpcyBzZWVkZWQgZm9yIHRoZSBzYW1lIHJlYXNvbjogaW4gcHJvZHVjdGlvblxuICAgICAgLy8gaXRzIGZpbGwgZnVuY3Rpb24gb25seSByZXR1cm5zIHdoYXQgdGhlIGNhY2hlIGFscmVhZHkgaG9sZHMsIHNvIHdpdGhcbiAgICAgIC8vIG5vdGhpbmcgc2VlZGVkIHRoZXJlIGlzIG5vIGBmYWxsYmFjazogdHJ1ZWAgc2hlbGwgdG8gc2VydmUgYW5kXG4gICAgICAvLyBgcm91dGVyLmlzRmFsbGJhY2tgIGlzIG5ldmVyIHRydWUgKGB0ZXN0L2UyZS9mYWxsYmFjay1yb3V0ZS1wYXJhbXNgKS5cbiAgICAgIC8vIE5vdGhpbmcgZXh0cmEgaXMgbmVlZGVkIHRvIGtlZXAgbm9uLVBQUiB0ZW1wbGF0ZXMgb3V0OiBhIHJvdXRlIHdpdGggbm9cbiAgICAgIC8vIHNoZWxsIGVtaXRzIG5vIHByZXJlbmRlciBvdXRwdXQuXG4gICAgICBjb25zdCBraW5kID0gY2FjaGVLaW5kT2YodmFyaWFudHMpO1xuICAgICAgaWYgKCFraW5kKSB7XG4gICAgICAgIGRlYnVnKGBTS0lQOiBObyByb3V0ZSBraW5kIGZvdW5kIGZvciAke2Jhc2VQYXRofWApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgZGVidWcoYFByb2Nlc3NpbmcgJHtiYXNlUGF0aH0gKCR7a2luZH0pYCk7XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgaHRtbDogaHRtbFByZXJlbmRlcixcbiAgICAgICAgcnNjOiByc2NQcmVyZW5kZXIsXG4gICAgICAgIHNlZ21lbnRzOiBzZWdtZW50UHJlcmVuZGVycyxcbiAgICAgICAgZGF0YTogZGF0YVByZXJlbmRlcixcbiAgICAgIH0gPSB2YXJpYW50cztcblxuICAgICAgaWYgKCFodG1sUHJlcmVuZGVyICYmICFyc2NQcmVyZW5kZXIgJiYgIWRhdGFQcmVyZW5kZXIpIHtcbiAgICAgICAgZGVidWcoYFNLSVA6IE5vIHByZXJlbmRlciBmaWxlcyBmb3VuZCBmb3IgJHtiYXNlUGF0aH1gKTtcbiAgICAgICAgY29udGludWU7IC8vIFNraXAgaWYgd2UgZG9uJ3QgaGF2ZSB0aGUgbWFpbiBmaWxlc1xuICAgICAgfVxuXG4gICAgICAvLyBDcmVhdGUgY2FjaGUgZW50cnkgd2l0aCB0aGUgYXBwcm9wcmlhdGUgc3RydWN0dXJlIGJhc2VkIG9uIGtpbmRcbiAgICAgIGxldCBjYWNoZUVudHJ5OiBDYWNoZUhhbmRsZXJWYWx1ZTtcblxuICAgICAgaWYgKGtpbmQgPT09IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSkge1xuICAgICAgICAvLyBSZWFkIEhUTUwgZmlsZVxuICAgICAgICBjb25zdCBodG1sID0gYXdhaXQgcmVhZFByZXJlbmRlckFzVGV4dChodG1sUHJlcmVuZGVyKTtcblxuICAgICAgICBpZiAoIWh0bWwpIHtcbiAgICAgICAgICBkZWJ1ZyhgU0tJUDogTm8gSFRNTCBjb250ZW50IGZvciBBUFBfUEFHRSAke2Jhc2VQYXRofWApO1xuICAgICAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIGlmIG5vIEhUTUwgY29udGVudFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVhZCBSU0MgZGF0YVxuICAgICAgICBjb25zdCByc2NEYXRhID0gYXdhaXQgcmVhZFByZXJlbmRlckFzQnVmZmVyKHJzY1ByZXJlbmRlcik7XG5cbiAgICAgICAgLy8gUmVhZCBzZWdtZW50IGRhdGFcbiAgICAgICAgY29uc3Qgc2VnbWVudERhdGEgPSBhd2FpdCBnZXRTZWdtZW50RGF0YShzZWdtZW50UHJlcmVuZGVycyk7XG5cbiAgICAgICAgLy8gRXh0cmFjdCBoZWFkZXJzIGZyb20gdGhlIEhUTUwgb3IgUlNDIHByZXJlbmRlclxuICAgICAgICBjb25zdCBoZWFkZXJzID0gYXBwUGFnZUNhY2hlSGVhZGVycyhcbiAgICAgICAgICBodG1sUHJlcmVuZGVyPy5mYWxsYmFjaz8uaW5pdGlhbEhlYWRlcnMgfHxcbiAgICAgICAgICAgIHJzY1ByZXJlbmRlcj8uZmFsbGJhY2s/LmluaXRpYWxIZWFkZXJzIHx8XG4gICAgICAgICAgICB7fSxcbiAgICAgICAgKTtcblxuICAgICAgICBjYWNoZUVudHJ5ID0ge1xuICAgICAgICAgIGxhc3RNb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICAgICAgaHRtbCxcbiAgICAgICAgICAgIHJzY0RhdGEsXG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgc2VnbWVudERhdGE6IHNlZ21lbnREYXRhLFxuICAgICAgICAgICAgLy8gcG9zdHBvbmVkU3RhdGUgZnJvbSBmYWxsYmFjayBhcHBlYXJzIHRvIGJlIHRoZSBSZWFjdCBwb3N0cG9uZWQgc3RhdGVcbiAgICAgICAgICAgIC8vIHdoaWNoIG1hdGNoZXMgd2hhdCB0aGUgY2FjaGUgZXhwZWN0cyBmb3IgcG9zdHBvbmVkXG4gICAgICAgICAgICBwb3N0cG9uZWQ6IGh0bWxQcmVyZW5kZXI/LmZhbGxiYWNrPy5wb3N0cG9uZWRTdGF0ZSxcbiAgICAgICAgICAgIC8vIGluaXRpYWxTdGF0dXMgZnJvbSBwcmVyZW5kZXIgaXMgdGhlIEhUVFAgc3RhdHVzIG9mIHRoZSBwcmVyZW5kZXJlZCBwYWdlXG4gICAgICAgICAgICBzdGF0dXM6IGh0bWxQcmVyZW5kZXI/LmZhbGxiYWNrPy5pbml0aWFsU3RhdHVzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKGtpbmQgPT09IENhY2hlZFJvdXRlS2luZC5BUFBfUk9VVEUpIHtcbiAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRQcmVyZW5kZXJBc0J1ZmZlcihodG1sUHJlcmVuZGVyKTtcblxuICAgICAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgICBkZWJ1ZyhgU0tJUDogTm8gYm9keSBjb250ZW50IGZvciBBUFBfUk9VVEUgJHtiYXNlUGF0aH1gKTtcbiAgICAgICAgICBjb250aW51ZTsgLy8gU2tpcCBpZiBubyBjb250ZW50XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeHRyYWN0IGhlYWRlcnNcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IGh0bWxQcmVyZW5kZXI/LmZhbGxiYWNrPy5pbml0aWFsSGVhZGVycyB8fCB7fTtcblxuICAgICAgICBjYWNoZUVudHJ5ID0ge1xuICAgICAgICAgIGxhc3RNb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9ST1VURSxcbiAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgc3RhdHVzOiBodG1sUHJlcmVuZGVyPy5mYWxsYmFjaz8uaW5pdGlhbFN0YXR1cyB8fCAyMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAoa2luZCA9PT0gQ2FjaGVkUm91dGVLaW5kLlBBR0VTKSB7XG4gICAgICAgIC8vIEEgYnVpbGQtdGltZSBgbm90Rm91bmQ6IHRydWVgLiBOZXh0LmpzIHJlcG9ydHMgdGhlIHJvdXRlIGFzXG4gICAgICAgIC8vIHByZXJlbmRlcmVkIGFuZCBoYW5kcyB1cyBhIHByZXJlbmRlciB3aG9zZSBgZmlsZVBhdGhgIGlzXG4gICAgICAgIC8vIGBwYWdlcy80MDQuaHRtbGAgYW5kIHdob3NlIGBpbml0aWFsU3RhdHVzYCBpcyA0MDQgLSBidXQgaXQgd3JpdGVzXG4gICAgICAgIC8vICpubyogb3V0cHV0IGZvciBpdCAobm8gYGZpcnN0Lmh0bWxgLCBgLmpzb25gIG9yIGAubWV0YWApLCBiZWNhdXNlIGFcbiAgICAgICAgLy8gUGFnZXMgUm91dGVyIGBub3RGb3VuZGAgaXMgcmVwcmVzZW50ZWQgaW4gdGhlIGNhY2hlIGFzIGFuIGVudHJ5XG4gICAgICAgIC8vIHdob3NlIGB2YWx1ZWAgaXMgYG51bGxgIChgcGFnZXMtaGFuZGxlci50c2AsIFwiaXNOb3RGb3VuZCBpblxuICAgICAgICAvLyBtZXRhZGF0YVwiKSwgYW5kIGBGaWxlU3lzdGVtQ2FjaGUuc2V0YCBrZWVwcyBhIG51bGwgdmFsdWUgaW4gaXRzIExSVVxuICAgICAgICAvLyBvbmx5LCBuZXZlciBvbiBkaXNrLiBTbyBgbmV4dCBzdGFydGAgbWlzc2VzLCByZS1ydW5zXG4gICAgICAgIC8vIGBnZXRTdGF0aWNQcm9wc2AsIGFuZCBhbnN3ZXJzIDQwNCBmcm9tIGByZW5kZXI0MDQoKWAuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFNlZWRpbmcgaXQgYXMgYW4gb3JkaW5hcnkgYFBBR0VTYCBlbnRyeSBtYWRlIHRoYXQgYSAyMDA6IHRoZSBlbnRyeVxuICAgICAgICAvLyBpcyBhIEhJVCBjYXJyeWluZyB0aGUgNDA0IHBhZ2UncyBIVE1MLCBhbmQgdGhlIHBhZ2VzIGhhbmRsZXIgbmV2ZXJcbiAgICAgICAgLy8gcmVhZHMgYHZhbHVlLnN0YXR1c2Agb24gdGhlIEhJVCBwYXRoLCBzbyB0aGUgc3RhdHVzIHN0YXllZCAyMDAgd2hpbGVcbiAgICAgICAgLy8gdGhlIGJvZHkgc2FpZCBcIjQwNCBwYWdlXCIuIFNraXBwaW5nIGl0IHJlc3RvcmVzIHRoZSBtaXNzLCBhbmQgd2l0aCBpdFxuICAgICAgICAvLyBgbmV4dCBzdGFydGAncyBzdGF0dXMuIENvc3RzIG9uZSByZW5kZXIgcGVyIHJldmFsaWRhdGUgd2luZG93LCB3aGljaFxuICAgICAgICAvLyBpcyB3aGF0IGBuZXh0IHN0YXJ0YCBwYXlzIHRvby5cbiAgICAgICAgY29uc3QgaW5pdGlhbFN0YXR1cyA9IGh0bWxQcmVyZW5kZXI/LmZhbGxiYWNrPy5pbml0aWFsU3RhdHVzO1xuICAgICAgICBpZiAoaW5pdGlhbFN0YXR1cyAhPT0gdW5kZWZpbmVkICYmIGluaXRpYWxTdGF0dXMgIT09IDIwMCkge1xuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYFNLSVA6IFBBR0VTICR7YmFzZVBhdGh9IHByZXJlbmRlcmVkIHdpdGggc3RhdHVzICR7aW5pdGlhbFN0YXR1c30gKGJ1aWxkLXRpbWUgbm90Rm91bmQpYCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlYWRQcmVyZW5kZXJBc1RleHQoaHRtbFByZXJlbmRlcik7XG5cbiAgICAgICAgaWYgKCFodG1sKSB7XG4gICAgICAgICAgZGVidWcoYFNLSVA6IE5vIEhUTUwgY29udGVudCBmb3IgUEFHRVMgJHtiYXNlUGF0aH1gKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGBnZXRTdGF0aWNQcm9wc2AnIHJlc3VsdCwgd2hpY2ggdGhlIGVudHJ5cG9pbnQgYW5zd2Vyc1xuICAgICAgICAvLyBgL19uZXh0L2RhdGEvPGJ1aWxkSWQ+LzxwYWdlPi5qc29uYCB3aXRoIGFuZCB0aGUgY2xpZW50IHJvdXRlciByZWFkc1xuICAgICAgICAvLyBvbiBhIG5hdmlnYXRpb24uIEEgcm91dGUncyAqZmFsbGJhY2sqIHRlbXBsYXRlIGhhcyBubyBkYXRhIGZpbGUgLVxuICAgICAgICAvLyB0aGVyZSBhcmUgbm8gcGFyYW1zIHRvIHJ1biBgZ2V0U3RhdGljUHJvcHNgIHdpdGggeWV0IC0gYW5kXG4gICAgICAgIC8vIGBGaWxlU3lzdGVtQ2FjaGVgIHNraXBzIHRoZSByZWFkIGZvciBvbmUgdG9vIChgaWYgKCFjdHguaXNGYWxsYmFjaylgKSxcbiAgICAgICAgLy8gbGVhdmluZyBgcGFnZURhdGFgIGFuIGVtcHR5IG9iamVjdC5cbiAgICAgICAgY29uc3QgcGFnZURhdGFKc29uID0gYXdhaXQgcmVhZFByZXJlbmRlckFzVGV4dChkYXRhUHJlcmVuZGVyKTtcblxuICAgICAgICBjYWNoZUVudHJ5ID0ge1xuICAgICAgICAgIGxhc3RNb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLlBBR0VTLFxuICAgICAgICAgICAgaHRtbCxcbiAgICAgICAgICAgIHBhZ2VEYXRhOiBwYWdlRGF0YUpzb24gPyBKU09OLnBhcnNlKHBhZ2VEYXRhSnNvbikgOiB7fSxcbiAgICAgICAgICAgIC8vIEJvdGggYHVuZGVmaW5lZGAsIHdoaWNoIGlzIHdoYXQgYEZpbGVTeXN0ZW1DYWNoZWAgaGFuZHMgYmFjayBmb3JcbiAgICAgICAgICAgIC8vIGEgYFBBR0VTYCBlbnRyeTogaXQgcmVhZHMgYSBgLm1ldGFgIHNpZGVjYXIgZm9yIHRoZSBBcHAgUm91dGVyXG4gICAgICAgICAgICAvLyBraW5kcyBvbmx5LCBhbmQgYHNlbmRSZW5kZXJSZXN1bHRgIHN1cHBsaWVzIHRoZSBjb250ZW50IHR5cGUuXG4gICAgICAgICAgICAvLyBTZWVkaW5nIGBmYWxsYmFjay5pbml0aWFsSGVhZGVyc2AgaW5zdGVhZCB3b3VsZCBwdXRcbiAgICAgICAgICAgIC8vIGBjb250ZW50LXR5cGU6IHRleHQvaHRtbGAgb24gdGhlIEpTT04gZGF0YSByZXNwb25zZXMgc2VydmVkIGZyb21cbiAgICAgICAgICAgIC8vIHRoaXMgc2FtZSBlbnRyeS5cbiAgICAgICAgICAgIGhlYWRlcnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHN0YXR1czogdW5kZWZpbmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTa2lwIHVuc3VwcG9ydGVkIGtpbmRzXG4gICAgICAgIGRlYnVnKGBTS0lQOiBVbnN1cHBvcnRlZCByb3V0ZSBraW5kICR7a2luZH0gZm9yICR7YmFzZVBhdGh9YCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBXcml0ZSBjYWNoZSBlbnRyeSB0byBmaWxlLCB1bmRlciB0aGUgcm91dGUgcmF0aGVyIHRoYW4gdGhlIFVSTCBpdCBpc1xuICAgICAgLy8gc2VydmVkIGF0IC0gc2VlIGBwcmVyZW5kZXJQYXRoVG9DYWNoZUtleWAuXG4gICAgICBjb25zdCBjYWNoZUtleSA9IHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFxuICAgICAgICBiYXNlUGF0aCxcbiAgICAgICAgY3R4LmNvbmZpZy5iYXNlUGF0aCB8fCBcIlwiLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGNhY2hlRmlsZVBhdGggPSBqb2luKGNhY2hlRGlyLCBgJHtjYWNoZUtleX0uanNvbmApO1xuXG4gICAgICAvLyBFbnN1cmUgcGFyZW50IGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGF3YWl0IG1rZGlyKGpvaW4oY2FjaGVEaXIsIGNhY2hlS2V5LnNwbGl0KFwiL1wiKS5zbGljZSgwLCAtMSkuam9pbihcIi9cIikpLCB7XG4gICAgICAgIHJlY3Vyc2l2ZTogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCB3cml0ZUZpbGUoY2FjaGVGaWxlUGF0aCwgc2VyaWFsaXplQ2FjaGVWYWx1ZShjYWNoZUVudHJ5KSk7XG5cbiAgICAgIGZvciAoY29uc3QgdGFnIG9mIGhlYWRlclRhZ3MoY2FjaGVFbnRyeS52YWx1ZSkpIHtcbiAgICAgICAgKHRhZ01hbmlmZXN0W3RhZ10gPz89IFtdKS5wdXNoKGNhY2hlS2V5KTtcbiAgICAgIH1cblxuICAgICAgZGVidWcoYENyZWF0ZWQgY2FjaGUgZW50cnk6ICR7Y2FjaGVGaWxlUGF0aH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgcHJvY2Vzc2luZyBwcmVyZW5kZXIgZ3JvdXAgJHtiYXNlUGF0aH06YCwgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHRhZ2dlZEtleXMgPSBPYmplY3Qua2V5cyh0YWdNYW5pZmVzdCkubGVuZ3RoO1xuICBpZiAodGFnZ2VkS2V5cyA+IDApIHtcbiAgICBhd2FpdCB3cml0ZUZpbGUoXG4gICAgICBqb2luKGNhY2hlRGlyLCBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVCksXG4gICAgICBKU09OLnN0cmluZ2lmeSh0YWdNYW5pZmVzdCksXG4gICAgKTtcbiAgICBkZWJ1ZyhgV3JvdGUgJHtJTklUX0NBQ0hFX1RBR19NQU5JRkVTVH0gd2l0aCAke3RhZ2dlZEtleXN9IHRhZ3NgKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlYWQgZmlsZSBjb250ZW50IGZyb20gYSBwcmVyZW5kZXIgYXMgVVRGLTggc3RyaW5nXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRQcmVyZW5kZXJBc1RleHQoXG4gIHByZXJlbmRlcjpcbiAgICB8IHsgZmFsbGJhY2s/OiB7IGZpbGVQYXRoPzogc3RyaW5nIH0gfCB7IHBvc3Rwb25lZFN0YXRlOiBzdHJpbmcgfSB9XG4gICAgfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBpZiAoXG4gICAgcHJlcmVuZGVyPy5mYWxsYmFjayAmJlxuICAgIFwiZmlsZVBhdGhcIiBpbiBwcmVyZW5kZXIuZmFsbGJhY2sgJiZcbiAgICBwcmVyZW5kZXIuZmFsbGJhY2suZmlsZVBhdGggJiZcbiAgICBleGlzdHNTeW5jKHByZXJlbmRlci5mYWxsYmFjay5maWxlUGF0aClcbiAgKSB7XG4gICAgcmV0dXJuIHJlYWRGaWxlKHByZXJlbmRlci5mYWxsYmFjay5maWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlYWQgZmlsZSBjb250ZW50IGZyb20gYSBwcmVyZW5kZXIgYXMgQnVmZmVyXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRQcmVyZW5kZXJBc0J1ZmZlcihcbiAgcHJlcmVuZGVyOlxuICAgIHwgeyBmYWxsYmFjaz86IHsgZmlsZVBhdGg/OiBzdHJpbmcgfSB8IHsgcG9zdHBvbmVkU3RhdGU6IHN0cmluZyB9IH1cbiAgICB8IHVuZGVmaW5lZCxcbik6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChcbiAgICBwcmVyZW5kZXI/LmZhbGxiYWNrICYmXG4gICAgXCJmaWxlUGF0aFwiIGluIHByZXJlbmRlci5mYWxsYmFjayAmJlxuICAgIHByZXJlbmRlci5mYWxsYmFjay5maWxlUGF0aCAmJlxuICAgIGV4aXN0c1N5bmMocHJlcmVuZGVyLmZhbGxiYWNrLmZpbGVQYXRoKVxuICApIHtcbiAgICByZXR1cm4gcmVhZEZpbGUocHJlcmVuZGVyLmZhbGxiYWNrLmZpbGVQYXRoKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlYWQgc2VnbWVudCBkYXRhIGZyb20gc2VnbWVudCBwcmVyZW5kZXJzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFNlZ21lbnREYXRhPFxuICBUIGV4dGVuZHMge1xuICAgIHBhdGhuYW1lOiBzdHJpbmc7XG4gICAgZmFsbGJhY2s/OiB7IGZpbGVQYXRoPzogc3RyaW5nIH0gfCB7IHBvc3Rwb25lZFN0YXRlOiBzdHJpbmcgfTtcbiAgfSxcbj4oc2VnbWVudFByZXJlbmRlcnM6IFRbXSk6IFByb21pc2U8TWFwPHN0cmluZywgQnVmZmVyPj4ge1xuICBjb25zdCBzZWdtZW50RGF0YSA9IG5ldyBNYXA8c3RyaW5nLCBCdWZmZXI+KCk7XG5cbiAgZm9yIChjb25zdCBzZWdtZW50UHJlcmVuZGVyIG9mIHNlZ21lbnRQcmVyZW5kZXJzKSB7XG4gICAgaWYgKFxuICAgICAgc2VnbWVudFByZXJlbmRlci5mYWxsYmFjayAmJlxuICAgICAgXCJmaWxlUGF0aFwiIGluIHNlZ21lbnRQcmVyZW5kZXIuZmFsbGJhY2sgJiZcbiAgICAgIHNlZ21lbnRQcmVyZW5kZXIuZmFsbGJhY2suZmlsZVBhdGggJiZcbiAgICAgIGV4aXN0c1N5bmMoc2VnbWVudFByZXJlbmRlci5mYWxsYmFjay5maWxlUGF0aClcbiAgICApIHtcbiAgICAgIGNvbnN0IHNlZ21lbnRDb250ZW50ID0gYXdhaXQgcmVhZEZpbGUoc2VnbWVudFByZXJlbmRlci5mYWxsYmFjay5maWxlUGF0aCk7XG4gICAgICAvLyBFeHRyYWN0IHNlZ21lbnQgbmFtZSBmcm9tIHBhdGhuYW1lXG4gICAgICBjb25zdCBzZWdtZW50TmFtZSA9XG4gICAgICAgIFwiL1wiICtcbiAgICAgICAgc2VnbWVudFByZXJlbmRlci5wYXRobmFtZVxuICAgICAgICAgIC5zcGxpdChcIi5zZWdtZW50cy9cIilbMV1cbiAgICAgICAgICAucmVwbGFjZSgvXFwuc2VnbWVudFxcLnJzYyQvLCBcIlwiKTtcbiAgICAgIHNlZ21lbnREYXRhLnNldChzZWdtZW50TmFtZSwgc2VnbWVudENvbnRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzZWdtZW50RGF0YTtcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_fs_1 = require("node:fs");
4
+ const promises_1 = require("node:fs/promises");
5
+ const node_os_1 = require("node:os");
6
+ const node_path_1 = require("node:path");
7
+ const cache_utils_1 = require("./cache-utils");
8
+ const init_cache_1 = require("./init-cache");
9
+ let dir;
10
+ let cacheDir;
11
+ beforeEach(async () => {
12
+ dir = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "init-cache-test-"));
13
+ cacheDir = (0, node_path_1.join)(dir, "cache");
14
+ });
15
+ afterEach(async () => {
16
+ await (0, promises_1.rm)(dir, { recursive: true, force: true });
17
+ });
18
+ /** A prerender output as `next build` hands it to `onBuildComplete`. */
19
+ async function prerender(pathname, parentOutputId, body, fallback = {}) {
20
+ const filePath = (0, node_path_1.join)(dir, `${pathname.replace(/\//g, "_")}.out`);
21
+ await (0, promises_1.writeFile)(filePath, body);
22
+ return { pathname, parentOutputId, fallback: { filePath, ...fallback } };
23
+ }
24
+ function context(prerenders, basePath = "") {
25
+ return {
26
+ config: { basePath },
27
+ outputs: {
28
+ pages: [{ id: "/blog/[slug]" }, { id: "/gone" }],
29
+ appPages: [{ id: "/shop" }, { id: "/isr/[id]" }],
30
+ appRoutes: [{ id: "/feed.xml" }],
31
+ pagesApi: [],
32
+ prerenders,
33
+ staticFiles: [],
34
+ },
35
+ };
36
+ }
37
+ const readEntry = async (key) => JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(cacheDir, `${key}.json`), "utf8"));
38
+ describe("writeInitCache", () => {
39
+ it("seeds each kind with the shape the cache handler reads", async () => {
40
+ const ctx = context([
41
+ await prerender("/shop", "/shop", "<html>shop</html>", {
42
+ initialStatus: 200,
43
+ postponedState: undefined,
44
+ initialHeaders: {
45
+ "content-type": "text/html; charset=utf-8",
46
+ "x-next-cache-tags": "shop,_N_T_/shop",
47
+ },
48
+ }),
49
+ await prerender("/shop.rsc", "/shop", "flight"),
50
+ await prerender("/shop.segments/_tree.segment.rsc", "/shop", "tree"),
51
+ await prerender("/feed.xml", "/feed.xml", "<rss/>", {
52
+ initialHeaders: { "content-type": "application/xml" },
53
+ }),
54
+ await prerender("/blog/hello", "/blog/[slug]", "<html>hello</html>", {
55
+ initialStatus: 200,
56
+ initialHeaders: { "content-type": "text/html" },
57
+ }),
58
+ await prerender("/_next/data/build/blog/hello.json", "/blog/[slug]", JSON.stringify({ pageProps: { slug: "hello" } })),
59
+ ]);
60
+ await (0, init_cache_1.writeInitCache)(ctx, cacheDir);
61
+ const shop = await readEntry("shop");
62
+ expect(shop.value.kind).toBe("APP_PAGE");
63
+ expect(shop.value.html).toBe("<html>shop</html>");
64
+ expect(shop.value.status).toBe(200);
65
+ // Presentational headers stay out of an APP_PAGE entry; the render's own
66
+ // (cache tags) stay in.
67
+ expect(shop.value.headers).toEqual({
68
+ "x-next-cache-tags": "shop,_N_T_/shop",
69
+ });
70
+ expect(JSON.stringify(shop.value.rscData)).toContain(Buffer.from("flight").toString("base64"));
71
+ expect(JSON.stringify(shop.value.segmentData)).toContain("/_tree");
72
+ const feed = await readEntry("feed.xml");
73
+ expect(feed.value.kind).toBe("APP_ROUTE");
74
+ expect(feed.value.status).toBe(200);
75
+ expect(feed.value.headers).toEqual({ "content-type": "application/xml" });
76
+ const hello = await readEntry("blog/hello");
77
+ expect(hello.value.kind).toBe("PAGES");
78
+ expect(hello.value.html).toBe("<html>hello</html>");
79
+ expect(hello.value.pageData).toEqual({ pageProps: { slug: "hello" } });
80
+ // `FileSystemCache` hands a PAGES entry back without headers; seeding
81
+ // `initialHeaders` would label its JSON data responses text/html.
82
+ expect(hello.value.headers).toBeUndefined();
83
+ });
84
+ it("seeds a dynamic route's template under its own key, with the PPR shell's postponed state", async () => {
85
+ // With PPR the template is the route's fallback shell, looked up under the
86
+ // literal template key; the Pages Router looks up an ISR fallback the same
87
+ // way. Unseeded, every such lookup missed and the shell rendered per request.
88
+ const ctx = context([
89
+ await prerender("/isr/[id]", "/isr/[id]", "<html>shell</html>", {
90
+ initialStatus: 200,
91
+ postponedState: "postponed-state",
92
+ }),
93
+ await prerender("/isr/[id].rsc", "/isr/[id]", "flight"),
94
+ await prerender("/blog/[slug]", "/blog/[slug]", "<html>fallback</html>", {
95
+ initialStatus: 200,
96
+ }),
97
+ ]);
98
+ await (0, init_cache_1.writeInitCache)(ctx, cacheDir);
99
+ const shell = await readEntry("isr/[id]");
100
+ expect(shell.value.kind).toBe("APP_PAGE");
101
+ expect(shell.value.html).toBe("<html>shell</html>");
102
+ expect(shell.value.postponed).toBe("postponed-state");
103
+ const fallback = await readEntry("blog/[slug]");
104
+ expect(fallback.value.kind).toBe("PAGES");
105
+ expect(fallback.value.html).toBe("<html>fallback</html>");
106
+ });
107
+ it("skips a Pages Router route prerendered with a non-200 status", async () => {
108
+ // A build-time `notFound: true`: seeding it would be a 200 HIT with the 404
109
+ // page's HTML.
110
+ const ctx = context([
111
+ await prerender("/gone", "/gone", "<html>404</html>", {
112
+ initialStatus: 404,
113
+ }),
114
+ ]);
115
+ await (0, init_cache_1.writeInitCache)(ctx, cacheDir);
116
+ expect((0, node_fs_1.existsSync)((0, node_path_1.join)(cacheDir, "gone.json"))).toBe(false);
117
+ });
118
+ it("maps each tag to the keys carrying it, under basePath-less keys", async () => {
119
+ const ctx = context([
120
+ await prerender("/docs/shop", "/shop", "<html>a</html>", {
121
+ initialHeaders: { "x-next-cache-tags": "products,_N_T_/shop" },
122
+ }),
123
+ ], "/docs");
124
+ await (0, init_cache_1.writeInitCache)(ctx, cacheDir);
125
+ const manifest = JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(cacheDir, cache_utils_1.INIT_CACHE_TAG_MANIFEST), "utf8"));
126
+ expect(manifest).toEqual({
127
+ products: ["shop"],
128
+ "_N_T_/shop": ["shop"],
129
+ });
130
+ });
131
+ it("writes no tag manifest when nothing is tagged", async () => {
132
+ const ctx = context([await prerender("/feed.xml", "/feed.xml", "<rss/>")]);
133
+ await (0, init_cache_1.writeInitCache)(ctx, cacheDir);
134
+ expect(await (0, promises_1.readdir)(cacheDir)).toEqual(["feed.xml.json"]);
135
+ });
136
+ });
137
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC1jYWNoZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvaW5pdC1jYWNoZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEscUNBQXFDO0FBQ3JDLCtDQUE2RTtBQUM3RSxxQ0FBaUM7QUFDakMseUNBQWlDO0FBRWpDLCtDQUF3RDtBQUN4RCw2Q0FBOEM7QUFFOUMsSUFBSSxHQUFXLENBQUM7QUFDaEIsSUFBSSxRQUFnQixDQUFDO0FBRXJCLFVBQVUsQ0FBQyxLQUFLLElBQUksRUFBRTtJQUNwQixHQUFHLEdBQUcsTUFBTSxJQUFBLGtCQUFPLEVBQUMsSUFBQSxnQkFBSSxFQUFDLElBQUEsZ0JBQU0sR0FBRSxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQztJQUN4RCxRQUFRLEdBQUcsSUFBQSxnQkFBSSxFQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNoQyxDQUFDLENBQUMsQ0FBQztBQUVILFNBQVMsQ0FBQyxLQUFLLElBQUksRUFBRTtJQUNuQixNQUFNLElBQUEsYUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDbEQsQ0FBQyxDQUFDLENBQUM7QUFFSCx3RUFBd0U7QUFDeEUsS0FBSyxVQUFVLFNBQVMsQ0FDdEIsUUFBZ0IsRUFDaEIsY0FBc0IsRUFDdEIsSUFBWSxFQUNaLFdBQW9DLEVBQUU7SUFFdEMsTUFBTSxRQUFRLEdBQUcsSUFBQSxnQkFBSSxFQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsRSxNQUFNLElBQUEsb0JBQVMsRUFBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLEdBQUcsUUFBUSxFQUFFLEVBQUUsQ0FBQztBQUMzRSxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQ2QsVUFBcUIsRUFDckIsUUFBUSxHQUFHLEVBQUU7SUFFYixPQUFPO1FBQ0wsTUFBTSxFQUFFLEVBQUUsUUFBUSxFQUFFO1FBQ3BCLE9BQU8sRUFBRTtZQUNQLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ2hELFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDO1lBQ2hELFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLFFBQVEsRUFBRSxFQUFFO1lBQ1osVUFBVTtZQUNWLFdBQVcsRUFBRSxFQUFFO1NBQ2hCO0tBQzZELENBQUM7QUFDbkUsQ0FBQztBQUVELE1BQU0sU0FBUyxHQUFHLEtBQUssRUFBRSxHQUFXLEVBQUUsRUFBRSxDQUN0QyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sSUFBQSxtQkFBUSxFQUFDLElBQUEsZ0JBQUksRUFBQyxRQUFRLEVBQUUsR0FBRyxHQUFHLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFFcEUsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixFQUFFLENBQUMsd0RBQXdELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdEUsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDO1lBQ2xCLE1BQU0sU0FBUyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUU7Z0JBQ3JELGFBQWEsRUFBRSxHQUFHO2dCQUNsQixjQUFjLEVBQUUsU0FBUztnQkFDekIsY0FBYyxFQUFFO29CQUNkLGNBQWMsRUFBRSwwQkFBMEI7b0JBQzFDLG1CQUFtQixFQUFFLGlCQUFpQjtpQkFDdkM7YUFDRixDQUFDO1lBQ0YsTUFBTSxTQUFTLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUM7WUFDL0MsTUFBTSxTQUFTLENBQUMsa0NBQWtDLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQztZQUNwRSxNQUFNLFNBQVMsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRTtnQkFDbEQsY0FBYyxFQUFFLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFO2FBQ3RELENBQUM7WUFDRixNQUFNLFNBQVMsQ0FBQyxhQUFhLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFO2dCQUNuRSxhQUFhLEVBQUUsR0FBRztnQkFDbEIsY0FBYyxFQUFFLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRTthQUNoRCxDQUFDO1lBQ0YsTUFBTSxTQUFTLENBQ2IsbUNBQW1DLEVBQ25DLGNBQWMsRUFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FDakQ7U0FDRixDQUFDLENBQUM7UUFDSCxNQUFNLElBQUEsMkJBQWMsRUFBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFcEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQyx5RUFBeUU7UUFDekUsd0JBQXdCO1FBQ3hCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNqQyxtQkFBbUIsRUFBRSxpQkFBaUI7U0FDdkMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FDbEQsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQ3pDLENBQUM7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRW5FLE1BQU0sSUFBSSxHQUFHLE1BQU0sU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUUxRSxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM1QyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDcEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN2RSxzRUFBc0U7UUFDdEUsa0VBQWtFO1FBQ2xFLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzlDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBGQUEwRixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3hHLDJFQUEyRTtRQUMzRSwyRUFBMkU7UUFDM0UsOEVBQThFO1FBQzlFLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQztZQUNsQixNQUFNLFNBQVMsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLG9CQUFvQixFQUFFO2dCQUM5RCxhQUFhLEVBQUUsR0FBRztnQkFDbEIsY0FBYyxFQUFFLGlCQUFpQjthQUNsQyxDQUFDO1lBQ0YsTUFBTSxTQUFTLENBQUMsZUFBZSxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUM7WUFDdkQsTUFBTSxTQUFTLENBQUMsY0FBYyxFQUFFLGNBQWMsRUFBRSx1QkFBdUIsRUFBRTtnQkFDdkUsYUFBYSxFQUFFLEdBQUc7YUFDbkIsQ0FBQztTQUNILENBQUMsQ0FBQztRQUNILE1BQU0sSUFBQSwyQkFBYyxFQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUVwQyxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDcEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFdEQsTUFBTSxRQUFRLEdBQUcsTUFBTSxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzVELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDhEQUE4RCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzVFLDRFQUE0RTtRQUM1RSxlQUFlO1FBQ2YsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDO1lBQ2xCLE1BQU0sU0FBUyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUU7Z0JBQ3BELGFBQWEsRUFBRSxHQUFHO2FBQ25CLENBQUM7U0FDSCxDQUFDLENBQUM7UUFDSCxNQUFNLElBQUEsMkJBQWMsRUFBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLElBQUEsb0JBQVUsRUFBQyxJQUFBLGdCQUFJLEVBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaUVBQWlFLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0UsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUNqQjtZQUNFLE1BQU0sU0FBUyxDQUFDLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBQ3ZELGNBQWMsRUFBRSxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFO2FBQy9ELENBQUM7U0FDSCxFQUNELE9BQU8sQ0FDUixDQUFDO1FBQ0YsTUFBTSxJQUFBLDJCQUFjLEVBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBRXBDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQ3pCLE1BQU0sSUFBQSxtQkFBUSxFQUFDLElBQUEsZ0JBQUksRUFBQyxRQUFRLEVBQUUscUNBQXVCLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FDaEUsQ0FBQztRQUNGLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDdkIsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDO1lBQ2xCLFlBQVksRUFBRSxDQUFDLE1BQU0sQ0FBQztTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM3RCxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRSxNQUFNLElBQUEsMkJBQWMsRUFBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLE1BQU0sSUFBQSxrQkFBTyxFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUM3RCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBta2R0ZW1wLCByZWFkRmlsZSwgcmVhZGRpciwgcm0sIHdyaXRlRmlsZSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgQnVpbGRDb21wbGV0ZUNvbnRleHQgfSBmcm9tIFwiLi9idWlsZC1vdXRwdXRzXCI7XG5pbXBvcnQgeyBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVCB9IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5pbXBvcnQgeyB3cml0ZUluaXRDYWNoZSB9IGZyb20gXCIuL2luaXQtY2FjaGVcIjtcblxubGV0IGRpcjogc3RyaW5nO1xubGV0IGNhY2hlRGlyOiBzdHJpbmc7XG5cbmJlZm9yZUVhY2goYXN5bmMgKCkgPT4ge1xuICBkaXIgPSBhd2FpdCBta2R0ZW1wKGpvaW4odG1wZGlyKCksIFwiaW5pdC1jYWNoZS10ZXN0LVwiKSk7XG4gIGNhY2hlRGlyID0gam9pbihkaXIsIFwiY2FjaGVcIik7XG59KTtcblxuYWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcbiAgYXdhaXQgcm0oZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG59KTtcblxuLyoqIEEgcHJlcmVuZGVyIG91dHB1dCBhcyBgbmV4dCBidWlsZGAgaGFuZHMgaXQgdG8gYG9uQnVpbGRDb21wbGV0ZWAuICovXG5hc3luYyBmdW5jdGlvbiBwcmVyZW5kZXIoXG4gIHBhdGhuYW1lOiBzdHJpbmcsXG4gIHBhcmVudE91dHB1dElkOiBzdHJpbmcsXG4gIGJvZHk6IHN0cmluZyxcbiAgZmFsbGJhY2s6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pIHtcbiAgY29uc3QgZmlsZVBhdGggPSBqb2luKGRpciwgYCR7cGF0aG5hbWUucmVwbGFjZSgvXFwvL2csIFwiX1wiKX0ub3V0YCk7XG4gIGF3YWl0IHdyaXRlRmlsZShmaWxlUGF0aCwgYm9keSk7XG4gIHJldHVybiB7IHBhdGhuYW1lLCBwYXJlbnRPdXRwdXRJZCwgZmFsbGJhY2s6IHsgZmlsZVBhdGgsIC4uLmZhbGxiYWNrIH0gfTtcbn1cblxuZnVuY3Rpb24gY29udGV4dChcbiAgcHJlcmVuZGVyczogdW5rbm93bltdLFxuICBiYXNlUGF0aCA9IFwiXCIsXG4pOiBQaWNrPEJ1aWxkQ29tcGxldGVDb250ZXh0LCBcImNvbmZpZ1wiIHwgXCJvdXRwdXRzXCI+IHtcbiAgcmV0dXJuIHtcbiAgICBjb25maWc6IHsgYmFzZVBhdGggfSxcbiAgICBvdXRwdXRzOiB7XG4gICAgICBwYWdlczogW3sgaWQ6IFwiL2Jsb2cvW3NsdWddXCIgfSwgeyBpZDogXCIvZ29uZVwiIH1dLFxuICAgICAgYXBwUGFnZXM6IFt7IGlkOiBcIi9zaG9wXCIgfSwgeyBpZDogXCIvaXNyL1tpZF1cIiB9XSxcbiAgICAgIGFwcFJvdXRlczogW3sgaWQ6IFwiL2ZlZWQueG1sXCIgfV0sXG4gICAgICBwYWdlc0FwaTogW10sXG4gICAgICBwcmVyZW5kZXJzLFxuICAgICAgc3RhdGljRmlsZXM6IFtdLFxuICAgIH0sXG4gIH0gYXMgdW5rbm93biBhcyBQaWNrPEJ1aWxkQ29tcGxldGVDb250ZXh0LCBcImNvbmZpZ1wiIHwgXCJvdXRwdXRzXCI+O1xufVxuXG5jb25zdCByZWFkRW50cnkgPSBhc3luYyAoa2V5OiBzdHJpbmcpID0+XG4gIEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihjYWNoZURpciwgYCR7a2V5fS5qc29uYCksIFwidXRmOFwiKSk7XG5cbmRlc2NyaWJlKFwid3JpdGVJbml0Q2FjaGVcIiwgKCkgPT4ge1xuICBpdChcInNlZWRzIGVhY2gga2luZCB3aXRoIHRoZSBzaGFwZSB0aGUgY2FjaGUgaGFuZGxlciByZWFkc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY3R4ID0gY29udGV4dChbXG4gICAgICBhd2FpdCBwcmVyZW5kZXIoXCIvc2hvcFwiLCBcIi9zaG9wXCIsIFwiPGh0bWw+c2hvcDwvaHRtbD5cIiwge1xuICAgICAgICBpbml0aWFsU3RhdHVzOiAyMDAsXG4gICAgICAgIHBvc3Rwb25lZFN0YXRlOiB1bmRlZmluZWQsXG4gICAgICAgIGluaXRpYWxIZWFkZXJzOiB7XG4gICAgICAgICAgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgICAgICBcIngtbmV4dC1jYWNoZS10YWdzXCI6IFwic2hvcCxfTl9UXy9zaG9wXCIsXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIGF3YWl0IHByZXJlbmRlcihcIi9zaG9wLnJzY1wiLCBcIi9zaG9wXCIsIFwiZmxpZ2h0XCIpLFxuICAgICAgYXdhaXQgcHJlcmVuZGVyKFwiL3Nob3Auc2VnbWVudHMvX3RyZWUuc2VnbWVudC5yc2NcIiwgXCIvc2hvcFwiLCBcInRyZWVcIiksXG4gICAgICBhd2FpdCBwcmVyZW5kZXIoXCIvZmVlZC54bWxcIiwgXCIvZmVlZC54bWxcIiwgXCI8cnNzLz5cIiwge1xuICAgICAgICBpbml0aWFsSGVhZGVyczogeyBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL3htbFwiIH0sXG4gICAgICB9KSxcbiAgICAgIGF3YWl0IHByZXJlbmRlcihcIi9ibG9nL2hlbGxvXCIsIFwiL2Jsb2cvW3NsdWddXCIsIFwiPGh0bWw+aGVsbG88L2h0bWw+XCIsIHtcbiAgICAgICAgaW5pdGlhbFN0YXR1czogMjAwLFxuICAgICAgICBpbml0aWFsSGVhZGVyczogeyBcImNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbFwiIH0sXG4gICAgICB9KSxcbiAgICAgIGF3YWl0IHByZXJlbmRlcihcbiAgICAgICAgXCIvX25leHQvZGF0YS9idWlsZC9ibG9nL2hlbGxvLmpzb25cIixcbiAgICAgICAgXCIvYmxvZy9bc2x1Z11cIixcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoeyBwYWdlUHJvcHM6IHsgc2x1ZzogXCJoZWxsb1wiIH0gfSksXG4gICAgICApLFxuICAgIF0pO1xuICAgIGF3YWl0IHdyaXRlSW5pdENhY2hlKGN0eCwgY2FjaGVEaXIpO1xuXG4gICAgY29uc3Qgc2hvcCA9IGF3YWl0IHJlYWRFbnRyeShcInNob3BcIik7XG4gICAgZXhwZWN0KHNob3AudmFsdWUua2luZCkudG9CZShcIkFQUF9QQUdFXCIpO1xuICAgIGV4cGVjdChzaG9wLnZhbHVlLmh0bWwpLnRvQmUoXCI8aHRtbD5zaG9wPC9odG1sPlwiKTtcbiAgICBleHBlY3Qoc2hvcC52YWx1ZS5zdGF0dXMpLnRvQmUoMjAwKTtcbiAgICAvLyBQcmVzZW50YXRpb25hbCBoZWFkZXJzIHN0YXkgb3V0IG9mIGFuIEFQUF9QQUdFIGVudHJ5OyB0aGUgcmVuZGVyJ3Mgb3duXG4gICAgLy8gKGNhY2hlIHRhZ3MpIHN0YXkgaW4uXG4gICAgZXhwZWN0KHNob3AudmFsdWUuaGVhZGVycykudG9FcXVhbCh7XG4gICAgICBcIngtbmV4dC1jYWNoZS10YWdzXCI6IFwic2hvcCxfTl9UXy9zaG9wXCIsXG4gICAgfSk7XG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHNob3AudmFsdWUucnNjRGF0YSkpLnRvQ29udGFpbihcbiAgICAgIEJ1ZmZlci5mcm9tKFwiZmxpZ2h0XCIpLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICk7XG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHNob3AudmFsdWUuc2VnbWVudERhdGEpKS50b0NvbnRhaW4oXCIvX3RyZWVcIik7XG5cbiAgICBjb25zdCBmZWVkID0gYXdhaXQgcmVhZEVudHJ5KFwiZmVlZC54bWxcIik7XG4gICAgZXhwZWN0KGZlZWQudmFsdWUua2luZCkudG9CZShcIkFQUF9ST1VURVwiKTtcbiAgICBleHBlY3QoZmVlZC52YWx1ZS5zdGF0dXMpLnRvQmUoMjAwKTtcbiAgICBleHBlY3QoZmVlZC52YWx1ZS5oZWFkZXJzKS50b0VxdWFsKHsgXCJjb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi94bWxcIiB9KTtcblxuICAgIGNvbnN0IGhlbGxvID0gYXdhaXQgcmVhZEVudHJ5KFwiYmxvZy9oZWxsb1wiKTtcbiAgICBleHBlY3QoaGVsbG8udmFsdWUua2luZCkudG9CZShcIlBBR0VTXCIpO1xuICAgIGV4cGVjdChoZWxsby52YWx1ZS5odG1sKS50b0JlKFwiPGh0bWw+aGVsbG88L2h0bWw+XCIpO1xuICAgIGV4cGVjdChoZWxsby52YWx1ZS5wYWdlRGF0YSkudG9FcXVhbCh7IHBhZ2VQcm9wczogeyBzbHVnOiBcImhlbGxvXCIgfSB9KTtcbiAgICAvLyBgRmlsZVN5c3RlbUNhY2hlYCBoYW5kcyBhIFBBR0VTIGVudHJ5IGJhY2sgd2l0aG91dCBoZWFkZXJzOyBzZWVkaW5nXG4gICAgLy8gYGluaXRpYWxIZWFkZXJzYCB3b3VsZCBsYWJlbCBpdHMgSlNPTiBkYXRhIHJlc3BvbnNlcyB0ZXh0L2h0bWwuXG4gICAgZXhwZWN0KGhlbGxvLnZhbHVlLmhlYWRlcnMpLnRvQmVVbmRlZmluZWQoKTtcbiAgfSk7XG5cbiAgaXQoXCJzZWVkcyBhIGR5bmFtaWMgcm91dGUncyB0ZW1wbGF0ZSB1bmRlciBpdHMgb3duIGtleSwgd2l0aCB0aGUgUFBSIHNoZWxsJ3MgcG9zdHBvbmVkIHN0YXRlXCIsIGFzeW5jICgpID0+IHtcbiAgICAvLyBXaXRoIFBQUiB0aGUgdGVtcGxhdGUgaXMgdGhlIHJvdXRlJ3MgZmFsbGJhY2sgc2hlbGwsIGxvb2tlZCB1cCB1bmRlciB0aGVcbiAgICAvLyBsaXRlcmFsIHRlbXBsYXRlIGtleTsgdGhlIFBhZ2VzIFJvdXRlciBsb29rcyB1cCBhbiBJU1IgZmFsbGJhY2sgdGhlIHNhbWVcbiAgICAvLyB3YXkuIFVuc2VlZGVkLCBldmVyeSBzdWNoIGxvb2t1cCBtaXNzZWQgYW5kIHRoZSBzaGVsbCByZW5kZXJlZCBwZXIgcmVxdWVzdC5cbiAgICBjb25zdCBjdHggPSBjb250ZXh0KFtcbiAgICAgIGF3YWl0IHByZXJlbmRlcihcIi9pc3IvW2lkXVwiLCBcIi9pc3IvW2lkXVwiLCBcIjxodG1sPnNoZWxsPC9odG1sPlwiLCB7XG4gICAgICAgIGluaXRpYWxTdGF0dXM6IDIwMCxcbiAgICAgICAgcG9zdHBvbmVkU3RhdGU6IFwicG9zdHBvbmVkLXN0YXRlXCIsXG4gICAgICB9KSxcbiAgICAgIGF3YWl0IHByZXJlbmRlcihcIi9pc3IvW2lkXS5yc2NcIiwgXCIvaXNyL1tpZF1cIiwgXCJmbGlnaHRcIiksXG4gICAgICBhd2FpdCBwcmVyZW5kZXIoXCIvYmxvZy9bc2x1Z11cIiwgXCIvYmxvZy9bc2x1Z11cIiwgXCI8aHRtbD5mYWxsYmFjazwvaHRtbD5cIiwge1xuICAgICAgICBpbml0aWFsU3RhdHVzOiAyMDAsXG4gICAgICB9KSxcbiAgICBdKTtcbiAgICBhd2FpdCB3cml0ZUluaXRDYWNoZShjdHgsIGNhY2hlRGlyKTtcblxuICAgIGNvbnN0IHNoZWxsID0gYXdhaXQgcmVhZEVudHJ5KFwiaXNyL1tpZF1cIik7XG4gICAgZXhwZWN0KHNoZWxsLnZhbHVlLmtpbmQpLnRvQmUoXCJBUFBfUEFHRVwiKTtcbiAgICBleHBlY3Qoc2hlbGwudmFsdWUuaHRtbCkudG9CZShcIjxodG1sPnNoZWxsPC9odG1sPlwiKTtcbiAgICBleHBlY3Qoc2hlbGwudmFsdWUucG9zdHBvbmVkKS50b0JlKFwicG9zdHBvbmVkLXN0YXRlXCIpO1xuXG4gICAgY29uc3QgZmFsbGJhY2sgPSBhd2FpdCByZWFkRW50cnkoXCJibG9nL1tzbHVnXVwiKTtcbiAgICBleHBlY3QoZmFsbGJhY2sudmFsdWUua2luZCkudG9CZShcIlBBR0VTXCIpO1xuICAgIGV4cGVjdChmYWxsYmFjay52YWx1ZS5odG1sKS50b0JlKFwiPGh0bWw+ZmFsbGJhY2s8L2h0bWw+XCIpO1xuICB9KTtcblxuICBpdChcInNraXBzIGEgUGFnZXMgUm91dGVyIHJvdXRlIHByZXJlbmRlcmVkIHdpdGggYSBub24tMjAwIHN0YXR1c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gQSBidWlsZC10aW1lIGBub3RGb3VuZDogdHJ1ZWA6IHNlZWRpbmcgaXQgd291bGQgYmUgYSAyMDAgSElUIHdpdGggdGhlIDQwNFxuICAgIC8vIHBhZ2UncyBIVE1MLlxuICAgIGNvbnN0IGN0eCA9IGNvbnRleHQoW1xuICAgICAgYXdhaXQgcHJlcmVuZGVyKFwiL2dvbmVcIiwgXCIvZ29uZVwiLCBcIjxodG1sPjQwNDwvaHRtbD5cIiwge1xuICAgICAgICBpbml0aWFsU3RhdHVzOiA0MDQsXG4gICAgICB9KSxcbiAgICBdKTtcbiAgICBhd2FpdCB3cml0ZUluaXRDYWNoZShjdHgsIGNhY2hlRGlyKTtcbiAgICBleHBlY3QoZXhpc3RzU3luYyhqb2luKGNhY2hlRGlyLCBcImdvbmUuanNvblwiKSkpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdChcIm1hcHMgZWFjaCB0YWcgdG8gdGhlIGtleXMgY2FycnlpbmcgaXQsIHVuZGVyIGJhc2VQYXRoLWxlc3Mga2V5c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY3R4ID0gY29udGV4dChcbiAgICAgIFtcbiAgICAgICAgYXdhaXQgcHJlcmVuZGVyKFwiL2RvY3Mvc2hvcFwiLCBcIi9zaG9wXCIsIFwiPGh0bWw+YTwvaHRtbD5cIiwge1xuICAgICAgICAgIGluaXRpYWxIZWFkZXJzOiB7IFwieC1uZXh0LWNhY2hlLXRhZ3NcIjogXCJwcm9kdWN0cyxfTl9UXy9zaG9wXCIgfSxcbiAgICAgICAgfSksXG4gICAgICBdLFxuICAgICAgXCIvZG9jc1wiLFxuICAgICk7XG4gICAgYXdhaXQgd3JpdGVJbml0Q2FjaGUoY3R4LCBjYWNoZURpcik7XG5cbiAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04ucGFyc2UoXG4gICAgICBhd2FpdCByZWFkRmlsZShqb2luKGNhY2hlRGlyLCBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVCksIFwidXRmOFwiKSxcbiAgICApO1xuICAgIGV4cGVjdChtYW5pZmVzdCkudG9FcXVhbCh7XG4gICAgICBwcm9kdWN0czogW1wic2hvcFwiXSxcbiAgICAgIFwiX05fVF8vc2hvcFwiOiBbXCJzaG9wXCJdLFxuICAgIH0pO1xuICB9KTtcblxuICBpdChcIndyaXRlcyBubyB0YWcgbWFuaWZlc3Qgd2hlbiBub3RoaW5nIGlzIHRhZ2dlZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY3R4ID0gY29udGV4dChbYXdhaXQgcHJlcmVuZGVyKFwiL2ZlZWQueG1sXCIsIFwiL2ZlZWQueG1sXCIsIFwiPHJzcy8+XCIpXSk7XG4gICAgYXdhaXQgd3JpdGVJbml0Q2FjaGUoY3R4LCBjYWNoZURpcik7XG4gICAgZXhwZWN0KGF3YWl0IHJlYWRkaXIoY2FjaGVEaXIpKS50b0VxdWFsKFtcImZlZWQueG1sLmpzb25cIl0pO1xuICB9KTtcbn0pO1xuIl19
@@ -1,3 +1,4 @@
1
+ import { CacheHandlerValue } from "next/dist/server/lib/incremental-cache";
1
2
  import type { IncrementalCacheValue } from "next/dist/server/response-cache";
2
3
  /**
3
4
  * Local file cache handler that writes cache entries during Next.js build
@@ -5,12 +6,34 @@ import type { IncrementalCacheValue } from "next/dist/server/response-cache";
5
6
  */
6
7
  export declare class LocalFileCacheHandler {
7
8
  private cacheDir;
9
+ /** What this process has written or read back; see {@link get}. */
10
+ private entries;
8
11
  constructor();
9
12
  /**
10
13
  * Build file path for cache entry
11
14
  * Structure: {cacheKey}.json (BucketDeployment will add buildId prefix)
12
15
  */
13
16
  private buildFilePath;
17
+ /**
18
+ * Read back an entry this build already wrote.
19
+ *
20
+ * Required, not an optimization. Under `cacheComponents` a prerender runs
21
+ * twice: a first pass that fills caches (every `fetch` misses, runs for real,
22
+ * and is `set`), then a final pass in which every await must settle in a
23
+ * microtask — anything still pending is by definition "runtime data", and
24
+ * Next.js aborts the page with `Route "/": Next.js encountered uncached or
25
+ * runtime data during prerendering`. The final pass only settles immediately
26
+ * if `get` returns what the first pass `set`, so a write-only build-time
27
+ * handler makes `fetch(url, { cache: 'force-cache' })` unprerenderable and
28
+ * fails the build. Next.js's own `FileSystemCache` reads back for exactly
29
+ * this reason. Measured against next.js's
30
+ * `test/e2e/app-dir/resume-data-cache`, which is unbuildable without it.
31
+ *
32
+ * Entries are read through a process-local map because the two passes are the
33
+ * same process, and because the deserialized value is what Next.js compares
34
+ * by reference when deduping within a render.
35
+ */
36
+ get(cacheKey: string): Promise<CacheHandlerValue | null>;
14
37
  /**
15
38
  * Write cache entry to local file
16
39
  */
@@ -23,6 +23,8 @@ const debug = (0, debug_1.default)("cdk-nextjs:cache-handler:local-file");
23
23
  */
24
24
  class LocalFileCacheHandler {
25
25
  cacheDir;
26
+ /** What this process has written or read back; see {@link get}. */
27
+ entries = new Map();
26
28
  constructor() {
27
29
  // Read cache directory from environment variable set by NextjsBuild
28
30
  // Falls back to default location for backward compatibility
@@ -41,6 +43,52 @@ class LocalFileCacheHandler {
41
43
  const filePath = (0, path_1.join)(this.cacheDir, `${cacheKey}.json`);
42
44
  return filePath;
43
45
  }
46
+ /**
47
+ * Read back an entry this build already wrote.
48
+ *
49
+ * Required, not an optimization. Under `cacheComponents` a prerender runs
50
+ * twice: a first pass that fills caches (every `fetch` misses, runs for real,
51
+ * and is `set`), then a final pass in which every await must settle in a
52
+ * microtask — anything still pending is by definition "runtime data", and
53
+ * Next.js aborts the page with `Route "/": Next.js encountered uncached or
54
+ * runtime data during prerendering`. The final pass only settles immediately
55
+ * if `get` returns what the first pass `set`, so a write-only build-time
56
+ * handler makes `fetch(url, { cache: 'force-cache' })` unprerenderable and
57
+ * fails the build. Next.js's own `FileSystemCache` reads back for exactly
58
+ * this reason. Measured against next.js's
59
+ * `test/e2e/app-dir/resume-data-cache`, which is unbuildable without it.
60
+ *
61
+ * Entries are read through a process-local map because the two passes are the
62
+ * same process, and because the deserialized value is what Next.js compares
63
+ * by reference when deduping within a render.
64
+ */
65
+ async get(cacheKey) {
66
+ const memoized = this.entries.get(cacheKey);
67
+ if (memoized !== undefined) {
68
+ return memoized;
69
+ }
70
+ try {
71
+ const filePath = this.buildFilePath(cacheKey);
72
+ if (!(0, fs_1.existsSync)(filePath)) {
73
+ return null;
74
+ }
75
+ // `tags` is stored alongside, not inside, the `CacheHandlerValue`; it is
76
+ // only consulted for tag revalidation, which cannot happen mid-build.
77
+ const stored = (0, cache_utils_1.parseCacheValue)((0, fs_1.readFileSync)(filePath, "utf-8"));
78
+ const entry = {
79
+ lastModified: stored.lastModified,
80
+ value: stored.value,
81
+ };
82
+ this.entries.set(cacheKey, entry);
83
+ debug(`LOCAL FILE CACHE HIT: ${cacheKey}`);
84
+ return entry;
85
+ }
86
+ catch (error) {
87
+ console.error(`Error reading local cache file for ${cacheKey}:`, error);
88
+ // Don't throw - a miss only costs the build a re-fetch.
89
+ return null;
90
+ }
91
+ }
44
92
  /**
45
93
  * Write cache entry to local file
46
94
  */
@@ -69,6 +117,9 @@ class LocalFileCacheHandler {
69
117
  const jsonString = (0, cache_utils_1.serializeCacheValue)(storageValue);
70
118
  // Write to file
71
119
  (0, fs_1.writeFileSync)(filePath, jsonString, "utf-8");
120
+ // Serve the rest of this build from memory rather than re-reading; see
121
+ // {@link get}.
122
+ this.entries.set(cacheKey, cacheHandlerValue);
72
123
  debug(`LOCAL FILE CACHE WRITE: ${cacheKey} -> ${filePath}`);
73
124
  }
74
125
  catch (error) {
@@ -84,4 +135,4 @@ class LocalFileCacheHandler {
84
135
  }
85
136
  }
86
137
  exports.LocalFileCacheHandler = LocalFileCacheHandler;
87
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZmlsZS1jYWNoZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvbG9jYWwtZmlsZS1jYWNoZS1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOzs7Ozs7RUFNRTtBQUNGLHNEQUFzRDtBQUN0RCwyQkFBMEQ7QUFDMUQsK0JBQXFDO0FBQ3JDLGtEQUE2QjtBQUc3QiwrQ0FBb0Q7QUFFcEQsTUFBTSxLQUFLLEdBQUcsSUFBQSxlQUFRLEVBQUMscUNBQXFDLENBQUMsQ0FBQztBQUU5RDs7O0dBR0c7QUFDSCxNQUFhLHFCQUFxQjtJQUN4QixRQUFRLENBQVM7SUFFekI7UUFDRSxvRUFBb0U7UUFDcEUsNERBQTREO1FBQzVELElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUI7WUFDbkQsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCO1lBQ3ZDLENBQUMsQ0FBQyxJQUFBLFdBQUksRUFBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFFMUQsNEZBQTRGO1FBQzVGLElBQUEsY0FBUyxFQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM5QyxLQUFLLENBQUMsa0NBQWtDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7O09BR0c7SUFDSyxhQUFhLENBQUMsUUFBZ0I7UUFDcEMsTUFBTSxRQUFRLEdBQUcsSUFBQSxXQUFJLEVBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLFFBQVEsT0FBTyxDQUFDLENBQUM7UUFDekQsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEdBQUcsQ0FDUCxRQUFnQixFQUNoQixJQUFrQyxFQUNsQyxJQUFlO1FBRWYsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNWLE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUU5Qyx1Q0FBdUM7WUFDdkMsTUFBTSxHQUFHLEdBQUcsSUFBQSxjQUFPLEVBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUIsSUFBSSxDQUFDLElBQUEsZUFBVSxFQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JCLElBQUEsY0FBUyxFQUFDLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3RDLENBQUM7WUFFRCwrQ0FBK0M7WUFDL0MsTUFBTSxpQkFBaUIsR0FBc0I7Z0JBQzNDLFlBQVksRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUN4QixLQUFLLEVBQUUsSUFBSTthQUNaLENBQUM7WUFFRiw0Q0FBNEM7WUFDNUMsTUFBTSxZQUFZLEdBQUc7Z0JBQ25CLEdBQUcsaUJBQWlCO2dCQUNwQixJQUFJLEVBQUUsSUFBSSxJQUFJLEVBQUU7YUFDakIsQ0FBQztZQUVGLDZEQUE2RDtZQUM3RCxNQUFNLFVBQVUsR0FBRyxJQUFBLGlDQUFtQixFQUFDLFlBQVksQ0FBQyxDQUFDO1lBRXJELGdCQUFnQjtZQUNoQixJQUFBLGtCQUFhLEVBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUU3QyxLQUFLLENBQUMsMkJBQTJCLFFBQVEsT0FBTyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxzQ0FBc0MsUUFBUSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDeEUsNERBQTREO1FBQzlELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7Q0FDRjtBQTVFRCxzREE0RUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBMb2NhbCBGaWxlIENhY2hlIEhhbmRsZXIgZm9yIE5leHQuanMgYnVpbGQtdGltZSBwcmUtY2FjaGluZ1xuICBcbiAgV3JpdGVzIGNhY2hlIGVudHJpZXMgdG8gLm5leHQvY2RrLW5leHRqcy1jYWNoZS1oYW5kbGVyL3tjYWNoZUtleX0uanNvblxuICBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3Mgc28gdGhleSBjYW4gYmUgZGVwbG95ZWQgdG8gUzMgdmlhIEJ1Y2tldERlcGxveW1lbnQuXG4gIEJ1Y2tldERlcGxveW1lbnQgd2lsbCBhZGQgdGhlIGJ1aWxkSWQgcHJlZml4IHdoZW4gdXBsb2FkaW5nIHRvIFMzLlxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgZXhpc3RzU3luYywgbWtkaXJTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSBcInBhdGhcIjtcbmltcG9ydCBnZXREZWJ1ZyBmcm9tIFwiZGVidWdcIjtcbmltcG9ydCB7IENhY2hlSGFuZGxlclZhbHVlIH0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvbGliL2luY3JlbWVudGFsLWNhY2hlXCI7XG5pbXBvcnQgdHlwZSB7IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5pbXBvcnQgeyBzZXJpYWxpemVDYWNoZVZhbHVlIH0gZnJvbSBcIi4vY2FjaGUtdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBnZXREZWJ1ZyhcImNkay1uZXh0anM6Y2FjaGUtaGFuZGxlcjpsb2NhbC1maWxlXCIpO1xuXG4vKipcbiAqIExvY2FsIGZpbGUgY2FjaGUgaGFuZGxlciB0aGF0IHdyaXRlcyBjYWNoZSBlbnRyaWVzIGR1cmluZyBOZXh0LmpzIGJ1aWxkXG4gKiB0byBiZSBkZXBsb3llZCB0byBTMyBsYXRlciB2aWEgQnVja2V0RGVwbG95bWVudFxuICovXG5leHBvcnQgY2xhc3MgTG9jYWxGaWxlQ2FjaGVIYW5kbGVyIHtcbiAgcHJpdmF0ZSBjYWNoZURpcjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIFJlYWQgY2FjaGUgZGlyZWN0b3J5IGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGUgc2V0IGJ5IE5leHRqc0J1aWxkXG4gICAgLy8gRmFsbHMgYmFjayB0byBkZWZhdWx0IGxvY2F0aW9uIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAgdGhpcy5jYWNoZURpciA9IHByb2Nlc3MuZW52LkNES19ORVhUSlNfSU5JVF9DQUNIRV9ESVJcbiAgICAgID8gcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19JTklUX0NBQ0hFX0RJUlxuICAgICAgOiBqb2luKHByb2Nlc3MuY3dkKCksIFwiLm5leHRcIiwgXCJjZGstbmV4dGpzLWluaXQtY2FjaGVcIik7XG5cbiAgICAvLyBDcmVhdGUgZnJlc2ggY2FjaGUgZGlyZWN0b3J5OyBjYWNoZSBkaXJlY3RvcnkgaXMgY2xlYW5lZCBiZWZvcmUgZWFjaCBidWlsZCBpbiBOZXh0anNCdWlsZFxuICAgIG1rZGlyU3luYyh0aGlzLmNhY2hlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBkZWJ1ZyhgQ3JlYXRlZCBsb2NhbCBjYWNoZSBkaXJlY3Rvcnk6ICR7dGhpcy5jYWNoZURpcn1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBmaWxlIHBhdGggZm9yIGNhY2hlIGVudHJ5XG4gICAqIFN0cnVjdHVyZToge2NhY2hlS2V5fS5qc29uIChCdWNrZXREZXBsb3ltZW50IHdpbGwgYWRkIGJ1aWxkSWQgcHJlZml4KVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEZpbGVQYXRoKGNhY2hlS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gam9pbih0aGlzLmNhY2hlRGlyLCBgJHtjYWNoZUtleX0uanNvbmApO1xuICAgIHJldHVybiBmaWxlUGF0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZSBjYWNoZSBlbnRyeSB0byBsb2NhbCBmaWxlXG4gICAqL1xuICBhc3luYyBzZXQoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICBkYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgfCBudWxsLFxuICAgIHRhZ3M/OiBzdHJpbmdbXSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghZGF0YSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gdGhpcy5idWlsZEZpbGVQYXRoKGNhY2hlS2V5KTtcblxuICAgICAgLy8gQ3JlYXRlIGRpcmVjdG9yeSBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgICBjb25zdCBkaXIgPSBkaXJuYW1lKGZpbGVQYXRoKTtcbiAgICAgIGlmICghZXhpc3RzU3luYyhkaXIpKSB7XG4gICAgICAgIG1rZGlyU3luYyhkaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBDcmVhdGUgQ2FjaGVIYW5kbGVyVmFsdWUgc3RydWN0dXJlIHdpdGggdGFnc1xuICAgICAgY29uc3QgY2FjaGVIYW5kbGVyVmFsdWU6IENhY2hlSGFuZGxlclZhbHVlID0ge1xuICAgICAgICBsYXN0TW9kaWZpZWQ6IERhdGUubm93KCksXG4gICAgICAgIHZhbHVlOiBkYXRhLFxuICAgICAgfTtcblxuICAgICAgLy8gU3RvcmUgd2l0aCB0YWdzIGZvciByZXZhbGlkYXRpb24gY2hlY2tpbmdcbiAgICAgIGNvbnN0IHN0b3JhZ2VWYWx1ZSA9IHtcbiAgICAgICAgLi4uY2FjaGVIYW5kbGVyVmFsdWUsXG4gICAgICAgIHRhZ3M6IHRhZ3MgfHwgW10sXG4gICAgICB9O1xuXG4gICAgICAvLyBTZXJpYWxpemUgdG8gSlNPTiB3aXRoIHNwZWNpYWwgaGFuZGxpbmcgZm9yIE1hcCBhbmQgQnVmZmVyXG4gICAgICBjb25zdCBqc29uU3RyaW5nID0gc2VyaWFsaXplQ2FjaGVWYWx1ZShzdG9yYWdlVmFsdWUpO1xuXG4gICAgICAvLyBXcml0ZSB0byBmaWxlXG4gICAgICB3cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBqc29uU3RyaW5nLCBcInV0Zi04XCIpO1xuXG4gICAgICBkZWJ1ZyhgTE9DQUwgRklMRSBDQUNIRSBXUklURTogJHtjYWNoZUtleX0gLT4gJHtmaWxlUGF0aH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihgRXJyb3Igd3JpdGluZyBsb2NhbCBjYWNoZSBmaWxlIGZvciAke2NhY2hlS2V5fTpgLCBlcnJvcik7XG4gICAgICAvLyBEb24ndCB0aHJvdyAtIGJ1aWxkIHNob3VsZCBjb250aW51ZSBldmVuIGlmIGNhY2hpbmcgZmFpbHNcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlIGRpcmVjdG9yeSBwYXRoXG4gICAqL1xuICBnZXRDYWNoZURpcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNhY2hlRGlyO1xuICB9XG59XG4iXX0=
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZmlsZS1jYWNoZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvbG9jYWwtZmlsZS1jYWNoZS1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOzs7Ozs7RUFNRTtBQUNGLHNEQUFzRDtBQUN0RCwyQkFBd0U7QUFDeEUsK0JBQXFDO0FBQ3JDLGtEQUE2QjtBQUc3QiwrQ0FBcUU7QUFFckUsTUFBTSxLQUFLLEdBQUcsSUFBQSxlQUFRLEVBQUMscUNBQXFDLENBQUMsQ0FBQztBQUU5RDs7O0dBR0c7QUFDSCxNQUFhLHFCQUFxQjtJQUN4QixRQUFRLENBQVM7SUFDekIsbUVBQW1FO0lBQzNELE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBNkIsQ0FBQztJQUV2RDtRQUNFLG9FQUFvRTtRQUNwRSw0REFBNEQ7UUFDNUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QjtZQUNuRCxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUI7WUFDdkMsQ0FBQyxDQUFDLElBQUEsV0FBSSxFQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztRQUUxRCw0RkFBNEY7UUFDNUYsSUFBQSxjQUFTLEVBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxrQ0FBa0MsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGFBQWEsQ0FBQyxRQUFnQjtRQUNwQyxNQUFNLFFBQVEsR0FBRyxJQUFBLFdBQUksRUFBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsUUFBUSxPQUFPLENBQUMsQ0FBQztRQUN6RCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQ7Ozs7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QUM7SUFFRDs7T0FFRztJQUNILFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztDQUNGO0FBL0hELHNEQStIQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gIExvY2FsIEZpbGUgQ2FjaGUgSGFuZGxlciBmb3IgTmV4dC5qcyBidWlsZC10aW1lIHByZS1jYWNoaW5nXG4gIFxuICBXcml0ZXMgY2FjaGUgZW50cmllcyB0byAubmV4dC9jZGstbmV4dGpzLWNhY2hlLWhhbmRsZXIve2NhY2hlS2V5fS5qc29uXG4gIGR1cmluZyB0aGUgYnVpbGQgcHJvY2VzcyBzbyB0aGV5IGNhbiBiZSBkZXBsb3llZCB0byBTMyB2aWEgQnVja2V0RGVwbG95bWVudC5cbiAgQnVja2V0RGVwbG95bWVudCB3aWxsIGFkZCB0aGUgYnVpbGRJZCBwcmVmaXggd2hlbiB1cGxvYWRpbmcgdG8gUzMuXG4qL1xuLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBleGlzdHNTeW5jLCBta2RpclN5bmMsIHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZ2V0RGVidWcgZnJvbSBcImRlYnVnXCI7XG5pbXBvcnQgeyBDYWNoZUhhbmRsZXJWYWx1ZSB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2xpYi9pbmNyZW1lbnRhbC1jYWNoZVwiO1xuaW1wb3J0IHR5cGUgeyBJbmNyZW1lbnRhbENhY2hlVmFsdWUgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZVwiO1xuaW1wb3J0IHsgcGFyc2VDYWNoZVZhbHVlLCBzZXJpYWxpemVDYWNoZVZhbHVlIH0gZnJvbSBcIi4vY2FjaGUtdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBnZXREZWJ1ZyhcImNkay1uZXh0anM6Y2FjaGUtaGFuZGxlcjpsb2NhbC1maWxlXCIpO1xuXG4vKipcbiAqIExvY2FsIGZpbGUgY2FjaGUgaGFuZGxlciB0aGF0IHdyaXRlcyBjYWNoZSBlbnRyaWVzIGR1cmluZyBOZXh0LmpzIGJ1aWxkXG4gKiB0byBiZSBkZXBsb3llZCB0byBTMyBsYXRlciB2aWEgQnVja2V0RGVwbG95bWVudFxuICovXG5leHBvcnQgY2xhc3MgTG9jYWxGaWxlQ2FjaGVIYW5kbGVyIHtcbiAgcHJpdmF0ZSBjYWNoZURpcjogc3RyaW5nO1xuICAvKiogV2hhdCB0aGlzIHByb2Nlc3MgaGFzIHdyaXR0ZW4gb3IgcmVhZCBiYWNrOyBzZWUge0BsaW5rIGdldH0uICovXG4gIHByaXZhdGUgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBDYWNoZUhhbmRsZXJWYWx1ZT4oKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBSZWFkIGNhY2hlIGRpcmVjdG9yeSBmcm9tIGVudmlyb25tZW50IHZhcmlhYmxlIHNldCBieSBOZXh0anNCdWlsZFxuICAgIC8vIEZhbGxzIGJhY2sgdG8gZGVmYXVsdCBsb2NhdGlvbiBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgIHRoaXMuY2FjaGVEaXIgPSBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0lOSVRfQ0FDSEVfRElSXG4gICAgICA/IHByb2Nlc3MuZW52LkNES19ORVhUSlNfSU5JVF9DQUNIRV9ESVJcbiAgICAgIDogam9pbihwcm9jZXNzLmN3ZCgpLCBcIi5uZXh0XCIsIFwiY2RrLW5leHRqcy1pbml0LWNhY2hlXCIpO1xuXG4gICAgLy8gQ3JlYXRlIGZyZXNoIGNhY2hlIGRpcmVjdG9yeTsgY2FjaGUgZGlyZWN0b3J5IGlzIGNsZWFuZWQgYmVmb3JlIGVhY2ggYnVpbGQgaW4gTmV4dGpzQnVpbGRcbiAgICBta2RpclN5bmModGhpcy5jYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgZGVidWcoYENyZWF0ZWQgbG9jYWwgY2FjaGUgZGlyZWN0b3J5OiAke3RoaXMuY2FjaGVEaXJ9YCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgZmlsZSBwYXRoIGZvciBjYWNoZSBlbnRyeVxuICAgKiBTdHJ1Y3R1cmU6IHtjYWNoZUtleX0uanNvbiAoQnVja2V0RGVwbG95bWVudCB3aWxsIGFkZCBidWlsZElkIHByZWZpeClcbiAgICovXG4gIHByaXZhdGUgYnVpbGRGaWxlUGF0aChjYWNoZUtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBmaWxlUGF0aCA9IGpvaW4odGhpcy5jYWNoZURpciwgYCR7Y2FjaGVLZXl9Lmpzb25gKTtcbiAgICByZXR1cm4gZmlsZVBhdGg7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBiYWNrIGFuIGVudHJ5IHRoaXMgYnVpbGQgYWxyZWFkeSB3cm90ZS5cbiAgICpcbiAgICogUmVxdWlyZWQsIG5vdCBhbiBvcHRpbWl6YXRpb24uIFVuZGVyIGBjYWNoZUNvbXBvbmVudHNgIGEgcHJlcmVuZGVyIHJ1bnNcbiAgICogdHdpY2U6IGEgZmlyc3QgcGFzcyB0aGF0IGZpbGxzIGNhY2hlcyAoZXZlcnkgYGZldGNoYCBtaXNzZXMsIHJ1bnMgZm9yIHJlYWwsXG4gICAqIGFuZCBpcyBgc2V0YCksIHRoZW4gYSBmaW5hbCBwYXNzIGluIHdoaWNoIGV2ZXJ5IGF3YWl0IG11c3Qgc2V0dGxlIGluIGFcbiAgICogbWljcm90YXNrIOKAlCBhbnl0aGluZyBzdGlsbCBwZW5kaW5nIGlzIGJ5IGRlZmluaXRpb24gXCJydW50aW1lIGRhdGFcIiwgYW5kXG4gICAqIE5leHQuanMgYWJvcnRzIHRoZSBwYWdlIHdpdGggYFJvdXRlIFwiL1wiOiBOZXh0LmpzIGVuY291bnRlcmVkIHVuY2FjaGVkIG9yXG4gICAqIHJ1bnRpbWUgZGF0YSBkdXJpbmcgcHJlcmVuZGVyaW5nYC4gVGhlIGZpbmFsIHBhc3Mgb25seSBzZXR0bGVzIGltbWVkaWF0ZWx5XG4gICAqIGlmIGBnZXRgIHJldHVybnMgd2hhdCB0aGUgZmlyc3QgcGFzcyBgc2V0YCwgc28gYSB3cml0ZS1vbmx5IGJ1aWxkLXRpbWVcbiAgICogaGFuZGxlciBtYWtlcyBgZmV0Y2godXJsLCB7IGNhY2hlOiAnZm9yY2UtY2FjaGUnIH0pYCB1bnByZXJlbmRlcmFibGUgYW5kXG4gICAqIGZhaWxzIHRoZSBidWlsZC4gTmV4dC5qcydzIG93biBgRmlsZVN5c3RlbUNhY2hlYCByZWFkcyBiYWNrIGZvciBleGFjdGx5XG4gICAqIHRoaXMgcmVhc29uLiBNZWFzdXJlZCBhZ2FpbnN0IG5leHQuanMnc1xuICAgKiBgdGVzdC9lMmUvYXBwLWRpci9yZXN1bWUtZGF0YS1jYWNoZWAsIHdoaWNoIGlzIHVuYnVpbGRhYmxlIHdpdGhvdXQgaXQuXG4gICAqXG4gICAqIEVudHJpZXMgYXJlIHJlYWQgdGhyb3VnaCBhIHByb2Nlc3MtbG9jYWwgbWFwIGJlY2F1c2UgdGhlIHR3byBwYXNzZXMgYXJlIHRoZVxuICAgKiBzYW1lIHByb2Nlc3MsIGFuZCBiZWNhdXNlIHRoZSBkZXNlcmlhbGl6ZWQgdmFsdWUgaXMgd2hhdCBOZXh0LmpzIGNvbXBhcmVzXG4gICAqIGJ5IHJlZmVyZW5jZSB3aGVuIGRlZHVwaW5nIHdpdGhpbiBhIHJlbmRlci5cbiAgICovXG4gIGFzeW5jIGdldChjYWNoZUtleTogc3RyaW5nKTogUHJvbWlzZTxDYWNoZUhhbmRsZXJWYWx1ZSB8IG51bGw+IHtcbiAgICBjb25zdCBtZW1vaXplZCA9IHRoaXMuZW50cmllcy5nZXQoY2FjaGVLZXkpO1xuICAgIGlmIChtZW1vaXplZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbWVtb2l6ZWQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHRoaXMuYnVpbGRGaWxlUGF0aChjYWNoZUtleSk7XG4gICAgICBpZiAoIWV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gYHRhZ3NgIGlzIHN0b3JlZCBhbG9uZ3NpZGUsIG5vdCBpbnNpZGUsIHRoZSBgQ2FjaGVIYW5kbGVyVmFsdWVgOyBpdCBpc1xuICAgICAgLy8gb25seSBjb25zdWx0ZWQgZm9yIHRhZyByZXZhbGlkYXRpb24sIHdoaWNoIGNhbm5vdCBoYXBwZW4gbWlkLWJ1aWxkLlxuICAgICAgY29uc3Qgc3RvcmVkID0gcGFyc2VDYWNoZVZhbHVlKHJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKSk7XG4gICAgICBjb25zdCBlbnRyeTogQ2FjaGVIYW5kbGVyVmFsdWUgPSB7XG4gICAgICAgIGxhc3RNb2RpZmllZDogc3RvcmVkLmxhc3RNb2RpZmllZCxcbiAgICAgICAgdmFsdWU6IHN0b3JlZC52YWx1ZSxcbiAgICAgIH07XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGNhY2hlS2V5LCBlbnRyeSk7XG4gICAgICBkZWJ1ZyhgTE9DQUwgRklMRSBDQUNIRSBISVQ6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICByZXR1cm4gZW50cnk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHJlYWRpbmcgbG9jYWwgY2FjaGUgZmlsZSBmb3IgJHtjYWNoZUtleX06YCwgZXJyb3IpO1xuICAgICAgLy8gRG9uJ3QgdGhyb3cgLSBhIG1pc3Mgb25seSBjb3N0cyB0aGUgYnVpbGQgYSByZS1mZXRjaC5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZSBjYWNoZSBlbnRyeSB0byBsb2NhbCBmaWxlXG4gICAqL1xuICBhc3luYyBzZXQoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICBkYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgfCBudWxsLFxuICAgIHRhZ3M/OiBzdHJpbmdbXSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghZGF0YSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gdGhpcy5idWlsZEZpbGVQYXRoKGNhY2hlS2V5KTtcblxuICAgICAgLy8gQ3JlYXRlIGRpcmVjdG9yeSBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgICBjb25zdCBkaXIgPSBkaXJuYW1lKGZpbGVQYXRoKTtcbiAgICAgIGlmICghZXhpc3RzU3luYyhkaXIpKSB7XG4gICAgICAgIG1rZGlyU3luYyhkaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBDcmVhdGUgQ2FjaGVIYW5kbGVyVmFsdWUgc3RydWN0dXJlIHdpdGggdGFnc1xuICAgICAgY29uc3QgY2FjaGVIYW5kbGVyVmFsdWU6IENhY2hlSGFuZGxlclZhbHVlID0ge1xuICAgICAgICBsYXN0TW9kaWZpZWQ6IERhdGUubm93KCksXG4gICAgICAgIHZhbHVlOiBkYXRhLFxuICAgICAgfTtcblxuICAgICAgLy8gU3RvcmUgd2l0aCB0YWdzIGZvciByZXZhbGlkYXRpb24gY2hlY2tpbmdcbiAgICAgIGNvbnN0IHN0b3JhZ2VWYWx1ZSA9IHtcbiAgICAgICAgLi4uY2FjaGVIYW5kbGVyVmFsdWUsXG4gICAgICAgIHRhZ3M6IHRhZ3MgfHwgW10sXG4gICAgICB9O1xuXG4gICAgICAvLyBTZXJpYWxpemUgdG8gSlNPTiB3aXRoIHNwZWNpYWwgaGFuZGxpbmcgZm9yIE1hcCBhbmQgQnVmZmVyXG4gICAgICBjb25zdCBqc29uU3RyaW5nID0gc2VyaWFsaXplQ2FjaGVWYWx1ZShzdG9yYWdlVmFsdWUpO1xuXG4gICAgICAvLyBXcml0ZSB0byBmaWxlXG4gICAgICB3cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBqc29uU3RyaW5nLCBcInV0Zi04XCIpO1xuICAgICAgLy8gU2VydmUgdGhlIHJlc3Qgb2YgdGhpcyBidWlsZCBmcm9tIG1lbW9yeSByYXRoZXIgdGhhbiByZS1yZWFkaW5nOyBzZWVcbiAgICAgIC8vIHtAbGluayBnZXR9LlxuICAgICAgdGhpcy5lbnRyaWVzLnNldChjYWNoZUtleSwgY2FjaGVIYW5kbGVyVmFsdWUpO1xuXG4gICAgICBkZWJ1ZyhgTE9DQUwgRklMRSBDQUNIRSBXUklURTogJHtjYWNoZUtleX0gLT4gJHtmaWxlUGF0aH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihgRXJyb3Igd3JpdGluZyBsb2NhbCBjYWNoZSBmaWxlIGZvciAke2NhY2hlS2V5fTpgLCBlcnJvcik7XG4gICAgICAvLyBEb24ndCB0aHJvdyAtIGJ1aWxkIHNob3VsZCBjb250aW51ZSBldmVuIGlmIGNhY2hpbmcgZmFpbHNcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlIGRpcmVjdG9yeSBwYXRoXG4gICAqL1xuICBnZXRDYWNoZURpcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNhY2hlRGlyO1xuICB9XG59XG4iXX0=