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
@@ -3,99 +3,145 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NextjsFunctions = void 0;
4
4
  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
5
  const node_fs_1 = require("node:fs");
6
- const node_path_1 = require("node:path");
7
- const posix_1 = require("node:path/posix");
8
6
  const aws_cdk_lib_1 = require("aws-cdk-lib");
9
- const aws_iam_1 = require("aws-cdk-lib/aws-iam");
10
7
  const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
11
8
  const constructs_1 = require("constructs");
9
+ const nextjs_compute_base_props_1 = require("./nextjs-compute-base-props");
10
+ const function_groups_1 = require("../adapter/function-groups");
12
11
  const constants_1 = require("../constants");
12
+ const manifest_1 = require("../runtime/manifest");
13
13
  const get_architecture_1 = require("../utils/get-architecture");
14
+ const zip_directory_1 = require("../utils/zip-directory");
14
15
  /**
15
16
  * Run Next.js in functions on AWS with AWS Lambda.
17
+ *
18
+ * A plain zip function on the Node.js managed runtime: the deployment root
19
+ * `NextjsBuild` staged is the asset, and cdk-nextjs's own bundled shell
20
+ * (`cdk-nextjs-runtime/lambda.mjs`) is the handler. It invokes the entrypoints
21
+ * `next build` produced in-process, so there is no Next.js HTTP server, no
22
+ * Docker image, and no Lambda Web Adapter — response streaming comes from
23
+ * `awslambda.streamifyResponse` directly.
16
24
  */
