cdk-nextjs 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/.jsii +2404 -2723
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1681 -1930
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
  7. package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
  8. package/docs/adapter-runtime.md +185 -0
  9. package/docs/breaking-changes.md +667 -4
  10. package/docs/caching-guide.md +156 -112
  11. package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
  12. package/docs/development-guide.md +1 -1
  13. package/docs/harness-coverage.md +598 -0
  14. package/docs/init-cache-deployment.md +32 -1
  15. package/docs/next-build-output-guide.md +30 -20
  16. package/examples/README.md +5 -1
  17. package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
  18. package/lib/adapter/__fixtures__/app-playground.json +4917 -0
  19. package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
  20. package/lib/adapter/adapter.mjs +1548 -185
  21. package/lib/adapter/adapter.test.js +106 -0
  22. package/lib/adapter/aws-cache-store.d.ts +489 -0
  23. package/lib/adapter/aws-cache-store.js +1004 -0
  24. package/lib/adapter/aws-cache-store.test.d.ts +1 -0
  25. package/lib/adapter/aws-cache-store.test.js +361 -0
  26. package/lib/adapter/build-outputs.d.ts +80 -0
  27. package/lib/adapter/build-outputs.js +852 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +861 -0
  30. package/lib/adapter/cache-handler.d.ts +9 -2
  31. package/lib/adapter/cache-handler.js +72 -96
  32. package/lib/adapter/cache-handler.mjs +18956 -17774
  33. package/lib/adapter/cache-handler.test.js +263 -31
  34. package/lib/adapter/cache-kinds.d.ts +32 -0
  35. package/lib/adapter/cache-kinds.js +35 -0
  36. package/lib/adapter/cache-kinds.test.d.ts +1 -0
  37. package/lib/adapter/cache-kinds.test.js +69 -0
  38. package/lib/adapter/cache-utils.d.ts +90 -0
  39. package/lib/adapter/cache-utils.js +199 -4
  40. package/lib/adapter/cache-utils.test.d.ts +1 -0
  41. package/lib/adapter/cache-utils.test.js +179 -0
  42. package/lib/adapter/function-groups.d.ts +215 -0
  43. package/lib/adapter/function-groups.js +1099 -0
  44. package/lib/adapter/function-groups.test.d.ts +1 -0
  45. package/lib/adapter/function-groups.test.js +743 -0
  46. package/lib/adapter/init-cache.d.ts +6 -0
  47. package/lib/adapter/init-cache.js +245 -0
  48. package/lib/adapter/init-cache.test.d.ts +1 -0
  49. package/lib/adapter/init-cache.test.js +137 -0
  50. package/lib/adapter/local-file-cache-handler.d.ts +23 -0
  51. package/lib/adapter/local-file-cache-handler.js +52 -1
  52. package/lib/adapter/memory-cache-handler.d.ts +26 -17
  53. package/lib/adapter/memory-cache-handler.js +32 -50
  54. package/lib/adapter/memory-cache-handler.test.js +105 -85
  55. package/lib/adapter/s3-cache-handler.d.ts +179 -40
  56. package/lib/adapter/s3-cache-handler.js +807 -277
  57. package/lib/adapter/s3-cache-handler.test.js +1186 -31
  58. package/lib/adapter/use-cache-common.d.ts +90 -0
  59. package/lib/adapter/use-cache-common.js +250 -0
  60. package/lib/adapter/use-cache-common.test.d.ts +1 -0
  61. package/lib/adapter/use-cache-common.test.js +646 -0
  62. package/lib/adapter/use-cache-default-handler.d.ts +24 -0
  63. package/lib/adapter/use-cache-default-handler.js +90 -0
  64. package/lib/adapter/use-cache-default-handler.mjs +38645 -0
  65. package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
  66. package/lib/adapter/use-cache-handlers.test.js +349 -0
  67. package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
  68. package/lib/adapter/use-cache-remote-handler.js +186 -0
  69. package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
  70. package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
  71. package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
  72. package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
  73. package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
  74. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
  75. package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
  76. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
  77. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  78. package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
  81. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
  82. package/lib/index.d.ts +6 -7
  83. package/lib/index.js +2 -4
  84. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  88. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  92. package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
  93. package/lib/lambdas/post-deploy/prune-s3.js +41 -12
  94. package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
  95. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  96. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  103. package/lib/nextjs-api.d.ts +102 -18
  104. package/lib/nextjs-api.js +338 -38
  105. package/lib/nextjs-api.test.js +537 -1
  106. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  107. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  108. package/lib/nextjs-build/nextjs-build.js +684 -327
  109. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  110. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  111. package/lib/nextjs-build/patch-fetch.js +1 -1
  112. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  113. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  114. package/lib/nextjs-cache.d.ts +82 -4
  115. package/lib/nextjs-cache.js +186 -10
  116. package/lib/nextjs-cache.test.js +176 -1
  117. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  118. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  120. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  121. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  122. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  123. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  124. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  125. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  126. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  127. package/lib/nextjs-distribution.d.ts +194 -23
  128. package/lib/nextjs-distribution.js +535 -62
  129. package/lib/nextjs-distribution.test.d.ts +1 -0
  130. package/lib/nextjs-distribution.test.js +697 -0
  131. package/lib/nextjs-post-deploy.d.ts +13 -5
  132. package/lib/nextjs-post-deploy.js +13 -10
  133. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  134. package/lib/nextjs-post-deploy.test.js +34 -0
  135. package/lib/nextjs-static-assets.d.ts +17 -4
  136. package/lib/nextjs-static-assets.js +22 -5
  137. package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
  138. package/lib/root-constructs/nextjs-base-construct.js +139 -47
  139. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  140. package/lib/root-constructs/nextjs-global-containers.js +20 -71
  141. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  142. package/lib/root-constructs/nextjs-global-functions.js +52 -70
  143. package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
  144. package/lib/root-constructs/nextjs-regional-containers.js +8 -15
  145. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  146. package/lib/root-constructs/nextjs-regional-functions.js +8 -26
  147. package/lib/runtime/api-gateway-path.d.ts +34 -0
  148. package/lib/runtime/api-gateway-path.js +71 -0
  149. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  150. package/lib/runtime/api-gateway-path.test.js +65 -0
  151. package/lib/runtime/case-redirect.d.ts +22 -0
  152. package/lib/runtime/case-redirect.js +63 -0
  153. package/lib/runtime/case-redirect.test.d.ts +1 -0
  154. package/lib/runtime/case-redirect.test.js +32 -0
  155. package/lib/runtime/core.d.ts +234 -0
  156. package/lib/runtime/core.js +1213 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1678 -0
  159. package/lib/runtime/deployment-root.d.ts +13 -0
  160. package/lib/runtime/deployment-root.js +29 -0
  161. package/lib/runtime/dispatch.d.ts +331 -0
  162. package/lib/runtime/dispatch.js +751 -0
  163. package/lib/runtime/dispatch.test.d.ts +1 -0
  164. package/lib/runtime/dispatch.test.js +853 -0
  165. package/lib/runtime/entrypoints.d.ts +57 -0
  166. package/lib/runtime/entrypoints.js +115 -0
  167. package/lib/runtime/http/abort-signal.d.ts +6 -0
  168. package/lib/runtime/http/abort-signal.js +19 -0
  169. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  170. package/lib/runtime/http/abort-signal.test.js +49 -0
  171. package/lib/runtime/http/node-server.d.ts +38 -0
  172. package/lib/runtime/http/node-server.js +99 -0
  173. package/lib/runtime/http/node-server.test.d.ts +1 -0
  174. package/lib/runtime/http/node-server.test.js +96 -0
  175. package/lib/runtime/http/node-sink.d.ts +16 -0
  176. package/lib/runtime/http/node-sink.js +48 -0
  177. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  178. package/lib/runtime/http/node-sink.test.js +66 -0
  179. package/lib/runtime/http/request.d.ts +62 -0
  180. package/lib/runtime/http/request.js +134 -0
  181. package/lib/runtime/http/request.test.d.ts +1 -0
  182. package/lib/runtime/http/request.test.js +103 -0
  183. package/lib/runtime/http/response.d.ts +77 -0
  184. package/lib/runtime/http/response.js +229 -0
  185. package/lib/runtime/http/response.test.d.ts +1 -0
  186. package/lib/runtime/http/response.test.js +178 -0
  187. package/lib/runtime/http/sink.d.ts +73 -0
  188. package/lib/runtime/http/sink.js +188 -0
  189. package/lib/runtime/http/sink.test.d.ts +1 -0
  190. package/lib/runtime/http/sink.test.js +257 -0
  191. package/lib/runtime/image-utils.d.ts +78 -0
  192. package/lib/runtime/image-utils.js +129 -0
  193. package/lib/runtime/image-utils.test.d.ts +1 -0
  194. package/lib/runtime/image-utils.test.js +237 -0
  195. package/lib/runtime/image.d.ts +76 -0
  196. package/lib/runtime/image.js +296 -0
  197. package/lib/runtime/image.test.d.ts +1 -0
  198. package/lib/runtime/image.test.js +405 -0
  199. package/lib/runtime/lambda-event.d.ts +4 -0
  200. package/lib/runtime/lambda-event.js +113 -0
  201. package/lib/runtime/lambda-event.test.d.ts +1 -0
  202. package/lib/runtime/lambda-event.test.js +119 -0
  203. package/lib/runtime/lambda.mjs +41595 -0
  204. package/lib/runtime/load-module.d.ts +8 -0
  205. package/lib/runtime/load-module.js +35 -0
  206. package/lib/runtime/manifest.d.ts +215 -0
  207. package/lib/runtime/manifest.js +118 -0
  208. package/lib/runtime/middleware.d.ts +43 -0
  209. package/lib/runtime/middleware.js +113 -0
  210. package/lib/runtime/middleware.test.d.ts +1 -0
  211. package/lib/runtime/middleware.test.js +259 -0
  212. package/lib/runtime/next-modules.d.ts +55 -0
  213. package/lib/runtime/next-modules.js +124 -0
  214. package/lib/runtime/next-modules.test.d.ts +1 -0
  215. package/lib/runtime/next-modules.test.js +34 -0
  216. package/lib/runtime/public-files.d.ts +32 -0
  217. package/lib/runtime/public-files.js +117 -0
  218. package/lib/runtime/public-files.test.d.ts +1 -0
  219. package/lib/runtime/public-files.test.js +97 -0
  220. package/lib/runtime/server.mjs +41588 -0
  221. package/lib/runtime/static-files.d.ts +50 -0
  222. package/lib/runtime/static-files.js +266 -0
  223. package/lib/runtime/static-files.test.d.ts +1 -0
  224. package/lib/runtime/static-files.test.js +118 -0
  225. package/lib/runtime/util.d.ts +28 -0
  226. package/lib/runtime/util.js +79 -0
  227. package/lib/utils/base-path.d.ts +106 -13
  228. package/lib/utils/base-path.js +254 -41
  229. package/lib/utils/base-path.test.js +219 -51
  230. package/lib/utils/get-architecture.d.ts +7 -8
  231. package/lib/utils/get-architecture.js +12 -13
  232. package/lib/utils/zip-directory.d.ts +14 -0
  233. package/lib/utils/zip-directory.js +121 -0
  234. package/lib/utils/zip-directory.test.d.ts +1 -0
  235. package/lib/utils/zip-directory.test.js +99 -0
  236. package/package.json +22 -3
  237. package/scripts/capture-adapter-fixture.mjs +325 -0
  238. package/scripts/e2e-deploy.sh +398 -0
  239. package/scripts/e2e-harness/README.md +707 -0
  240. package/scripts/e2e-harness/app.js +370 -0
  241. package/scripts/e2e-harness/common.sh +249 -0
  242. package/scripts/e2e-harness/screen.mjs +302 -0
  243. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  244. package/scripts/e2e-harness/type-filters.mjs +47 -0
  245. package/scripts/e2e-logs.sh +75 -0
  246. package/scripts/e2e-offline.sh +91 -0
  247. package/scripts/e2e-sweep.sh +370 -0
  248. package/scripts/e2e-warm.sh +114 -0
  249. package/scripts/zero-config-build.mjs +418 -0
  250. package/docs/1k-concurrent-users-executions.png +0 -0
  251. package/docs/plans/adapter-runtime-release.md +0 -362
  252. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  253. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  254. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  255. package/lib/image-optimization/handler-utils.d.ts +0 -34
  256. package/lib/image-optimization/handler-utils.js +0 -83
  257. package/lib/image-optimization/handler-utils.test.js +0 -178
  258. package/lib/nextjs-build/functions.Dockerfile +0 -31
  259. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  260. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  261. package/lib/utils/experimental-flags.d.ts +0 -24
  262. package/lib/utils/experimental-flags.js +0 -30
  263. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageTooLargeError = void 0;
