cdk-nextjs 0.6.2 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/.jsii +2404 -2723
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1681 -1930
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
  7. package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
  8. package/docs/adapter-runtime.md +185 -0
  9. package/docs/breaking-changes.md +667 -4
  10. package/docs/caching-guide.md +156 -112
  11. package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
  12. package/docs/development-guide.md +1 -1
  13. package/docs/harness-coverage.md +598 -0
  14. package/docs/init-cache-deployment.md +32 -1
  15. package/docs/next-build-output-guide.md +30 -20
  16. package/examples/README.md +5 -1
  17. package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
  18. package/lib/adapter/__fixtures__/app-playground.json +4917 -0
  19. package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
  20. package/lib/adapter/adapter.mjs +1551 -185
  21. package/lib/adapter/adapter.test.js +106 -0
  22. package/lib/adapter/aws-cache-store.d.ts +489 -0
  23. package/lib/adapter/aws-cache-store.js +1004 -0
  24. package/lib/adapter/aws-cache-store.test.d.ts +1 -0
  25. package/lib/adapter/aws-cache-store.test.js +361 -0
  26. package/lib/adapter/build-outputs.d.ts +80 -0
  27. package/lib/adapter/build-outputs.js +857 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +863 -0
  30. package/lib/adapter/cache-handler.d.ts +9 -2
  31. package/lib/adapter/cache-handler.js +72 -96
  32. package/lib/adapter/cache-handler.mjs +18956 -17774
  33. package/lib/adapter/cache-handler.test.js +263 -31
  34. package/lib/adapter/cache-kinds.d.ts +32 -0
  35. package/lib/adapter/cache-kinds.js +35 -0
  36. package/lib/adapter/cache-kinds.test.d.ts +1 -0
  37. package/lib/adapter/cache-kinds.test.js +69 -0
  38. package/lib/adapter/cache-utils.d.ts +90 -0
  39. package/lib/adapter/cache-utils.js +199 -4
  40. package/lib/adapter/cache-utils.test.d.ts +1 -0
  41. package/lib/adapter/cache-utils.test.js +179 -0
  42. package/lib/adapter/function-groups.d.ts +215 -0
  43. package/lib/adapter/function-groups.js +1099 -0
  44. package/lib/adapter/function-groups.test.d.ts +1 -0
  45. package/lib/adapter/function-groups.test.js +743 -0
  46. package/lib/adapter/init-cache.d.ts +6 -0
  47. package/lib/adapter/init-cache.js +245 -0
  48. package/lib/adapter/init-cache.test.d.ts +1 -0
  49. package/lib/adapter/init-cache.test.js +137 -0
  50. package/lib/adapter/local-file-cache-handler.d.ts +23 -0
  51. package/lib/adapter/local-file-cache-handler.js +52 -1
  52. package/lib/adapter/memory-cache-handler.d.ts +26 -17
  53. package/lib/adapter/memory-cache-handler.js +32 -50
  54. package/lib/adapter/memory-cache-handler.test.js +105 -85
  55. package/lib/adapter/s3-cache-handler.d.ts +179 -40
  56. package/lib/adapter/s3-cache-handler.js +807 -277
  57. package/lib/adapter/s3-cache-handler.test.js +1186 -31
  58. package/lib/adapter/use-cache-common.d.ts +90 -0
  59. package/lib/adapter/use-cache-common.js +250 -0
  60. package/lib/adapter/use-cache-common.test.d.ts +1 -0
  61. package/lib/adapter/use-cache-common.test.js +646 -0
  62. package/lib/adapter/use-cache-default-handler.d.ts +24 -0
  63. package/lib/adapter/use-cache-default-handler.js +90 -0
  64. package/lib/adapter/use-cache-default-handler.mjs +38645 -0
  65. package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
  66. package/lib/adapter/use-cache-handlers.test.js +349 -0
  67. package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
  68. package/lib/adapter/use-cache-remote-handler.js +186 -0
  69. package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
  70. package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
  71. package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
  72. package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
  73. package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
  74. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
  75. package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
  76. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
  77. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  78. package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
  81. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
  82. package/lib/index.d.ts +6 -7
  83. package/lib/index.js +2 -4
  84. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  88. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  92. package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
  93. package/lib/lambdas/post-deploy/prune-s3.js +41 -12
  94. package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
  95. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  96. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  103. package/lib/nextjs-api.d.ts +102 -18
  104. package/lib/nextjs-api.js +338 -38
  105. package/lib/nextjs-api.test.js +537 -1
  106. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  107. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  108. package/lib/nextjs-build/nextjs-build.js +684 -327
  109. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  110. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  111. package/lib/nextjs-build/patch-fetch.js +1 -1
  112. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  113. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  114. package/lib/nextjs-cache.d.ts +82 -4
  115. package/lib/nextjs-cache.js +186 -10
  116. package/lib/nextjs-cache.test.js +176 -1
  117. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  118. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  120. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  121. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  122. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  123. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  124. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  125. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  126. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  127. package/lib/nextjs-distribution.d.ts +194 -23
  128. package/lib/nextjs-distribution.js +535 -62
  129. package/lib/nextjs-distribution.test.d.ts +1 -0
  130. package/lib/nextjs-distribution.test.js +697 -0
  131. package/lib/nextjs-post-deploy.d.ts +13 -5
  132. package/lib/nextjs-post-deploy.js +13 -10
  133. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  134. package/lib/nextjs-post-deploy.test.js +34 -0
  135. package/lib/nextjs-static-assets.d.ts +17 -4
  136. package/lib/nextjs-static-assets.js +22 -5
  137. package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
  138. package/lib/root-constructs/nextjs-base-construct.js +139 -47
  139. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  140. package/lib/root-constructs/nextjs-global-containers.js +20 -71
  141. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  142. package/lib/root-constructs/nextjs-global-functions.js +52 -70
  143. package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
  144. package/lib/root-constructs/nextjs-regional-containers.js +8 -15
  145. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  146. package/lib/root-constructs/nextjs-regional-functions.js +8 -26
  147. package/lib/runtime/api-gateway-path.d.ts +34 -0
  148. package/lib/runtime/api-gateway-path.js +71 -0
  149. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  150. package/lib/runtime/api-gateway-path.test.js +65 -0
  151. package/lib/runtime/case-redirect.d.ts +22 -0
  152. package/lib/runtime/case-redirect.js +63 -0
  153. package/lib/runtime/case-redirect.test.d.ts +1 -0
  154. package/lib/runtime/case-redirect.test.js +32 -0
  155. package/lib/runtime/core.d.ts +234 -0
  156. package/lib/runtime/core.js +1216 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1686 -0
  159. package/lib/runtime/deployment-root.d.ts +13 -0
  160. package/lib/runtime/deployment-root.js +29 -0
  161. package/lib/runtime/dispatch.d.ts +331 -0
  162. package/lib/runtime/dispatch.js +751 -0
  163. package/lib/runtime/dispatch.test.d.ts +1 -0
  164. package/lib/runtime/dispatch.test.js +853 -0
  165. package/lib/runtime/entrypoints.d.ts +57 -0
  166. package/lib/runtime/entrypoints.js +115 -0
  167. package/lib/runtime/http/abort-signal.d.ts +6 -0
  168. package/lib/runtime/http/abort-signal.js +19 -0
  169. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  170. package/lib/runtime/http/abort-signal.test.js +49 -0
  171. package/lib/runtime/http/node-server.d.ts +38 -0
  172. package/lib/runtime/http/node-server.js +99 -0
  173. package/lib/runtime/http/node-server.test.d.ts +1 -0
  174. package/lib/runtime/http/node-server.test.js +96 -0
  175. package/lib/runtime/http/node-sink.d.ts +16 -0
  176. package/lib/runtime/http/node-sink.js +48 -0
  177. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  178. package/lib/runtime/http/node-sink.test.js +66 -0
  179. package/lib/runtime/http/request.d.ts +62 -0
  180. package/lib/runtime/http/request.js +134 -0
  181. package/lib/runtime/http/request.test.d.ts +1 -0
  182. package/lib/runtime/http/request.test.js +103 -0
  183. package/lib/runtime/http/response.d.ts +77 -0
  184. package/lib/runtime/http/response.js +229 -0
  185. package/lib/runtime/http/response.test.d.ts +1 -0
  186. package/lib/runtime/http/response.test.js +178 -0
  187. package/lib/runtime/http/sink.d.ts +73 -0
  188. package/lib/runtime/http/sink.js +188 -0
  189. package/lib/runtime/http/sink.test.d.ts +1 -0
  190. package/lib/runtime/http/sink.test.js +257 -0
  191. package/lib/runtime/image-utils.d.ts +78 -0
  192. package/lib/runtime/image-utils.js +129 -0
  193. package/lib/runtime/image-utils.test.d.ts +1 -0
  194. package/lib/runtime/image-utils.test.js +237 -0
  195. package/lib/runtime/image.d.ts +76 -0
  196. package/lib/runtime/image.js +296 -0
  197. package/lib/runtime/image.test.d.ts +1 -0
  198. package/lib/runtime/image.test.js +405 -0
  199. package/lib/runtime/lambda-event.d.ts +4 -0
  200. package/lib/runtime/lambda-event.js +113 -0
  201. package/lib/runtime/lambda-event.test.d.ts +1 -0
  202. package/lib/runtime/lambda-event.test.js +119 -0
  203. package/lib/runtime/lambda.mjs +41600 -0
  204. package/lib/runtime/load-module.d.ts +8 -0
  205. package/lib/runtime/load-module.js +35 -0
  206. package/lib/runtime/manifest.d.ts +215 -0
  207. package/lib/runtime/manifest.js +118 -0
  208. package/lib/runtime/middleware.d.ts +43 -0
  209. package/lib/runtime/middleware.js +113 -0
  210. package/lib/runtime/middleware.test.d.ts +1 -0
  211. package/lib/runtime/middleware.test.js +259 -0
  212. package/lib/runtime/next-modules.d.ts +71 -0
  213. package/lib/runtime/next-modules.js +144 -0
  214. package/lib/runtime/next-modules.test.d.ts +1 -0
  215. package/lib/runtime/next-modules.test.js +34 -0
  216. package/lib/runtime/public-files.d.ts +32 -0
  217. package/lib/runtime/public-files.js +117 -0
  218. package/lib/runtime/public-files.test.d.ts +1 -0
  219. package/lib/runtime/public-files.test.js +97 -0
  220. package/lib/runtime/server.mjs +41593 -0
  221. package/lib/runtime/static-files.d.ts +50 -0
  222. package/lib/runtime/static-files.js +266 -0
  223. package/lib/runtime/static-files.test.d.ts +1 -0
  224. package/lib/runtime/static-files.test.js +118 -0
  225. package/lib/runtime/util.d.ts +28 -0
  226. package/lib/runtime/util.js +79 -0
  227. package/lib/utils/base-path.d.ts +106 -13
  228. package/lib/utils/base-path.js +254 -41
  229. package/lib/utils/base-path.test.js +219 -51
  230. package/lib/utils/get-architecture.d.ts +7 -8
  231. package/lib/utils/get-architecture.js +12 -13
  232. package/lib/utils/zip-directory.d.ts +14 -0
  233. package/lib/utils/zip-directory.js +121 -0
  234. package/lib/utils/zip-directory.test.d.ts +1 -0
  235. package/lib/utils/zip-directory.test.js +99 -0
  236. package/package.json +22 -3
  237. package/scripts/capture-adapter-fixture.mjs +325 -0
  238. package/scripts/e2e-deploy.sh +398 -0
  239. package/scripts/e2e-harness/README.md +707 -0
  240. package/scripts/e2e-harness/app.js +370 -0
  241. package/scripts/e2e-harness/common.sh +249 -0
  242. package/scripts/e2e-harness/screen.mjs +302 -0
  243. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  244. package/scripts/e2e-harness/type-filters.mjs +47 -0
  245. package/scripts/e2e-logs.sh +75 -0
  246. package/scripts/e2e-offline.sh +91 -0
  247. package/scripts/e2e-sweep.sh +370 -0
  248. package/scripts/e2e-warm.sh +114 -0
  249. package/scripts/zero-config-build.mjs +418 -0
  250. package/docs/1k-concurrent-users-executions.png +0 -0
  251. package/docs/plans/adapter-runtime-release.md +0 -362
  252. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  253. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  254. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  255. package/lib/image-optimization/handler-utils.d.ts +0 -34
  256. package/lib/image-optimization/handler-utils.js +0 -83
  257. package/lib/image-optimization/handler-utils.test.js +0 -178
  258. package/lib/nextjs-build/functions.Dockerfile +0 -31
  259. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  260. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  261. package/lib/utils/experimental-flags.d.ts +0 -24
  262. package/lib/utils/experimental-flags.js +0 -30
  263. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publicDirKey = publicDirKey;