17
25
  class NextjsFunctions extends constructs_1.Construct {
18
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsFunctions", version: "0.6.2" };
26
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsFunctions", version: "0.7.1" };
27
+ /**
28
+ * The `default` group's function: the one the distribution's default behavior
29
+ * targets, and the only one at all unless `functionGroups` is used.
30
+ *
31
+ * A zip-packaged `lambda.Function` since 0.7.0; before that it was a
32
+ * `DockerImageFunction`. Code that relied on the image-specific type (its
33
+ * repository, or `DockerImageCode`) has to change.
34
+ */
19
35
  function;
36
+ /** The `default` group's Function URL. Only for `GLOBAL_FUNCTIONS`. */
20
37
  functionUrl;
38
+ /**
39
+ * Every deployed group, `default` first. Iterate this rather than
40
+ * {@link function} for anything that must reach all of them — IAM grants and
41
+ * CloudFront behaviors both do.
42
+ */
43
+ functionGroups;
21
44
  props;
22
45
  constructor(scope, id, props) {
23
46
  super(scope, id);
24
47
  this.props = props;
25
- this.function = this.createFunction();
26
- if (props.nextjsType === constants_1.NextjsType.GLOBAL_FUNCTIONS) {
27
- this.function.grantInvoke(new aws_iam_1.ServicePrincipal("cloudfront.amazonaws.com"));
28
- this.functionUrl = this.function.addFunctionUrl({
29
- authType: aws_lambda_1.FunctionUrlAuthType.AWS_IAM,
30
- invokeMode: aws_lambda_1.InvokeMode.RESPONSE_STREAM,
31
- ...this.props.overrides?.functionUrlProps,
32
- });
48
+ const roots = props.deploymentRoots;
49
+ this.functionGroups = roots.map((root) => {
50
+ const group = props.functionGroups?.find((it) => it.name === root.name);
51
+ // The default group keeps the unsuffixed construct id it has always had,
52
+ // so adding `functionGroups` to a deployed app does not replace the
53
+ // function that was already serving everything.
54
+ const fn = this.createFunction(root.name === function_groups_1.DEFAULT_FUNCTION_GROUP
55
+ ? "Functions"
56
+ : `Functions-${root.name}`, root, group?.overrides);
57
+ let functionUrl;
58
+ if (props.nextjsType === constants_1.NextjsType.GLOBAL_FUNCTIONS) {
59
+ functionUrl = fn.addFunctionUrl({
60
+ authType: aws_lambda_1.FunctionUrlAuthType.AWS_IAM,
61
+ invokeMode: aws_lambda_1.InvokeMode.RESPONSE_STREAM,
62
+ ...props.overrides?.functionUrlProps,
63
+ ...group?.overrides?.functionUrlProps,
64
+ });
65
+ }
66
+ return {
67
+ name: root.name,
68
+ routes: root.routes,
69
+ function: fn,
70
+ functionUrl,
71
+ };
72
+ });
73
+ const defaultGroup = this.functionGroups.find((group) => group.name === function_groups_1.DEFAULT_FUNCTION_GROUP);
74
+ if (!defaultGroup) {
75
+ throw new Error(`Expected a "${function_groups_1.DEFAULT_FUNCTION_GROUP}" deployment root, got ` +
76
+ `[${roots.map((root) => root.name).join(", ")}].`);
33
77
  }
78
+ this.function = defaultGroup.function;
79
+ this.functionUrl = defaultGroup.functionUrl;
34
80
  }
35
- createFunction() {
36
- // Create DockerImageCode from local build output or use provided dockerImageCode
37
- const dockerImageCode = this.createDockerImageCode();
81
+ createFunction(id, root, groupOverrides) {
82
+ const architecture = this.props.architecture ?? (0, get_architecture_1.getLambdaArchitecture)();
83
+ const requested = groupOverrides?.functionProps?.architecture ??
84
+ this.props.overrides?.functionProps?.architecture;
85
+ if (requested && requested.name !== architecture.name) {
86
+ // Ignoring it would deploy a function the user didn't ask for; honoring
87
+ // it would deploy one that can't load the `sharp` binaries staged for
88
+ // the root. The root constructs pass the same value to both unless a
89
+ // group's own override asks for another (one architecture per
90
+ // deployment), or `NextjsBuild` and `NextjsFunctions` are wired by hand.
91
+ throw new Error(`${constants_1.LOG_PREFIX} functionProps.architecture for function group "${root.name}" is ${requested.name}, ` +
92
+ `but NextjsBuild staged its native dependencies (sharp) for ${architecture.name}. ` +
93
+ "Every function group deploys one architecture: set it construct-wide in " +
94
+ "`overrides.nextjsFunctions.functionProps` or, wiring the constructs yourself, pass " +
95
+ "NextjsBuild's `architecture` to NextjsFunctions.");
96
+ }
97
+ // Zipped here rather than by `cdk-assets`, which would dereference the
98
+ // pnpm symlinks the root depends on; see `zipDirectory`.
99
+ const zipPath = `${root.path}.zip`;
100
+ (0, node_fs_1.writeFileSync)(zipPath, (0, zip_directory_1.zipDirectory)(root.path));
38
101
  const functionProps = {
39
- architecture: (0, get_architecture_1.getLambdaArchitecture)(),
40
- code: dockerImageCode,
102
+ code: aws_lambda_1.Code.fromAsset(zipPath),
103
+ handler: `${manifest_1.RUNTIME_DIR_NAME}/lambda.handler`,
41
104
  memorySize: 2048,
105
+ runtime: new aws_lambda_1.Runtime("nodejs24.x", aws_lambda_1.RuntimeFamily.NODEJS),
42
106
  timeout: aws_cdk_lib_1.Duration.seconds(30),
43
- ...this.props.overrides?.dockerImageFunctionProps,
107
+ ...this.sharedFunctionProps(root.name),
108
+ ...groupOverrides?.functionProps,
109
+ // After the overrides: the function must run what `NextjsBuild` staged.
110
+ // An override that disagrees throws above rather than being dropped here.
111
+ architecture,
44
112
  environment: {
45
- AWS_LWA_ENABLE_COMPRESSION: "true",
46
- AWS_LWA_INVOKE_MODE: "response_stream",
47
- AWS_LWA_READINESS_CHECK_PATH: this.props.healthCheckPath,
48
- AWS_LWA_READINESS_CHECK_PORT: "3000",
49
- READINESS_CHECK_PATH: `http://127.0.0.1:3000${this.props.healthCheckPath}`,
50
- // Cache configuration environment variables
51
- CDK_NEXTJS_CACHE_BUCKET_NAME: this.props.cacheBucket.bucketName,
52
- CDK_NEXTJS_REVALIDATION_TABLE_NAME: this.props.revalidationTable.tableName,
53
- CDK_NEXTJS_BUILD_ID: this.props.buildId,
54
- ...this.props.overrides?.dockerImageFunctionProps?.environment,
113
+ // What `next start` and the Containers Dockerfiles set. Externalized
114
+ // packages (React for Pages Router SSR among them) load their dev
115
+ // builds without it.
116
+ NODE_ENV: "production",
117
+ ...(0, nextjs_compute_base_props_1.runtimeEnvironment)(this.props),
118
+ // Which group this function is. Only used to make a misroute legible:
119
+ // if CloudFront sends a request here for a route that was packaged
120
+ // elsewhere, the 500 says which function got it and which group it
121
+ // belongs to, rather than surfacing as a module-not-found deep inside
122
+ // the Next.js server.
123
+ [manifest_1.FUNCTION_GROUP_ENV_VAR]: root.name,
124
+ ...this.props.overrides?.functionProps?.environment,
125
+ ...groupOverrides?.functionProps?.environment,
55
126
  },
56
127
  };
57
- const fn = new aws_lambda_1.DockerImageFunction(this, "Functions", functionProps);
58
- // Grant cache access permissions
59
- this.props.cacheBucket.grantReadWrite(fn);
60
- this.props.revalidationTable.grantReadWriteData(fn);
128
+ const fn = new aws_lambda_1.Function(this, id, functionProps);
129
+ (0, nextjs_compute_base_props_1.grantRuntimeAccess)(this.props, fn);
61
130
  return fn;
62
131
  }
63
- createDockerImageCode() {
64
- // Build context is the buildDirectory (where the Next.js app is located)
65
- const buildContext = this.props.buildDirectory;
66
- const dockerfileName = "functions.Dockerfile";
67
- // Copy Dockerfile to build context to avoid path resolution issues
68
- this.copyDockerfileToContext(buildContext, dockerfileName);
69
- const relativeEntrypointPath = this.props.relativePathToPackage
70
- ? // joinPosix b/c this will be referenced in Docker container (Linux)
71
- (0, posix_1.join)(this.props.relativePathToPackage, "server.js")
72
- : "server.js";
73
- return aws_lambda_1.DockerImageCode.fromImageAsset(buildContext, {
74
- file: dockerfileName, // Now it's just the filename in the build context
75
- cmd: ["node", relativeEntrypointPath],
76
- exclude: ["cdk.out"], // for common case where cdk deploy is run in same directory as nextjs app
77
- buildArgs: {
78
- RELATIVE_PATH_TO_PACKAGE: this.props.relativePathToPackage || ".",
79
- ...this.props.overrides?.assetImageCodeProps?.buildArgs,
80
- },
81
- ...this.props.overrides?.assetImageCodeProps,
82
- });
83
- }
84
- copyDockerfileToContext(buildContext, dockerfileName) {
85
- const targetDockerfile = (0, node_path_1.join)(buildContext, dockerfileName);
86
- // Check if Dockerfile already exists - if so, use the existing one (developer control)
87
- if ((0, node_fs_1.existsSync)(targetDockerfile)) {
88
- console.log(`${constants_1.LOG_PREFIX} Using existing Dockerfile: ${dockerfileName}`);
89
- }
90
- else {
91
- const sourceDockerfile = (0, node_path_1.join)(__dirname, "..", "nextjs-build", dockerfileName);
92
- if (!(0, node_fs_1.existsSync)(sourceDockerfile)) {
93
- throw new Error(`Source Dockerfile not found: ${sourceDockerfile}. Ensure the cdk-nextjs package is properly built.`);
94
- }
95
- (0, node_fs_1.copyFileSync)(sourceDockerfile, targetDockerfile);
96
- console.log(`${constants_1.LOG_PREFIX} Created ${dockerfileName} in your project directory.`);
132
+ /**
133
+ * The construct-wide `functionProps`, minus what identifies a single function
134
+ * when this is not the `default` group; see
135
+ * {@link NextjsFunctionsOverrides.functionProps}.
136
+ */
137
+ sharedFunctionProps(groupName) {
138
+ const shared = this.props.overrides?.functionProps;
139
+ if (!shared || groupName === function_groups_1.DEFAULT_FUNCTION_GROUP) {
140
+ return shared;
97
141
  }
142
+ const { functionName, code, handler, ...rest } = shared;
143
+ return rest;
98
144
  }
99
145
  }
100
146
  exports.NextjsFunctions = NextjsFunctions;
101
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWZ1bmN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZXh0anMtY29tcHV0ZS9uZXh0anMtZnVuY3Rpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxxQ0FBbUQ7QUFDbkQseUNBQTZDO0FBQzdDLDJDQUFvRDtBQUNwRCw2Q0FBdUM7QUFDdkMsaURBQXVEO0FBQ3ZELHVEQVFnQztBQUNoQywyQ0FBdUM7QUFFdkMsNENBQXNEO0FBR3RELGdFQUFrRTtBQVlsRTs7R0FFRztBQUNILE1BQWEsZUFBZ0IsU0FBUSxzQkFBUzs7SUFDNUMsUUFBUSxDQUFzQjtJQUM5QixXQUFXLENBQWU7SUFFbEIsS0FBSyxDQUF1QjtJQUVwQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTJCO1FBQ25FLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEMsSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLHNCQUFVLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNyRCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FDdkIsSUFBSSwwQkFBZ0IsQ0FBQywwQkFBMEIsQ0FBQyxDQUNqRCxDQUFDO1lBQ0YsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQztnQkFDOUMsUUFBUSxFQUFFLGdDQUFtQixDQUFDLE9BQU87Z0JBQ3JDLFVBQVUsRUFBRSx1QkFBVSxDQUFDLGVBQWU7Z0JBQ3RDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCO2FBQzFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRU8sY0FBYztRQUNwQixpRkFBaUY7UUFDakYsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFFckQsTUFBTSxhQUFhLEdBQTZCO1lBQzlDLFlBQVksRUFBRSxJQUFBLHdDQUFxQixHQUFFO1lBQ3JDLElBQUksRUFBRSxlQUFlO1lBQ3JCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDN0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSx3QkFBd0I7WUFDakQsV0FBVyxFQUFFO2dCQUNYLDBCQUEwQixFQUFFLE1BQU07Z0JBQ2xDLG1CQUFtQixFQUFFLGlCQUFpQjtnQkFDdEMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlO2dCQUN4RCw0QkFBNEIsRUFBRSxNQUFNO2dCQUNwQyxvQkFBb0IsRUFBRSx3QkFBd0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7Z0JBQzFFLDRDQUE0QztnQkFDNUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsVUFBVTtnQkFDL0Qsa0NBQWtDLEVBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsU0FBUztnQkFDeEMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPO2dCQUN2QyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLHdCQUF3QixFQUFFLFdBQVc7YUFDL0Q7U0FDRixDQUFDO1FBRUYsTUFBTSxFQUFFLEdBQUcsSUFBSSxnQ0FBbUIsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBRXJFLGlDQUFpQztRQUNqQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVwRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTyxxQkFBcUI7UUFDM0IseUVBQXlFO1FBQ3pFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO1FBQy9DLE1BQU0sY0FBYyxHQUFHLHNCQUFzQixDQUFDO1FBRTlDLG1FQUFtRTtRQUNuRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBRTNELE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUI7WUFDN0QsQ0FBQyxDQUFDLG9FQUFvRTtnQkFDcEUsSUFBQSxZQUFTLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxXQUFXLENBQUM7WUFDMUQsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUVoQixPQUFPLDRCQUFlLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRTtZQUNsRCxJQUFJLEVBQUUsY0FBYyxFQUFFLGtEQUFrRDtZQUN4RSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsc0JBQXNCLENBQUM7WUFDckMsT0FBTyxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsMEVBQTBFO1lBQ2hHLFNBQVMsRUFBRTtnQkFDVCx3QkFBd0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixJQUFJLEdBQUc7Z0JBQ2pFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsU0FBUzthQUN4RDtZQUNELEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsbUJBQW1CO1NBQzdDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyx1QkFBdUIsQ0FDN0IsWUFBb0IsRUFDcEIsY0FBc0I7UUFFdEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLGdCQUFRLEVBQUMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBRWhFLHVGQUF1RjtRQUN2RixJQUFJLElBQUEsb0JBQVUsRUFBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7WUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLHNCQUFVLCtCQUErQixjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQzVFLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLGdCQUFRLEVBQy9CLFNBQVMsRUFDVCxJQUFJLEVBQ0osY0FBYyxFQUNkLGNBQWMsQ0FDZixDQUFDO1lBRUYsSUFBSSxDQUFDLElBQUEsb0JBQVUsRUFBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0NBQWdDLGdCQUFnQixvREFBb0QsQ0FDckcsQ0FBQztZQUNKLENBQUM7WUFFRCxJQUFBLHNCQUFZLEVBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUNqRCxPQUFPLENBQUMsR0FBRyxDQUNULEdBQUcsc0JBQVUsWUFBWSxjQUFjLDZCQUE2QixDQUNyRSxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7O0FBN0dILDBDQThHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvcHlGaWxlU3luYywgZXhpc3RzU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBqb2luIGFzIGpvaW5QYXRoIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgam9pbiBhcyBqb2luUG9zaXggfSBmcm9tIFwibm9kZTpwYXRoL3Bvc2l4XCI7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgU2VydmljZVByaW5jaXBhbCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQge1xuICBBc3NldEltYWdlQ29kZVByb3BzLFxuICBEb2NrZXJJbWFnZUNvZGUsXG4gIERvY2tlckltYWdlRnVuY3Rpb24sXG4gIERvY2tlckltYWdlRnVuY3Rpb25Qcm9wcyxcbiAgRnVuY3Rpb25VcmwsXG4gIEZ1bmN0aW9uVXJsQXV0aFR5cGUsXG4gIEludm9rZU1vZGUsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgTmV4dGpzQ29tcHV0ZUJhc2VQcm9wcyB9IGZyb20gXCIuL25leHRqcy1jb21wdXRlLWJhc2UtcHJvcHNcIjtcbmltcG9ydCB7IExPR19QUkVGSVgsIE5leHRqc1R5cGUgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcHRpb25hbERvY2tlckltYWdlRnVuY3Rpb25Qcm9wcyB9IGZyb20gXCIuLi9nZW5lcmF0ZWQtc3RydWN0cy9PcHRpb25hbERvY2tlckltYWdlRnVuY3Rpb25Qcm9wc1wiO1xuaW1wb3J0IHsgT3B0aW9uYWxGdW5jdGlvblVybFByb3BzIH0gZnJvbSBcIi4uL2dlbmVyYXRlZC1zdHJ1Y3RzL09wdGlvbmFsRnVuY3Rpb25VcmxQcm9wc1wiO1xuaW1wb3J0IHsgZ2V0TGFtYmRhQXJjaGl0ZWN0dXJlIH0gZnJvbSBcIi4uL3V0aWxzL2dldC1hcmNoaXRlY3R1cmVcIjtcblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNGdW5jdGlvbnNPdmVycmlkZXMge1xuICByZWFkb25seSBkb2NrZXJJbWFnZUZ1bmN0aW9uUHJvcHM/OiBPcHRpb25hbERvY2tlckltYWdlRnVuY3Rpb25Qcm9wcztcbiAgcmVhZG9ubHkgZnVuY3Rpb25VcmxQcm9wcz86IE9wdGlvbmFsRnVuY3Rpb25VcmxQcm9wcztcbiAgcmVhZG9ubHkgYXNzZXRJbWFnZUNvZGVQcm9wcz86IEFzc2V0SW1hZ2VDb2RlUHJvcHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzRnVuY3Rpb25zUHJvcHMgZXh0ZW5kcyBOZXh0anNDb21wdXRlQmFzZVByb3BzIHtcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzRnVuY3Rpb25zT3ZlcnJpZGVzO1xufVxuXG4vKipcbiAqIFJ1biBOZXh0LmpzIGluIGZ1bmN0aW9ucyBvbiBBV1Mgd2l0aCBBV1MgTGFtYmRhLlxuICovXG5leHBvcnQgY2xhc3MgTmV4dGpzRnVuY3Rpb25zIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgZnVuY3Rpb246IERvY2tlckltYWdlRnVuY3Rpb247XG4gIGZ1bmN0aW9uVXJsPzogRnVuY3Rpb25Vcmw7XG5cbiAgcHJpdmF0ZSBwcm9wczogTmV4dGpzRnVuY3Rpb25zUHJvcHM7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE5leHRqc0Z1bmN0aW9uc1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gICAgdGhpcy5mdW5jdGlvbiA9IHRoaXMuY3JlYXRlRnVuY3Rpb24oKTtcbiAgICBpZiAocHJvcHMubmV4dGpzVHlwZSA9PT0gTmV4dGpzVHlwZS5HTE9CQUxfRlVOQ1RJT05TKSB7XG4gICAgICB0aGlzLmZ1bmN0aW9uLmdyYW50SW52b2tlKFxuICAgICAgICBuZXcgU2VydmljZVByaW5jaXBhbChcImNsb3VkZnJvbnQuYW1hem9uYXdzLmNvbVwiKSxcbiAgICAgICk7XG4gICAgICB0aGlzLmZ1bmN0aW9uVXJsID0gdGhpcy5mdW5jdGlvbi5hZGRGdW5jdGlvblVybCh7XG4gICAgICAgIGF1dGhUeXBlOiBGdW5jdGlvblVybEF1dGhUeXBlLkFXU19JQU0sXG4gICAgICAgIGludm9rZU1vZGU6IEludm9rZU1vZGUuUkVTUE9OU0VfU1RSRUFNLFxuICAgICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uZnVuY3Rpb25VcmxQcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRnVuY3Rpb24oKSB7XG4gICAgLy8gQ3JlYXRlIERvY2tlckltYWdlQ29kZSBmcm9tIGxvY2FsIGJ1aWxkIG91dHB1dCBvciB1c2UgcHJvdmlkZWQgZG9ja2VySW1hZ2VDb2RlXG4gICAgY29uc3QgZG9ja2VySW1hZ2VDb2RlID0gdGhpcy5jcmVhdGVEb2NrZXJJbWFnZUNvZGUoKTtcblxuICAgIGNvbnN0IGZ1bmN0aW9uUHJvcHM6IERvY2tlckltYWdlRnVuY3Rpb25Qcm9wcyA9IHtcbiAgICAgIGFyY2hpdGVjdHVyZTogZ2V0TGFtYmRhQXJjaGl0ZWN0dXJlKCksXG4gICAgICBjb2RlOiBkb2NrZXJJbWFnZUNvZGUsXG4gICAgICBtZW1vcnlTaXplOiAyMDQ4LFxuICAgICAgdGltZW91dDogRHVyYXRpb24uc2Vjb25kcygzMCksXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uZG9ja2VySW1hZ2VGdW5jdGlvblByb3BzLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQVdTX0xXQV9FTkFCTEVfQ09NUFJFU1NJT046IFwidHJ1ZVwiLFxuICAgICAgICBBV1NfTFdBX0lOVk9LRV9NT0RFOiBcInJlc3BvbnNlX3N0cmVhbVwiLFxuICAgICAgICBBV1NfTFdBX1JFQURJTkVTU19DSEVDS19QQVRIOiB0aGlzLnByb3BzLmhlYWx0aENoZWNrUGF0aCxcbiAgICAgICAgQVdTX0xXQV9SRUFESU5FU1NfQ0hFQ0tfUE9SVDogXCIzMDAwXCIsXG4gICAgICAgIFJFQURJTkVTU19DSEVDS19QQVRIOiBgaHR0cDovLzEyNy4wLjAuMTozMDAwJHt0aGlzLnByb3BzLmhlYWx0aENoZWNrUGF0aH1gLFxuICAgICAgICAvLyBDYWNoZSBjb25maWd1cmF0aW9uIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgICAgICBDREtfTkVYVEpTX0NBQ0hFX0JVQ0tFVF9OQU1FOiB0aGlzLnByb3BzLmNhY2hlQnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgIENES19ORVhUSlNfUkVWQUxJREFUSU9OX1RBQkxFX05BTUU6XG4gICAgICAgICAgdGhpcy5wcm9wcy5yZXZhbGlkYXRpb25UYWJsZS50YWJsZU5hbWUsXG4gICAgICAgIENES19ORVhUSlNfQlVJTERfSUQ6IHRoaXMucHJvcHMuYnVpbGRJZCxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmRvY2tlckltYWdlRnVuY3Rpb25Qcm9wcz8uZW52aXJvbm1lbnQsXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCBmbiA9IG5ldyBEb2NrZXJJbWFnZUZ1bmN0aW9uKHRoaXMsIFwiRnVuY3Rpb25zXCIsIGZ1bmN0aW9uUHJvcHMpO1xuXG4gICAgLy8gR3JhbnQgY2FjaGUgYWNjZXNzIHBlcm1pc3Npb25zXG4gICAgdGhpcy5wcm9wcy5jYWNoZUJ1Y2tldC5ncmFudFJlYWRXcml0ZShmbik7XG4gICAgdGhpcy5wcm9wcy5yZXZhbGlkYXRpb25UYWJsZS5ncmFudFJlYWRXcml0ZURhdGEoZm4pO1xuXG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEb2NrZXJJbWFnZUNvZGUoKTogRG9ja2VySW1hZ2VDb2RlIHtcbiAgICAvLyBCdWlsZCBjb250ZXh0IGlzIHRoZSBidWlsZERpcmVjdG9yeSAod2hlcmUgdGhlIE5leHQuanMgYXBwIGlzIGxvY2F0ZWQpXG4gICAgY29uc3QgYnVpbGRDb250ZXh0ID0gdGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeTtcbiAgICBjb25zdCBkb2NrZXJmaWxlTmFtZSA9IFwiZnVuY3Rpb25zLkRvY2tlcmZpbGVcIjtcblxuICAgIC8vIENvcHkgRG9ja2VyZmlsZSB0byBidWlsZCBjb250ZXh0IHRvIGF2b2lkIHBhdGggcmVzb2x1dGlvbiBpc3N1ZXNcbiAgICB0aGlzLmNvcHlEb2NrZXJmaWxlVG9Db250ZXh0KGJ1aWxkQ29udGV4dCwgZG9ja2VyZmlsZU5hbWUpO1xuXG4gICAgY29uc3QgcmVsYXRpdmVFbnRyeXBvaW50UGF0aCA9IHRoaXMucHJvcHMucmVsYXRpdmVQYXRoVG9QYWNrYWdlXG4gICAgICA/IC8vIGpvaW5Qb3NpeCBiL2MgdGhpcyB3aWxsIGJlIHJlZmVyZW5jZWQgaW4gRG9ja2VyIGNvbnRhaW5lciAoTGludXgpXG4gICAgICAgIGpvaW5Qb3NpeCh0aGlzLnByb3BzLnJlbGF0aXZlUGF0aFRvUGFja2FnZSwgXCJzZXJ2ZXIuanNcIilcbiAgICAgIDogXCJzZXJ2ZXIuanNcIjtcblxuICAgIHJldHVybiBEb2NrZXJJbWFnZUNvZGUuZnJvbUltYWdlQXNzZXQoYnVpbGRDb250ZXh0LCB7XG4gICAgICBmaWxlOiBkb2NrZXJmaWxlTmFtZSwgLy8gTm93IGl0J3MganVzdCB0aGUgZmlsZW5hbWUgaW4gdGhlIGJ1aWxkIGNvbnRleHRcbiAgICAgIGNtZDogW1wibm9kZVwiLCByZWxhdGl2ZUVudHJ5cG9pbnRQYXRoXSxcbiAgICAgIGV4Y2x1ZGU6IFtcImNkay5vdXRcIl0sIC8vIGZvciBjb21tb24gY2FzZSB3aGVyZSBjZGsgZGVwbG95IGlzIHJ1biBpbiBzYW1lIGRpcmVjdG9yeSBhcyBuZXh0anMgYXBwXG4gICAgICBidWlsZEFyZ3M6IHtcbiAgICAgICAgUkVMQVRJVkVfUEFUSF9UT19QQUNLQUdFOiB0aGlzLnByb3BzLnJlbGF0aXZlUGF0aFRvUGFja2FnZSB8fCBcIi5cIixcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmFzc2V0SW1hZ2VDb2RlUHJvcHM/LmJ1aWxkQXJncyxcbiAgICAgIH0sXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uYXNzZXRJbWFnZUNvZGVQcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29weURvY2tlcmZpbGVUb0NvbnRleHQoXG4gICAgYnVpbGRDb250ZXh0OiBzdHJpbmcsXG4gICAgZG9ja2VyZmlsZU5hbWU6IHN0cmluZyxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0RG9ja2VyZmlsZSA9IGpvaW5QYXRoKGJ1aWxkQ29udGV4dCwgZG9ja2VyZmlsZU5hbWUpO1xuXG4gICAgLy8gQ2hlY2sgaWYgRG9ja2VyZmlsZSBhbHJlYWR5IGV4aXN0cyAtIGlmIHNvLCB1c2UgdGhlIGV4aXN0aW5nIG9uZSAoZGV2ZWxvcGVyIGNvbnRyb2wpXG4gICAgaWYgKGV4aXN0c1N5bmModGFyZ2V0RG9ja2VyZmlsZSkpIHtcbiAgICAgIGNvbnNvbGUubG9nKGAke0xPR19QUkVGSVh9IFVzaW5nIGV4aXN0aW5nIERvY2tlcmZpbGU6ICR7ZG9ja2VyZmlsZU5hbWV9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHNvdXJjZURvY2tlcmZpbGUgPSBqb2luUGF0aChcbiAgICAgICAgX19kaXJuYW1lLFxuICAgICAgICBcIi4uXCIsXG4gICAgICAgIFwibmV4dGpzLWJ1aWxkXCIsXG4gICAgICAgIGRvY2tlcmZpbGVOYW1lLFxuICAgICAgKTtcblxuICAgICAgaWYgKCFleGlzdHNTeW5jKHNvdXJjZURvY2tlcmZpbGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgU291cmNlIERvY2tlcmZpbGUgbm90IGZvdW5kOiAke3NvdXJjZURvY2tlcmZpbGV9LiBFbnN1cmUgdGhlIGNkay1uZXh0anMgcGFja2FnZSBpcyBwcm9wZXJseSBidWlsdC5gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb3B5RmlsZVN5bmMoc291cmNlRG9ja2VyZmlsZSwgdGFyZ2V0RG9ja2VyZmlsZSk7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYCR7TE9HX1BSRUZJWH0gQ3JlYXRlZCAke2RvY2tlcmZpbGVOYW1lfSBpbiB5b3VyIHByb2plY3QgZGlyZWN0b3J5LmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIl19
147
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWZ1bmN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZXh0anMtY29tcHV0ZS9uZXh0anMtZnVuY3Rpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxxQ0FBd0M7QUFDeEMsNkNBQXVDO0FBQ3ZDLHVEQVVnQztBQUNoQywyQ0FBdUM7QUFDdkMsMkVBSXFDO0FBQ3JDLGdFQUFvRTtBQUNwRSw0Q0FBc0Q7QUFJdEQsa0RBQStFO0FBQy9FLGdFQUFrRTtBQUNsRSwwREFBc0Q7QUFzR3REOzs7Ozs7Ozs7R0FTRztBQUNILE1BQWEsZUFBZ0IsU0FBUSxzQkFBUzs7SUFDNUM7Ozs7Ozs7T0FPRztJQUNILFFBQVEsQ0FBaUI7SUFDekIsdUVBQXVFO0lBQ3ZFLFdBQVcsQ0FBZTtJQUMxQjs7OztPQUlHO0lBQ0gsY0FBYyxDQUFpQztJQUV2QyxLQUFLLENBQXVCO0lBRXBDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMkI7UUFDbkUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUVuQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3ZDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4RSx5RUFBeUU7WUFDekUsb0VBQW9FO1lBQ3BFLGdEQUFnRDtZQUNoRCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUM1QixJQUFJLENBQUMsSUFBSSxLQUFLLHdDQUFzQjtnQkFDbEMsQ0FBQyxDQUFDLFdB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QUFFLEdBQUcsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBQ3hELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQzs7QUFoSkgsMENBaUpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtcbiAgQXJjaGl0ZWN0dXJlLFxuICBDb2RlLFxuICBGdW5jdGlvbiBhcyBMYW1iZGFGdW5jdGlvbixcbiAgRnVuY3Rpb25Qcm9wcyxcbiAgRnVuY3Rpb25VcmwsXG4gIEZ1bmN0aW9uVXJsQXV0aFR5cGUsXG4gIEludm9rZU1vZGUsXG4gIFJ1bnRpbWUsXG4gIFJ1bnRpbWVGYW1pbHksXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHtcbiAgZ3JhbnRSdW50aW1lQWNjZXNzLFxuICBOZXh0anNDb21wdXRlQmFzZVByb3BzLFxuICBydW50aW1lRW52aXJvbm1lbnQsXG59IGZyb20gXCIuL25leHRqcy1jb21wdXRlLWJhc2UtcHJvcHNcIjtcbmltcG9ydCB7IERFRkFVTFRfRlVOQ1RJT05fR1JPVVAgfSBmcm9tIFwiLi4vYWRhcHRlci9mdW5jdGlvbi1ncm91cHNcIjtcbmltcG9ydCB7IExPR19QUkVGSVgsIE5leHRqc1R5cGUgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcHRpb25hbEZ1bmN0aW9uUHJvcHMgfSBmcm9tIFwiLi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxGdW5jdGlvblByb3BzXCI7XG5pbXBvcnQgeyBPcHRpb25hbEZ1bmN0aW9uVXJsUHJvcHMgfSBmcm9tIFwiLi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxGdW5jdGlvblVybFByb3BzXCI7XG5pbXBvcnQgeyBOZXh0anNEZXBsb3ltZW50Um9vdCB9IGZyb20gXCIuLi9uZXh0anMtYnVpbGQvbmV4dGpzLWJ1aWxkXCI7XG5pbXBvcnQgeyBGVU5DVElPTl9HUk9VUF9FTlZfVkFSLCBSVU5USU1FX0RJUl9OQU1FIH0gZnJvbSBcIi4uL3J1bnRpbWUvbWFuaWZlc3RcIjtcbmltcG9ydCB7IGdldExhbWJkYUFyY2hpdGVjdHVyZSB9IGZyb20gXCIuLi91dGlscy9nZXQtYXJjaGl0ZWN0dXJlXCI7XG5pbXBvcnQgeyB6aXBEaXJlY3RvcnkgfSBmcm9tIFwiLi4vdXRpbHMvemlwLWRpcmVjdG9yeVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5leHRqc0Z1bmN0aW9uc092ZXJyaWRlcyB7XG4gIC8qKlxuICAgKiBQcm9wcyBmb3IgdGhlIExhbWJkYSBmdW5jdGlvbi5cbiAgICpcbiAgICogQ29uc3RydWN0LXdpZGUgKGBOZXh0anNGdW5jdGlvbnNQcm9wcy5vdmVycmlkZXNgKSwgdGhlc2UgYXBwbHkgdG8gZXZlcnlcbiAgICogZnVuY3Rpb24gZ3JvdXAncyBMYW1iZGEg4oCUIG1lbW9yeSwgdGltZW91dCwgVlBDLCByb2xlIGFuZCB0aGUgcmVzdCBhcmVcbiAgICogc2hhcmVkIOKAlCBleGNlcHQgdGhlIHByb3BzIHRoYXQgaWRlbnRpZnkgb25lIGZ1bmN0aW9uOiBgZnVuY3Rpb25OYW1lYCxcbiAgICogYGNvZGVgIGFuZCBgaGFuZGxlcmAgYXBwbHkgdG8gdGhlIGBkZWZhdWx0YCBncm91cCBvbmx5LiBBIHNlY29uZCBmdW5jdGlvblxuICAgKiB3aXRoIHRoZSBzYW1lIG5hbWUgZmFpbHMgdGhlIGRlcGxveSwgYW5kIGFub3RoZXIgZ3JvdXAncyBjb2RlIG9yIGhhbmRsZXJcbiAgICogd291bGQgc2hpcCB0aGUgd3JvbmcgZGVwbG95bWVudCByb290LiBTZXQgdGhvc2UgcGVyIGdyb3VwLCBpbiB0aGUgZ3JvdXAnc1xuICAgKiBvd24gYG92ZXJyaWRlc2AsIHdoZXJlIHRoZXkgYXBwbHkgdG8gdGhhdCBncm91cCBhbG9uZS5cbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uUHJvcHM/OiBPcHRpb25hbEZ1bmN0aW9uUHJvcHM7XG4gIHJlYWRvbmx5IGZ1bmN0aW9uVXJsUHJvcHM/OiBPcHRpb25hbEZ1bmN0aW9uVXJsUHJvcHM7XG59XG5cbi8qKlxuICogQSBzZXQgb2Ygcm91dGVzIHRvIHBhY2thZ2UgaW50byB0aGVpciBvd24gTGFtYmRhIGZ1bmN0aW9uLlxuICpcbiAqIFRoZSBvbmx5IHJlYXNvbiB0byByZWFjaCBmb3IgdGhpcyBpcyBMYW1iZGEncyAyNTAgTUIgdW56aXBwZWQgbGltaXQuIEV2ZXJ5XG4gKiBncm91cCBzaGlwcyB0aGUgKnNhbWUqIE5leHQuanMgcnVudGltZSBhbmQgdGhlIHNhbWUgc2hhcmVkIGNvZGUg4oCUIHNwbGl0dGluZ1xuICogb25seSBtb3ZlcyByb3V0ZS1sb2NhbCBjb2RlIChhbmQgd2hhdGV2ZXIgaXQgcHVsbHMgaW4pIG91dCBvZiB0aGUgb3RoZXJcbiAqIGZ1bmN0aW9ucy4gU28gZ3JvdXAgYnkgd2hhdCBpcyBoZWF2eSwgbm90IGJ5IHdoYXQgaXMgbG9naWNhbGx5IHJlbGF0ZWQuXG4gKlxuICogRWFjaCBncm91cCBiZWNvbWVzIG9uZSBMYW1iZGEgZnVuY3Rpb24gYW5kIG9uZSBDbG91ZEZyb250IGJlaGF2aW9yIHBlclxuICogcGF0dGVybiwgb3V0IG9mIGEgcGVyLWRpc3RyaWJ1dGlvbiBidWRnZXQgb2YgNzUgdGhhdCBgcHVibGljL2AgZW50cmllcyBhbHNvXG4gKiBkcmF3IG9uLiBSb3V0ZXMgbm90IG1hdGNoZWQgYnkgYW55IGdyb3VwIHN0YXkgaW4gdGhlIGltcGxpY2l0IGBkZWZhdWx0YCBncm91cC5cbiAqXG4gKiBQYXR0ZXJucyBhcmUgYW4gZXhhY3QgcGF0aCBvciBhIHN1YnRyZWUsIGFuZCBub3RoaW5nIGVsc2U6XG4gKlxuICogLSBgL3ByaWNpbmdgIOKAlCB0aGF0IHJvdXRlLCBleGFjdGx5LlxuICogLSBgL2FwaS9yZXBvcnRzLyoqYCDigJQgZXZlcnl0aGluZyAqdW5kZXIqIGAvYXBpL3JlcG9ydHNgLCBpbmNsdWRpbmdcbiAqICAgYC9hcGkvcmVwb3J0cy9baWRdYCwgYnV0IG5vdCBgL2FwaS9yZXBvcnRzYCBpdHNlbGYuIExpc3QgYm90aCB0byBvd24gYm90aC5cbiAqXG4gKiBEeW5hbWljIHNlZ21lbnRzIChgL2Jsb2cvW3NsdWddYCkgYW5kIHJvdXRlIGdyb3VwcyAoYC8obWFya2V0aW5nKS9hYm91dGApIGFyZVxuICogc3ludGggZXJyb3JzOiBDbG91ZEZyb250IHBhdGggcGF0dGVybnMgc3VwcG9ydCBvbmx5IGAqYCBhbmQgYD9gLCBzbyBuZWl0aGVyXG4gKiBjb3VsZCBiZSBob25vcmVkIGF0IHRoZSBncmFudWxhcml0eSBpdCBpbXBsaWVzLiBVc2UgYSBzdWJ0cmVlLlxuICpcbiAqIFdoZW4gdHdvIHBhdHRlcm5zIG1hdGNoIGEgcm91dGUsIHRoZSBsb25nZXN0IHdpbnMg4oCUIGAvYXBpLyoqYCBpbiBvbmUgZ3JvdXAgYW5kXG4gKiBgL2FwaS9yZXBvcnRzLyoqYCBpbiBhbm90aGVyIGlzIGEgdmFsaWQgYW5kIHVzZWZ1bCBwYWlyLlxuICpcbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbkdyb3VwczogW1xuICogICB7IG5hbWU6IFwicmVwb3J0c1wiLCByb3V0ZXM6IFtcIi9hcGkvcmVwb3J0cy8qKlwiXSB9LFxuICogICB7IG5hbWU6IFwiYWRtaW5cIiwgcm91dGVzOiBbXCIvYWRtaW4vKipcIl0sIG92ZXJyaWRlczogeyBmdW5jdGlvblByb3BzOiB7IG1lbW9yeVNpemU6IDMwMDggfSB9IH0sXG4gKiBdXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzRnVuY3Rpb25Hcm91cCB7XG4gIC8qKlxuICAgKiBHcm91cCBuYW1lLiBCZWNvbWVzIGEgY29uc3RydWN0IGlkIGFuZCBwYXJ0IG9mIHRoZSBMYW1iZGEgZnVuY3Rpb24gbmFtZSwgc29cbiAgICogaXQgbXVzdCBtYXRjaCBgL15bYS16QS1aMC05LV0rJC9gLiBgZGVmYXVsdGAgaXMgcmVzZXJ2ZWQuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIC8qKiBQYXRoIHBhdHRlcm5zIHRoaXMgZ3JvdXAgb3ducy4gQXQgbGVhc3Qgb25lOyBzZWUge0BsaW5rIE5leHRqc0Z1bmN0aW9uR3JvdXB9LiAqL1xuICByZWFkb25seSByb3V0ZXM6IHN0cmluZ1tdO1xuICAvKipcbiAgICogUGVyLWdyb3VwIG92ZXJyaWRlcywgbWVyZ2VkIG92ZXIgdGhlIGNvbnN0cnVjdC13aWRlIGBvdmVycmlkZXNgIOKAlCB3aGljaCBpc1xuICAgKiB0aGUgcG9pbnQgb2Ygc3BsaXR0aW5nIGZvciBhbnl0aGluZyBvdGhlciB0aGFuIHNpemU6IGEgZ3JvdXAgY2FuIGhhdmUgaXRzXG4gICAqIG93biBtZW1vcnksIHRpbWVvdXQsIG9yIGNvbmN1cnJlbmN5LiBOb3QgaXRzIG93biBhcmNoaXRlY3R1cmU6IGV2ZXJ5IGdyb3VwXG4gICAqIGRlcGxveXMgdGhlIG9uZSB0aGUgYnVpbGQgc3RhZ2VkIGBzaGFycGAgZm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzRnVuY3Rpb25zT3ZlcnJpZGVzO1xufVxuXG4vKiogT25lIGRlcGxveWVkIGZ1bmN0aW9uIGdyb3VwOiBpdHMgTGFtYmRhLCBpdHMgVVJMLCBhbmQgd2hhdCBpdCBzZXJ2ZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIE5leHRqc0Z1bmN0aW9uR3JvdXBSZXNvdXJjZXMge1xuICAvKiogR3JvdXAgbmFtZTsgYGRlZmF1bHRgIGZvciB0aGUgaW1wbGljaXQgY2F0Y2gtYWxsIGdyb3VwLiAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBSb3V0ZSB0ZW1wbGF0ZXMgcGFja2FnZWQgaW50byB0aGlzIGZ1bmN0aW9uLCBhcyB0aGUgYWRhcHRlciBhc3NpZ25lZCB0aGVtLlxuICAgKiBFbXB0eSBmb3IgdGhlIGRlZmF1bHQgZ3JvdXAgaXMgbm9ybWFsIGluIGEgaGVhdmlseSBzcGxpdCBhcHAuXG4gICAqL1xuICByZWFkb25seSByb3V0ZXM6IHN0cmluZ1tdO1xuICByZWFkb25seSBmdW5jdGlvbjogTGFtYmRhRnVuY3Rpb247XG4gIC8qKiBPbmx5IGZvciBgR0xPQkFMX0ZVTkNUSU9OU2A7IFJlZ2lvbmFsIGZyb250cyBpdHMgZnVuY3Rpb25zIHdpdGggQVBJIEdhdGV3YXkuICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uVXJsPzogRnVuY3Rpb25Vcmw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzRnVuY3Rpb25zUHJvcHMgZXh0ZW5kcyBOZXh0anNDb21wdXRlQmFzZVByb3BzIHtcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzRnVuY3Rpb25zT3ZlcnJpZGVzO1xuICAvKipcbiAgICogVGhlIHN0YWdlZCBkZXBsb3ltZW50IHJvb3RzLCBvbmUgcGVyIGZ1bmN0aW9uIGdyb3VwLCBgZGVmYXVsdGAgYW1vbmcgdGhlbS5cbiAgICogQHNlZSBOZXh0anNCdWlsZC5kZXBsb3ltZW50Um9vdHNcbiAgICovXG4gIHJlYWRvbmx5IGRlcGxveW1lbnRSb290czogTmV4dGpzRGVwbG95bWVudFJvb3RbXTtcbiAgLyoqXG4gICAqIFRoZSBhcmNoaXRlY3R1cmUgYE5leHRqc0J1aWxkYCBzdGFnZWQgdGhlIGRlcGxveW1lbnQgcm9vdHMnIG5hdGl2ZVxuICAgKiBkZXBlbmRlbmNpZXMgKGBzaGFycGApIGZvciwgd2hpY2ggZXZlcnkgZnVuY3Rpb24gZGVwbG95cy5cbiAgICogQHNlZSBOZXh0anNCdWlsZC5hcmNoaXRlY3R1cmVcbiAgICogQGRlZmF1bHQgLSB0aGUgYXJjaGl0ZWN0dXJlIG9mIHRoZSBtYWNoaW5lIHJ1bm5pbmcgc3ludGgsIGFzIGBOZXh0anNCdWlsZGAnc1xuICAgKi9cbiAgcmVhZG9ubHkgYXJjaGl0ZWN0dXJlPzogQXJjaGl0ZWN0dXJlO1xuICAvKipcbiAgICogUGVyLWdyb3VwIGNvbmZpZ3VyYXRpb24sIGtleWVkIGJ5IG5hbWUgYWdhaW5zdCB7QGxpbmsgZGVwbG95bWVudFJvb3RzfS5cbiAgICogUm91dGVzIGNvbWUgZnJvbSB0aGUgYnVpbGQgcmF0aGVyIHRoYW4gZnJvbSBoZXJlLCBzaW5jZSB0aGUgYWRhcHRlciByZXNvbHZlZFxuICAgKiB0aGVtOyB0aGlzIG9ubHkgY2FycmllcyBgb3ZlcnJpZGVzYC5cbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uR3JvdXBzPzogTmV4dGpzRnVuY3Rpb25Hcm91cFtdO1xufVxuXG4vKipcbiAqIFJ1biBOZXh0LmpzIGluIGZ1bmN0aW9ucyBvbiBBV1Mgd2l0aCBBV1MgTGFtYmRhLlxuICpcbiAqIEEgcGxhaW4gemlwIGZ1bmN0aW9uIG9uIHRoZSBOb2RlLmpzIG1hbmFnZWQgcnVudGltZTogdGhlIGRlcGxveW1lbnQgcm9vdFxuICogYE5leHRqc0J1aWxkYCBzdGFnZWQgaXMgdGhlIGFzc2V0LCBhbmQgY2RrLW5leHRqcydzIG93biBidW5kbGVkIHNoZWxsXG4gKiAoYGNkay1uZXh0anMtcnVudGltZS9sYW1iZGEubWpzYCkgaXMgdGhlIGhhbmRsZXIuIEl0IGludm9rZXMgdGhlIGVudHJ5cG9pbnRzXG4gKiBgbmV4dCBidWlsZGAgcHJvZHVjZWQgaW4tcHJvY2Vzcywgc28gdGhlcmUgaXMgbm8gTmV4dC5qcyBIVFRQIHNlcnZlciwgbm9cbiAqIERvY2tlciBpbWFnZSwgYW5kIG5vIExhbWJkYSBXZWIgQWRhcHRlciDigJQgcmVzcG9uc2Ugc3RyZWFtaW5nIGNvbWVzIGZyb21cbiAqIGBhd3NsYW1iZGEuc3RyZWFtaWZ5UmVzcG9uc2VgIGRpcmVjdGx5LlxuICovXG5leHBvcnQgY2xhc3MgTmV4dGpzRnVuY3Rpb25zIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBgZGVmYXVsdGAgZ3JvdXAncyBmdW5jdGlvbjogdGhlIG9uZSB0aGUgZGlzdHJpYnV0aW9uJ3MgZGVmYXVsdCBiZWhhdmlvclxuICAgKiB0YXJnZXRzLCBhbmQgdGhlIG9ubHkgb25lIGF0IGFsbCB1bmxlc3MgYGZ1bmN0aW9uR3JvdXBzYCBpcyB1c2VkLlxuICAgKlxuICAgKiBBIHppcC1wYWNrYWdlZCBgbGFtYmRhLkZ1bmN0aW9uYCBzaW5jZSAwLjcuMDsgYmVmb3JlIHRoYXQgaXQgd2FzIGFcbiAgICogYERvY2tlckltYWdlRnVuY3Rpb25gLiBDb2RlIHRoYXQgcmVsaWVkIG9uIHRoZSBpbWFnZS1zcGVjaWZpYyB0eXBlIChpdHNcbiAgICogcmVwb3NpdG9yeSwgb3IgYERvY2tlckltYWdlQ29kZWApIGhhcyB0byBjaGFuZ2UuXG4gICAqL1xuICBmdW5jdGlvbjogTGFtYmRhRnVuY3Rpb247XG4gIC8qKiBUaGUgYGRlZmF1bHRgIGdyb3VwJ3MgRnVuY3Rpb24gVVJMLiBPbmx5IGZvciBgR0xPQkFMX0ZVTkNUSU9OU2AuICovXG4gIGZ1bmN0aW9uVXJsPzogRnVuY3Rpb25Vcmw7XG4gIC8qKlxuICAgKiBFdmVyeSBkZXBsb3llZCBncm91cCwgYGRlZmF1bHRgIGZpcnN0LiBJdGVyYXRlIHRoaXMgcmF0aGVyIHRoYW5cbiAgICoge0BsaW5rIGZ1bmN0aW9ufSBmb3IgYW55dGhpbmcgdGhhdCBtdXN0IHJlYWNoIGFsbCBvZiB0aGVtIOKAlCBJQU0gZ3JhbnRzIGFuZFxuICAgKiBDbG91ZEZyb250IGJlaGF2aW9ycyBib3RoIGRvLlxuICAgKi9cbiAgZnVuY3Rpb25Hcm91cHM6IE5leHRqc0Z1bmN0aW9uR3JvdXBSZXNvdXJjZXNbXTtcblxuICBwcml2YXRlIHByb3BzOiBOZXh0anNGdW5jdGlvbnNQcm9wcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzRnVuY3Rpb25zUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcblxuICAgIGNvbnN0IHJvb3RzID0gcHJvcHMuZGVwbG95bWVudFJvb3RzO1xuICAgIHRoaXMuZnVuY3Rpb25Hcm91cHMgPSByb290cy5tYXAoKHJvb3QpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gcHJvcHMuZnVuY3Rpb25Hcm91cHM/LmZpbmQoKGl0KSA9PiBpdC5uYW1lID09PSByb290Lm5hbWUpO1xuICAgICAgLy8gVGhlIGRlZmF1bHQgZ3JvdXAga2VlcHMgdGhlIHVuc3VmZml4ZWQgY29uc3RydWN0IGlkIGl0IGhhcyBhbHdheXMgaGFkLFxuICAgICAgLy8gc28gYWRkaW5nIGBmdW5jdGlvbkdyb3Vwc2AgdG8gYSBkZXBsb3llZCBhcHAgZG9lcyBub3QgcmVwbGFjZSB0aGVcbiAgICAgIC8vIGZ1bmN0aW9uIHRoYXQgd2FzIGFscmVhZHkgc2VydmluZyBldmVyeXRoaW5nLlxuICAgICAgY29uc3QgZm4gPSB0aGlzLmNyZWF0ZUZ1bmN0aW9uKFxuICAgICAgICByb290Lm5hbWUgPT09IERFRkFVTFRfRlVOQ1RJT05fR1JPVVBcbiAgICAgICAgICA/IFwiRnVuY3Rpb25zXCJcbiAgICAgICAgICA6IGBGdW5jdGlvbnMtJHtyb290Lm5hbWV9YCxcbiAgICAgICAgcm9vdCxcbiAgICAgICAgZ3JvdXA/Lm92ZXJyaWRlcyxcbiAgICAgICk7XG4gICAgICBsZXQgZnVuY3Rpb25Vcmw6IEZ1bmN0aW9uVXJsIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHByb3BzLm5leHRqc1R5cGUgPT09IE5leHRqc1R5cGUuR0xPQkFMX0ZVTkNUSU9OUykge1xuICAgICAgICBmdW5jdGlvblVybCA9IGZuLmFkZEZ1bmN0aW9uVXJsKHtcbiAgICAgICAgICBhdXRoVHlwZTogRnVuY3Rpb25VcmxBdXRoVHlwZS5BV1NfSUFNLFxuICAgICAgICAgIGludm9rZU1vZGU6IEludm9rZU1vZGUuUkVTUE9OU0VfU1RSRUFNLFxuICAgICAgICAgIC4uLnByb3BzLm92ZXJyaWRlcz8uZnVuY3Rpb25VcmxQcm9wcyxcbiAgICAgICAgICAuLi5ncm91cD8ub3ZlcnJpZGVzPy5mdW5jdGlvblVybFByb3BzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IHJvb3QubmFtZSxcbiAgICAgICAgcm91dGVzOiByb290LnJvdXRlcyxcbiAgICAgICAgZnVuY3Rpb246IGZuLFxuICAgICAgICBmdW5jdGlvblVybCxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBkZWZhdWx0R3JvdXAgPSB0aGlzLmZ1bmN0aW9uR3JvdXBzLmZpbmQoXG4gICAgICAoZ3JvdXApID0+IGdyb3VwLm5hbWUgPT09IERFRkFVTFRfRlVOQ1RJT05fR1JPVVAsXG4gICAgKTtcbiAgICBpZiAoIWRlZmF1bHRHcm91cCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRXhwZWN0ZWQgYSBcIiR7REVGQVVMVF9GVU5DVElPTl9HUk9VUH1cIiBkZXBsb3ltZW50IHJvb3QsIGdvdCBgICtcbiAgICAgICAgICBgWyR7cm9vdHMubWFwKChyb290KSA9PiByb290Lm5hbWUpLmpvaW4oXCIsIFwiKX1dLmAsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmZ1bmN0aW9uID0gZGVmYXVsdEdyb3VwLmZ1bmN0aW9uO1xuICAgIHRoaXMuZnVuY3Rpb25VcmwgPSBkZWZhdWx0R3JvdXAuZnVuY3Rpb25Vcmw7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZ1bmN0aW9uKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcm9vdDogTmV4dGpzRGVwbG95bWVudFJvb3QsXG4gICAgZ3JvdXBPdmVycmlkZXM6IE5leHRqc0Z1bmN0aW9uc092ZXJyaWRlcyB8IHVuZGVmaW5lZCxcbiAgKSB7XG4gICAgY29uc3QgYXJjaGl0ZWN0dXJlID0gdGhpcy5wcm9wcy5hcmNoaXRlY3R1cmUgPz8gZ2V0TGFtYmRhQXJjaGl0ZWN0dXJlKCk7XG4gICAgY29uc3QgcmVxdWVzdGVkID1cbiAgICAgIGdyb3VwT3ZlcnJpZGVzPy5mdW5jdGlvblByb3BzPy5hcmNoaXRlY3R1cmUgPz9cbiAgICAgIHRoaXMucHJvcHMub3ZlcnJpZGVzPy5mdW5jdGlvblByb3BzPy5hcmNoaXRlY3R1cmU7XG4gICAgaWYgKHJlcXVlc3RlZCAmJiByZXF1ZXN0ZWQubmFtZSAhPT0gYXJjaGl0ZWN0dXJlLm5hbWUpIHtcbiAgICAgIC8vIElnbm9yaW5nIGl0IHdvdWxkIGRlcGxveSBhIGZ1bmN0aW9uIHRoZSB1c2VyIGRpZG4ndCBhc2sgZm9yOyBob25vcmluZ1xuICAgICAgLy8gaXQgd291bGQgZGVwbG95IG9uZSB0aGF0IGNhbid0IGxvYWQgdGhlIGBzaGFycGAgYmluYXJpZXMgc3RhZ2VkIGZvclxuICAgICAgLy8gdGhlIHJvb3QuIFRoZSByb290IGNvbnN0cnVjdHMgcGFzcyB0aGUgc2FtZSB2YWx1ZSB0byBib3RoIHVubGVzcyBhXG4gICAgICAvLyBncm91cCdzIG93biBvdmVycmlkZSBhc2tzIGZvciBhbm90aGVyIChvbmUgYXJjaGl0ZWN0dXJlIHBlclxuICAgICAgLy8gZGVwbG95bWVudCksIG9yIGBOZXh0anNCdWlsZGAgYW5kIGBOZXh0anNGdW5jdGlvbnNgIGFyZSB3aXJlZCBieSBoYW5kLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgJHtMT0dfUFJFRklYfSBmdW5jdGlvblByb3BzLmFyY2hpdGVjdHVyZSBmb3IgZnVuY3Rpb24gZ3JvdXAgXCIke3Jvb3QubmFtZX1cIiBpcyAke3JlcXVlc3RlZC5uYW1lfSwgYCArXG4gICAgICAgICAgYGJ1dCBOZXh0anNCdWlsZCBzdGFnZWQgaXRzIG5hdGl2ZSBkZXBlbmRlbmNpZXMgKHNoYXJwKSBmb3IgJHthcmNoaXRlY3R1cmUubmFtZX0uIGAgK1xuICAgICAgICAgIFwiRXZlcnkgZnVuY3Rpb24gZ3JvdXAgZGVwbG95cyBvbmUgYXJjaGl0ZWN0dXJlOiBzZXQgaXQgY29uc3RydWN0LXdpZGUgaW4gXCIgK1xuICAgICAgICAgIFwiYG92ZXJyaWRlcy5uZXh0anNGdW5jdGlvbnMuZnVuY3Rpb25Qcm9wc2Agb3IsIHdpcmluZyB0aGUgY29uc3RydWN0cyB5b3Vyc2VsZiwgcGFzcyBcIiArXG4gICAgICAgICAgXCJOZXh0anNCdWlsZCdzIGBhcmNoaXRlY3R1cmVgIHRvIE5leHRqc0Z1bmN0aW9ucy5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIFppcHBlZCBoZXJlIHJhdGhlciB0aGFuIGJ5IGBjZGstYXNzZXRzYCwgd2hpY2ggd291bGQgZGVyZWZlcmVuY2UgdGhlXG4gICAgLy8gcG5wbSBzeW1saW5rcyB0aGUgcm9vdCBkZXBlbmRzIG9uOyBzZWUgYHppcERpcmVjdG9yeWAuXG4gICAgY29uc3QgemlwUGF0aCA9IGAke3Jvb3QucGF0aH0uemlwYDtcbiAgICB3cml0ZUZpbGVTeW5jKHppcFBhdGgsIHppcERpcmVjdG9yeShyb290LnBhdGgpKTtcbiAgICBjb25zdCBmdW5jdGlvblByb3BzOiBGdW5jdGlvblByb3BzID0ge1xuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoemlwUGF0aCksXG4gICAgICBoYW5kbGVyOiBgJHtSVU5USU1FX0RJUl9OQU1FfS9sYW1iZGEuaGFuZGxlcmAsXG4gICAgICBtZW1vcnlTaXplOiAyMDQ4LFxuICAgICAgcnVudGltZTogbmV3IFJ1bnRpbWUoXCJub2RlanMyNC54XCIsIFJ1bnRpbWVGYW1pbHkuTk9ERUpTKSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMzApLFxuICAgICAgLi4udGhpcy5zaGFyZWRGdW5jdGlvblByb3BzKHJvb3QubmFtZSksXG4gICAgICAuLi5ncm91cE92ZXJyaWRlcz8uZnVuY3Rpb25Qcm9wcyxcbiAgICAgIC8vIEFmdGVyIHRoZSBvdmVycmlkZXM6IHRoZSBmdW5jdGlvbiBtdXN0IHJ1biB3aGF0IGBOZXh0anNCdWlsZGAgc3RhZ2VkLlxuICAgICAgLy8gQW4gb3ZlcnJpZGUgdGhhdCBkaXNhZ3JlZXMgdGhyb3dzIGFib3ZlIHJhdGhlciB0aGFuIGJlaW5nIGRyb3BwZWQgaGVyZS5cbiAgICAgIGFyY2hpdGVjdHVyZSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIC8vIFdoYXQgYG5leHQgc3RhcnRgIGFuZCB0aGUgQ29udGFpbmVycyBEb2NrZXJmaWxlcyBzZXQuIEV4dGVybmFsaXplZFxuICAgICAgICAvLyBwYWNrYWdlcyAoUmVhY3QgZm9yIFBhZ2VzIFJvdXRlciBTU1IgYW1vbmcgdGhlbSkgbG9hZCB0aGVpciBkZXZcbiAgICAgICAgLy8gYnVpbGRzIHdpdGhvdXQgaXQuXG4gICAgICAgIE5PREVfRU5WOiBcInByb2R1Y3Rpb25cIixcbiAgICAgICAgLi4ucnVudGltZUVudmlyb25tZW50KHRoaXMucHJvcHMpLFxuICAgICAgICAvLyBXaGljaCBncm91cCB0aGlzIGZ1bmN0aW9uIGlzLiBPbmx5IHVzZWQgdG8gbWFrZSBhIG1pc3JvdXRlIGxlZ2libGU6XG4gICAgICAgIC8vIGlmIENsb3VkRnJvbnQgc2VuZHMgYSByZXF1ZXN0IGhlcmUgZm9yIGEgcm91dGUgdGhhdCB3YXMgcGFja2FnZWRcbiAgICAgICAgLy8gZWxzZXdoZXJlLCB0aGUgNTAwIHNheXMgd2hpY2ggZnVuY3Rpb24gZ290IGl0IGFuZCB3aGljaCBncm91cCBpdFxuICAgICAgICAvLyBiZWxvbmdzIHRvLCByYXRoZXIgdGhhbiBzdXJmYWNpbmcgYXMgYSBtb2R1bGUtbm90LWZvdW5kIGRlZXAgaW5zaWRlXG4gICAgICAgIC8vIHRoZSBOZXh0LmpzIHNlcnZlci5cbiAgICAgICAgW0ZVTkNUSU9OX0dST1VQX0VOVl9WQVJdOiByb290Lm5hbWUsXG4gICAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5mdW5jdGlvblByb3BzPy5lbnZpcm9ubWVudCxcbiAgICAgICAgLi4uZ3JvdXBPdmVycmlkZXM/LmZ1bmN0aW9uUHJvcHM/LmVudmlyb25tZW50LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgZm4gPSBuZXcgTGFtYmRhRnVuY3Rpb24odGhpcywgaWQsIGZ1bmN0aW9uUHJvcHMpO1xuXG4gICAgZ3JhbnRSdW50aW1lQWNjZXNzKHRoaXMucHJvcHMsIGZuKTtcblxuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY29uc3RydWN0LXdpZGUgYGZ1bmN0aW9uUHJvcHNgLCBtaW51cyB3aGF0IGlkZW50aWZpZXMgYSBzaW5nbGUgZnVuY3Rpb25cbiAgICogd2hlbiB0aGlzIGlzIG5vdCB0aGUgYGRlZmF1bHRgIGdyb3VwOyBzZWVcbiAgICoge0BsaW5rIE5leHRqc0Z1bmN0aW9uc092ZXJyaWRlcy5mdW5jdGlvblByb3BzfS5cbiAgICovXG4gIHByaXZhdGUgc2hhcmVkRnVuY3Rpb25Qcm9wcyhcbiAgICBncm91cE5hbWU6IHN0cmluZyxcbiAgKTogT3B0aW9uYWxGdW5jdGlvblByb3BzIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBzaGFyZWQgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uZnVuY3Rpb25Qcm9wcztcbiAgICBpZiAoIXNoYXJlZCB8fCBncm91cE5hbWUgPT09IERFRkFVTFRfRlVOQ1RJT05fR1JPVVApIHtcbiAgICAgIHJldHVybiBzaGFyZWQ7XG4gICAgfVxuICAgIGNvbnN0IHsgZnVuY3Rpb25OYW1lLCBjb2RlLCBoYW5kbGVyLCAuLi5yZXN0IH0gPSBzaGFyZWQ7XG4gICAgcmV0dXJuIHJlc3Q7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable import/no-extraneous-dependencies */
4
+ const node_fs_1 = require("node:fs");
5
+ const node_os_1 = require("node:os");
6
+ const node_path_1 = require("node:path");
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const assertions_1 = require("aws-cdk-lib/assertions");
9
+ const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
10
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
11
+ const aws_s3_1 = require("aws-cdk-lib/aws-s3");
12
+ const nextjs_functions_1 = require("./nextjs-functions");
13
+ const constants_1 = require("../constants");
14
+ describe("NextjsFunctions overrides", () => {
15
+ let dir;
16
+ beforeAll(() => {
17
+ dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "nextjs-functions-test-"));
18
+ for (const name of ["default", "reports", "other"]) {
19
+ // Distinct content, so each root is a distinct asset hash.
20
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(dir, name));
21
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, name, "index.js"), `// ${name}`);
22
+ }
23
+ });
24
+ afterAll(() => {
25
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
26
+ });
27
+ /** Lambda function properties by the group env var each function carries. */
28
+ function synth(overrides, groupOverrides, staged = aws_lambda_1.Architecture.X86_64) {
29
+ const stack = new aws_cdk_lib_1.Stack(new aws_cdk_lib_1.App(), "TestStack");
30
+ new nextjs_functions_1.NextjsFunctions(stack, "Functions", {
31
+ cacheBucket: new aws_s3_1.Bucket(stack, "Cache"),
32
+ revalidationTable: new aws_dynamodb_1.TableV2(stack, "Table", {
33
+ partitionKey: { name: "pk", type: aws_dynamodb_1.AttributeType.STRING },
34
+ }),
35
+ staticAssetsBucket: new aws_s3_1.Bucket(stack, "Assets"),
36
+ buildId: "build",
37
+ nextjsType: constants_1.NextjsType.REGIONAL_FUNCTIONS,
38
+ deploymentRoots: [
39
+ { name: "default", path: (0, node_path_1.join)(dir, "default"), routes: [] },
40
+ { name: "reports", path: (0, node_path_1.join)(dir, "reports"), routes: ["/reports"] },
41
+ ],
42
+ architecture: staged,
43
+ functionGroups: [
44
+ { name: "reports", routes: ["/reports"], overrides: groupOverrides },
45
+ ],
46
+ overrides,
47
+ });
48
+ const functions = assertions_1.Template.fromStack(stack).findResources("AWS::Lambda::Function");
49
+ return Object.fromEntries(Object.values(functions).map((fn) => [
50
+ fn.Properties.Environment.Variables.CDK_NEXTJS_FUNCTION_GROUP,
51
+ fn.Properties,
52
+ ]));
53
+ }
54
+ it("applies shared props to every group", () => {
55
+ const functions = synth({ functionProps: { memorySize: 3008 } });
56
+ expect(functions.default.MemorySize).toBe(3008);
57
+ expect(functions.reports.MemorySize).toBe(3008);
58
+ });
59
+ it("applies functionName, code and handler to the default group only", () => {
60
+ const functions = synth({
61
+ functionProps: {
62
+ functionName: "my-app",
63
+ code: aws_lambda_1.Code.fromAsset((0, node_path_1.join)(dir, "other")),
64
+ handler: "custom.handler",
65
+ },
66
+ });
67
+ expect(functions.default.FunctionName).toBe("my-app");
68
+ expect(functions.default.Handler).toBe("custom.handler");
69
+ expect(functions.reports.FunctionName).toBeUndefined();
70
+ expect(functions.reports.Handler).toBe("cdk-nextjs-runtime/lambda.handler");
71
+ // Each group still ships its own deployment root.
72
+ expect(functions.reports.Code).not.toEqual(functions.default.Code);
73
+ });
74
+ it("lets a group set its own functionName", () => {
75
+ const functions = synth({ functionProps: { functionName: "my-app" } }, { functionProps: { functionName: "my-app-reports" } });
76
+ expect(functions.default.FunctionName).toBe("my-app");
77
+ expect(functions.reports.FunctionName).toBe("my-app-reports");
78
+ });
79
+ describe("architecture", () => {
80
+ it("deploys what the roots were staged for, whatever this machine is", () => {
81
+ expect(synth({}).default.Architectures).toEqual(["x86_64"]);
82
+ const arm = synth({}, undefined, aws_lambda_1.Architecture.ARM_64);
83
+ expect(arm.default.Architectures).toEqual(["arm64"]);
84
+ expect(arm.reports.Architectures).toEqual(["arm64"]);
85
+ });
86
+ it("accepts an override that matches the staged binaries", () => {
87
+ const functions = synth({ functionProps: { architecture: aws_lambda_1.Architecture.ARM_64 } }, undefined, aws_lambda_1.Architecture.ARM_64);
88
+ expect(functions.default.Architectures).toEqual(["arm64"]);
89
+ });
90
+ // Silently deploying the staged architecture instead of the one asked for
91
+ // is how this used to fail. A group can't ask for its own either: one
92
+ // architecture per deployment.
93
+ it("throws on an override the staged binaries can't run on", () => {
94
+ expect(() => synth({ functionProps: { architecture: aws_lambda_1.Architecture.ARM_64 } })).toThrow(/staged its native dependencies \(sharp\) for x86_64/);
95
+ expect(() => synth({}, { functionProps: { architecture: aws_lambda_1.Architecture.ARM_64 } })).toThrow(/function group "reports" is arm64/);
96
+ });
97
+ });
98
+ });
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWZ1bmN0aW9ucy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL25leHRqcy1jb21wdXRlL25leHRqcy1mdW5jdGlvbnMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNEQUFzRDtBQUN0RCxxQ0FBd0U7QUFDeEUscUNBQWlDO0FBQ2pDLHlDQUFpQztBQUNqQyw2Q0FBeUM7QUFDekMsdURBQWtEO0FBQ2xELDJEQUFrRTtBQUNsRSx1REFBNEQ7QUFDNUQsK0NBQTRDO0FBQzVDLHlEQUErRTtBQUMvRSw0Q0FBMEM7QUFFMUMsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtJQUN6QyxJQUFJLEdBQVcsQ0FBQztJQUVoQixTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsR0FBRyxHQUFHLElBQUEscUJBQVcsRUFBQyxJQUFBLGdCQUFJLEVBQUMsSUFBQSxnQkFBTSxHQUFFLEVBQUUsd0JBQXdCLENBQUMsQ0FBQyxDQUFDO1FBQzVELEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDbkQsMkRBQTJEO1lBQzNELElBQUEsbUJBQVMsRUFBQyxJQUFBLGdCQUFJLEVBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDM0IsSUFBQSx1QkFBYSxFQUFDLElBQUEsZ0JBQUksRUFBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMzRCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQ1osSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQyxDQUFDLENBQUM7SUFFSCw2RUFBNkU7SUFDN0Us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LENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCB7IG1rZGlyU3luYywgbWtkdGVtcFN5bmMsIHJtU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IEFwcCwgU3RhY2sgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IFRlbXBsYXRlIH0gZnJvbSBcImF3cy1jZGstbGliL2Fzc2VydGlvbnNcIjtcbmltcG9ydCB7IEF0dHJpYnV0ZVR5cGUsIFRhYmxlVjIgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiXCI7XG5pbXBvcnQgeyBBcmNoaXRlY3R1cmUsIENvZGUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgQnVja2V0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHsgTmV4dGpzRnVuY3Rpb25zLCBOZXh0anNGdW5jdGlvbnNPdmVycmlkZXMgfSBmcm9tIFwiLi9uZXh0anMtZnVuY3Rpb25zXCI7XG5pbXBvcnQgeyBOZXh0anNUeXBlIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG5kZXNjcmliZShcIk5leHRqc0Z1bmN0aW9ucyBvdmVycmlkZXNcIiwgKCkgPT4ge1xuICBsZXQgZGlyOiBzdHJpbmc7XG5cbiAgYmVmb3JlQWxsKCgpID0+IHtcbiAgICBkaXIgPSBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBcIm5leHRqcy1mdW5jdGlvbnMtdGVzdC1cIikpO1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBbXCJkZWZhdWx0XCIsIFwicmVwb3J0c1wiLCBcIm90aGVyXCJdKSB7XG4gICAgICAvLyBEaXN0aW5jdCBjb250ZW50LCBzbyBlYWNoIHJvb3QgaXMgYSBkaXN0aW5jdCBhc3NldCBoYXNoLlxuICAgICAgbWtkaXJTeW5jKGpvaW4oZGlyLCBuYW1lKSk7XG4gICAgICB3cml0ZUZpbGVTeW5jKGpvaW4oZGlyLCBuYW1lLCBcImluZGV4LmpzXCIpLCBgLy8gJHtuYW1lfWApO1xuICAgIH1cbiAgfSk7XG5cbiAgYWZ0ZXJBbGwoKCkgPT4ge1xuICAgIHJtU3luYyhkaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgfSk7XG5cbiAgLyoqIExhbWJkYSBmdW5jdGlvbiBwcm9wZXJ0aWVzIGJ5IHRoZSBncm91cCBlbnYgdmFyIGVhY2ggZnVuY3Rpb24gY2Fycmllcy4gKi9cbiAgZnVuY3Rpb24gc3ludGgoXG4gICAgb3ZlcnJpZGVzOiBOZXh0anNGdW5jdGlvbnNPdmVycmlkZXMsXG4gICAgZ3JvdXBPdmVycmlkZXM/OiBOZXh0anNGdW5jdGlvbnNPdmVycmlkZXMsXG4gICAgc3RhZ2VkOiBBcmNoaXRlY3R1cmUgPSBBcmNoaXRlY3R1cmUuWDg2XzY0LFxuICApIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayhuZXcgQXBwKCksIFwiVGVzdFN0YWNrXCIpO1xuICAgIG5ldyBOZXh0anNGdW5jdGlvbnMoc3RhY2ssIFwiRnVuY3Rpb25zXCIsIHtcbiAgICAgIGNhY2hlQnVja2V0OiBuZXcgQnVja2V0KHN0YWNrLCBcIkNhY2hlXCIpLFxuICAgICAgcmV2YWxpZGF0aW9uVGFibGU6IG5ldyBUYWJsZVYyKHN0YWNrLCBcIlRhYmxlXCIsIHtcbiAgICAgICAgcGFydGl0aW9uS2V5OiB7IG5hbWU6IFwicGtcIiwgdHlwZTogQXR0cmlidXRlVHlwZS5TVFJJTkcgfSxcbiAgICAgIH0pLFxuICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBuZXcgQnVja2V0KHN0YWNrLCBcIkFzc2V0c1wiKSxcbiAgICAgIGJ1aWxkSWQ6IFwiYnVpbGRcIixcbiAgICAgIG5leHRqc1R5cGU6IE5leHRqc1R5cGUuUkVHSU9OQUxfRlVOQ1RJT05TLFxuICAgICAgZGVwbG95bWVudFJvb3RzOiBbXG4gICAgICAgIHsgbmFtZTogXCJkZWZhdWx0XCIsIHBhdGg6IGpvaW4oZGlyLCBcImRlZmF1bHRcIiksIHJvdXRlczogW10gfSxcbiAgICAgICAgeyBuYW1lOiBcInJlcG9ydHNcIiwgcGF0aDogam9pbihkaXIsIFwicmVwb3J0c1wiKSwgcm91dGVzOiBbXCIvcmVwb3J0c1wiXSB9LFxuICAgICAgXSxcbiAgICAgIGFyY2hpdGVjdHVyZTogc3RhZ2VkLFxuICAgICAgZnVuY3Rpb25Hcm91cHM6IFtcbiAgICAgICAgeyBuYW1lOiBcInJlcG9ydHNcIiwgcm91dGVzOiBbXCIvcmVwb3J0c1wiXSwgb3ZlcnJpZGVzOiBncm91cE92ZXJyaWRlcyB9LFxuICAgICAgXSxcbiAgICAgIG92ZXJyaWRlcyxcbiAgICB9KTtcbiAgICBjb25zdCBmdW5jdGlvbnMgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmZpbmRSZXNvdXJjZXMoXG4gICAgICBcIkFXUzo6TGFtYmRhOjpGdW5jdGlvblwiLFxuICAgICk7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC52YWx1ZXMoZnVuY3Rpb25zKS5tYXAoKGZuKSA9PiBbXG4gICAgICAgIGZuLlByb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNES19ORVhUSlNfRlVOQ1RJT05fR1JPVVAsXG4gICAgICAgIGZuLlByb3BlcnRpZXMsXG4gICAgICBdKSxcbiAgICApO1xuICB9XG5cbiAgaXQoXCJhcHBsaWVzIHNoYXJlZCBwcm9wcyB0byBldmVyeSBncm91cFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZnVuY3Rpb25zID0gc3ludGgoeyBmdW5jdGlvblByb3BzOiB7IG1lbW9yeVNpemU6IDMwMDggfSB9KTtcblxuICAgIGV4cGVjdChmdW5jdGlvbnMuZGVmYXVsdC5NZW1vcnlTaXplKS50b0JlKDMwMDgpO1xuICAgIGV4cGVjdChmdW5jdGlvbnMucmVwb3J0cy5NZW1vcnlTaXplKS50b0JlKDMwMDgpO1xuICB9KTtcblxuICBpdChcImFwcGxpZXMgZnVuY3Rpb25OYW1lLCBjb2RlIGFuZCBoYW5kbGVyIHRvIHRoZSBkZWZhdWx0IGdyb3VwIG9ubHlcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGZ1bmN0aW9ucyA9IHN5bnRoKHtcbiAgICAgIGZ1bmN0aW9uUHJvcHM6IHtcbiAgICAgICAgZnVuY3Rpb25OYW1lOiBcIm15LWFwcFwiLFxuICAgICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChqb2luKGRpciwgXCJvdGhlclwiKSksXG4gICAgICAgIGhhbmRsZXI6IFwiY3VzdG9tLmhhbmRsZXJcIixcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QoZnVuY3Rpb25zLmRlZmF1bHQuRnVuY3Rpb25OYW1lKS50b0JlKFwibXktYXBwXCIpO1xuICAgIGV4cGVjdChmdW5jdGlvbnMuZGVmYXVsdC5IYW5kbGVyKS50b0JlKFwiY3VzdG9tLmhhbmRsZXJcIik7XG4gICAgZXhwZWN0KGZ1bmN0aW9ucy5yZXBvcnRzLkZ1bmN0aW9uTmFtZSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIGV4cGVjdChmdW5jdGlvbnMucmVwb3J0cy5IYW5kbGVyKS50b0JlKFwiY2RrLW5leHRqcy1ydW50aW1lL2xhbWJkYS5oYW5kbGVyXCIpO1xuICAgIC8vIEVhY2ggZ3JvdXAgc3RpbGwgc2hpcHMgaXRzIG93biBkZXBsb3ltZW50IHJvb3QuXG4gICAgZXhwZWN0KGZ1bmN0aW9ucy5yZXBvcnRzLkNvZGUpLm5vdC50b0VxdWFsKGZ1bmN0aW9ucy5kZWZhdWx0LkNvZGUpO1xuICB9KTtcblxuICBpdChcImxldHMgYSBncm91cCBzZXQgaXRzIG93biBmdW5jdGlvbk5hbWVcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGZ1bmN0aW9ucyA9IHN5bnRoKFxuICAgICAgeyBmdW5jdGlvblByb3BzOiB7IGZ1bmN0aW9uTmFtZTogXCJteS1hcHBcIiB9IH0sXG4gICAgICB7IGZ1bmN0aW9uUHJvcHM6IHsgZnVuY3Rpb25OYW1lOiBcIm15LWFwcC1yZXBvcnRzXCIgfSB9LFxuICAgICk7XG5cbiAgICBleHBlY3QoZnVuY3Rpb25zLmRlZmF1bHQuRnVuY3Rpb25OYW1lKS50b0JlKFwibXktYXBwXCIpO1xuICAgIGV4cGVjdChmdW5jdGlvbnMucmVwb3J0cy5GdW5jdGlvbk5hbWUpLnRvQmUoXCJteS1hcHAtcmVwb3J0c1wiKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJhcmNoaXRlY3R1cmVcIiwgKCkgPT4ge1xuICAgIGl0KFwiZGVwbG95cyB3aGF0IHRoZSByb290cyB3ZXJlIHN0YWdlZCBmb3IsIHdoYXRldmVyIHRoaXMgbWFjaGluZSBpc1wiLCAoKSA9PiB7XG4gICAgICBleHBlY3Qoc3ludGgoe30pLmRlZmF1bHQuQXJjaGl0ZWN0dXJlcykudG9FcXVhbChbXCJ4ODZfNjRcIl0pO1xuICAgICAgY29uc3QgYXJtID0gc3ludGgoe30sIHVuZGVmaW5lZCwgQXJjaGl0ZWN0dXJlLkFSTV82NCk7XG4gICAgICBleHBlY3QoYXJtLmRlZmF1bHQuQXJjaGl0ZWN0dXJlcykudG9FcXVhbChbXCJhcm02NFwiXSk7XG4gICAgICBleHBlY3QoYXJtLnJlcG9ydHMuQXJjaGl0ZWN0dXJlcykudG9FcXVhbChbXCJhcm02NFwiXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImFjY2VwdHMgYW4gb3ZlcnJpZGUgdGhhdCBtYXRjaGVzIHRoZSBzdGFnZWQgYmluYXJpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZnVuY3Rpb25zID0gc3ludGgoXG4gICAgICAgIHsgZnVuY3Rpb25Qcm9wczogeyBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZS5BUk1fNjQgfSB9LFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIEFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICApO1xuICAgICAgZXhwZWN0KGZ1bmN0aW9ucy5kZWZhdWx0LkFyY2hpdGVjdHVyZXMpLnRvRXF1YWwoW1wiYXJtNjRcIl0pO1xuICAgIH0pO1xuXG4gICAgLy8gU2lsZW50bHkgZGVwbG95aW5nIHRoZSBzdGFnZWQgYXJjaGl0ZWN0dXJlIGluc3RlYWQgb2YgdGhlIG9uZSBhc2tlZCBmb3JcbiAgICAvLyBpcyBob3cgdGhpcyB1c2VkIHRvIGZhaWwuIEEgZ3JvdXAgY2FuJ3QgYXNrIGZvciBpdHMgb3duIGVpdGhlcjogb25lXG4gICAgLy8gYXJjaGl0ZWN0dXJlIHBlciBkZXBsb3ltZW50LlxuICAgIGl0KFwidGhyb3dzIG9uIGFuIG92ZXJyaWRlIHRoZSBzdGFnZWQgYmluYXJpZXMgY2FuJ3QgcnVuIG9uXCIsICgpID0+IHtcbiAgICAgIGV4cGVjdCgoKSA9PlxuICAgICAgICBzeW50aCh7IGZ1bmN0aW9uUHJvcHM6IHsgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0IH0gfSksXG4gICAgICApLnRvVGhyb3coL3N0YWdlZCBpdHMgbmF0aXZlIGRlcGVuZGVuY2llcyBcXChzaGFycFxcKSBmb3IgeDg2XzY0Lyk7XG4gICAgICBleHBlY3QoKCkgPT5cbiAgICAgICAgc3ludGgoe30sIHsgZnVuY3Rpb25Qcm9wczogeyBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZS5BUk1fNjQgfSB9KSxcbiAgICAgICkudG9UaHJvdygvZnVuY3Rpb24gZ3JvdXAgXCJyZXBvcnRzXCIgaXMgYXJtNjQvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==