4
+ exports.fetchFromS3 = fetchFromS3;
5
+ exports.resolveErrorResponse = resolveErrorResponse;
6
+ /* eslint-disable import/no-extraneous-dependencies */
7
+ /**
8
+ * S3 fetching and error mapping for `/_next/image`, split out from
9
+ * {@link ./image.ts} so it is unit-testable without `next` present.
10
+ *
11
+ * The one value from `next` that this file needs is passed in rather than
12
+ * imported: `next` is external to the shell bundles, so a static `import` here
13
+ * would be hoisted into the bundle where it cannot resolve. `image.ts` requires
14
+ * it through `./next-modules` instead.
15
+ */
16
+ const client_s3_1 = require("@aws-sdk/client-s3");
17
+ const util_1 = require("./util");
18
+ /**
19
+ * Fetches a non-absolute (local) image referenced by an `<Image>` from S3.
20
+ *
21
+ * `url` is inconsistent about the app's `basePath`: next-image-loader bakes it
22
+ * into the href for statically imported images, while plain string paths are
23
+ * passed through as literally written by the app. So it is stripped when present,
24
+ * leaving a path relative to the asset root, and the bucket's own key prefix is
25
+ * applied to that. Deriving the key from `basePath` instead is wrong whenever the
26
+ * two differ, which they do for every API Gateway deployment.
27
+ *
28
+ * The key is percent-decoded, because an S3 key is the file's real name while
29
+ * `url` is a URL path. `public/hello world.jpg` arrives here as
30
+ * `/hello%20world.jpg` — the `url` query value is double-encoded, so decoding the
31
+ * query string leaves one layer — and its object key is `hello world.jpg`.
32
+ * Next.js's own `fetchInternalImage` gets the decode for free, since it makes an
33
+ * HTTP subrequest and its static file server resolves the path against the
34
+ * filesystem; skipping it here 400'd that file
35
+ * (`next-image-legacy/unicode`). Unicode needs nothing: `äöüščří.png` survives
36
+ * the query decode as itself and is already the object's name.
37
+ *
38
+ * Throws {@link ImageTooLargeError} rather than read past `maximumBody`
39
+ * (`images.maximumResponseBody`), which `next start` enforces on local sources
40
+ * too: a large `public/` file would otherwise be read into memory whole.
41
+ */
42
+ async function fetchFromS3(s3, bucket, url, location, maximumBody) {
43
+ const { urlBasePath, keyPrefix } = location;
44
+ // The key is the path alone. `/logo.png?v=2` is a cache-buster on a file
45
+ // named `logo.png`, and `next start` treats it as one: `fetchInternalImage`
46
+ // routes the href as a request, whose query and fragment never reach the
47
+ // static file lookup. Left on, they became part of the key, which missed.
48
+ // Cut before decoding, so a `?` that is part of the name (`%3F`) survives.
49
+ const path = withoutAssetPrefix(url.split(/[?#]/, 1)[0], location);
50
+ // Matching on a path boundary keeps a sibling like "/basement/logo.png" from
51
+ // being treated as basePath "/base" plus "ment/logo.png". It's still
52
+ // indistinguishable from a real `public/base/` directory, which loses; that's
53
+ // the right trade, since every statically imported image carries the prefix
54
+ // and the alternative costs an S3 round trip per request to detect it.
55
+ const assetPath = (0, util_1.withoutPathPrefix)(path, urlBasePath).replace(/^\/+/, "");
56
+ const prefix = keyPrefix.replace(/^\/+|\/+$/g, "");
57
+ // A malformed encoding that isn't a literal `%` just misses the key and gets
58
+ // the 400 an absent file gets.
59
+ const decoded = (0, util_1.safeDecode)(assetPath);
60
+ const key = prefix ? `${prefix}/${decoded}` : decoded;
61
+ const response = await s3.send(new client_s3_1.GetObjectCommand({
62
+ Bucket: bucket,
63
+ Key: key,
64
+ }));
65
+ const body = response.Body;
66
+ if (!body) {
67
+ throw new Error(`Empty response from S3 for key: ${key}`);
68
+ }
69
+ if ((response.ContentLength ?? 0) > maximumBody) {
70
+ body.destroy?.();
71
+ throw new ImageTooLargeError(key);
72
+ }
73
+ const chunks = [];
74
+ let size = 0;
75
+ // Counted as well, for an object without a `ContentLength`. Throwing out of
76
+ // the loop destroys the stream.
77
+ for await (const chunk of body) {
78
+ size += chunk.byteLength;
79
+ if (size > maximumBody) {
80
+ throw new ImageTooLargeError(key);
81
+ }
82
+ chunks.push(Buffer.from(chunk));
83
+ }
84
+ return {
85
+ buffer: Buffer.concat(chunks),
86
+ contentType: response.ContentType || null,
87
+ etag: response.ETag || "",
88
+ };
89
+ }
90
+ /**
91
+ * `/cdn/_next/static/media/logo.png` → `/_next/static/media/logo.png`, for a
92
+ * path `assetPrefix` of `/cdn`: only in front of `/_next/`, the one place
93
+ * Next.js puts it.
94
+ */
95
+ function withoutAssetPrefix(path, location) {
96
+ const assetPrefix = location.assetPrefix?.replace(/\/+$/, "") ?? "";
97
+ if (!assetPrefix.startsWith("/"))
98
+ return path;
99
+ return path.startsWith(`${assetPrefix}/_next/`)
100
+ ? path.slice(assetPrefix.length)
101
+ : path;
102
+ }
103
+ /** A source over `images.maximumResponseBody`; see {@link fetchFromS3}. */
104
+ class ImageTooLargeError extends Error {
105
+ constructor(key) {
106
+ super(`S3 object ${key} is over images.maximumResponseBody`);
107
+ this.name = "ImageTooLargeError";
108
+ }
109
+ }
110
+ exports.ImageTooLargeError = ImageTooLargeError;
111
+ /**
112
+ * Maps an error thrown while processing an image request to the HTTP
113
+ * status/message it should produce, preserving the status Next.js's own
114
+ * `ImageError`/`fetchExternalImage` attach. A source over
115
+ * `images.maximumResponseBody` is the 413 `fetchInternalImage` answers.
116
+ */
117
+ function resolveErrorResponse(error, ImageError) {
118
+ if (error instanceof ImageError) {
119
+ return { statusCode: error.statusCode, message: error.message };
120
+ }
121
+ if (error instanceof ImageTooLargeError) {
122
+ return {
123
+ statusCode: 413,
124
+ message: '"url" parameter is valid but internal response is invalid',
125
+ };
126
+ }
127
+ return { statusCode: 500, message: "Internal Server Error" };
128
+ }
129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9pbWFnZS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2REEsa0NBMkRDO0FBaUNELG9EQWlCQztBQTFLRCxzREFBc0Q7QUFDdEQ7Ozs7Ozs7O0dBUUc7QUFDSCxrREFBZ0U7QUFDaEUsaUNBQXVEO0FBMEJ2RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSSxLQUFLLFVBQVUsV0FBVyxDQUMvQixFQUFZLEVBQ1osTUFBYyxFQUNkLEdBQVcsRUFDWCxRQUF5QixFQUN6QixXQUFtQjtJQUVuQixNQUFNLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxHQUFHLFFBQVEsQ0FBQztJQUM1Qyx5RUFBeUU7SUFDekUsNEVBQTRFO0lBQzVFLHlFQUF5RTtJQUN6RSwwRUFBMEU7SUFDMUUsMkVBQTJFO0lBQzNFLE1BQU0sSUFBSSxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ25FLDZFQUE2RTtJQUM3RSxxRUFBcUU7SUFDckUsOEVBQThFO0lBQzlFLDRFQUE0RTtJQUM1RSx1RUFBdUU7SUFDdkUsTUFBTSxTQUFTLEdBQUcsSUFBQSx3QkFBaUIsRUFBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMzRSxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNuRCw2RUFBNkU7SUFDN0UsK0JBQStCO0lBQy9CLE1BQU0sT0FBTyxHQUFHLElBQUEsaUJBQVUsRUFBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxJ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LHVCQUF1QixFQUFFLENBQUM7QUFDL0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuLyoqXG4gKiBTMyBmZXRjaGluZyBhbmQgZXJyb3IgbWFwcGluZyBmb3IgYC9fbmV4dC9pbWFnZWAsIHNwbGl0IG91dCBmcm9tXG4gKiB7QGxpbmsgLi9pbWFnZS50c30gc28gaXQgaXMgdW5pdC10ZXN0YWJsZSB3aXRob3V0IGBuZXh0YCBwcmVzZW50LlxuICpcbiAqIFRoZSBvbmUgdmFsdWUgZnJvbSBgbmV4dGAgdGhhdCB0aGlzIGZpbGUgbmVlZHMgaXMgcGFzc2VkIGluIHJhdGhlciB0aGFuXG4gKiBpbXBvcnRlZDogYG5leHRgIGlzIGV4dGVybmFsIHRvIHRoZSBzaGVsbCBidW5kbGVzLCBzbyBhIHN0YXRpYyBgaW1wb3J0YCBoZXJlXG4gKiB3b3VsZCBiZSBob2lzdGVkIGludG8gdGhlIGJ1bmRsZSB3aGVyZSBpdCBjYW5ub3QgcmVzb2x2ZS4gYGltYWdlLnRzYCByZXF1aXJlc1xuICogaXQgdGhyb3VnaCBgLi9uZXh0LW1vZHVsZXNgIGluc3RlYWQuXG4gKi9cbmltcG9ydCB7IEdldE9iamVjdENvbW1hbmQsIFMzQ2xpZW50IH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuaW1wb3J0IHsgc2FmZURlY29kZSwgd2l0aG91dFBhdGhQcmVmaXggfSBmcm9tIFwiLi91dGlsXCI7XG5cbi8qKiBXaGVyZSB0aGUgYXBwIGlzIHNlcnZlZCB2ZXJzdXMgd2hlcmUgaXRzIGFzc2V0cyB3ZXJlIHVwbG9hZGVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTM0Fzc2V0TG9jYXRpb24ge1xuICAvKipcbiAgICogVGhlIGFwcCdzIG93biBgYmFzZVBhdGhgIOKAlCB0aGUgcHJlZml4IG9mIHRoZSAqVVJMKiBpdCBpcyBzZXJ2ZWQgYXQuIE9ubHlcbiAgICogc3RyaXBwZWQgZnJvbSB0aGUgaHJlZiwgbmV2ZXIgdXNlZCB0byBidWlsZCBhIGtleTogb24gdGhlIEFQSSBHYXRld2F5XG4gICAqIGRlcGxveW1lbnQgdHlwZXMgdGhpcyBpcyB0aGUgc3RhZ2UgbmFtZSwgd2hpY2ggbmV2ZXIgYXBwZWFycyBpbiBTMy5cbiAgICovXG4gIHJlYWRvbmx5IHVybEJhc2VQYXRoOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBgTmV4dGpzU3RhdGljQXNzZXRzLmtleVByZWZpeGA6IHRoZSBTMyBrZXkgcHJlZml4IHRoZSBhc3NldHMgd2VyZSB1cGxvYWRlZFxuICAgKiB1bmRlciwgd2l0aG91dCBhIGxlYWRpbmcgc2xhc2guIEVtcHR5IGZvciBhIGJ1Y2tldC1yb290IGRlcGxveW1lbnQuXG4gICAqL1xuICByZWFkb25seSBrZXlQcmVmaXg6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBhcHAncyBgYXNzZXRQcmVmaXhgLCB3aGVuIGl0IGlzIGEgcGF0aCAoYC9jZG5gKS4gTmV4dC5qcyBwdXRzIGl0IGluXG4gICAqIGZyb250IG9mIGAvX25leHQvYCBpbiBwbGFjZSBvZiBgYmFzZVBhdGhgLCBzbyBhIHN0YXRpY2FsbHkgaW1wb3J0ZWQgaW1hZ2Unc1xuICAgKiBocmVmIGlzIGAvY2RuL19uZXh0L3N0YXRpYy9tZWRpYS/igKZgLCBhbmQgYG5leHQgc3RhcnRgIHN0cmlwcyBpdCBhZ2FpbiB3aGVuXG4gICAqIGl0IHNlcnZlcyB0aGUgZmlsZS4gQW4gYWJzb2x1dGUgYGFzc2V0UHJlZml4YCBtYWtlcyB0aGUgaHJlZiBhYnNvbHV0ZSwgd2hpY2hcbiAgICogbmV2ZXIgcmVhY2hlcyBoZXJlLlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGFzc2V0UHJlZml4Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEZldGNoZXMgYSBub24tYWJzb2x1dGUgKGxvY2FsKSBpbWFnZSByZWZlcmVuY2VkIGJ5IGFuIGA8SW1hZ2U+YCBmcm9tIFMzLlxuICpcbiAqIGB1cmxgIGlzIGluY29uc2lzdGVudCBhYm91dCB0aGUgYXBwJ3MgYGJhc2VQYXRoYDogbmV4dC1pbWFnZS1sb2FkZXIgYmFrZXMgaXRcbiAqIGludG8gdGhlIGhyZWYgZm9yIHN0YXRpY2FsbHkgaW1wb3J0ZWQgaW1hZ2VzLCB3aGlsZSBwbGFpbiBzdHJpbmcgcGF0aHMgYXJlXG4gKiBwYXNzZWQgdGhyb3VnaCBhcyBsaXRlcmFsbHkgd3JpdHRlbiBieSB0aGUgYXBwLiBTbyBpdCBpcyBzdHJpcHBlZCB3aGVuIHByZXNlbnQsXG4gKiBsZWF2aW5nIGEgcGF0aCByZWxhdGl2ZSB0byB0aGUgYXNzZXQgcm9vdCwgYW5kIHRoZSBidWNrZXQncyBvd24ga2V5IHByZWZpeCBpc1xuICogYXBwbGllZCB0byB0aGF0LiBEZXJpdmluZyB0aGUga2V5IGZyb20gYGJhc2VQYXRoYCBpbnN0ZWFkIGlzIHdyb25nIHdoZW5ldmVyIHRoZVxuICogdHdvIGRpZmZlciwgd2hpY2ggdGhleSBkbyBmb3IgZXZlcnkgQVBJIEdhdGV3YXkgZGVwbG95bWVudC5cbiAqXG4gKiBUaGUga2V5IGlzIHBlcmNlbnQtZGVjb2RlZCwgYmVjYXVzZSBhbiBTMyBrZXkgaXMgdGhlIGZpbGUncyByZWFsIG5hbWUgd2hpbGVcbiAqIGB1cmxgIGlzIGEgVVJMIHBhdGguIGBwdWJsaWMvaGVsbG8gd29ybGQuanBnYCBhcnJpdmVzIGhlcmUgYXNcbiAqIGAvaGVsbG8lMjB3b3JsZC5qcGdgIOKAlCB0aGUgYHVybGAgcXVlcnkgdmFsdWUgaXMgZG91YmxlLWVuY29kZWQsIHNvIGRlY29kaW5nIHRoZVxuICogcXVlcnkgc3RyaW5nIGxlYXZlcyBvbmUgbGF5ZXIg4oCUIGFuZCBpdHMgb2JqZWN0IGtleSBpcyBgaGVsbG8gd29ybGQuanBnYC5cbiAqIE5leHQuanMncyBvd24gYGZldGNoSW50ZXJuYWxJbWFnZWAgZ2V0cyB0aGUgZGVjb2RlIGZvciBmcmVlLCBzaW5jZSBpdCBtYWtlcyBhblxuICogSFRUUCBzdWJyZXF1ZXN0IGFuZCBpdHMgc3RhdGljIGZpbGUgc2VydmVyIHJlc29sdmVzIHRoZSBwYXRoIGFnYWluc3QgdGhlXG4gKiBmaWxlc3lzdGVtOyBza2lwcGluZyBpdCBoZXJlIDQwMCdkIHRoYXQgZmlsZVxuICogKGBuZXh0LWltYWdlLWxlZ2FjeS91bmljb2RlYCkuIFVuaWNvZGUgbmVlZHMgbm90aGluZzogYMOkw7bDvMWhxI3FmcOtLnBuZ2Agc3Vydml2ZXNcbiAqIHRoZSBxdWVyeSBkZWNvZGUgYXMgaXRzZWxmIGFuZCBpcyBhbHJlYWR5IHRoZSBvYmplY3QncyBuYW1lLlxuICpcbiAqIFRocm93cyB7QGxpbmsgSW1hZ2VUb29MYXJnZUVycm9yfSByYXRoZXIgdGhhbiByZWFkIHBhc3QgYG1heGltdW1Cb2R5YFxuICogKGBpbWFnZXMubWF4aW11bVJlc3BvbnNlQm9keWApLCB3aGljaCBgbmV4dCBzdGFydGAgZW5mb3JjZXMgb24gbG9jYWwgc291cmNlc1xuICogdG9vOiBhIGxhcmdlIGBwdWJsaWMvYCBmaWxlIHdvdWxkIG90aGVyd2lzZSBiZSByZWFkIGludG8gbWVtb3J5IHdob2xlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hGcm9tUzMoXG4gIHMzOiBTM0NsaWVudCxcbiAgYnVja2V0OiBzdHJpbmcsXG4gIHVybDogc3RyaW5nLFxuICBsb2NhdGlvbjogUzNBc3NldExvY2F0aW9uLFxuICBtYXhpbXVtQm9keTogbnVtYmVyLFxuKTogUHJvbWlzZTx7IGJ1ZmZlcjogQnVmZmVyOyBjb250ZW50VHlwZTogc3RyaW5nIHwgbnVsbDsgZXRhZzogc3RyaW5nIH0+IHtcbiAgY29uc3QgeyB1cmxCYXNlUGF0aCwga2V5UHJlZml4IH0gPSBsb2NhdGlvbjtcbiAgLy8gVGhlIGtleSBpcyB0aGUgcGF0aCBhbG9uZS4gYC9sb2dvLnBuZz92PTJgIGlzIGEgY2FjaGUtYnVzdGVyIG9uIGEgZmlsZVxuICAvLyBuYW1lZCBgbG9nby5wbmdgLCBhbmQgYG5leHQgc3RhcnRgIHRyZWF0cyBpdCBhcyBvbmU6IGBmZXRjaEludGVybmFsSW1hZ2VgXG4gIC8vIHJvdXRlcyB0aGUgaHJlZiBhcyBhIHJlcXVlc3QsIHdob3NlIHF1ZXJ5IGFuZCBmcmFnbWVudCBuZXZlciByZWFjaCB0aGVcbiAgLy8gc3RhdGljIGZpbGUgbG9va3VwLiBMZWZ0IG9uLCB0aGV5IGJlY2FtZSBwYXJ0IG9mIHRoZSBrZXksIHdoaWNoIG1pc3NlZC5cbiAgLy8gQ3V0IGJlZm9yZSBkZWNvZGluZywgc28gYSBgP2AgdGhhdCBpcyBwYXJ0IG9mIHRoZSBuYW1lIChgJTNGYCkgc3Vydml2ZXMuXG4gIGNvbnN0IHBhdGggPSB3aXRob3V0QXNzZXRQcmVmaXgodXJsLnNwbGl0KC9bPyNdLywgMSlbMF0sIGxvY2F0aW9uKTtcbiAgLy8gTWF0Y2hpbmcgb24gYSBwYXRoIGJvdW5kYXJ5IGtlZXBzIGEgc2libGluZyBsaWtlIFwiL2Jhc2VtZW50L2xvZ28ucG5nXCIgZnJvbVxuICAvLyBiZWluZyB0cmVhdGVkIGFzIGJhc2VQYXRoIFwiL2Jhc2VcIiBwbHVzIFwibWVudC9sb2dvLnBuZ1wiLiBJdCdzIHN0aWxsXG4gIC8vIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gYSByZWFsIGBwdWJsaWMvYmFzZS9gIGRpcmVjdG9yeSwgd2hpY2ggbG9zZXM7IHRoYXQnc1xuICAvLyB0aGUgcmlnaHQgdHJhZGUsIHNpbmNlIGV2ZXJ5IHN0YXRpY2FsbHkgaW1wb3J0ZWQgaW1hZ2UgY2FycmllcyB0aGUgcHJlZml4XG4gIC8vIGFuZCB0aGUgYWx0ZXJuYXRpdmUgY29zdHMgYW4gUzMgcm91bmQgdHJpcCBwZXIgcmVxdWVzdCB0byBkZXRlY3QgaXQuXG4gIGNvbnN0IGFzc2V0UGF0aCA9IHdpdGhvdXRQYXRoUHJlZml4KHBhdGgsIHVybEJhc2VQYXRoKS5yZXBsYWNlKC9eXFwvKy8sIFwiXCIpO1xuICBjb25zdCBwcmVmaXggPSBrZXlQcmVmaXgucmVwbGFjZSgvXlxcLyt8XFwvKyQvZywgXCJcIik7XG4gIC8vIEEgbWFsZm9ybWVkIGVuY29kaW5nIHRoYXQgaXNuJ3QgYSBsaXRlcmFsIGAlYCBqdXN0IG1pc3NlcyB0aGUga2V5IGFuZCBnZXRzXG4gIC8vIHRoZSA0MDAgYW4gYWJzZW50IGZpbGUgZ2V0cy5cbiAgY29uc3QgZGVjb2RlZCA9IHNhZmVEZWNvZGUoYXNzZXRQYXRoKTtcbiAgY29uc3Qga2V5ID0gcHJlZml4ID8gYCR7cHJlZml4fS8ke2RlY29kZWR9YCA6IGRlY29kZWQ7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzMy5zZW5kKFxuICAgIG5ldyBHZXRPYmplY3RDb21tYW5kKHtcbiAgICAgIEJ1Y2tldDogYnVja2V0LFxuICAgICAgS2V5OiBrZXksXG4gICAgfSksXG4gICk7XG5cbiAgY29uc3QgYm9keSA9IHJlc3BvbnNlLkJvZHk7XG4gIGlmICghYm9keSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRW1wdHkgcmVzcG9uc2UgZnJvbSBTMyBmb3Iga2V5OiAke2tleX1gKTtcbiAgfVxuXG4gIGlmICgocmVzcG9uc2UuQ29udGVudExlbmd0aCA/PyAwKSA+IG1heGltdW1Cb2R5KSB7XG4gICAgKGJvZHkgYXMgeyBkZXN0cm95PzogKCkgPT4gdm9pZCB9KS5kZXN0cm95Py4oKTtcbiAgICB0aHJvdyBuZXcgSW1hZ2VUb29MYXJnZUVycm9yKGtleSk7XG4gIH1cbiAgY29uc3QgY2h1bmtzOiBCdWZmZXJbXSA9IFtdO1xuICBsZXQgc2l6ZSA9IDA7XG4gIC8vIENvdW50ZWQgYXMgd2VsbCwgZm9yIGFuIG9iamVjdCB3aXRob3V0IGEgYENvbnRlbnRMZW5ndGhgLiBUaHJvd2luZyBvdXQgb2ZcbiAgLy8gdGhlIGxvb3AgZGVzdHJveXMgdGhlIHN0cmVhbS5cbiAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBib2R5IGFzIEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pIHtcbiAgICBzaXplICs9IGNodW5rLmJ5dGVMZW5ndGg7XG4gICAgaWYgKHNpemUgPiBtYXhpbXVtQm9keSkge1xuICAgICAgdGhyb3cgbmV3IEltYWdlVG9vTGFyZ2VFcnJvcihrZXkpO1xuICAgIH1cbiAgICBjaHVua3MucHVzaChCdWZmZXIuZnJvbShjaHVuaykpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBidWZmZXI6IEJ1ZmZlci5jb25jYXQoY2h1bmtzKSxcbiAgICBjb250ZW50VHlwZTogcmVzcG9uc2UuQ29udGVudFR5cGUgfHwgbnVsbCxcbiAgICBldGFnOiByZXNwb25zZS5FVGFnIHx8IFwiXCIsXG4gIH07XG59XG5cbi8qKlxuICogYC9jZG4vX25leHQvc3RhdGljL21lZGlhL2xvZ28ucG5nYCDihpIgYC9fbmV4dC9zdGF0aWMvbWVkaWEvbG9nby5wbmdgLCBmb3IgYVxuICogcGF0aCBgYXNzZXRQcmVmaXhgIG9mIGAvY2RuYDogb25seSBpbiBmcm9udCBvZiBgL19uZXh0L2AsIHRoZSBvbmUgcGxhY2VcbiAqIE5leHQuanMgcHV0cyBpdC5cbiAqL1xuZnVuY3Rpb24gd2l0aG91dEFzc2V0UHJlZml4KHBhdGg6IHN0cmluZywgbG9jYXRpb246IFMzQXNzZXRMb2NhdGlvbik6IHN0cmluZyB7XG4gIGNvbnN0IGFzc2V0UHJlZml4ID0gbG9jYXRpb24uYXNzZXRQcmVmaXg/LnJlcGxhY2UoL1xcLyskLywgXCJcIikgPz8gXCJcIjtcbiAgaWYgKCFhc3NldFByZWZpeC5zdGFydHNXaXRoKFwiL1wiKSkgcmV0dXJuIHBhdGg7XG4gIHJldHVybiBwYXRoLnN0YXJ0c1dpdGgoYCR7YXNzZXRQcmVmaXh9L19uZXh0L2ApXG4gICAgPyBwYXRoLnNsaWNlKGFzc2V0UHJlZml4Lmxlbmd0aClcbiAgICA6IHBhdGg7XG59XG5cbi8qKiBBIHNvdXJjZSBvdmVyIGBpbWFnZXMubWF4aW11bVJlc3BvbnNlQm9keWA7IHNlZSB7QGxpbmsgZmV0Y2hGcm9tUzN9LiAqL1xuZXhwb3J0IGNsYXNzIEltYWdlVG9vTGFyZ2VFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcHVibGljIGNvbnN0cnVjdG9yKGtleTogc3RyaW5nKSB7XG4gICAgc3VwZXIoYFMzIG9iamVjdCAke2tleX0gaXMgb3ZlciBpbWFnZXMubWF4aW11bVJlc3BvbnNlQm9keWApO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VUb29MYXJnZUVycm9yXCI7XG4gIH1cbn1cblxuLyoqIGBJbWFnZUVycm9yYCBmcm9tIGBuZXh0L2Rpc3Qvc2VydmVyL2ltYWdlLW9wdGltaXplci5qc2AuICovXG5leHBvcnQgdHlwZSBJbWFnZUVycm9yQ2xhc3MgPVxuICAodHlwZW9mIGltcG9ydChcIm5leHQvZGlzdC9zZXJ2ZXIvaW1hZ2Utb3B0aW1pemVyLmpzXCIpKVtcIkltYWdlRXJyb3JcIl07XG5cbi8qKlxuICogTWFwcyBhbiBlcnJvciB0aHJvd24gd2hpbGUgcHJvY2Vzc2luZyBhbiBpbWFnZSByZXF1ZXN0IHRvIHRoZSBIVFRQXG4gKiBzdGF0dXMvbWVzc2FnZSBpdCBzaG91bGQgcHJvZHVjZSwgcHJlc2VydmluZyB0aGUgc3RhdHVzIE5leHQuanMncyBvd25cbiAqIGBJbWFnZUVycm9yYC9gZmV0Y2hFeHRlcm5hbEltYWdlYCBhdHRhY2guIEEgc291cmNlIG92ZXJcbiAqIGBpbWFnZXMubWF4aW11bVJlc3BvbnNlQm9keWAgaXMgdGhlIDQxMyBgZmV0Y2hJbnRlcm5hbEltYWdlYCBhbnN3ZXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUVycm9yUmVzcG9uc2UoXG4gIGVycm9yOiB1bmtub3duLFxuICBJbWFnZUVycm9yOiBJbWFnZUVycm9yQ2xhc3MsXG4pOiB7XG4gIHN0YXR1c0NvZGU6IG51bWJlcjtcbiAgbWVzc2FnZTogc3RyaW5nO1xufSB7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIEltYWdlRXJyb3IpIHtcbiAgICByZXR1cm4geyBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlIH07XG4gIH1cbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgSW1hZ2VUb29MYXJnZUVycm9yKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1c0NvZGU6IDQxMyxcbiAgICAgIG1lc3NhZ2U6ICdcInVybFwiIHBhcmFtZXRlciBpcyB2YWxpZCBidXQgaW50ZXJuYWwgcmVzcG9uc2UgaXMgaW52YWxpZCcsXG4gICAgfTtcbiAgfVxuICByZXR1cm4geyBzdGF0dXNDb2RlOiA1MDAsIG1lc3NhZ2U6IFwiSW50ZXJuYWwgU2VydmVyIEVycm9yXCIgfTtcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable import/no-extraneous-dependencies */
4
+ jest.mock("@aws-sdk/client-s3");
5
+ const client_s3_1 = require("@aws-sdk/client-s3");
6
+ const image_optimizer_js_1 = require("next/dist/server/image-optimizer.js");
7
+ const image_utils_1 = require("./image-utils");
8
+ function asyncIterableFrom(chunks) {
9
+ return {
10
+ [Symbol.asyncIterator]() {
11
+ let i = 0;
12
+ return {
13
+ next: async () => i < chunks.length
14
+ ? { done: false, value: chunks[i++] }
15
+ : { done: true, value: undefined },
16
+ };
17
+ },
18
+ };
19
+ }
20
+ /** No app `basePath`, assets at the root of the bucket: the default. */
21
+ const ROOT = { urlBasePath: "", keyPrefix: "" };
22
+ describe("fetchFromS3", () => {
23
+ const mockSend = jest.fn();
24
+ const s3 = new client_s3_1.S3Client({});
25
+ beforeEach(() => {
26
+ s3.send = mockSend;
27
+ mockSend.mockReset();
28
+ });
29
+ const ok = () => mockSend.mockResolvedValue({
30
+ Body: asyncIterableFrom([Buffer.from("data")]),
31
+ ContentType: "image/png",
32
+ ETag: '"abc123"',
33
+ });
34
+ const keyOf = () => client_s3_1.GetObjectCommand.mock.calls[0][0].Key;
35
+ it("strips the leading slash when the assets sit at the bucket root", async () => {
36
+ ok();
37
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/static/foo.png", {
38
+ urlBasePath: "",
39
+ keyPrefix: "",
40
+ }, Infinity);
41
+ expect(client_s3_1.GetObjectCommand.mock.calls[0][0]).toEqual({ Bucket: "my-bucket", Key: "static/foo.png" });
42
+ });
43
+ it("applies the bucket key prefix", async () => {
44
+ ok();
45
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/static/foo.jpg", {
46
+ urlBasePath: "/base",
47
+ keyPrefix: "base",
48
+ }, Infinity);
49
+ expect(keyOf()).toBe("base/static/foo.jpg");
50
+ });
51
+ it("does not repeat the prefix when the url already carries basePath", async () => {
52
+ ok();
53
+ // next-image-loader bakes `basePath` into the href of a statically imported
54
+ // image, unlike a plain string path.
55
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/base/_next/static/media/a.png", {
56
+ urlBasePath: "/base",
57
+ keyPrefix: "base",
58
+ }, Infinity);
59
+ expect(keyOf()).toBe("base/_next/static/media/a.png");
60
+ });
61
+ /**
62
+ * The API Gateway deployment types serve the app under the stage name, so the
63
+ * app's `basePath` is `/prod` while the assets were uploaded to the root of the
64
+ * bucket. Building the key from `basePath` asks S3 for `prod/...`, which does
65
+ * not exist, and every local `<Image>` 400s.
66
+ */
67
+ it("strips a basePath that is not part of the key", async () => {
68
+ ok();
69
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/prod/_next/static/media/a.png", {
70
+ urlBasePath: "/prod",
71
+ keyPrefix: "",
72
+ }, Infinity);
73
+ expect(keyOf()).toBe("_next/static/media/a.png");
74
+ });
75
+ it("leaves a url without basePath alone when there is no key prefix", async () => {
76
+ ok();
77
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/static/foo.jpg", {
78
+ urlBasePath: "/prod",
79
+ keyPrefix: "",
80
+ }, Infinity);
81
+ expect(keyOf()).toBe("static/foo.jpg");
82
+ });
83
+ // With `assetPrefix: "/cdn"`, a static import's href is
84
+ // `/cdn/_next/static/media/…`, with `basePath` nowhere in it.
85
+ it("strips a path assetPrefix in front of /_next/", async () => {
86
+ ok();
87
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/cdn/_next/static/media/a.png", {
88
+ urlBasePath: "/base",
89
+ keyPrefix: "",
90
+ assetPrefix: "/cdn/",
91
+ }, Infinity);
92
+ expect(keyOf()).toBe("_next/static/media/a.png");
93
+ });
94
+ it("leaves a public/ file under a directory named like the assetPrefix alone", async () => {
95
+ ok();
96
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/cdn/logo.png", {
97
+ urlBasePath: "",
98
+ keyPrefix: "",
99
+ assetPrefix: "/cdn",
100
+ }, Infinity);
101
+ expect(keyOf()).toBe("cdn/logo.png");
102
+ });
103
+ it("ignores an absolute assetPrefix", async () => {
104
+ ok();
105
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/_next/static/media/a.png", {
106
+ urlBasePath: "",
107
+ keyPrefix: "",
108
+ assetPrefix: "https://cdn.example.test",
109
+ }, Infinity);
110
+ expect(keyOf()).toBe("_next/static/media/a.png");
111
+ });
112
+ it("only matches basePath on a path boundary", async () => {
113
+ ok();
114
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/basement/logo.png", {
115
+ urlBasePath: "/base",
116
+ keyPrefix: "base",
117
+ }, Infinity);
118
+ expect(keyOf()).toBe("base/basement/logo.png");
119
+ });
120
+ // Carried over from #267, which fixed the same bug in the pre-adapter image
121
+ // handler: a `destinationKeyPrefix` override can arrive with a trailing slash.
122
+ it("doesn't double the separator when the key prefix has a trailing slash", async () => {
123
+ ok();
124
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/static/foo.jpg", {
125
+ urlBasePath: "",
126
+ keyPrefix: "base/",
127
+ }, Infinity);
128
+ expect(keyOf()).toBe("base/static/foo.jpg");
129
+ });
130
+ // `next-image-legacy/unicode`, whose `public/` holds both of these names. The
131
+ // space is what broke: the key is the file's real name, the url is a URL path.
132
+ it.each([
133
+ ["/hello%20world.jpg", "hello world.jpg"],
134
+ ["/äöüščří.png", "äöüščří.png"],
135
+ ["/%C3%A4%C3%B6.png", "äö.png"],
136
+ ])("decodes %s into the object's real name", async (url, key) => {
137
+ ok();
138
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", url, ROOT, Infinity);
139
+ expect(keyOf()).toBe(key);
140
+ });
141
+ // A cache-buster on a local src: `next start` routes the href as a request, so
142
+ // the query and fragment never reach the file lookup.
143
+ it.each([
144
+ ["/logo.png?v=2", "logo.png"],
145
+ ["/logo.png#top", "logo.png"],
146
+ ["/logo.png?v=2#top", "logo.png"],
147
+ ["/base/logo.png?v=2", "logo.png"],
148
+ // A `?` that is part of the name arrives encoded and is not a query.
149
+ ["/what%3F.png?v=2", "what?.png"],
150
+ ])("keys %s by its path alone", async (url, key) => {
151
+ ok();
152
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", url, {
153
+ urlBasePath: "/base",
154
+ keyPrefix: "",
155
+ }, Infinity);
156
+ expect(keyOf()).toBe(key);
157
+ });
158
+ it("leaves a name that isn't valid percent-encoding alone", async () => {
159
+ ok();
160
+ await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/100%.png", ROOT, Infinity);
161
+ expect(keyOf()).toBe("100%.png");
162
+ });
163
+ it("returns the concatenated buffer, content type, and etag", async () => {
164
+ mockSend.mockResolvedValue({
165
+ Body: asyncIterableFrom([Buffer.from("hel"), Buffer.from("lo")]),
166
+ ContentType: "image/jpeg",
167
+ ETag: '"the-etag"',
168
+ });
169
+ const result = await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/foo.jpg", ROOT, Infinity);
170
+ expect(result.buffer.toString()).toBe("hello");
171
+ expect(result.contentType).toBe("image/jpeg");
172
+ expect(result.etag).toBe('"the-etag"');
173
+ });
174
+ it("returns an empty etag when S3 doesn't provide one", async () => {
175
+ mockSend.mockResolvedValue({
176
+ Body: asyncIterableFrom([Buffer.from("data")]),
177
+ ContentType: null,
178
+ ETag: undefined,
179
+ });
180
+ const result = await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/foo.png", ROOT, Infinity);
181
+ expect(result.etag).toBe("");
182
+ expect(result.contentType).toBeNull();
183
+ });
184
+ // `images.maximumResponseBody`, which `next start` enforces on local sources.
185
+ it("refuses an object whose ContentLength is over the limit, unread", async () => {
186
+ const destroy = jest.fn();
187
+ mockSend.mockResolvedValue({
188
+ Body: { ...asyncIterableFrom([Buffer.from("never read")]), destroy },
189
+ ContentLength: 11,
190
+ });
191
+ await expect((0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/big.png", ROOT, 10)).rejects.toBeInstanceOf(image_utils_1.ImageTooLargeError);
192
+ expect(destroy).toHaveBeenCalled();
193
+ });
194
+ it("stops reading once the bytes read pass the limit", async () => {
195
+ mockSend.mockResolvedValue({
196
+ Body: asyncIterableFrom([Buffer.from("hel"), Buffer.from("lo")]),
197
+ });
198
+ await expect((0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/big.png", ROOT, 4)).rejects.toBeInstanceOf(image_utils_1.ImageTooLargeError);
199
+ // At the limit exactly is fine.
200
+ mockSend.mockResolvedValue({
201
+ Body: asyncIterableFrom([Buffer.from("hel"), Buffer.from("lo")]),
202
+ ContentLength: 5,
203
+ });
204
+ const result = await (0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/ok.png", ROOT, 5);
205
+ expect(result.buffer.toString()).toBe("hello");
206
+ });
207
+ it("throws when S3 returns no body", async () => {
208
+ mockSend.mockResolvedValue({ Body: undefined });
209
+ await expect((0, image_utils_1.fetchFromS3)(s3, "my-bucket", "/missing.png", ROOT, Infinity)).rejects.toThrow(/Empty response from S3/);
210
+ });
211
+ });
212
+ describe("resolveErrorResponse", () => {
213
+ it("preserves the status code and message from an ImageError", () => {
214
+ const error = new image_optimizer_js_1.ImageError(400, '"url" parameter is not allowed');
215
+ expect((0, image_utils_1.resolveErrorResponse)(error, image_optimizer_js_1.ImageError)).toEqual({
216
+ statusCode: 400,
217
+ message: '"url" parameter is not allowed',
218
+ });
219
+ });
220
+ it("maps a source over images.maximumResponseBody to next start's 413", () => {
221
+ expect((0, image_utils_1.resolveErrorResponse)(new image_utils_1.ImageTooLargeError("big.png"), image_optimizer_js_1.ImageError)).toEqual({
222
+ statusCode: 413,
223
+ message: '"url" parameter is valid but internal response is invalid',
224
+ });
225
+ });
226
+ it("falls back to 500 for unrecognized errors", () => {
227
+ expect((0, image_utils_1.resolveErrorResponse)(new Error("boom"), image_optimizer_js_1.ImageError)).toEqual({
228
+ statusCode: 500,
229
+ message: "Internal Server Error",
230
+ });
231
+ expect((0, image_utils_1.resolveErrorResponse)("not an error", image_optimizer_js_1.ImageError)).toEqual({
232
+ statusCode: 500,
233
+ message: "Internal Server Error",
234
+ });
235
+ });
236
+ });
237
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtdXRpbHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2ltYWdlLXV0aWxzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzREFBc0Q7QUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBRWhDLGtEQUFnRTtBQUNoRSw0RUFBaUU7QUFDakUsK0NBSXVCO0FBRXZCLFNBQVMsaUJBQWlCLENBQUMsTUFBb0I7SUFDN0MsT0FBTztRQUNMLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztZQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixPQUFPO2dCQUNMLElBQUksRUFBRSxLQUFLLElBQUksRUFBRSxDQUNmLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTTtvQkFDZixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtvQkFDckMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFO2FBQ3ZDLENBQUM7UUFDSixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCx3RUFBd0U7QUFDeEUsTUFBTSxJQUFJLEdBQUcsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUVoRCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7SUFDM0IsTUFBTSxFQUFFLEdBQUcsSUFBSSxvQkFBUSxDQUFDLEVBQUUsQ0FBd0IsQ0FBQztJQUVuRCxVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2IsRUFBMkMsQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO1FBQzdELFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN2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QU0sQ0FDSixJQUFBLGtDQUFvQixFQUFDLElBQUksZ0NBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsK0JBQVUsQ0FBQyxDQUNwRSxDQUFDLE9BQU8sQ0FBQztZQUNSLFVBQVUsRUFBRSxHQUFHO1lBQ2YsT0FBTyxFQUFFLDJEQUEyRDtTQUNyRSxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywyQ0FBMkMsRUFBRSxHQUFHLEVBQUU7UUFDbkQsTUFBTSxDQUFDLElBQUEsa0NBQW9CLEVBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsK0JBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ2xFLFVBQVUsRUFBRSxHQUFHO1lBQ2YsT0FBTyxFQUFFLHVCQUF1QjtTQUNqQyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsSUFBQSxrQ0FBb0IsRUFBQyxjQUFjLEVBQUUsK0JBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQy9ELFVBQVUsRUFBRSxHQUFHO1lBQ2YsT0FBTyxFQUFFLHVCQUF1QjtTQUNqQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5qZXN0Lm1vY2soXCJAYXdzLXNkay9jbGllbnQtczNcIik7XG5cbmltcG9ydCB7IEdldE9iamVjdENvbW1hbmQsIFMzQ2xpZW50IH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuaW1wb3J0IHsgSW1hZ2VFcnJvciB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2ltYWdlLW9wdGltaXplci5qc1wiO1xuaW1wb3J0IHtcbiAgZmV0Y2hGcm9tUzMsXG4gIEltYWdlVG9vTGFyZ2VFcnJvcixcbiAgcmVzb2x2ZUVycm9yUmVzcG9uc2UsXG59IGZyb20gXCIuL2ltYWdlLXV0aWxzXCI7XG5cbmZ1bmN0aW9uIGFzeW5jSXRlcmFibGVGcm9tKGNodW5rczogVWludDhBcnJheVtdKTogQXN5bmNJdGVyYWJsZTxVaW50OEFycmF5PiB7XG4gIHJldHVybiB7XG4gICAgW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSgpIHtcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5leHQ6IGFzeW5jICgpID0+XG4gICAgICAgICAgaSA8IGNodW5rcy5sZW5ndGhcbiAgICAgICAgICAgID8geyBkb25lOiBmYWxzZSwgdmFsdWU6IGNodW5rc1tpKytdIH1cbiAgICAgICAgICAgIDogeyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH0sXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG5cbi8qKiBObyBhcHAgYGJhc2VQYXRoYCwgYXNzZXRzIGF0IHRoZSByb290IG9mIHRoZSBidWNrZXQ6IHRoZSBkZWZhdWx0LiAqL1xuY29uc3QgUk9PVCA9IHsgdXJsQmFzZVBhdGg6IFwiXCIsIGtleVByZWZpeDogXCJcIiB9O1xuXG5kZXNjcmliZShcImZldGNoRnJvbVMzXCIsICgpID0+IHtcbiAgY29uc3QgbW9ja1NlbmQgPSBqZXN0LmZuKCk7XG4gIGNvbnN0IHMzID0gbmV3IFMzQ2xpZW50KHt9KSBhcyB1bmtub3duIGFzIFMzQ2xpZW50O1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIChzMyBhcyB1bmtub3duIGFzIHsgc2VuZDogdHlwZW9mIG1vY2tTZW5kIH0pLnNlbmQgPSBtb2NrU2VuZDtcbiAgICBtb2NrU2VuZC5tb2NrUmVzZXQoKTtcbiAgfSk7XG5cbiAgY29uc3Qgb2sgPSAoKSA9PlxuICAgIG1vY2tTZW5kLm1vY2tSZXNvbHZlZFZhbHVlKHtcbiAgICAgIEJvZHk6IGFzeW5jSXRlcmFibGVGcm9tKFtCdWZmZXIuZnJvbShcImRhdGFcIildKSxcbiAgICAgIENvbnRlbnRUeXBlOiBcImltYWdlL3BuZ1wiLFxuICAgICAgRVRhZzogJ1wiYWJjMTIzXCInLFxuICAgIH0pO1xuICBjb25zdCBrZXlPZiA9ICgpID0+XG4gICAgKEdldE9iamVjdENvbW1hbmQgYXMgdW5rbm93biBhcyBqZXN0Lk1vY2spLm1vY2suY2FsbHNbMF1bMF0uS2V5O1xuXG4gIGl0KFwic3RyaXBzIHRoZSBsZWFkaW5nIHNsYXNoIHdoZW4gdGhlIGFzc2V0cyBzaXQgYXQgdGhlIGJ1Y2tldCByb290XCIsIGFzeW5jICgpID0+IHtcbiAgICBvaygpO1xuXG4gICAgYXdhaXQgZmV0Y2hGcm9tUzMoXG4gICAgICBzMyxcbiAgICAgIFwibXktYnVja2V0XCIsXG4gICAgICBcIi9zdGF0aWMvZm9vLnBuZ1wiLFxuICAgICAge1xuICAgICAgICB1cmxCYXNlUGF0aDogXCJcIixcbiAgICAgICAga2V5UHJlZml4OiBcIlwiLFxuICAgICAgfSxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3QoKEdldE9iamVjdENvbW1hbmQgYXMgdW5rbm93biBhcyBqZXN0Lk1vY2spLm1vY2suY2FsbHNbMF1bMF0pLnRvRXF1YWwoXG4gICAgICB7IEJ1Y2tldDogXCJteS1idWNrZXRcIiwgS2V5OiBcInN0YXRpYy9mb28ucG5nXCIgfSxcbiAgICApO1xuICB9KTtcblxuICBpdChcImFwcGxpZXMgdGhlIGJ1Y2tldCBrZXkgcHJlZml4XCIsIGFzeW5jICgpID0+IHtcbiAgICBvaygpO1xuXG4gICAgYXdhaXQgZmV0Y2hGcm9tUzMoXG4gICAgICBzMyxcbiAgICAgIFwibXktYnVja2V0XCIsXG4gICAgICBcIi9zdGF0aWMvZm9vLmpwZ1wiLFxuICAgICAge1xuICAgICAgICB1cmxCYXNlUGF0aDogXCIvYmFzZVwiLFxuICAgICAgICBrZXlQcmVmaXg6IFwiYmFzZVwiLFxuICAgICAgfSxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3Qoa2V5T2YoKSkudG9CZShcImJhc2Uvc3RhdGljL2Zvby5qcGdcIik7XG4gIH0pO1xuXG4gIGl0KFwiZG9lcyBub3QgcmVwZWF0IHRoZSBwcmVmaXggd2hlbiB0aGUgdXJsIGFscmVhZHkgY2FycmllcyBiYXNlUGF0aFwiLCBhc3luYyAoKSA9PiB7XG4gICAgb2soKTtcblxuICAgIC8vIG5leHQtaW1hZ2UtbG9hZGVyIGJha2VzIGBiYXNlUGF0aGAgaW50byB0aGUgaHJlZiBvZiBhIHN0YXRpY2FsbHkgaW1wb3J0ZWRcbiAgICAvLyBpbWFnZSwgdW5saWtlIGEgcGxhaW4gc3RyaW5nIHBhdGguXG4gICAgYXdhaXQgZmV0Y2hGcm9tUzMoXG4gICAgICBzMyxcbiAgICAgIFwibXktYnVja2V0XCIsXG4gICAgICBcIi9iYXNlL19uZXh0L3N0YXRpYy9tZWRpYS9hLnBuZ1wiLFxuICAgICAge1xuICAgICAgICB1cmxCYXNlUGF0aDogXCIvYmFzZVwiLFxuICAgICAgICBrZXlQcmVmaXg6IFwiYmFzZVwiLFxuICAgICAgfSxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3Qoa2V5T2YoKSkudG9CZShcImJhc2UvX25leHQvc3RhdGljL21lZGlhL2EucG5nXCIpO1xuICB9KTtcblxuICAvKipcbiAgICogVGhlIEFQSSBHYXRld2F5IGRlcGxveW1lbnQgdHlwZXMgc2VydmUgdGhlIGFwcCB1bmRlciB0aGUgc3RhZ2UgbmFtZSwgc28gdGhlXG4gICAqIGFwcCdzIGBiYXNlUGF0aGAgaXMgYC9wcm9kYCB3aGlsZSB0aGUgYXNzZXRzIHdlcmUgdXBsb2FkZWQgdG8gdGhlIHJvb3Qgb2YgdGhlXG4gICAqIGJ1Y2tldC4gQnVpbGRpbmcgdGhlIGtleSBmcm9tIGBiYXNlUGF0aGAgYXNrcyBTMyBmb3IgYHByb2QvLi4uYCwgd2hpY2ggZG9lc1xuICAgKiBub3QgZXhpc3QsIGFuZCBldmVyeSBsb2NhbCBgPEltYWdlPmAgNDAwcy5cbiAgICovXG4gIGl0KFwic3RyaXBzIGEgYmFzZVBhdGggdGhhdCBpcyBub3QgcGFydCBvZiB0aGUga2V5XCIsIGFzeW5jICgpID0+IHtcbiAgICBvaygpO1xuXG4gICAgYXdhaXQgZmV0Y2hGcm9tUzMoXG4gICAgICBzMyxcbiAgICAgIFwibXktYnVja2V0XCIsXG4gICAgICBcIi9wcm9kL19uZXh0L3N0YXRpYy9tZWRpYS9hLnBuZ1wiLFxuICAgICAge1xuICAgICAgICB1cmxCYXNlUGF0aDogXCIvcHJvZFwiLFxuICAgICAgICBrZXlQcmVmaXg6IFwiXCIsXG4gICAgICB9LFxuICAgICAgSW5maW5pdHksXG4gICAgKTtcblxuICAgIGV4cGVjdChrZXlPZigpKS50b0JlKFwiX25leHQvc3RhdGljL21lZGlhL2EucG5nXCIpO1xuICB9KTtcblxuICBpdChcImxlYXZlcyBhIHVybCB3aXRob3V0IGJhc2VQYXRoIGFsb25lIHdoZW4gdGhlcmUgaXMgbm8ga2V5IHByZWZpeFwiLCBhc3luYyAoKSA9PiB7XG4gICAgb2soKTtcblxuICAgIGF3YWl0IGZldGNoRnJvbVMzKFxuICAgICAgczMsXG4gICAgICBcIm15LWJ1Y2tldFwiLFxuICAgICAgXCIvc3RhdGljL2Zvby5qcGdcIixcbiAgICAgIHtcbiAgICAgICAgdXJsQmFzZVBhdGg6IFwiL3Byb2RcIixcbiAgICAgICAga2V5UHJlZml4OiBcIlwiLFxuICAgICAgfSxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3Qoa2V5T2YoKSkudG9CZShcInN0YXRpYy9mb28uanBnXCIpO1xuICB9KTtcblxuICAvLyBXaXRoIGBhc3NldFByZWZpeDogXCIvY2RuXCJgLCBhIHN0YXRpYyBpbXBvcnQncyBocmVmIGlzXG4gIC8vIGAvY2RuL19uZXh0L3N0YXRpYy9tZWRpYS/igKZgLCB3aXRoIGBiYXNlUGF0aGAgbm93aGVyZSBpbiBpdC5cbiAgaXQoXCJzdHJpcHMgYSBwYXRoIGFzc2V0UHJlZml4IGluIGZyb250IG9mIC9fbmV4dC9cIiwgYXN5bmMgKCkgPT4ge1xuICAgIG9rKCk7XG5cbiAgICBhd2FpdCBmZXRjaEZyb21TMyhcbiAgICAgIHMzLFxuICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgIFwiL2Nkbi9fbmV4dC9zdGF0aWMvbWVkaWEvYS5wbmdcIixcbiAgICAgIHtcbiAgICAgICAgdXJsQmFzZVBhdGg6IFwiL2Jhc2VcIixcbiAgICAgICAga2V5UHJlZml4OiBcIlwiLFxuICAgICAgICBhc3NldFByZWZpeDogXCIvY2RuL1wiLFxuICAgICAgfSxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3Qoa2V5T2YoKSkudG9CZShcIl9uZXh0L3N0YXRpYy9tZWRpYS9hLnBuZ1wiKTtcbiAgfSk7XG5cbiAgaXQoXCJsZWF2ZXMgYSBwdWJsaWMvIGZpbGUgdW5kZXIgYSBkaXJlY3RvcnkgbmFtZWQgbGlrZSB0aGUgYXNzZXRQcmVmaXggYWxvbmVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIG9rKCk7XG5cbiAgICBhd2FpdCBmZXRjaEZyb21TMyhcbiAgICAgIHMzLFxuICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgIFwiL2Nkbi9sb2dvLnBuZ1wiLFxuICAgICAge1xuICAgICAgICB1cmxCYXNlUGF0aDogXCJcIixcbiAgICAgICAga2V5UHJlZml4OiBcIlwiLFxuICAgICAgICBhc3NldFByZWZpeDogXCIvY2RuXCIsXG4gICAgICB9LFxuICAgICAgSW5maW5pdHksXG4gICAgKTtcblxuICAgIGV4cGVjdChrZXlPZigpKS50b0JlKFwiY2RuL2xvZ28ucG5nXCIpO1xuICB9KTtcblxuICBpdChcImlnbm9yZXMgYW4gYWJzb2x1dGUgYXNzZXRQcmVmaXhcIiwgYXN5bmMgKCkgPT4ge1xuICAgIG9rKCk7XG5cbiAgICBhd2FpdCBmZXRjaEZyb21TMyhcbiAgICAgIHMzLFxuICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgIFwiL19uZXh0L3N0YXRpYy9tZWRpYS9hLnBuZ1wiLFxuICAgICAge1xuICAgICAgICB1cmxCYXNlUGF0aDogXCJcIixcbiAgICAgICAga2V5UHJlZml4OiBcIlwiLFxuICAgICAgICBhc3NldFByZWZpeDogXCJodHRwczovL2Nkbi5leGFtcGxlLnRlc3RcIixcbiAgICAgIH0sXG4gICAgICBJbmZpbml0eSxcbiAgICApO1xuXG4gICAgZXhwZWN0KGtleU9mKCkpLnRvQmUoXCJfbmV4dC9zdGF0aWMvbWVkaWEvYS5wbmdcIik7XG4gIH0pO1xuXG4gIGl0KFwib25seSBtYXRjaGVzIGJhc2VQYXRoIG9uIGEgcGF0aCBib3VuZGFyeVwiLCBhc3luYyAoKSA9PiB7XG4gICAgb2soKTtcblxuICAgIGF3YWl0IGZldGNoRnJvbVMzKFxuICAgICAgczMsXG4gICAgICBcIm15LWJ1Y2tldFwiLFxuICAgICAgXCIvYmFzZW1lbnQvbG9nby5wbmdcIixcbiAgICAgIHtcbiAgICAgICAgdXJsQmFzZVBhdGg6IFwiL2Jhc2VcIixcbiAgICAgICAga2V5UHJlZml4OiBcImJhc2VcIixcbiAgICAgIH0sXG4gICAgICBJbmZpbml0eSxcbiAgICApO1xuXG4gICAgZXhwZWN0KGtleU9mKCkpLnRvQmUoXCJiYXNlL2Jhc2VtZW50L2xvZ28ucG5nXCIpO1xuICB9KTtcblxuICAvLyBDYXJyaWVkIG92ZXIgZnJvbSAjMjY3LCB3aGljaCBmaXhlZCB0aGUgc2FtZSBidWcgaW4gdGhlIHByZS1hZGFwdGVyIGltYWdlXG4gIC8vIGhhbmRsZXI6IGEgYGRlc3RpbmF0aW9uS2V5UHJlZml4YCBvdmVycmlkZSBjYW4gYXJyaXZlIHdpdGggYSB0cmFpbGluZyBzbGFzaC5cbiAgaXQoXCJkb2Vzbid0IGRvdWJsZSB0aGUgc2VwYXJhdG9yIHdoZW4gdGhlIGtleSBwcmVmaXggaGFzIGEgdHJhaWxpbmcgc2xhc2hcIiwgYXN5bmMgKCkgPT4ge1xuICAgIG9rKCk7XG5cbiAgICBhd2FpdCBmZXRjaEZyb21TMyhcbiAgICAgIHMzLFxuICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgIFwiL3N0YXRpYy9mb28uanBnXCIsXG4gICAgICB7XG4gICAgICAgIHVybEJhc2VQYXRoOiBcIlwiLFxuICAgICAgICBrZXlQcmVmaXg6IFwiYmFzZS9cIixcbiAgICAgIH0sXG4gICAgICBJbmZpbml0eSxcbiAgICApO1xuXG4gICAgZXhwZWN0KGtleU9mKCkpLnRvQmUoXCJiYXNlL3N0YXRpYy9mb28uanBnXCIpO1xuICB9KTtcblxuICAvLyBgbmV4dC1pbWFnZS1sZWdhY3kvdW5pY29kZWAsIHdob3NlIGBwdWJsaWMvYCBob2xkcyBib3RoIG9mIHRoZXNlIG5hbWVzLiBUaGVcbiAgLy8gc3BhY2UgaXMgd2hhdCBicm9rZTogdGhlIGtleSBpcyB0aGUgZmlsZSdzIHJlYWwgbmFtZSwgdGhlIHVybCBpcyBhIFVSTCBwYXRoLlxuICBpdC5lYWNoKFtcbiAgICBbXCIvaGVsbG8lMjB3b3JsZC5qcGdcIiwgXCJoZWxsbyB3b3JsZC5qcGdcIl0sXG4gICAgW1wiL8Okw7bDvMWhxI3FmcOtLnBuZ1wiLCBcIsOkw7bDvMWhxI3FmcOtLnBuZ1wiXSxcbiAgICBbXCIvJUMzJUE0JUMzJUI2LnBuZ1wiLCBcIsOkw7YucG5nXCJdLFxuICBdKShcImRlY29kZXMgJXMgaW50byB0aGUgb2JqZWN0J3MgcmVhbCBuYW1lXCIsIGFzeW5jICh1cmwsIGtleSkgPT4ge1xuICAgIG9rKCk7XG5cbiAgICBhd2FpdCBmZXRjaEZyb21TMyhzMywgXCJteS1idWNrZXRcIiwgdXJsLCBST09ULCBJbmZpbml0eSk7XG5cbiAgICBleHBlY3Qoa2V5T2YoKSkudG9CZShrZXkpO1xuICB9KTtcblxuICAvLyBBIGNhY2hlLWJ1c3RlciBvbiBhIGxvY2FsIHNyYzogYG5leHQgc3RhcnRgIHJvdXRlcyB0aGUgaHJlZiBhcyBhIHJlcXVlc3QsIHNvXG4gIC8vIHRoZSBxdWVyeSBhbmQgZnJhZ21lbnQgbmV2ZXIgcmVhY2ggdGhlIGZpbGUgbG9va3VwLlxuICBpdC5lYWNoKFtcbiAgICBbXCIvbG9nby5wbmc/dj0yXCIsIFwibG9nby5wbmdcIl0sXG4gICAgW1wiL2xvZ28ucG5nI3RvcFwiLCBcImxvZ28ucG5nXCJdLFxuICAgIFtcIi9sb2dvLnBuZz92PTIjdG9wXCIsIFwibG9nby5wbmdcIl0sXG4gICAgW1wiL2Jhc2UvbG9nby5wbmc/dj0yXCIsIFwibG9nby5wbmdcIl0sXG4gICAgLy8gQSBgP2AgdGhhdCBpcyBwYXJ0IG9mIHRoZSBuYW1lIGFycml2ZXMgZW5jb2RlZCBhbmQgaXMgbm90IGEgcXVlcnkuXG4gICAgW1wiL3doYXQlM0YucG5nP3Y9MlwiLCBcIndoYXQ/LnBuZ1wiXSxcbiAgXSkoXCJrZXlzICVzIGJ5IGl0cyBwYXRoIGFsb25lXCIsIGFzeW5jICh1cmwsIGtleSkgPT4ge1xuICAgIG9rKCk7XG5cbiAgICBhd2FpdCBmZXRjaEZyb21TMyhcbiAgICAgIHMzLFxuICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgIHVybCxcbiAgICAgIHtcbiAgICAgICAgdXJsQmFzZVBhdGg6IFwiL2Jhc2VcIixcbiAgICAgICAga2V5UHJlZml4OiBcIlwiLFxuICAgICAgfSxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3Qoa2V5T2YoKSkudG9CZShrZXkpO1xuICB9KTtcblxuICBpdChcImxlYXZlcyBhIG5hbWUgdGhhdCBpc24ndCB2YWxpZCBwZXJjZW50LWVuY29kaW5nIGFsb25lXCIsIGFzeW5jICgpID0+IHtcbiAgICBvaygpO1xuXG4gICAgYXdhaXQgZmV0Y2hGcm9tUzMoczMsIFwibXktYnVja2V0XCIsIFwiLzEwMCUucG5nXCIsIFJPT1QsIEluZmluaXR5KTtcblxuICAgIGV4cGVjdChrZXlPZigpKS50b0JlKFwiMTAwJS5wbmdcIik7XG4gIH0pO1xuXG4gIGl0KFwicmV0dXJucyB0aGUgY29uY2F0ZW5hdGVkIGJ1ZmZlciwgY29udGVudCB0eXBlLCBhbmQgZXRhZ1wiLCBhc3luYyAoKSA9PiB7XG4gICAgbW9ja1NlbmQubW9ja1Jlc29sdmVkVmFsdWUoe1xuICAgICAgQm9keTogYXN5bmNJdGVyYWJsZUZyb20oW0J1ZmZlci5mcm9tKFwiaGVsXCIpLCBCdWZmZXIuZnJvbShcImxvXCIpXSksXG4gICAgICBDb250ZW50VHlwZTogXCJpbWFnZS9qcGVnXCIsXG4gICAgICBFVGFnOiAnXCJ0aGUtZXRhZ1wiJyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZldGNoRnJvbVMzKFxuICAgICAgczMsXG4gICAgICBcIm15LWJ1Y2tldFwiLFxuICAgICAgXCIvZm9vLmpwZ1wiLFxuICAgICAgUk9PVCxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3QocmVzdWx0LmJ1ZmZlci50b1N0cmluZygpKS50b0JlKFwiaGVsbG9cIik7XG4gICAgZXhwZWN0KHJlc3VsdC5jb250ZW50VHlwZSkudG9CZShcImltYWdlL2pwZWdcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5ldGFnKS50b0JlKCdcInRoZS1ldGFnXCInKTtcbiAgfSk7XG5cbiAgaXQoXCJyZXR1cm5zIGFuIGVtcHR5IGV0YWcgd2hlbiBTMyBkb2Vzbid0IHByb3ZpZGUgb25lXCIsIGFzeW5jICgpID0+IHtcbiAgICBtb2NrU2VuZC5tb2NrUmVzb2x2ZWRWYWx1ZSh7XG4gICAgICBCb2R5OiBhc3luY0l0ZXJhYmxlRnJvbShbQnVmZmVyLmZyb20oXCJkYXRhXCIpXSksXG4gICAgICBDb250ZW50VHlwZTogbnVsbCxcbiAgICAgIEVUYWc6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZldGNoRnJvbVMzKFxuICAgICAgczMsXG4gICAgICBcIm15LWJ1Y2tldFwiLFxuICAgICAgXCIvZm9vLnBuZ1wiLFxuICAgICAgUk9PVCxcbiAgICAgIEluZmluaXR5LFxuICAgICk7XG5cbiAgICBleHBlY3QocmVzdWx0LmV0YWcpLnRvQmUoXCJcIik7XG4gICAgZXhwZWN0KHJlc3VsdC5jb250ZW50VHlwZSkudG9CZU51bGwoKTtcbiAgfSk7XG5cbiAgLy8gYGltYWdlcy5tYXhpbXVtUmVzcG9uc2VCb2R5YCwgd2hpY2ggYG5leHQgc3RhcnRgIGVuZm9yY2VzIG9uIGxvY2FsIHNvdXJjZXMuXG4gIGl0KFwicmVmdXNlcyBhbiBvYmplY3Qgd2hvc2UgQ29udGVudExlbmd0aCBpcyBvdmVyIHRoZSBsaW1pdCwgdW5yZWFkXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95ID0gamVzdC5mbigpO1xuICAgIG1vY2tTZW5kLm1vY2tSZXNvbHZlZFZhbHVlKHtcbiAgICAgIEJvZHk6IHsgLi4uYXN5bmNJdGVyYWJsZUZyb20oW0J1ZmZlci5mcm9tKFwibmV2ZXIgcmVhZFwiKV0pLCBkZXN0cm95IH0sXG4gICAgICBDb250ZW50TGVuZ3RoOiAxMSxcbiAgICB9KTtcblxuICAgIGF3YWl0IGV4cGVjdChcbiAgICAgIGZldGNoRnJvbVMzKHMzLCBcIm15LWJ1Y2tldFwiLCBcIi9iaWcucG5nXCIsIFJPT1QsIDEwKSxcbiAgICApLnJlamVjdHMudG9CZUluc3RhbmNlT2YoSW1hZ2VUb29MYXJnZUVycm9yKTtcbiAgICBleHBlY3QoZGVzdHJveSkudG9IYXZlQmVlbkNhbGxlZCgpO1xuICB9KTtcblxuICBpdChcInN0b3BzIHJlYWRpbmcgb25jZSB0aGUgYnl0ZXMgcmVhZCBwYXNzIHRoZSBsaW1pdFwiLCBhc3luYyAoKSA9PiB7XG4gICAgbW9ja1NlbmQubW9ja1Jlc29sdmVkVmFsdWUoe1xuICAgICAgQm9keTogYXN5bmNJdGVyYWJsZUZyb20oW0J1ZmZlci5mcm9tKFwiaGVsXCIpLCBCdWZmZXIuZnJvbShcImxvXCIpXSksXG4gICAgfSk7XG5cbiAgICBhd2FpdCBleHBlY3QoXG4gICAgICBmZXRjaEZyb21TMyhzMywgXCJteS1idWNrZXRcIiwgXCIvYmlnLnBuZ1wiLCBST09ULCA0KSxcbiAgICApLnJlamVjdHMudG9CZUluc3RhbmNlT2YoSW1hZ2VUb29MYXJnZUVycm9yKTtcbiAgICAvLyBBdCB0aGUgbGltaXQgZXhhY3RseSBpcyBmaW5lLlxuICAgIG1vY2tTZW5kLm1vY2tSZXNvbHZlZFZhbHVlKHtcbiAgICAgIEJvZHk6IGFzeW5jSXRlcmFibGVGcm9tKFtCdWZmZXIuZnJvbShcImhlbFwiKSwgQnVmZmVyLmZyb20oXCJsb1wiKV0pLFxuICAgICAgQ29udGVudExlbmd0aDogNSxcbiAgICB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmZXRjaEZyb21TMyhzMywgXCJteS1idWNrZXRcIiwgXCIvb2sucG5nXCIsIFJPT1QsIDUpO1xuICAgIGV4cGVjdChyZXN1bHQuYnVmZmVyLnRvU3RyaW5nKCkpLnRvQmUoXCJoZWxsb1wiKTtcbiAgfSk7XG5cbiAgaXQoXCJ0aHJvd3Mgd2hlbiBTMyByZXR1cm5zIG5vIGJvZHlcIiwgYXN5bmMgKCkgPT4ge1xuICAgIG1vY2tTZW5kLm1vY2tSZXNvbHZlZFZhbHVlKHsgQm9keTogdW5kZWZpbmVkIH0pO1xuXG4gICAgYXdhaXQgZXhwZWN0KFxuICAgICAgZmV0Y2hGcm9tUzMoczMsIFwibXktYnVja2V0XCIsIFwiL21pc3NpbmcucG5nXCIsIFJPT1QsIEluZmluaXR5KSxcbiAgICApLnJlamVjdHMudG9UaHJvdygvRW1wdHkgcmVzcG9uc2UgZnJvbSBTMy8pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcInJlc29sdmVFcnJvclJlc3BvbnNlXCIsICgpID0+IHtcbiAgaXQoXCJwcmVzZXJ2ZXMgdGhlIHN0YXR1cyBjb2RlIGFuZCBtZXNzYWdlIGZyb20gYW4gSW1hZ2VFcnJvclwiLCAoKSA9PiB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgSW1hZ2VFcnJvcig0MDAsICdcInVybFwiIHBhcmFtZXRlciBpcyBub3QgYWxsb3dlZCcpO1xuXG4gICAgZXhwZWN0KHJlc29sdmVFcnJvclJlc3BvbnNlKGVycm9yLCBJbWFnZUVycm9yKSkudG9FcXVhbCh7XG4gICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICBtZXNzYWdlOiAnXCJ1cmxcIiBwYXJhbWV0ZXIgaXMgbm90IGFsbG93ZWQnLFxuICAgIH0pO1xuICB9KTtcblxuICBpdChcIm1hcHMgYSBzb3VyY2Ugb3ZlciBpbWFnZXMubWF4aW11bVJlc3BvbnNlQm9keSB0byBuZXh0IHN0YXJ0J3MgNDEzXCIsICgpID0+IHtcbiAgICBleHBlY3QoXG4gICAgICByZXNvbHZlRXJyb3JSZXNwb25zZShuZXcgSW1hZ2VUb29MYXJnZUVycm9yKFwiYmlnLnBuZ1wiKSwgSW1hZ2VFcnJvciksXG4gICAgKS50b0VxdWFsKHtcbiAgICAgIHN0YXR1c0NvZGU6IDQxMyxcbiAgICAgIG1lc3NhZ2U6ICdcInVybFwiIHBhcmFtZXRlciBpcyB2YWxpZCBidXQgaW50ZXJuYWwgcmVzcG9uc2UgaXMgaW52YWxpZCcsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwiZmFsbHMgYmFjayB0byA1MDAgZm9yIHVucmVjb2duaXplZCBlcnJvcnNcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChyZXNvbHZlRXJyb3JSZXNwb25zZShuZXcgRXJyb3IoXCJib29tXCIpLCBJbWFnZUVycm9yKSkudG9FcXVhbCh7XG4gICAgICBzdGF0dXNDb2RlOiA1MDAsXG4gICAgICBtZXNzYWdlOiBcIkludGVybmFsIFNlcnZlciBFcnJvclwiLFxuICAgIH0pO1xuICAgIGV4cGVjdChyZXNvbHZlRXJyb3JSZXNwb25zZShcIm5vdCBhbiBlcnJvclwiLCBJbWFnZUVycm9yKSkudG9FcXVhbCh7XG4gICAgICBzdGF0dXNDb2RlOiA1MDAsXG4gICAgICBtZXNzYWdlOiBcIkludGVybmFsIFNlcnZlciBFcnJvclwiLFxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,76 @@
1
+ import type { ShimIncomingMessage } from "./http/request";
2
+ import { ShimServerResponse } from "./http/response";
3
+ import { AdapterManifest } from "./manifest";
4
+ export interface ImageOptimizerOptions {
5
+ readonly deploymentRoot: string;
6
+ readonly manifest: AdapterManifest;
7
+ /**
8
+ * `CDK_NEXTJS_STATIC_ASSETS_BUCKET_NAME`. Empty when the sources are on disk
9
+ * (`NextjsRegionalContainers`), which sends every one to `fetchInternal`.
10
+ */
11
+ readonly bucket: string;
12
+ /**
13
+ * `CDK_NEXTJS_STATIC_ASSETS_KEY_PREFIX`. Empty when the assets sit at the root
14
+ * of the bucket, which is the default.
15
+ */
16
+ readonly bucketKeyPrefix: string;
17
+ /**
18
+ * Requests a local source from the app's own routes, for one S3 has no file
19
+ * for: `<Image src="/api/avatar?id=42">`, served by a route handler. `next
20
+ * start` fetches every local source that way (`fetchInternalImage`); here it
21
+ * is the fallback, since nearly every source is a file, and a `GetObject` is
22
+ * far cheaper than a route invocation.
23
+ *
24
+ * Given the request being optimized, for its authority; like `next start`,
25
+ * the viewer's cookies and other headers are not the implementation's to
26
+ * forward. And given `images.maximumResponseBody`, past which it stops
27
+ * reading and answers {@link InternalImageResponse.tooLarge}.
28
+ */
29
+ readonly fetchInternal: (href: string, req: ShimIncomingMessage, maximumResponseBody: number) => Promise<InternalImageResponse>;
30
+ /**
31
+ * Loads the `cacheHandler` module from its file URL. A seam for tests, which
32
+ * run as CommonJS and cannot `import()` a URL.
33
+ * @default - `import()`
34
+ */
35
+ readonly importModule?: (url: string) => Promise<unknown>;
36
+ }
37
+ /** The response {@link ImageOptimizerOptions.fetchInternal} got. */
38
+ export interface InternalImageResponse {
39
+ readonly statusCode: number;
40
+ readonly headers: Readonly<Record<string, string | string[] | undefined>>;
41
+ readonly body: Buffer;
42
+ /**
43
+ * The `functionGroups` group whose package has the route that serves the
44
+ * source, when it is not this function's: there is no response to use, and
45
+ * the optimizer answers an explicit 502 rather than a "not a valid image".
46
+ */
47
+ readonly otherGroup?: string;
48
+ /**
49
+ * The body passed `images.maximumResponseBody`, so it was cut off: a 413, as
50
+ * `next start` answers.
51
+ */
52
+ readonly tooLarge?: boolean;
53
+ }
54
+ export declare class RuntimeImageOptimizer {
55
+ private readonly options;
56
+ private readonly s3;
57
+ private loaded?;
58
+ private imageCache?;
59
+ constructor(options: ImageOptimizerOptions);
60
+ /**
61
+ * Whether the app serves `/_next/image` at all. `next start` answers 404
62
+ * when `images.unoptimized` is set or a non-default `loader` is configured
63
+ * (`next-server.js`), and so does the runtime: otherwise anyone can make the
64
+ * compute run sharp and write the image cache on an endpoint the app turned
65
+ * off.
66
+ */
67
+ isEnabled(): boolean;
68
+ handle(req: ShimIncomingMessage, res: ShimServerResponse, url: URL, waitUntil: (promise: Promise<unknown>) => void): Promise<void>;
69
+ /**
70
+ * Evicted on failure, as `EntrypointRegistry.load` evicts a failed module load:
71
+ * a transient failure importing the `cacheHandler` (EMFILE under a cold-start
72
+ * burst) would otherwise 500 every image request until the sandbox recycles.
73
+ */
74
+ private loadCache;
75
+ private fetchLocal;
76
+ }