4
+ exports.readPublicFiles = readPublicFiles;
5
+ exports.resolvePublicFiles = resolvePublicFiles;
6
+ /**
7
+ * `public/`, as the runtime finds it on disk.
8
+ *
9
+ * Listed at cold start, the way `next start` lists it
10
+ * (`next/dist/server/lib/router-utils/filesystem.js`, `recursiveReadDir` of
11
+ * `public/`), rather than at build time in the manifest. The build-time list
12
+ * was the wrong source of truth in two ways: `onBuildComplete` runs inside
13
+ * `next build`, so anything an app's `postbuild` writes into `public/` —
14
+ * `next-sitemap`'s `sitemap.xml` and `robots.txt`, Pagefind's `_pagefind/` — was
15
+ * in the image and missing from the list; and every Lambda deployment carried
16
+ * the whole list for files CloudFront or API Gateway always answers from S3.
17
+ *
18
+ * Only the `NextjsRegionalContainers` image copies `public/` in. The other
19
+ * types' deployment roots carry the list instead — {@link PUBLIC_FILES_FILE_NAME}, written at synth after the build
20
+ * command, so a `postbuild` file is in it — and the runtime streams a listed
21
+ * file from the assets bucket when a request lands on it. A file's own URL
22
+ * never gets that far (the edge routes it to S3); a rewrite onto one does.
23
+ */
24
+ const node_fs_1 = require("node:fs");
25
+ const node_path_1 = require("node:path");
26
+ const manifest_1 = require("./manifest");
27
+ /** Where `public/` sits in the deployment root, as a POSIX key. */
28
+ function publicDirKey(manifest) {
29
+ const { relativeProjectDir } = manifest;
30
+ return relativeProjectDir ? `${relativeProjectDir}/public` : "public";
31
+ }
32
+ /**
33
+ * Every file under `public/`, as `/`-separated paths relative to it, unencoded:
34
+ * `static/hello e2e.png`, `images/logo@2x.png`.
35
+ *
36
+ * Symlinks are followed, files and directories alike, because Next.js's
37
+ * `recursiveReadDir` follows them and so does everything that puts `public/` in
38
+ * front of a user: Docker `COPY` keeps a working link in the image, and CDK's
39
+ * asset staging uploads the target's bytes to S3. `Dirent.isFile()` describes the
40
+ * link, not its target, so filtering on it silently dropped them. A directory
41
+ * is not entered from inside itself, so a link cycle terminates.
42
+ */
43
+ function readPublicFiles(dir) {
44
+ const files = [];
45
+ /** The real paths of the directories being walked, root to current. */
46
+ const ancestors = new Set();
47
+ const walk = (absolute, relative) => {
48
+ let real;
49
+ try {
50
+ real = (0, node_fs_1.realpathSync)(absolute);
51
+ }
52
+ catch {
53
+ return;
54
+ }
55
+ if (ancestors.has(real))
56
+ return;
57
+ ancestors.add(real);
58
+ for (const entry of (0, node_fs_1.readdirSync)(absolute, { withFileTypes: true })) {
59
+ const childAbsolute = (0, node_path_1.join)(absolute, entry.name);
60
+ const childRelative = relative ? `${relative}/${entry.name}` : entry.name;
61
+ let isDirectory = entry.isDirectory();
62
+ let isFile = entry.isFile();
63
+ if (entry.isSymbolicLink()) {
64
+ try {
65
+ const target = (0, node_fs_1.statSync)(childAbsolute);
66
+ isDirectory = target.isDirectory();
67
+ isFile = target.isFile();
68
+ }
69
+ catch {
70
+ // A dangling link: nothing to serve.
71
+ continue;
72
+ }
73
+ }
74
+ if (isDirectory) {
75
+ walk(childAbsolute, childRelative);
76
+ }
77
+ else if (isFile) {
78
+ files.push(childRelative);
79
+ }
80
+ }
81
+ ancestors.delete(real);
82
+ };
83
+ try {
84
+ walk(dir, "");
85
+ }
86
+ catch (error) {
87
+ if (error.code !== "ENOENT")
88
+ throw error;
89
+ }
90
+ return files.sort();
91
+ }
92
+ /**
93
+ * The synth-time list when the deployment root has one, which is every type but
94
+ * `NextjsRegionalContainers`, and `public/` off disk otherwise. The list wins
95
+ * even when some of `public/` is on disk: a route that reads a `public/` file
96
+ * through `fs` gets that file traced into a Lambda root, and the rest of
97
+ * `public/` is still only in S3.
98
+ */
99
+ function resolvePublicFiles(deploymentRoot, manifest) {
100
+ let listed;
101
+ try {
102
+ listed = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(deploymentRoot, manifest_1.RUNTIME_DIR_NAME, manifest_1.PUBLIC_FILES_FILE_NAME), "utf-8"));
103
+ }
104
+ catch (error) {
105
+ if (error.code === "ENOENT") {
106
+ const onDisk = (0, node_path_1.join)(deploymentRoot, publicDirKey(manifest));
107
+ return { files: readPublicFiles(onDisk), inS3: false };
108
+ }
109
+ throw error;
110
+ }
111
+ if (!Array.isArray(listed) ||
112
+ !listed.every((file) => typeof file === "string")) {
113
+ throw new Error(`${manifest_1.RUNTIME_DIR_NAME}/${manifest_1.PUBLIC_FILES_FILE_NAME} is not a JSON array of paths.`);
114
+ }
115
+ return { files: listed, inS3: true };
116
+ }
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWZpbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvcHVibGljLWZpbGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkJBLG9DQUdDO0FBYUQsMENBNkNDO0FBbUJELGdEQTRCQztBQXZJRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxxQ0FBNEU7QUFDNUUseUNBQWlDO0FBQ2pDLHlDQUlvQjtBQUVwQixtRUFBbUU7QUFDbkUsU0FBZ0IsWUFBWSxDQUFDLFFBQXlCO0lBQ3BELE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxHQUFHLFFBQVEsQ0FBQztJQUN4QyxPQUFPLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxHQUFHLGtCQUFrQixTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztBQUN4RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxHQUFXO0lBQ3pDLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUMzQix1RUFBdUU7SUFDdkUsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUVwQyxNQUFNLElBQUksR0FBRyxDQUFDLFFBQWdCLEVBQUUsUUFBZ0IsRUFBRSxFQUFFO1FBQ2xELElBQUksSUFBWSxDQUFDO1FBQ2pCLElBQUksQ0FBQztZQUNILElBQUksR0FBRyxJQUFBLHNCQUFZLEVBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU87UUFDaEMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVwQixLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUEscUJBQVcsRUFBQyxRQUFRLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ25F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ZSBmaW5kcyBpdCBvbiBkaXNrLlxuICpcbiAqIExpc3RlZCBhdCBjb2xkIHN0YXJ0LCB0aGUgd2F5IGBuZXh0IHN0YXJ0YCBsaXN0cyBpdFxuICogKGBuZXh0L2Rpc3Qvc2VydmVyL2xpYi9yb3V0ZXItdXRpbHMvZmlsZXN5c3RlbS5qc2AsIGByZWN1cnNpdmVSZWFkRGlyYCBvZlxuICogYHB1YmxpYy9gKSwgcmF0aGVyIHRoYW4gYXQgYnVpbGQgdGltZSBpbiB0aGUgbWFuaWZlc3QuIFRoZSBidWlsZC10aW1lIGxpc3RcbiAqIHdhcyB0aGUgd3Jvbmcgc291cmNlIG9mIHRydXRoIGluIHR3byB3YXlzOiBgb25CdWlsZENvbXBsZXRlYCBydW5zIGluc2lkZVxuICogYG5leHQgYnVpbGRgLCBzbyBhbnl0aGluZyBhbiBhcHAncyBgcG9zdGJ1aWxkYCB3cml0ZXMgaW50byBgcHVibGljL2Ag4oCUXG4gKiBgbmV4dC1zaXRlbWFwYCdzIGBzaXRlbWFwLnhtbGAgYW5kIGByb2JvdHMudHh0YCwgUGFnZWZpbmQncyBgX3BhZ2VmaW5kL2Ag4oCUIHdhc1xuICogaW4gdGhlIGltYWdlIGFuZCBtaXNzaW5nIGZyb20gdGhlIGxpc3Q7IGFuZCBldmVyeSBMYW1iZGEgZGVwbG95bWVudCBjYXJyaWVkXG4gKiB0aGUgd2hvbGUgbGlzdCBmb3IgZmlsZXMgQ2xvdWRGcm9udCBvciBBUEkgR2F0ZXdheSBhbHdheXMgYW5zd2VycyBmcm9tIFMzLlxuICpcbiAqIE9ubHkgdGhlIGBOZXh0anNSZWdpb25hbENvbnRhaW5lcnNgIGltYWdlIGNvcGllcyBgcHVibGljL2AgaW4uIFRoZSBvdGhlclxuICogdHlwZXMnIGRlcGxveW1lbnQgcm9vdHMgY2FycnkgdGhlIGxpc3QgaW5zdGVhZCDigJQge0BsaW5rIFBVQkxJQ19GSUxFU19GSUxFX05BTUV9LCB3cml0dGVuIGF0IHN5bnRoIGFmdGVyIHRoZSBidWlsZFxuICogY29tbWFuZCwgc28gYSBgcG9zdGJ1aWxkYCBmaWxlIGlzIGluIGl0IOKAlCBhbmQgdGhlIHJ1bnRpbWUgc3RyZWFtcyBhIGxpc3RlZFxuICogZmlsZSBmcm9tIHRoZSBhc3NldHMgYnVja2V0IHdoZW4gYSByZXF1ZXN0IGxhbmRzIG9uIGl0LiBBIGZpbGUncyBvd24gVVJMXG4gKiBuZXZlciBnZXRzIHRoYXQgZmFyICh0aGUgZWRnZSByb3V0ZXMgaXQgdG8gUzMpOyBhIHJld3JpdGUgb250byBvbmUgZG9lcy5cbiAqL1xuaW1wb3J0IHsgcmVhZGRpclN5bmMsIHJlYWRGaWxlU3luYywgcmVhbHBhdGhTeW5jLCBzdGF0U3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHtcbiAgQWRhcHRlck1hbmlmZXN0LFxuICBQVUJMSUNfRklMRVNfRklMRV9OQU1FLFxuICBSVU5USU1FX0RJUl9OQU1FLFxufSBmcm9tIFwiLi9tYW5pZmVzdFwiO1xuXG4vKiogV2hlcmUgYHB1YmxpYy9gIHNpdHMgaW4gdGhlIGRlcGxveW1lbnQgcm9vdCwgYXMgYSBQT1NJWCBrZXkuICovXG5leHBvcnQgZnVuY3Rpb24gcHVibGljRGlyS2V5KG1hbmlmZXN0OiBBZGFwdGVyTWFuaWZlc3QpOiBzdHJpbmcge1xuICBjb25zdCB7IHJlbGF0aXZlUHJvamVjdERpciB9ID0gbWFuaWZlc3Q7XG4gIHJldHVybiByZWxhdGl2ZVByb2plY3REaXIgPyBgJHtyZWxhdGl2ZVByb2plY3REaXJ9L3B1YmxpY2AgOiBcInB1YmxpY1wiO1xufVxuXG4vKipcbiAqIEV2ZXJ5IGZpbGUgdW5kZXIgYHB1YmxpYy9gLCBhcyBgL2Atc2VwYXJhdGVkIHBhdGhzIHJlbGF0aXZlIHRvIGl0LCB1bmVuY29kZWQ6XG4gKiBgc3RhdGljL2hlbGxvIGUyZS5wbmdgLCBgaW1hZ2VzL2xvZ29AMngucG5nYC5cbiAqXG4gKiBTeW1saW5rcyBhcmUgZm9sbG93ZWQsIGZpbGVzIGFuZCBkaXJlY3RvcmllcyBhbGlrZSwgYmVjYXVzZSBOZXh0LmpzJ3NcbiAqIGByZWN1cnNpdmVSZWFkRGlyYCBmb2xsb3dzIHRoZW0gYW5kIHNvIGRvZXMgZXZlcnl0aGluZyB0aGF0IHB1dHMgYHB1YmxpYy9gIGluXG4gKiBmcm9udCBvZiBhIHVzZXI6IERvY2tlciBgQ09QWWAga2VlcHMgYSB3b3JraW5nIGxpbmsgaW4gdGhlIGltYWdlLCBhbmQgQ0RLJ3NcbiAqIGFzc2V0IHN0YWdpbmcgdXBsb2FkcyB0aGUgdGFyZ2V0J3MgYnl0ZXMgdG8gUzMuIGBEaXJlbnQuaXNGaWxlKClgIGRlc2NyaWJlcyB0aGVcbiAqIGxpbmssIG5vdCBpdHMgdGFyZ2V0LCBzbyBmaWx0ZXJpbmcgb24gaXQgc2lsZW50bHkgZHJvcHBlZCB0aGVtLiBBIGRpcmVjdG9yeVxuICogaXMgbm90IGVudGVyZWQgZnJvbSBpbnNpZGUgaXRzZWxmLCBzbyBhIGxpbmsgY3ljbGUgdGVybWluYXRlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRQdWJsaWNGaWxlcyhkaXI6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgZmlsZXM6IHN0cmluZ1tdID0gW107XG4gIC8qKiBUaGUgcmVhbCBwYXRocyBvZiB0aGUgZGlyZWN0b3JpZXMgYmVpbmcgd2Fsa2VkLCByb290IHRvIGN1cnJlbnQuICovXG4gIGNvbnN0IGFuY2VzdG9ycyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIGNvbnN0IHdhbGsgPSAoYWJzb2x1dGU6IHN0cmluZywgcmVsYXRpdmU6IHN0cmluZykgPT4ge1xuICAgIGxldCByZWFsOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIHJlYWwgPSByZWFscGF0aFN5bmMoYWJzb2x1dGUpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoYW5jZXN0b3JzLmhhcyhyZWFsKSkgcmV0dXJuO1xuICAgIGFuY2VzdG9ycy5hZGQocmVhbCk7XG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKGFic29sdXRlLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkpIHtcbiAgICAgIGNvbnN0IGNoaWxkQWJzb2x1dGUgPSBqb2luKGFic29sdXRlLCBlbnRyeS5uYW1lKTtcbiAgICAgIGNvbnN0IGNoaWxkUmVsYXRpdmUgPSByZWxhdGl2ZSA/IGAke3JlbGF0aXZlfS8ke2VudHJ5Lm5hbWV9YCA6IGVudHJ5Lm5hbWU7XG4gICAgICBsZXQgaXNEaXJlY3RvcnkgPSBlbnRyeS5pc0RpcmVjdG9yeSgpO1xuICAgICAgbGV0IGlzRmlsZSA9IGVudHJ5LmlzRmlsZSgpO1xuICAgICAgaWYgKGVudHJ5LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBzdGF0U3luYyhjaGlsZEFic29sdXRlKTtcbiAgICAgICAgICBpc0RpcmVjdG9yeSA9IHRhcmdldC5pc0RpcmVjdG9yeSgpO1xuICAgICAgICAgIGlzRmlsZSA9IHRhcmdldC5pc0ZpbGUoKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gQSBkYW5nbGluZyBsaW5rOiBub3RoaW5nIHRvIHNlcnZlLlxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNEaXJlY3RvcnkpIHtcbiAgICAgICAgd2FsayhjaGlsZEFic29sdXRlLCBjaGlsZFJlbGF0aXZlKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNGaWxlKSB7XG4gICAgICAgIGZpbGVzLnB1c2goY2hpbGRSZWxhdGl2ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGFuY2VzdG9ycy5kZWxldGUocmVhbCk7XG4gIH07XG5cbiAgdHJ5IHtcbiAgICB3YWxrKGRpciwgXCJcIik7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKChlcnJvciBhcyB7IGNvZGU/OiBzdHJpbmcgfSkuY29kZSAhPT0gXCJFTk9FTlRcIikgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmV0dXJuIGZpbGVzLnNvcnQoKTtcbn1cblxuLyoqIGBwdWJsaWMvYCBhcyB0aGUgcnVudGltZSBzZXJ2ZXMgaXQsIGFuZCB3aGVyZSBpdHMgYnl0ZXMgYXJlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQdWJsaWNGaWxlcyB7XG4gIHJlYWRvbmx5IGZpbGVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIGB0cnVlYCB3aGVuIGBmaWxlc2AgY2FtZSBmcm9tIHtAbGluayBQVUJMSUNfRklMRVNfRklMRV9OQU1FfTogZXZlcnkgdHlwZVxuICAgKiBidXQgYE5leHRqc1JlZ2lvbmFsQ29udGFpbmVyc2AuIFRoZWlyIGJ5dGVzIGFyZSBpbiBTMy5cbiAgICovXG4gIHJlYWRvbmx5IGluUzM6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIHN5bnRoLXRpbWUgbGlzdCB3aGVuIHRoZSBkZXBsb3ltZW50IHJvb3QgaGFzIG9uZSwgd2hpY2ggaXMgZXZlcnkgdHlwZSBidXRcbiAqIGBOZXh0anNSZWdpb25hbENvbnRhaW5lcnNgLCBhbmQgYHB1YmxpYy9gIG9mZiBkaXNrIG90aGVyd2lzZS4gVGhlIGxpc3Qgd2luc1xuICogZXZlbiB3aGVuIHNvbWUgb2YgYHB1YmxpYy9gIGlzIG9uIGRpc2s6IGEgcm91dGUgdGhhdCByZWFkcyBhIGBwdWJsaWMvYCBmaWxlXG4gKiB0aHJvdWdoIGBmc2AgZ2V0cyB0aGF0IGZpbGUgdHJhY2VkIGludG8gYSBMYW1iZGEgcm9vdCwgYW5kIHRoZSByZXN0IG9mXG4gKiBgcHVibGljL2AgaXMgc3RpbGwgb25seSBpbiBTMy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVQdWJsaWNGaWxlcyhcbiAgZGVwbG95bWVudFJvb3Q6IHN0cmluZyxcbiAgbWFuaWZlc3Q6IEFkYXB0ZXJNYW5pZmVzdCxcbik6IFB1YmxpY0ZpbGVzIHtcbiAgbGV0IGxpc3RlZDogdW5rbm93bjtcbiAgdHJ5IHtcbiAgICBsaXN0ZWQgPSBKU09OLnBhcnNlKFxuICAgICAgcmVhZEZpbGVTeW5jKFxuICAgICAgICBqb2luKGRlcGxveW1lbnRSb290LCBSVU5USU1FX0RJUl9OQU1FLCBQVUJMSUNfRklMRVNfRklMRV9OQU1FKSxcbiAgICAgICAgXCJ1dGYtOFwiLFxuICAgICAgKSxcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmICgoZXJyb3IgYXMgeyBjb2RlPzogc3RyaW5nIH0pLmNvZGUgPT09IFwiRU5PRU5UXCIpIHtcbiAgICAgIGNvbnN0IG9uRGlzayA9IGpvaW4oZGVwbG95bWVudFJvb3QsIHB1YmxpY0RpcktleShtYW5pZmVzdCkpO1xuICAgICAgcmV0dXJuIHsgZmlsZXM6IHJlYWRQdWJsaWNGaWxlcyhvbkRpc2spLCBpblMzOiBmYWxzZSB9O1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICBpZiAoXG4gICAgIUFycmF5LmlzQXJyYXkobGlzdGVkKSB8fFxuICAgICFsaXN0ZWQuZXZlcnkoKGZpbGUpID0+IHR5cGVvZiBmaWxlID09PSBcInN0cmluZ1wiKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgJHtSVU5USU1FX0RJUl9OQU1FfS8ke1BVQkxJQ19GSUxFU19GSUxFX05BTUV9IGlzIG5vdCBhIEpTT04gYXJyYXkgb2YgcGF0aHMuYCxcbiAgICApO1xuICB9XG4gIHJldHVybiB7IGZpbGVzOiBsaXN0ZWQgYXMgc3RyaW5nW10sIGluUzM6IHRydWUgfTtcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_fs_1 = require("node:fs");
4
+ const node_os_1 = require("node:os");
5
+ const node_path_1 = require("node:path");
6
+ const manifest_1 = require("./manifest");
7
+ const public_files_1 = require("./public-files");
8
+ function tempDir() {
9
+ return (0, node_fs_1.realpathSync)((0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "cdk-nextjs-public-")));
10
+ }
11
+ describe("readPublicFiles", () => {
12
+ it("lists every file, nested, unencoded and sorted", () => {
13
+ const dir = tempDir();
14
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(dir, "images"));
15
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "robots.txt"), "");
16
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "images", "logo@2x.png"), "");
17
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "hello e2e.png"), "");
18
+ expect((0, public_files_1.readPublicFiles)(dir)).toEqual([
19
+ "hello e2e.png",
20
+ "images/logo@2x.png",
21
+ "robots.txt",
22
+ ]);
23
+ });
24
+ it("follows symlinks to files and directories, as Next.js does", () => {
25
+ // `Dirent.isFile()` describes the link, so filtering on it dropped
26
+ // `public/latest.pdf -> v2/report.pdf` while Docker and S3 both carry it.
27
+ const dir = tempDir();
28
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(dir, "v2"));
29
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "v2", "report.pdf"), "");
30
+ (0, node_fs_1.symlinkSync)((0, node_path_1.join)(dir, "v2", "report.pdf"), (0, node_path_1.join)(dir, "latest.pdf"));
31
+ (0, node_fs_1.symlinkSync)((0, node_path_1.join)(dir, "v2"), (0, node_path_1.join)(dir, "current"));
32
+ expect((0, public_files_1.readPublicFiles)(dir)).toEqual([
33
+ "current/report.pdf",
34
+ "latest.pdf",
35
+ "v2/report.pdf",
36
+ ]);
37
+ });
38
+ it("stops at a link cycle and skips a dangling link", () => {
39
+ const dir = tempDir();
40
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(dir, "a"));
41
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "a", "file.txt"), "");
42
+ (0, node_fs_1.symlinkSync)((0, node_path_1.join)(dir, "a"), (0, node_path_1.join)(dir, "a", "loop"));
43
+ (0, node_fs_1.symlinkSync)((0, node_path_1.join)(dir, "missing"), (0, node_path_1.join)(dir, "dangling"));
44
+ expect((0, public_files_1.readPublicFiles)(dir)).toEqual(["a/file.txt"]);
45
+ });
46
+ it("is empty when there is no public/, as on the Lambda types", () => {
47
+ expect((0, public_files_1.readPublicFiles)((0, node_path_1.join)(tempDir(), "public"))).toEqual([]);
48
+ });
49
+ });
50
+ describe("resolvePublicFiles", () => {
51
+ const manifest = { relativeProjectDir: "apps/web" };
52
+ function writeList(root, contents) {
53
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, manifest_1.RUNTIME_DIR_NAME), { recursive: true });
54
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, manifest_1.RUNTIME_DIR_NAME, manifest_1.PUBLIC_FILES_FILE_NAME), contents);
55
+ }
56
+ it("lists public/ off disk when there is no list, on RegionalContainers", () => {
57
+ const root = tempDir();
58
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, "apps/web/public"), { recursive: true });
59
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "apps/web/public/robots.txt"), "");
60
+ expect((0, public_files_1.resolvePublicFiles)(root, manifest)).toEqual({
61
+ files: ["robots.txt"],
62
+ inS3: false,
63
+ });
64
+ });
65
+ it("reads the synth-time list when public/ is not staged, on the Lambda types", () => {
66
+ const root = tempDir();
67
+ writeList(root, JSON.stringify(["feed.xml", "sitemap.xml"]));
68
+ expect((0, public_files_1.resolvePublicFiles)(root, manifest)).toEqual({
69
+ files: ["feed.xml", "sitemap.xml"],
70
+ inS3: true,
71
+ });
72
+ });
73
+ it("prefers the list over a public/ file the trace staged", () => {
74
+ // An OG-image route reading `public/fonts/Inter.ttf` through `fs` gets it
75
+ // traced into a Lambda root; the rest of `public/` is still only in S3.
76
+ const root = tempDir();
77
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, "apps/web/public/fonts"), { recursive: true });
78
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "apps/web/public/fonts/Inter.ttf"), "");
79
+ writeList(root, JSON.stringify(["fonts/Inter.ttf", "logo.png"]));
80
+ expect((0, public_files_1.resolvePublicFiles)(root, manifest)).toEqual({
81
+ files: ["fonts/Inter.ttf", "logo.png"],
82
+ inS3: true,
83
+ });
84
+ });
85
+ it("is empty for an app with neither", () => {
86
+ expect((0, public_files_1.resolvePublicFiles)(tempDir(), manifest)).toEqual({
87
+ files: [],
88
+ inS3: false,
89
+ });
90
+ });
91
+ it("rejects a list that is not an array of paths", () => {
92
+ const root = tempDir();
93
+ writeList(root, JSON.stringify({ files: [] }));
94
+ expect(() => (0, public_files_1.resolvePublicFiles)(root, manifest)).toThrow(/is not a JSON array of paths/);
95
+ });
96
+ });
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWZpbGVzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9wdWJsaWMtZmlsZXMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFDQU1pQjtBQUNqQixxQ0FBaUM7QUFDakMseUNBQWlDO0FBQ2pDLHlDQUlvQjtBQUNwQixpREFBcUU7QUFFckUsU0FBUyxPQUFPO0lBQ2QsT0FBTyxJQUFBLHNCQUFZLEVBQUMsSUFBQSxxQkFBVyxFQUFDLElBQUEsZ0JBQUksRUFBQyxJQUFBLGdCQUFNLEdBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RSxDQUFDO0FBRUQsUUFBUSxDQUFDLGlCQUFpQixFQUFFLEdBQUcsRUFBRTtJQUMvQixFQUFFLENBQUMsZ0RBQWdELEVBQUUsR0FBRyxFQUFFO1FBQ3hELE1BQU0sR0FBRyxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBQ3RCLElBQUEsbUJBQVMsRUFBQyxJQUFBLGdCQUFJLEVBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDL0IsSUFBQSx1QkFBYSxFQUFDLElBQUEsZ0JBQUksRUFBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0MsSUFBQSx1QkFBYSxFQUFDLElBQUEsZ0JBQUksRUFBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELElBQUEsdUJBQWEsRUFBQyxJQUFBLGdCQUFJLEVBQUMsR0FBRyxFQUFFLGVBQWUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sQ0FBQyxJQUFBLDhCQUFlLEVBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDbkMsZUFBZTtZQUNmLG9CQUFvQjtZQUNwQixZQUFZO1NBQ2IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENB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LENBQUMsQ0FBQztRQUNqRSxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLElBQUEsaUNBQWtCLEVBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ2pELEtBQUssRUFBRSxDQUFDLGlCQUFpQixFQUFFLFVBQVUsQ0FBQztZQUN0QyxJQUFJLEVBQUUsSUFBSTtTQUNYLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGtDQUFrQyxFQUFFLEdBQUcsRUFBRTtRQUMxQyxNQUFNLENBQUMsSUFBQSxpQ0FBa0IsRUFBQyxPQUFPLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUN0RCxLQUFLLEVBQUUsRUFBRTtZQUNULElBQUksRUFBRSxLQUFLO1NBQ1osQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO1FBQ3RELE1BQU0sSUFBSSxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBQ3ZCLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDL0MsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsaUNBQWtCLEVBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUN0RCw4QkFBOEIsQ0FDL0IsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBta2RpclN5bmMsXG4gIG1rZHRlbXBTeW5jLFxuICByZWFscGF0aFN5bmMsXG4gIHN5bWxpbmtTeW5jLFxuICB3cml0ZUZpbGVTeW5jLFxufSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQge1xuICBBZGFwdGVyTWFuaWZlc3QsXG4gIFBVQkxJQ19GSUxFU19GSUxFX05BTUUsXG4gIFJVTlRJTUVfRElSX05BTUUsXG59IGZyb20gXCIuL21hbmlmZXN0XCI7XG5pbXBvcnQgeyByZWFkUHVibGljRmlsZXMsIHJlc29sdmVQdWJsaWNGaWxlcyB9IGZyb20gXCIuL3B1YmxpYy1maWxlc1wiO1xuXG5mdW5jdGlvbiB0ZW1wRGlyKCk6IHN0cmluZyB7XG4gIHJldHVybiByZWFscGF0aFN5bmMobWtkdGVtcFN5bmMoam9pbih0bXBkaXIoKSwgXCJjZGstbmV4dGpzLXB1YmxpYy1cIikpKTtcbn1cblxuZGVzY3JpYmUoXCJyZWFkUHVibGljRmlsZXNcIiwgKCkgPT4ge1xuICBpdChcImxpc3RzIGV2ZXJ5IGZpbGUsIG5lc3RlZCwgdW5lbmNvZGVkIGFuZCBzb3J0ZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGRpciA9IHRlbXBEaXIoKTtcbiAgICBta2RpclN5bmMoam9pbihkaXIsIFwiaW1hZ2VzXCIpKTtcbiAgICB3cml0ZUZpbGVTeW5jKGpvaW4oZGlyLCBcInJvYm90cy50eHRcIiksIFwiXCIpO1xuICAgIHdyaXRlRmlsZVN5bmMoam9pbihkaXIsIFwiaW1hZ2VzXCIsIFwibG9nb0AyeC5wbmdcIiksIFwiXCIpO1xuICAgIHdyaXRlRmlsZVN5bmMoam9pbihkaXIsIFwiaGVsbG8gZTJlLnBuZ1wiKSwgXCJcIik7XG4gICAgZXhwZWN0KHJlYWRQdWJsaWNGaWxlcyhkaXIpKS50b0VxdWFsKFtcbiAgICAgIFwiaGVsbG8gZTJlLnBuZ1wiLFxuICAgICAgXCJpbWFnZXMvbG9nb0AyeC5wbmdcIixcbiAgICAgIFwicm9ib3RzLnR4dFwiLFxuICAgIF0pO1xuICB9KTtcblxuICBpdChcImZvbGxvd3Mgc3ltbGlua3MgdG8gZmlsZXMgYW5kIGRpcmVjdG9yaWVzLCBhcyBOZXh0LmpzIGRvZXNcIiwgKCkgPT4ge1xuICAgIC8vIGBEaXJlbnQuaXNGaWxlKClgIGRlc2NyaWJlcyB0aGUgbGluaywgc28gZmlsdGVyaW5nIG9uIGl0IGRyb3BwZWRcbiAgICAvLyBgcHVibGljL2xhdGVzdC5wZGYgLT4gdjIvcmVwb3J0LnBkZmAgd2hpbGUgRG9ja2VyIGFuZCBTMyBib3RoIGNhcnJ5IGl0LlxuICAgIGNvbnN0IGRpciA9IHRlbXBEaXIoKTtcbiAgICBta2RpclN5bmMoam9pbihkaXIsIFwidjJcIikpO1xuICAgIHdyaXRlRmlsZVN5bmMoam9pbihkaXIsIFwidjJcIiwgXCJyZXBvcnQucGRmXCIpLCBcIlwiKTtcbiAgICBzeW1saW5rU3luYyhqb2luKGRpciwgXCJ2MlwiLCBcInJlcG9ydC5wZGZcIiksIGpvaW4oZGlyLCBcImxhdGVzdC5wZGZcIikpO1xuICAgIHN5bWxpbmtTeW5jKGpvaW4oZGlyLCBcInYyXCIpLCBqb2luKGRpciwgXCJjdXJyZW50XCIpKTtcbiAgICBleHBlY3QocmVhZFB1YmxpY0ZpbGVzKGRpcikpLnRvRXF1YWwoW1xuICAgICAgXCJjdXJyZW50L3JlcG9ydC5wZGZcIixcbiAgICAgIFwibGF0ZXN0LnBkZlwiLFxuICAgICAgXCJ2Mi9yZXBvcnQucGRmXCIsXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KFwic3RvcHMgYXQgYSBsaW5rIGN5Y2xlIGFuZCBza2lwcyBhIGRhbmdsaW5nIGxpbmtcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGRpciA9IHRlbXBEaXIoKTtcbiAgICBta2RpclN5bmMoam9pbihkaXIsIFwiYVwiKSk7XG4gICAgd3JpdGVGaWxlU3luYyhqb2luKGRpciwgXCJhXCIsIFwiZmlsZS50eHRcIiksIFwiXCIpO1xuICAgIHN5bWxpbmtTeW5jKGpvaW4oZGlyLCBcImFcIiksIGpvaW4oZGlyLCBcImFcIiwgXCJsb29wXCIpKTtcbiAgICBzeW1saW5rU3luYyhqb2luKGRpciwgXCJtaXNzaW5nXCIpLCBqb2luKGRpciwgXCJkYW5nbGluZ1wiKSk7XG4gICAgZXhwZWN0KHJlYWRQdWJsaWNGaWxlcyhkaXIpKS50b0VxdWFsKFtcImEvZmlsZS50eHRcIl0pO1xuICB9KTtcblxuICBpdChcImlzIGVtcHR5IHdoZW4gdGhlcmUgaXMgbm8gcHVibGljLywgYXMgb24gdGhlIExhbWJkYSB0eXBlc1wiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHJlYWRQdWJsaWNGaWxlcyhqb2luKHRlbXBEaXIoKSwgXCJwdWJsaWNcIikpKS50b0VxdWFsKFtdKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJyZXNvbHZlUHVibGljRmlsZXNcIiwgKCkgPT4ge1xuICBjb25zdCBtYW5pZmVzdCA9IHsgcmVsYXRpdmVQcm9qZWN0RGlyOiBcImFwcHMvd2ViXCIgfSBhcyBBZGFwdGVyTWFuaWZlc3Q7XG5cbiAgZnVuY3Rpb24gd3JpdGVMaXN0KHJvb3Q6IHN0cmluZywgY29udGVudHM6IHN0cmluZyk6IHZvaWQge1xuICAgIG1rZGlyU3luYyhqb2luKHJvb3QsIFJVTlRJTUVfRElSX05BTUUpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB3cml0ZUZpbGVTeW5jKFxuICAgICAgam9pbihyb290LCBSVU5USU1FX0RJUl9OQU1FLCBQVUJMSUNfRklMRVNfRklMRV9OQU1FKSxcbiAgICAgIGNvbnRlbnRzLFxuICAgICk7XG4gIH1cblxuICBpdChcImxpc3RzIHB1YmxpYy8gb2ZmIGRpc2sgd2hlbiB0aGVyZSBpcyBubyBsaXN0LCBvbiBSZWdpb25hbENvbnRhaW5lcnNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSB0ZW1wRGlyKCk7XG4gICAgbWtkaXJTeW5jKGpvaW4ocm9vdCwgXCJhcHBzL3dlYi9wdWJsaWNcIiksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIHdyaXRlRmlsZVN5bmMoam9pbihyb290LCBcImFwcHMvd2ViL3B1YmxpYy9yb2JvdHMudHh0XCIpLCBcIlwiKTtcbiAgICBleHBlY3QocmVzb2x2ZVB1YmxpY0ZpbGVzKHJvb3QsIG1hbmlmZXN0KSkudG9FcXVhbCh7XG4gICAgICBmaWxlczogW1wicm9ib3RzLnR4dFwiXSxcbiAgICAgIGluUzM6IGZhbHNlLFxuICAgIH0pO1xuICB9KTtcblxuICBpdChcInJlYWRzIHRoZSBzeW50aC10aW1lIGxpc3Qgd2hlbiBwdWJsaWMvIGlzIG5vdCBzdGFnZWQsIG9uIHRoZSBMYW1iZGEgdHlwZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSB0ZW1wRGlyKCk7XG4gICAgd3JpdGVMaXN0KHJvb3QsIEpTT04uc3RyaW5naWZ5KFtcImZlZWQueG1sXCIsIFwic2l0ZW1hcC54bWxcIl0pKTtcbiAgICBleHBlY3QocmVzb2x2ZVB1YmxpY0ZpbGVzKHJvb3QsIG1hbmlmZXN0KSkudG9FcXVhbCh7XG4gICAgICBmaWxlczogW1wiZmVlZC54bWxcIiwgXCJzaXRlbWFwLnhtbFwiXSxcbiAgICAgIGluUzM6IHRydWUsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwicHJlZmVycyB0aGUgbGlzdCBvdmVyIGEgcHVibGljLyBmaWxlIHRoZSB0cmFjZSBzdGFnZWRcIiwgKCkgPT4ge1xuICAgIC8vIEFuIE9HLWltYWdlIHJvdXRlIHJlYWRpbmcgYHB1YmxpYy9mb250cy9JbnRlci50dGZgIHRocm91Z2ggYGZzYCBnZXRzIGl0XG4gICAgLy8gdHJhY2VkIGludG8gYSBMYW1iZGEgcm9vdDsgdGhlIHJlc3Qgb2YgYHB1YmxpYy9gIGlzIHN0aWxsIG9ubHkgaW4gUzMuXG4gICAgY29uc3Qgcm9vdCA9IHRlbXBEaXIoKTtcbiAgICBta2RpclN5bmMoam9pbihyb290LCBcImFwcHMvd2ViL3B1YmxpYy9mb250c1wiKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgd3JpdGVGaWxlU3luYyhqb2luKHJvb3QsIFwiYXBwcy93ZWIvcHVibGljL2ZvbnRzL0ludGVyLnR0ZlwiKSwgXCJcIik7XG4gICAgd3JpdGVMaXN0KHJvb3QsIEpTT04uc3RyaW5naWZ5KFtcImZvbnRzL0ludGVyLnR0ZlwiLCBcImxvZ28ucG5nXCJdKSk7XG4gICAgZXhwZWN0KHJlc29sdmVQdWJsaWNGaWxlcyhyb290LCBtYW5pZmVzdCkpLnRvRXF1YWwoe1xuICAgICAgZmlsZXM6IFtcImZvbnRzL0ludGVyLnR0ZlwiLCBcImxvZ28ucG5nXCJdLFxuICAgICAgaW5TMzogdHJ1ZSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJpcyBlbXB0eSBmb3IgYW4gYXBwIHdpdGggbmVpdGhlclwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHJlc29sdmVQdWJsaWNGaWxlcyh0ZW1wRGlyKCksIG1hbmlmZXN0KSkudG9FcXVhbCh7XG4gICAgICBmaWxlczogW10sXG4gICAgICBpblMzOiBmYWxzZSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJyZWplY3RzIGEgbGlzdCB0aGF0IGlzIG5vdCBhbiBhcnJheSBvZiBwYXRoc1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgcm9vdCA9IHRlbXBEaXIoKTtcbiAgICB3cml0ZUxpc3Qocm9vdCwgSlNPTi5zdHJpbmdpZnkoeyBmaWxlczogW10gfSkpO1xuICAgIGV4cGVjdCgoKSA9PiByZXNvbHZlUHVibGljRmlsZXMocm9vdCwgbWFuaWZlc3QpKS50b1Rocm93KFxuICAgICAgL2lzIG5vdCBhIEpTT04gYXJyYXkgb2YgcGF0aHMvLFxuICAgICk7XG4gIH0pO1xufSk7XG4iXX0=