cdk-nextjs 0.1.0 → 0.1.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 (132) hide show
  1. package/.jsii +13834 -0
  2. package/.prettierrc +0 -0
  3. package/API.md +9655 -0
  4. package/LICENSE +202 -0
  5. package/README.md +164 -2
  6. package/THIRD-PARTY-LICENSES.md +31 -0
  7. package/assets/lambdas/assets-deployment/assets-deployment.lambda/assets-deployment.Dockerfile +18 -0
  8. package/assets/lambdas/assets-deployment/assets-deployment.lambda/index.js +8833 -0
  9. package/assets/lambdas/revalidate/revalidate.lambda/index.js +67 -0
  10. package/assets/lambdas/sign-fn-url/sign-fn-url.edge-lambda/index.js +2024 -0
  11. package/docs/breaking-changes.md +8 -0
  12. package/docs/cdk-nextjs-NextjsGlobalContainers.png +0 -0
  13. package/docs/cdk-nextjs-NextjsGlobalFunctions.png +0 -0
  14. package/docs/cdk-nextjs-NextjsRegionalContainers.png +0 -0
  15. package/docs/cdk-nextjs.drawio +163 -0
  16. package/docs/notes.md +26 -0
  17. package/examples/README.md +15 -0
  18. package/lib/common.d.ts +23 -0
  19. package/lib/common.js +28 -0
  20. package/lib/generated-structs/OptionalApplicationLoadBalancedTaskImageOptions.d.ts +106 -0
  21. package/lib/generated-structs/OptionalApplicationLoadBalancedTaskImageOptions.js +3 -0
  22. package/lib/generated-structs/OptionalCloudFrontFunctionProps.d.ts +43 -0
  23. package/lib/generated-structs/OptionalCloudFrontFunctionProps.js +3 -0
  24. package/lib/generated-structs/OptionalClusterProps.d.ts +62 -0
  25. package/lib/generated-structs/OptionalClusterProps.js +3 -0
  26. package/lib/generated-structs/OptionalDistributionProps.d.ts +155 -0
  27. package/lib/generated-structs/OptionalDistributionProps.js +3 -0
  28. package/lib/generated-structs/OptionalDockerImageAssetProps.d.ts +124 -0
  29. package/lib/generated-structs/OptionalDockerImageAssetProps.js +3 -0
  30. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +399 -0
  31. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +3 -0
  32. package/lib/generated-structs/OptionalEdgeFunctionProps.d.ts +428 -0
  33. package/lib/generated-structs/OptionalEdgeFunctionProps.js +3 -0
  34. package/lib/generated-structs/OptionalFunctionProps.d.ts +422 -0
  35. package/lib/generated-structs/OptionalFunctionProps.js +3 -0
  36. package/lib/generated-structs/OptionalFunctionUrlProps.d.ts +30 -0
  37. package/lib/generated-structs/OptionalFunctionUrlProps.js +3 -0
  38. package/lib/generated-structs/OptionalNextjsAssetsDeploymentProps.d.ts +40 -0
  39. package/lib/generated-structs/OptionalNextjsAssetsDeploymentProps.js +3 -0
  40. package/lib/generated-structs/OptionalNextjsBuildProps.d.ts +26 -0
  41. package/lib/generated-structs/OptionalNextjsBuildProps.js +3 -0
  42. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +39 -0
  43. package/lib/generated-structs/OptionalNextjsContainersProps.js +3 -0
  44. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +45 -0
  45. package/lib/generated-structs/OptionalNextjsDistributionProps.js +3 -0
  46. package/lib/generated-structs/OptionalNextjsFileSystemProps.d.ts +10 -0
  47. package/lib/generated-structs/OptionalNextjsFileSystemProps.js +3 -0
  48. package/lib/generated-structs/OptionalNextjsInvalidationProps.d.ts +11 -0
  49. package/lib/generated-structs/OptionalNextjsInvalidationProps.js +3 -0
  50. package/lib/generated-structs/OptionalNextjsVpcProps.d.ts +16 -0
  51. package/lib/generated-structs/OptionalNextjsVpcProps.js +3 -0
  52. package/lib/generated-structs/OptionalS3OriginBucketWithOACProps.d.ts +70 -0
  53. package/lib/generated-structs/OptionalS3OriginBucketWithOACProps.js +3 -0
  54. package/lib/generated-structs/OptionalVpcProps.d.ts +224 -0
  55. package/lib/generated-structs/OptionalVpcProps.js +3 -0
  56. package/lib/index.d.ts +35 -0
  57. package/lib/index.js +32 -0
  58. package/lib/lambdas/assets-deployment/assets-deployment-function.d.ts +13 -0
  59. package/lib/lambdas/assets-deployment/assets-deployment-function.js +22 -0
  60. package/lib/lambdas/assets-deployment/assets-deployment.lambda.d.ts +2 -0
  61. package/lib/lambdas/assets-deployment/assets-deployment.lambda.js +63 -0
  62. package/lib/lambdas/assets-deployment/common.d.ts +8 -0
  63. package/lib/lambdas/assets-deployment/common.js +32 -0
  64. package/lib/lambdas/assets-deployment/fs-to-fs.d.ts +2 -0
  65. package/lib/lambdas/assets-deployment/fs-to-fs.js +9 -0
  66. package/lib/lambdas/assets-deployment/fs-to-s3.d.ts +2 -0
  67. package/lib/lambdas/assets-deployment/fs-to-s3.js +45 -0
  68. package/lib/lambdas/assets-deployment/prune-s3.d.ts +15 -0
  69. package/lib/lambdas/assets-deployment/prune-s3.js +42 -0
  70. package/lib/lambdas/assets-deployment/s3.d.ts +2 -0
  71. package/lib/lambdas/assets-deployment/s3.js +7 -0
  72. package/lib/lambdas/assets-deployment/utils.d.ts +18 -0
  73. package/lib/lambdas/assets-deployment/utils.js +35 -0
  74. package/lib/lambdas/revalidate/revalidate-function.d.ts +13 -0
  75. package/lib/lambdas/revalidate/revalidate-function.js +22 -0
  76. package/lib/lambdas/revalidate/revalidate.lambda.d.ts +2 -0
  77. package/lib/lambdas/revalidate/revalidate.lambda.js +53 -0
  78. package/lib/lambdas/sign-fn-url/sign-fn-url-function.d.ts +13 -0
  79. package/lib/lambdas/sign-fn-url/sign-fn-url-function.js +23 -0
  80. package/lib/lambdas/sign-fn-url/sign-fn-url.edge-lambda.d.ts +9 -0
  81. package/lib/lambdas/sign-fn-url/sign-fn-url.edge-lambda.js +35 -0
  82. package/lib/lambdas/sign-fn-url/sign-request.d.ts +28 -0
  83. package/lib/lambdas/sign-fn-url/sign-request.js +119 -0
  84. package/lib/lambdas/sign-fn-url/sign-request.test.d.ts +1 -0
  85. package/lib/lambdas/sign-fn-url/sign-request.test.js +129 -0
  86. package/lib/nextjs-assets-deployment.d.ts +116 -0
  87. package/lib/nextjs-assets-deployment.js +93 -0
  88. package/lib/nextjs-build/add-cache-handler.d.ts +1 -0
  89. package/lib/nextjs-build/add-cache-handler.js +23 -0
  90. package/lib/nextjs-build/add-cache-handler.mjs +18 -0
  91. package/lib/nextjs-build/builder.Dockerfile +25 -0
  92. package/lib/nextjs-build/cache-handler.cjs +21080 -0
  93. package/lib/nextjs-build/cache-handler.d.ts +6 -0
  94. package/lib/nextjs-build/cache-handler.js +22 -0
  95. package/lib/nextjs-build/global-containers.Dockerfile +45 -0
  96. package/lib/nextjs-build/global-functions.Dockerfile +46 -0
  97. package/lib/nextjs-build/nextjs-build.d.ts +150 -0
  98. package/lib/nextjs-build/nextjs-build.js +220 -0
  99. package/lib/nextjs-build/regional-containers.Dockerfile +45 -0
  100. package/lib/nextjs-build/symlink-full-route-cache.d.ts +1 -0
  101. package/lib/nextjs-build/symlink-full-route-cache.js +37 -0
  102. package/lib/nextjs-build/symlink-full-route-cache.mjs +23 -0
  103. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +8 -0
  104. package/lib/nextjs-compute/nextjs-compute-base-props.js +3 -0
  105. package/lib/nextjs-compute/nextjs-containers.d.ts +43 -0
  106. package/lib/nextjs-compute/nextjs-containers.js +149 -0
  107. package/lib/nextjs-compute/nextjs-functions.d.ts +23 -0
  108. package/lib/nextjs-compute/nextjs-functions.js +57 -0
  109. package/lib/nextjs-distribution.d.ts +107 -0
  110. package/lib/nextjs-distribution.js +331 -0
  111. package/lib/nextjs-file-system.d.ts +42 -0
  112. package/lib/nextjs-file-system.js +74 -0
  113. package/lib/nextjs-invalidation.d.ts +19 -0
  114. package/lib/nextjs-invalidation.js +52 -0
  115. package/lib/nextjs-revalidation.d.ts +30 -0
  116. package/lib/nextjs-revalidation.js +65 -0
  117. package/lib/nextjs-static-assets.d.ts +21 -0
  118. package/lib/nextjs-static-assets.js +33 -0
  119. package/lib/nextjs-vpc.d.ts +42 -0
  120. package/lib/nextjs-vpc.js +64 -0
  121. package/lib/root-constructs/nextjs-base-overrides.d.ts +26 -0
  122. package/lib/root-constructs/nextjs-base-overrides.js +3 -0
  123. package/lib/root-constructs/nextjs-base-props.d.ts +56 -0
  124. package/lib/root-constructs/nextjs-base-props.js +3 -0
  125. package/lib/root-constructs/nextjs-global-containers.d.ts +74 -0
  126. package/lib/root-constructs/nextjs-global-containers.js +125 -0
  127. package/lib/root-constructs/nextjs-global-functions.d.ts +76 -0
  128. package/lib/root-constructs/nextjs-global-functions.js +131 -0
  129. package/lib/root-constructs/nextjs-regional-containers.d.ts +43 -0
  130. package/lib/root-constructs/nextjs-regional-containers.js +92 -0
  131. package/package.json +163 -2
  132. package/dist/index.js +0 -1
@@ -0,0 +1,331 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.NextjsDistribution = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront");
8
+ const aws_cloudfront_origins_1 = require("aws-cdk-lib/aws-cloudfront-origins");
9
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
10
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
11
+ const constructs_1 = require("constructs");
12
+ const common_1 = require("./common");
13
+ const sign_fn_url_function_1 = require("./lambdas/sign-fn-url/sign-fn-url-function");
14
+ class NextjsDistribution extends constructs_1.Construct {
15
+ constructor(scope, id, props) {
16
+ super(scope, id);
17
+ /**
18
+ * Common security headers applied by default to all origins
19
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html#managed-response-headers-policies-security
20
+ */
21
+ this.commonSecurityHeadersBehavior = {
22
+ contentTypeOptions: { override: false },
23
+ frameOptions: {
24
+ frameOption: aws_cloudfront_1.HeadersFrameOption.SAMEORIGIN,
25
+ override: false,
26
+ },
27
+ referrerPolicy: {
28
+ override: false,
29
+ referrerPolicy: aws_cloudfront_1.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
30
+ },
31
+ strictTransportSecurity: {
32
+ accessControlMaxAge: aws_cdk_lib_1.Duration.days(365),
33
+ includeSubdomains: true,
34
+ override: false,
35
+ preload: true,
36
+ },
37
+ xssProtection: { override: false, protection: true, modeBlock: true },
38
+ };
39
+ this.props = props;
40
+ this.staticOrigin = this.createStaticOrigin();
41
+ this.isFunctionCompute = props.nextjsType === common_1.NextjsType.GLOBAL_FUNCTIONS;
42
+ this.dynamicOrigin = this.createDynamicOrigin();
43
+ this.dynamicOriginResponsePolicy = this.createDynamicOriginRequestPolicy();
44
+ this.dynamicCloudFrontFunctionAssociations =
45
+ this.createDynamicCloudFrontFunctionAssociations();
46
+ if (this.isFunctionCompute) {
47
+ this.edgeLambdas = this.createEdgeLambdas();
48
+ }
49
+ this.staticBehaviorOptions = this.createStaticBehaviorOptions();
50
+ this.dynamicBehaviorOptions = this.createDynamicBehaviorOptions();
51
+ this.imageBehaviorOptions = this.createImageBehaviorOptions();
52
+ this.distribution = this.getDistribution();
53
+ this.addStaticBehaviors();
54
+ this.addDynamicBehaviors();
55
+ if (this.isFunctionCompute) {
56
+ // this.addLambdaOac(); // TODO: wait for POST body encryption feature for Lambda OAC
57
+ }
58
+ new aws_cdk_lib_1.CfnOutput(this, "DistributionDomainName", {
59
+ value: this.distribution.domainName,
60
+ });
61
+ }
62
+ createStaticOrigin() {
63
+ const s3Origin = aws_cloudfront_origins_1.S3BucketOrigin.withOriginAccessControl(this.props.assetsBucket, this.props.overrides?.s3BucketOriginProps);
64
+ return s3Origin;
65
+ }
66
+ createDynamicOrigin() {
67
+ let protocolPolicy;
68
+ if (this.isFunctionCompute) {
69
+ protocolPolicy = aws_cloudfront_1.OriginProtocolPolicy.HTTPS_ONLY;
70
+ }
71
+ else {
72
+ protocolPolicy = this.props.certificate
73
+ ? aws_cloudfront_1.OriginProtocolPolicy.HTTPS_ONLY
74
+ : aws_cloudfront_1.OriginProtocolPolicy.HTTP_ONLY;
75
+ }
76
+ // WAITING FOR CLOUDFRONT FEATURE: CloudFront Lambda Function URL OAC
77
+ // doesn't support POST with body since CloudFront doesn't include sha256
78
+ // hash of body. see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-lambda.html
79
+ // We could monkey patch `fetch` to include sha256 in request for server
80
+ // actions, but better solution is for cloudfront to support it
81
+ //
82
+ // TODO: use L2 construct when released: https://github.com/aws/aws-cdk/issues/31629
83
+ /**
84
+ * Given stack id: "arn:aws:cloudformation:us-east-1:905418358903:stack/lh-stickb-idp/4bf74be0-e880-11ee-aea9-0affc6185b25",
85
+ * returns "4bf74be0"
86
+ */
87
+ // const uniqueStackIdPart = Fn.select(
88
+ // 0,
89
+ // Fn.split("-", Fn.select(2, Fn.split("/", `${Aws.STACK_ID}`))),
90
+ // );
91
+ // const lambdaOac = new CfnOriginAccessControl(this, "OAC", {
92
+ // originAccessControlConfig: {
93
+ // name: `OAC-Lambda-${uniqueStackIdPart}`,
94
+ // originAccessControlOriginType: "lambda",
95
+ // signingBehavior: "always",
96
+ // signingProtocol: "sigv4",
97
+ // },
98
+ // });
99
+ // const cfnDistribution = this.distribution.node
100
+ // .defaultChild as CfnDistribution;
101
+ // cfnDistribution.addPropertyOverride(
102
+ // "DistributionConfig.Origins.0.OriginAccessControlId",
103
+ // lambdaOac.getAtt("Id"),
104
+ // );
105
+ return new aws_cloudfront_origins_1.HttpOrigin(aws_cdk_lib_1.Fn.parseDomainName(this.props.dynamicUrl), {
106
+ protocolPolicy,
107
+ ...this.props.overrides?.dynamicHttpOriginProps,
108
+ });
109
+ }
110
+ /**
111
+ * Lambda Function URLs "expect the `Host` header to contain the origin domain
112
+ * name, not the domain name of the CloudFront distribution."
113
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-except-host-header
114
+ */
115
+ createDynamicOriginRequestPolicy() {
116
+ return this.isFunctionCompute
117
+ ? aws_cloudfront_1.OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER
118
+ : aws_cloudfront_1.OriginRequestPolicy.ALL_VIEWER;
119
+ }
120
+ /**
121
+ * Ensures Next.js `request.url` will be correct domain instead of URL of
122
+ * compute option (App Runner, Fargate, or Lambda)
123
+ * @see https://open-next.js.org/advanced/workaround#workaround-set-x-forwarded-host-header-aws-specific
124
+ */
125
+ createDynamicCloudFrontFunctionAssociations() {
126
+ const associations = [];
127
+ if (this.isFunctionCompute) {
128
+ const cloudFrontFn = new aws_cloudfront_1.Function(this, "CloudFrontFn", {
129
+ code: aws_cloudfront_1.FunctionCode.fromInline(`
130
+ function handler(event) {
131
+ var request = event.request;
132
+ request.headers["x-forwarded-host"] = request.headers.host;
133
+ return request;
134
+ }
135
+ `),
136
+ });
137
+ associations.push({
138
+ eventType: aws_cloudfront_1.FunctionEventType.VIEWER_REQUEST,
139
+ function: cloudFrontFn,
140
+ });
141
+ }
142
+ return associations;
143
+ }
144
+ /**
145
+ * Required to sign requests so that we can use IAM_AUTH for Lambda Function URL
146
+ * to prevent public access. Once CloudFront Lambda OAC is released, we can
147
+ * use infra configuration for this instead of custom code.
148
+ */
149
+ createEdgeLambdas() {
150
+ if (!this.props.functionArn)
151
+ throw new Error("functionArn is required");
152
+ const edgeFn = new sign_fn_url_function_1.SignFnUrlFunction(this, "SignFnUrl", {
153
+ currentVersionOptions: {
154
+ retryAttempts: 0, // fail fast when trying to delete b/c replicated functions take long time to delete
155
+ },
156
+ initialPolicy: [
157
+ new aws_iam_1.PolicyStatement({
158
+ actions: ["lambda:InvokeFunctionUrl"],
159
+ resources: [this.props.functionArn],
160
+ }),
161
+ ],
162
+ code: aws_lambda_1.Code.fromInline("export function handler() {}"),
163
+ handler: "handler",
164
+ runtime: aws_lambda_1.Runtime.NODEJS_LATEST,
165
+ ...this.props.overrides?.edgeFunctionProps,
166
+ });
167
+ edgeFn.currentVersion.grantInvoke(new aws_iam_1.ServicePrincipal("edgelambda.amazonaws.com"));
168
+ edgeFn.currentVersion.grantInvoke(new aws_iam_1.ServicePrincipal("lambda.amazonaws.com"));
169
+ return [
170
+ {
171
+ eventType: aws_cloudfront_1.LambdaEdgeEventType.ORIGIN_REQUEST,
172
+ functionVersion: edgeFn.currentVersion,
173
+ includeBody: true,
174
+ },
175
+ ];
176
+ }
177
+ createStaticBehaviorOptions() {
178
+ const staticBehaviorOptions = this.props.overrides?.staticBehaviorOptions;
179
+ const responseHeadersPolicy = staticBehaviorOptions?.responseHeadersPolicy ??
180
+ new aws_cloudfront_1.ResponseHeadersPolicy(this, "StaticResponseHeadersPolicy", {
181
+ securityHeadersBehavior: this.commonSecurityHeadersBehavior,
182
+ comment: `Nextjs Static Response Headers Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
183
+ ...this.props.overrides?.staticResponseHeadersPolicyProps,
184
+ });
185
+ return {
186
+ allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
187
+ cachedMethods: aws_cloudfront_1.CachedMethods.CACHE_GET_HEAD_OPTIONS,
188
+ cachePolicy: aws_cloudfront_1.CachePolicy.CACHING_OPTIMIZED,
189
+ origin: this.staticOrigin,
190
+ responseHeadersPolicy,
191
+ viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
192
+ ...staticBehaviorOptions,
193
+ };
194
+ }
195
+ createDynamicBehaviorOptions() {
196
+ const dynamicBehaviorOptions = this.props.overrides?.dynamicBehaviorOptions;
197
+ // create default cache policy if not provided
198
+ const cachePolicy = dynamicBehaviorOptions?.cachePolicy ??
199
+ new aws_cloudfront_1.CachePolicy(this, "DynamicCachePolicy", {
200
+ queryStringBehavior: aws_cloudfront_1.CacheQueryStringBehavior.all(),
201
+ headerBehavior: aws_cloudfront_1.CacheHeaderBehavior.allowList("accept", "rsc", "next-router-prefetch", "next-router-state-tree", "next-url", "x-prerender-revalidate"),
202
+ cookieBehavior: aws_cloudfront_1.CacheCookieBehavior.all(),
203
+ enableAcceptEncodingBrotli: true,
204
+ enableAcceptEncodingGzip: true,
205
+ comment: `Nextjs Dynamic Cache Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
206
+ ...this.props.overrides?.dynamicCachePolicyProps,
207
+ });
208
+ const responseHeadersPolicy = dynamicBehaviorOptions?.responseHeadersPolicy ??
209
+ new aws_cloudfront_1.ResponseHeadersPolicy(this, "DynamicResponseHeadersPolicy", {
210
+ securityHeadersBehavior: this.commonSecurityHeadersBehavior,
211
+ comment: `Nextjs Dynamic Response Headers Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
212
+ ...this.props.overrides?.dynamicBehaviorOptions?.responseHeadersPolicy,
213
+ });
214
+ const behaviorOptions = {
215
+ allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_ALL,
216
+ cachePolicy,
217
+ edgeLambdas: this.edgeLambdas,
218
+ functionAssociations: this.dynamicCloudFrontFunctionAssociations,
219
+ origin: this.dynamicOrigin,
220
+ originRequestPolicy: this.dynamicOriginResponsePolicy,
221
+ responseHeadersPolicy,
222
+ viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
223
+ ...dynamicBehaviorOptions,
224
+ };
225
+ return behaviorOptions;
226
+ }
227
+ createImageBehaviorOptions() {
228
+ const imageBehaviorOptions = this.props.overrides?.imageBehaviorOptions;
229
+ // add default cache policy if not provided
230
+ const cachePolicy = imageBehaviorOptions?.cachePolicy ??
231
+ new aws_cloudfront_1.CachePolicy(this, "ImageCachePolicy", {
232
+ // SECURITY NOTE: by default we don't include cookies in cache for
233
+ // images b/c it significantly improves image perf for most sites BUT
234
+ // if you have private images locked behind auth implemented with cookies
235
+ // you need to override this.
236
+ queryStringBehavior: aws_cloudfront_1.CacheQueryStringBehavior.all(),
237
+ headerBehavior: aws_cloudfront_1.CacheHeaderBehavior.allowList("accept"),
238
+ cookieBehavior: aws_cloudfront_1.CacheCookieBehavior.none(),
239
+ enableAcceptEncodingBrotli: true,
240
+ enableAcceptEncodingGzip: true,
241
+ comment: `Nextjs Image Cache Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
242
+ ...this.props.overrides?.imageCachePolicyProps,
243
+ });
244
+ // add default response headers policy if not provided
245
+ const responseHeadersPolicy = imageBehaviorOptions?.responseHeadersPolicy ??
246
+ new aws_cloudfront_1.ResponseHeadersPolicy(this, "ImageResponseHeadersPolicy", {
247
+ securityHeadersBehavior: this.commonSecurityHeadersBehavior,
248
+ comment: `Nextjs Image Response Headers Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
249
+ ...this.props.overrides?.imageResponseHeadersPolicyProps,
250
+ });
251
+ return {
252
+ allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
253
+ cachedMethods: aws_cloudfront_1.CachedMethods.CACHE_GET_HEAD_OPTIONS,
254
+ edgeLambdas: this.edgeLambdas,
255
+ functionAssociations: this.dynamicCloudFrontFunctionAssociations,
256
+ origin: this.dynamicOrigin,
257
+ originRequestPolicy: this.dynamicOriginResponsePolicy,
258
+ cachePolicy,
259
+ responseHeadersPolicy,
260
+ viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
261
+ ...imageBehaviorOptions,
262
+ };
263
+ }
264
+ /**
265
+ * Creates or uses user specified CloudFront Distribution
266
+ */
267
+ getDistribution() {
268
+ let distribution;
269
+ if (this.props.distribution) {
270
+ distribution = this.props.distribution;
271
+ }
272
+ else {
273
+ distribution = new aws_cloudfront_1.Distribution(this, "Distribution", {
274
+ minimumProtocolVersion: aws_cloudfront_1.SecurityPolicyProtocol.TLS_V1_2_2021,
275
+ defaultBehavior: this.dynamicBehaviorOptions,
276
+ // best to use HTTP 2 and 3 for compatability (HTTP 2) and performance (HTTP3)
277
+ // CloudFront will choose best option for client
278
+ httpVersion: aws_cloudfront_1.HttpVersion.HTTP2_AND_3,
279
+ comment: `cdk-nextjs Distribution for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
280
+ ...this.props.overrides?.distributionProps,
281
+ });
282
+ }
283
+ return distribution;
284
+ }
285
+ addDynamicBehaviors() {
286
+ // Image Behavior
287
+ this.distribution.addBehavior(this.getPathPattern("_next/image*"), this.imageBehaviorOptions.origin, this.imageBehaviorOptions);
288
+ // Root Path Behaviors
289
+ if (this.props.basePath) {
290
+ // because we already have a basePath we don't use / instead we use /base-path
291
+ this.distribution.addBehavior(this.props.basePath, this.dynamicBehaviorOptions.origin, this.dynamicBehaviorOptions);
292
+ // when basePath is set, we emulate the "default behavior" (*) for the site as `/base-path/*`
293
+ this.distribution.addBehavior(this.getPathPattern("*"), this.dynamicBehaviorOptions.origin, this.dynamicBehaviorOptions);
294
+ }
295
+ else {
296
+ // if no base path, then default behavior will handle all other paths
297
+ }
298
+ }
299
+ addStaticBehaviors() {
300
+ this.distribution.addBehavior("_next/static*", this.staticOrigin, this.staticBehaviorOptions);
301
+ // 22 = 25 (max) - 1 (_next/image) - 1 (_next/static) - 1 (*)
302
+ if (this.props.publicDirEntries.length >= 22) {
303
+ throw new Error(`Too many public/ files in Next.js build. CloudFront limits Distributions to 25 Cache Behaviors. See documented limit here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html#limits-web-distributions. Try including all public files into 1 top level directory (i.e. static/*).`);
304
+ }
305
+ for (const publicFile of this.props.publicDirEntries) {
306
+ const pathPattern = publicFile.isDirectory
307
+ ? `${publicFile.name}/*`
308
+ : publicFile.name;
309
+ if (!/^[a-zA-Z0-9_\-.*$/~"'@:+?&]+$/.test(pathPattern)) {
310
+ throw new Error(`Invalid CloudFront Distribution Cache Behavior Path Pattern: ${pathPattern}. Please see documentation here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesPathPattern`);
311
+ }
312
+ const finalPathPattern = this.getPathPattern(pathPattern);
313
+ this.distribution.addBehavior(finalPathPattern, this.staticOrigin, this.staticBehaviorOptions);
314
+ }
315
+ }
316
+ /**
317
+ * Optionally prepends base path to given path pattern.
318
+ */
319
+ getPathPattern(pathPattern) {
320
+ if (this.props.basePath) {
321
+ return `${this.props.basePath}/${pathPattern}`;
322
+ }
323
+ else {
324
+ return pathPattern;
325
+ }
326
+ }
327
+ }
328
+ exports.NextjsDistribution = NextjsDistribution;
329
+ _a = JSII_RTTI_SYMBOL_1;
330
+ NextjsDistribution[_a] = { fqn: "cdk-nextjs.NextjsDistribution", version: "0.1.1" };
331
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWRpc3RyaWJ1dGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXh0anMtZGlzdHJpYnV0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBQTZEO0FBRTdELCtEQTRCb0M7QUFDcEMsK0VBSTRDO0FBQzVDLGlEQUF3RTtBQUN4RSx1REFBdUQ7QUFFdkQsMkNBQXVDO0FBQ3ZDLHFDQUFzQztBQUl0QyxxRkFBK0U7QUFrRC9FLE1BQWEsa0JBQW1CLFNBQVEsc0JBQVM7SUFxQy9DLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBOEI7UUFDdEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQWxDbkI7OztXQUdHO1FBQ0ssa0NBQTZCLEdBQW9DO1lBQ3ZFLGtCQUFrQixFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRTtZQUN2QyxZQUFZLEVBQUU7Z0JBQ1osV0FBVyxFQUFFLG1DQUFrQixDQUFDLFVBQVU7Z0JBQzFDLFFBQVEsRUFBRSxLQUFLO2FBQ2hCO1lBQ0QsY0FBYyxFQUFFO2dCQUNkLFFBQVEsRUFBRSxLQUFLO2dCQUNmLGNBQWMsRUFBRSxzQ0FBcUIsQ0FBQywrQkFBK0I7YUFDdEU7WUFFRCx1QkFBdUIsRUFBRTtnQkFDdkIsbUJBQW1CLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO2dCQUN2QyxpQkFBaUIsRUFBRSxJQUFJO2dCQUN2QixRQUFRLEVBQUUsS0FBSztnQkFDZixPQUFPLEVBQUUsSUFBSTthQUNkO1lBQ0QsYUFBYSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUU7U0FDdEUsQ0FBQztRQWFBLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDOUMs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QVUsQ0FBQyxXQUFXO2dCQUN4QyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxJQUFJO2dCQUN4QixDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUNwQixJQUFJLENBQUMsK0JBQStCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZELE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0VBQWdFLFdBQVcsd0tBQXdLLENBQ3BQLENBQUM7WUFDSixDQUFDO1lBQ0QsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUMzQixnQkFBZ0IsRUFDaEIsSUFBSSxDQUFDLFlBQVksRUFDakIsSUFBSSxDQUFDLHFCQUFxQixDQUMzQixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFDRDs7T0FFRztJQUNLLGNBQWMsQ0FBQyxXQUFtQjtRQUN4QyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDeEIsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ2pELENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxXQUFXLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7O0FBN1dILGdEQThXQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENmbk91dHB1dCwgRHVyYXRpb24sIEZuLCBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgSUNlcnRpZmljYXRlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jZXJ0aWZpY2F0ZW1hbmFnZXJcIjtcbmltcG9ydCB7XG4gIEFkZEJlaGF2aW9yT3B0aW9ucyxcbiAgQWxsb3dlZE1ldGhvZHMsXG4gIEJlaGF2aW9yT3B0aW9ucyxcbiAgQ2FjaGVDb29raWVCZWhhdmlvcixcbiAgQ2FjaGVIZWFkZXJCZWhhdmlvcixcbiAgQ2FjaGVQb2xpY3ksXG4gIENhY2hlUG9saWN5UHJvcHMsXG4gIENhY2hlUXVlcnlTdHJpbmdCZWhhdmlvcixcbiAgQ2FjaGVkTWV0aG9kcyxcbiAgRnVuY3Rpb24gYXMgQ2xvdWRGcm9udEZ1bmN0aW9uLFxuICBEaXN0cmlidXRpb24sXG4gIEZ1bmN0aW9uQXNzb2NpYXRpb24sXG4gIEZ1bmN0aW9uQ29kZSxcbiAgRnVuY3Rpb25FdmVudFR5cGUsXG4gIEhlYWRlcnNGcmFtZU9wdGlvbixcbiAgSGVhZGVyc1JlZmVycmVyUG9saWN5LFxuICBIdHRwVmVyc2lvbixcbiAgSU9yaWdpbixcbiAgSU9yaWdpblJlcXVlc3RQb2xpY3ksXG4gIExhbWJkYUVkZ2VFdmVudFR5cGUsXG4gIE9yaWdpblByb3RvY29sUG9saWN5LFxuICBPcmlnaW5SZXF1ZXN0UG9saWN5LFxuICBSZXNwb25zZUhlYWRlcnNQb2xpY3ksXG4gIFJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzLFxuICBSZXNwb25zZVNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yLFxuICBTZWN1cml0eVBvbGljeVByb3RvY29sLFxuICBWaWV3ZXJQcm90b2NvbFBvbGljeSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCI7XG5pbXBvcnQge1xuICBIdHRwT3JpZ2luLFxuICBIdHRwT3JpZ2luUHJvcHMsXG4gIFMzQnVja2V0T3JpZ2luLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQtb3JpZ2luc1wiO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBTZXJ2aWNlUHJpbmNpcGFsIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IENvZGUsIFJ1bnRpbWUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgSUJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBOZXh0anNUeXBlIH0gZnJvbSBcIi4vY29tbW9uXCI7XG5pbXBvcnQgeyBPcHRpb25hbERpc3RyaWJ1dGlvblByb3BzIH0gZnJvbSBcIi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxEaXN0cmlidXRpb25Qcm9wc1wiO1xuaW1wb3J0IHsgT3B0aW9uYWxGdW5jdGlvblByb3BzIH0gZnJvbSBcIi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxGdW5jdGlvblByb3BzXCI7XG5pbXBvcnQgeyBPcHRpb25hbFMzT3JpZ2luQnVja2V0V2l0aE9BQ1Byb3BzIH0gZnJvbSBcIi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxTM09yaWdpbkJ1Y2tldFdpdGhPQUNQcm9wc1wiO1xuaW1wb3J0IHsgU2lnbkZuVXJsRnVuY3Rpb24gfSBmcm9tIFwiLi9sYW1iZGFzL3NpZ24tZm4tdXJsL3NpZ24tZm4tdXJsLWZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBQdWJsaWNEaXJFbnRyeSB9IGZyb20gXCIuL25leHRqcy1idWlsZC9uZXh0anMtYnVpbGRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNEaXN0cmlidXRpb25PdmVycmlkZXMge1xuICByZWFkb25seSBlZGdlRnVuY3Rpb25Qcm9wcz86IE9wdGlvbmFsRnVuY3Rpb25Qcm9wcztcbiAgcmVhZG9ubHkgZGlzdHJpYnV0aW9uUHJvcHM/OiBPcHRpb25hbERpc3RyaWJ1dGlvblByb3BzO1xuICByZWFkb25seSBpbWFnZUJlaGF2aW9yT3B0aW9ucz86IEFkZEJlaGF2aW9yT3B0aW9ucztcbiAgcmVhZG9ubHkgaW1hZ2VDYWNoZVBvbGljeVByb3BzPzogQ2FjaGVQb2xpY3lQcm9wcztcbiAgcmVhZG9ubHkgaW1hZ2VSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcz86IFJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzO1xuICByZWFkb25seSBkeW5hbWljQmVoYXZpb3JPcHRpb25zPzogQWRkQmVoYXZpb3JPcHRpb25zO1xuICByZWFkb25seSBkeW5hbWljQ2FjaGVQb2xpY3lQcm9wcz86IENhY2hlUG9saWN5UHJvcHM7XG4gIHJlYWRvbmx5IGR5bmFtaWNSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcz86IFJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzO1xuICByZWFkb25seSBkeW5hbWljSHR0cE9yaWdpblByb3BzPzogSHR0cE9yaWdpblByb3BzO1xuICByZWFkb25seSBzdGF0aWNCZWhhdmlvck9wdGlvbnM/OiBBZGRCZWhhdmlvck9wdGlvbnM7XG4gIHJlYWRvbmx5IHN0YXRpY1Jlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzPzogUmVzcG9uc2VIZWFkZXJzUG9saWN5UHJvcHM7XG4gIHJlYWRvbmx5IHMzQnVja2V0T3JpZ2luUHJvcHM/OiBPcHRpb25hbFMzT3JpZ2luQnVja2V0V2l0aE9BQ1Byb3BzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5leHRqc0Rpc3RyaWJ1dGlvblByb3BzIHtcbiAgLyoqXG4gICAqIEJ1Y2tldCBjb250YWluaW5nIHN0YXRpYyBhc3NldHMuXG4gICAqIE11c3QgYmUgcHJvdmlkZWQgaWYgeW91IHdhbnQgdG8gc2VydmUgc3RhdGljIGZpbGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgYXNzZXRzQnVja2V0OiBJQnVja2V0O1xuICByZWFkb25seSBiYXNlUGF0aD86IHN0cmluZztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGJ1dCBvbmx5IGFwcGxpY2FibGUgZm9yIGBOZXh0anNUeXBlLkdMT0JBTF9DT05UQUlORVJTYFxuICAgKi9cbiAgcmVhZG9ubHkgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGU7XG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbj86IERpc3RyaWJ1dGlvbjtcbiAgLyoqXG4gICAqIER5bmFtaWMgKE5leHQuanMgc2VydmVyKSBVUkwgdG8gYWRkIGJlaGF2aW9yIHRvIGRpc3RyaWJ1dGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZHluYW1pY1VybDogc3RyaW5nO1xuICAvKipcbiAgICogUmVxdWlyZWQgaWYgYE5leHRqc1R5cGUuR0xPQkFMX0ZVTkNUSU9OU2BcbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uQXJuPzogc3RyaW5nO1xuICByZWFkb25seSBuZXh0anNUeXBlOiBOZXh0anNUeXBlO1xuICAvKipcbiAgICogT3ZlcnJpZGUgcHJvcHMgZm9yIGV2ZXJ5IGNvbnN0cnVjdC5cbiAgICovXG4gIHJlYWRvbmx5IG92ZXJyaWRlcz86IE5leHRqc0Rpc3RyaWJ1dGlvbk92ZXJyaWRlcztcbiAgLyoqXG4gICAqIFBhdGggdG8gZGlyZWN0b3J5IG9mIE5leHQuanMgYXBwJ3MgcHVibGljIGRpcmVjdG9yeS4gVXNlZCB0byBhZGQgc3RhdGljXG4gICAqIGJlaGF2aW9ycyB0byBkaXN0cmlidXRpb24uXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNEaXJFbnRyaWVzOiBQdWJsaWNEaXJFbnRyeVtdO1xufVxuXG5leHBvcnQgY2xhc3MgTmV4dGpzRGlzdHJpYnV0aW9uIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgZGlzdHJpYnV0aW9uOiBEaXN0cmlidXRpb247XG5cbiAgcHJpdmF0ZSBwcm9wczogTmV4dGpzRGlzdHJpYnV0aW9uUHJvcHM7XG4gIC8qKlxuICAgKiBDb21tb24gc2VjdXJpdHkgaGVhZGVycyBhcHBsaWVkIGJ5IGRlZmF1bHQgdG8gYWxsIG9yaWdpbnNcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvdXNpbmctbWFuYWdlZC1yZXNwb25zZS1oZWFkZXJzLXBvbGljaWVzLmh0bWwjbWFuYWdlZC1yZXNwb25zZS1oZWFkZXJzLXBvbGljaWVzLXNlY3VyaXR5XG4gICAqL1xuICBwcml2YXRlIGNvbW1vblNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yOiBSZXNwb25zZVNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yID0ge1xuICAgIGNvbnRlbnRUeXBlT3B0aW9uczogeyBvdmVycmlkZTogZmFsc2UgfSxcbiAgICBmcmFtZU9wdGlvbnM6IHtcbiAgICAgIGZyYW1lT3B0aW9uOiBIZWFkZXJzRnJhbWVPcHRpb24uU0FNRU9SSUdJTixcbiAgICAgIG92ZXJyaWRlOiBmYWxzZSxcbiAgICB9LFxuICAgIHJlZmVycmVyUG9saWN5OiB7XG4gICAgICBvdmVycmlkZTogZmFsc2UsXG4gICAgICByZWZlcnJlclBvbGljeTogSGVhZGVyc1JlZmVycmVyUG9saWN5LlNUUklDVF9PUklHSU5fV0hFTl9DUk9TU19PUklHSU4sXG4gICAgfSxcblxuICAgIHN0cmljdFRyYW5zcG9ydFNlY3VyaXR5OiB7XG4gICAgICBhY2Nlc3NDb250cm9sTWF4QWdlOiBEdXJhdGlvbi5kYXlzKDM2NSksXG4gICAgICBpbmNsdWRlU3ViZG9tYWluczogdHJ1ZSxcbiAgICAgIG92ZXJyaWRlOiBmYWxzZSxcbiAgICAgIHByZWxvYWQ6IHRydWUsXG4gICAgfSxcbiAgICB4c3NQcm90ZWN0aW9uOiB7IG92ZXJyaWRlOiBmYWxzZSwgcHJvdGVjdGlvbjogdHJ1ZSwgbW9kZUJsb2NrOiB0cnVlIH0sXG4gIH07XG4gIHByaXZhdGUgc3RhdGljT3JpZ2luOiBJT3JpZ2luO1xuICBwcml2YXRlIGR5bmFtaWNPcmlnaW46IElPcmlnaW47XG4gIHByaXZhdGUgZHluYW1pY09yaWdpblJlc3BvbnNlUG9saWN5OiBJT3JpZ2luUmVxdWVzdFBvbGljeTtcbiAgcHJpdmF0ZSBkeW5hbWljQ2xvdWRGcm9udEZ1bmN0aW9uQXNzb2NpYXRpb25zOiBGdW5jdGlvbkFzc29jaWF0aW9uW107XG4gIHByaXZhdGUgZWRnZUxhbWJkYXM/OiBBZGRCZWhhdmlvck9wdGlvbnNbXCJlZGdlTGFtYmRhc1wiXTtcbiAgcHJpdmF0ZSBpc0Z1bmN0aW9uQ29tcHV0ZTogYm9vbGVhbjtcbiAgcHJpdmF0ZSBzdGF0aWNCZWhhdmlvck9wdGlvbnM6IEJlaGF2aW9yT3B0aW9ucztcbiAgcHJpdmF0ZSBkeW5hbWljQmVoYXZpb3JPcHRpb25zOiBCZWhhdmlvck9wdGlvbnM7XG4gIHByaXZhdGUgaW1hZ2VCZWhhdmlvck9wdGlvbnM6IEJlaGF2aW9yT3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzRGlzdHJpYnV0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLnN0YXRpY09yaWdpbiA9IHRoaXMuY3JlYXRlU3RhdGljT3JpZ2luKCk7XG4gICAgdGhpcy5pc0Z1bmN0aW9uQ29tcHV0ZSA9IHByb3BzLm5leHRqc1R5cGUgPT09IE5leHRqc1R5cGUuR0xPQkFMX0ZVTkNUSU9OUztcbiAgICB0aGlzLmR5bmFtaWNPcmlnaW4gPSB0aGlzLmNyZWF0ZUR5bmFtaWNPcmlnaW4oKTtcbiAgICB0aGlzLmR5bmFtaWNPcmlnaW5SZXNwb25zZVBvbGljeSA9IHRoaXMuY3JlYXRlRHluYW1pY09yaWdpblJlcXVlc3RQb2xpY3koKTtcbiAgICB0aGlzLmR5bmFtaWNDbG91ZEZyb250RnVuY3Rpb25Bc3NvY2lhdGlvbnMgPVxuICAgICAgdGhpcy5jcmVhdGVEeW5hbWljQ2xvdWRGcm9udEZ1bmN0aW9uQXNzb2NpYXRpb25zKCk7XG4gICAgaWYgKHRoaXMuaXNGdW5jdGlvbkNvbXB1dGUpIHtcbiAgICAgIHRoaXMuZWRnZUxhbWJkYXMgPSB0aGlzLmNyZWF0ZUVkZ2VMYW1iZGFzKCk7XG4gICAgfVxuICAgIHRoaXMuc3RhdGljQmVoYXZpb3JPcHRpb25zID0gdGhpcy5jcmVhdGVTdGF0aWNCZWhhdmlvck9wdGlvbnMoKTtcbiAgICB0aGlzLmR5bmFtaWNCZWhhdmlvck9wdGlvbnMgPSB0aGlzLmNyZWF0ZUR5bmFtaWNCZWhhdmlvck9wdGlvbnMoKTtcbiAgICB0aGlzLmltYWdlQmVoYXZpb3JPcHRpb25zID0gdGhpcy5jcmVhdGVJbWFnZUJlaGF2aW9yT3B0aW9ucygpO1xuICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gdGhpcy5nZXREaXN0cmlidXRpb24oKTtcbiAgICB0aGlzLmFkZFN0YXRpY0JlaGF2aW9ycygpO1xuICAgIHRoaXMuYWRkRHluYW1pY0JlaGF2aW9ycygpO1xuICAgIGlmICh0aGlzLmlzRnVuY3Rpb25Db21wdXRlKSB7XG4gICAgICAvLyB0aGlzLmFkZExhbWJkYU9hYygpOyAvLyBUT0RPOiB3YWl0IGZvciBQT1NUIGJvZHkgZW5jcnlwdGlvbiBmZWF0dXJlIGZvciBMYW1iZGEgT0FDXG4gICAgfVxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJEaXN0cmlidXRpb25Eb21haW5OYW1lXCIsIHtcbiAgICAgIHZhbHVlOiB0aGlzLmRpc3RyaWJ1dGlvbi5kb21haW5OYW1lLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTdGF0aWNPcmlnaW4oKTogSU9yaWdpbiB7XG4gICAgY29uc3QgczNPcmlnaW4gPSBTM0J1Y2tldE9yaWdpbi53aXRoT3JpZ2luQWNjZXNzQ29udHJvbChcbiAgICAgIHRoaXMucHJvcHMuYXNzZXRzQnVja2V0LFxuICAgICAgdGhpcy5wcm9wcy5vdmVycmlkZXM/LnMzQnVja2V0T3JpZ2luUHJvcHMsXG4gICAgKTtcbiAgICByZXR1cm4gczNPcmlnaW47XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVEeW5hbWljT3JpZ2luKCk6IEh0dHBPcmlnaW4ge1xuICAgIGxldCBwcm90b2NvbFBvbGljeTogT3JpZ2luUHJvdG9jb2xQb2xpY3k7XG4gICAgaWYgKHRoaXMuaXNGdW5jdGlvbkNvbXB1dGUpIHtcbiAgICAgIHByb3RvY29sUG9saWN5ID0gT3JpZ2luUHJvdG9jb2xQb2xpY3kuSFRUUFNfT05MWTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvdG9jb2xQb2xpY3kgPSB0aGlzLnByb3BzLmNlcnRpZmljYXRlXG4gICAgICAgID8gT3JpZ2luUHJvdG9jb2xQb2xpY3kuSFRUUFNfT05MWVxuICAgICAgICA6IE9yaWdpblByb3RvY29sUG9saWN5LkhUVFBfT05MWTtcbiAgICB9XG4gICAgLy8gV0FJVElORyBGT1IgQ0xPVURGUk9OVCBGRUFUVVJFOiBDbG91ZEZyb250IExhbWJkYSBGdW5jdGlvbiBVUkwgT0FDXG4gICAgLy8gZG9lc24ndCBzdXBwb3J0IFBPU1Qgd2l0aCBib2R5IHNpbmNlIENsb3VkRnJvbnQgZG9lc24ndCBpbmNsdWRlIHNoYTI1NlxuICAgIC8vIGhhc2ggb2YgYm9keS4gc2VlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvcHJpdmF0ZS1jb250ZW50LXJlc3RyaWN0aW5nLWFjY2Vzcy10by1sYW1iZGEuaHRtbFxuICAgIC8vIFdlIGNvdWxkIG1vbmtleSBwYXRjaCBgZmV0Y2hgIHRvIGluY2x1ZGUgc2hhMjU2IGluIHJlcXVlc3QgZm9yIHNlcnZlclxuICAgIC8vIGFjdGlvbnMsIGJ1dCBiZXR0ZXIgc29sdXRpb24gaXMgZm9yIGNsb3VkZnJvbnQgdG8gc3VwcG9ydCBpdFxuICAgIC8vXG4gICAgLy8gVE9ETzogdXNlIEwyIGNvbnN0cnVjdCB3aGVuIHJlbGVhc2VkOiBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzLzMxNjI5XG4gICAgLyoqXG4gICAgICogR2l2ZW4gc3RhY2sgaWQ6IFwiYXJuOmF3czpjbG91ZGZvcm1hdGlvbjp1cy1lYXN0LTE6OTA1NDE4MzU4OTAzOnN0YWNrL2xoLXN0aWNrYi1pZHAvNGJmNzRiZTAtZTg4MC0xMWVlLWFlYTktMGFmZmM2MTg1YjI1XCIsXG4gICAgICogcmV0dXJucyBcIjRiZjc0YmUwXCJcbiAgICAgKi9cbiAgICAvLyBjb25zdCB1bmlxdWVTdGFja0lkUGFydCA9IEZuLnNlbGVjdChcbiAgICAvLyAgIDAsXG4gICAgLy8gICBGbi5zcGxpdChcIi1cIiwgRm4uc2VsZWN0KDIsIEZuLnNwbGl0KFwiL1wiLCBgJHtBd3MuU1RBQ0tfSUR9YCkpKSxcbiAgICAvLyApO1xuICAgIC8vIGNvbnN0IGxhbWJkYU9hYyA9IG5ldyBDZm5PcmlnaW5BY2Nlc3NDb250cm9sKHRoaXMsIFwiT0FDXCIsIHtcbiAgICAvLyAgIG9yaWdpbkFjY2Vzc0NvbnRyb2xDb25maWc6IHtcbiAgICAvLyAgICAgbmFtZTogYE9BQy1MYW1iZGEtJHt1bmlxdWVTdGFja0lkUGFydH1gLFxuICAgIC8vICAgICBvcmlnaW5BY2Nlc3NDb250cm9sT3JpZ2luVHlwZTogXCJsYW1iZGFcIixcbiAgICAvLyAgICAgc2lnbmluZ0JlaGF2aW9yOiBcImFsd2F5c1wiLFxuICAgIC8vICAgICBzaWduaW5nUHJvdG9jb2w6IFwic2lndjRcIixcbiAgICAvLyAgIH0sXG4gICAgLy8gfSk7XG4gICAgLy8gY29uc3QgY2ZuRGlzdHJpYnV0aW9uID0gdGhpcy5kaXN0cmlidXRpb24ubm9kZVxuICAgIC8vICAgLmRlZmF1bHRDaGlsZCBhcyBDZm5EaXN0cmlidXRpb247XG4gICAgLy8gY2ZuRGlzdHJpYnV0aW9uLmFkZFByb3BlcnR5T3ZlcnJpZGUoXG4gICAgLy8gICBcIkRpc3RyaWJ1dGlvbkNvbmZpZy5PcmlnaW5zLjAuT3JpZ2luQWNjZXNzQ29udHJvbElkXCIsXG4gICAgLy8gICBsYW1iZGFPYWMuZ2V0QXR0KFwiSWRcIiksXG4gICAgLy8gKTtcbiAgICByZXR1cm4gbmV3IEh0dHBPcmlnaW4oRm4ucGFyc2VEb21haW5OYW1lKHRoaXMucHJvcHMuZHluYW1pY1VybCksIHtcbiAgICAgIHByb3RvY29sUG9saWN5LFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmR5bmFtaWNIdHRwT3JpZ2luUHJvcHMsXG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIExhbWJkYSBGdW5jdGlvbiBVUkxzIFwiZXhwZWN0IHRoZSBgSG9zdGAgaGVhZGVyIHRvIGNvbnRhaW4gdGhlIG9yaWdpbiBkb21haW5cbiAgICogbmFtZSwgbm90IHRoZSBkb21haW4gbmFtZSBvZiB0aGUgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXCJcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvdXNpbmctbWFuYWdlZC1vcmlnaW4tcmVxdWVzdC1wb2xpY2llcy5odG1sI21hbmFnZWQtb3JpZ2luLXJlcXVlc3QtcG9saWN5LWFsbC12aWV3ZXItZXhjZXB0LWhvc3QtaGVhZGVyXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUR5bmFtaWNPcmlnaW5SZXF1ZXN0UG9saWN5KCk6IElPcmlnaW5SZXF1ZXN0UG9saWN5IHtcbiAgICByZXR1cm4gdGhpcy5pc0Z1bmN0aW9uQ29tcHV0ZVxuICAgICAgPyBPcmlnaW5SZXF1ZXN0UG9saWN5LkFMTF9WSUVXRVJfRVhDRVBUX0hPU1RfSEVBREVSXG4gICAgICA6IE9yaWdpblJlcXVlc3RQb2xpY3kuQUxMX1ZJRVdFUjtcbiAgfVxuICAvKipcbiAgICogRW5zdXJlcyBOZXh0LmpzIGByZXF1ZXN0LnVybGAgd2lsbCBiZSBjb3JyZWN0IGRvbWFpbiBpbnN0ZWFkIG9mIFVSTCBvZlxuICAgKiBjb21wdXRlIG9wdGlvbiAoQXBwIFJ1bm5lciwgRmFyZ2F0ZSwgb3IgTGFtYmRhKVxuICAgKiBAc2VlIGh0dHBzOi8vb3Blbi1uZXh0LmpzLm9yZy9hZHZhbmNlZC93b3JrYXJvdW5kI3dvcmthcm91bmQtc2V0LXgtZm9yd2FyZGVkLWhvc3QtaGVhZGVyLWF3cy1zcGVjaWZpY1xuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEeW5hbWljQ2xvdWRGcm9udEZ1bmN0aW9uQXNzb2NpYXRpb25zKCk6IEZ1bmN0aW9uQXNzb2NpYXRpb25bXSB7XG4gICAgY29uc3QgYXNzb2NpYXRpb25zOiBGdW5jdGlvbkFzc29jaWF0aW9uW10gPSBbXTtcbiAgICBpZiAodGhpcy5pc0Z1bmN0aW9uQ29tcHV0ZSkge1xuICAgICAgY29uc3QgY2xvdWRGcm9udEZuID0gbmV3IENsb3VkRnJvbnRGdW5jdGlvbih0aGlzLCBcIkNsb3VkRnJvbnRGblwiLCB7XG4gICAgICAgIGNvZGU6IEZ1bmN0aW9uQ29kZS5mcm9tSW5saW5lKGBcbiAgICAgICAgICBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgcmVxdWVzdCA9IGV2ZW50LnJlcXVlc3Q7XG4gICAgICAgICAgICByZXF1ZXN0LmhlYWRlcnNbXCJ4LWZvcndhcmRlZC1ob3N0XCJdID0gcmVxdWVzdC5oZWFkZXJzLmhvc3Q7XG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYCksXG4gICAgICB9KTtcbiAgICAgIGFzc29jaWF0aW9ucy5wdXNoKHtcbiAgICAgICAgZXZlbnRUeXBlOiBGdW5jdGlvbkV2ZW50VHlwZS5WSUVXRVJfUkVRVUVTVCxcbiAgICAgICAgZnVuY3Rpb246IGNsb3VkRnJvbnRGbixcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYXNzb2NpYXRpb25zO1xuICB9XG4gIC8qKlxuICAgKiBSZXF1aXJlZCB0byBzaWduIHJlcXVlc3RzIHNvIHRoYXQgd2UgY2FuIHVzZSBJQU1fQVVUSCBmb3IgTGFtYmRhIEZ1bmN0aW9uIFVSTFxuICAgKiB0byBwcmV2ZW50IHB1YmxpYyBhY2Nlc3MuIE9uY2UgQ2xvdWRGcm9udCBMYW1iZGEgT0FDIGlzIHJlbGVhc2VkLCB3ZSBjYW5cbiAgICogdXNlIGluZnJhIGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgaW5zdGVhZCBvZiBjdXN0b20gY29kZS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRWRnZUxhbWJkYXMoKTogQWRkQmVoYXZpb3JPcHRpb25zW1wiZWRnZUxhbWJkYXNcIl0ge1xuICAgIGlmICghdGhpcy5wcm9wcy5mdW5jdGlvbkFybikgdGhyb3cgbmV3IEVycm9yKFwiZnVuY3Rpb25Bcm4gaXMgcmVxdWlyZWRcIik7XG4gICAgY29uc3QgZWRnZUZuID0gbmV3IFNpZ25GblVybEZ1bmN0aW9uKHRoaXMsIFwiU2lnbkZuVXJsXCIsIHtcbiAgICAgIGN1cnJlbnRWZXJzaW9uT3B0aW9uczoge1xuICAgICAgICByZXRyeUF0dGVtcHRzOiAwLCAvLyBmYWlsIGZhc3Qgd2hlbiB0cnlpbmcgdG8gZGVsZXRlIGIvYyByZXBsaWNhdGVkIGZ1bmN0aW9ucyB0YWtlIGxvbmcgdGltZSB0byBkZWxldGVcbiAgICAgIH0sXG4gICAgICBpbml0aWFsUG9saWN5OiBbXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcImxhbWJkYTpJbnZva2VGdW5jdGlvblVybFwiXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFt0aGlzLnByb3BzLmZ1bmN0aW9uQXJuXSxcbiAgICAgICAgfSksXG4gICAgICBdLFxuICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZXIoKSB7fVwiKSxcbiAgICAgIGhhbmRsZXI6IFwiaGFuZGxlclwiLFxuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfTEFURVNULFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmVkZ2VGdW5jdGlvblByb3BzLFxuICAgIH0pO1xuICAgIGVkZ2VGbi5jdXJyZW50VmVyc2lvbi5ncmFudEludm9rZShcbiAgICAgIG5ldyBTZXJ2aWNlUHJpbmNpcGFsKFwiZWRnZWxhbWJkYS5hbWF6b25hd3MuY29tXCIpLFxuICAgICk7XG4gICAgZWRnZUZuLmN1cnJlbnRWZXJzaW9uLmdyYW50SW52b2tlKFxuICAgICAgbmV3IFNlcnZpY2VQcmluY2lwYWwoXCJsYW1iZGEuYW1hem9uYXdzLmNvbVwiKSxcbiAgICApO1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIGV2ZW50VHlwZTogTGFtYmRhRWRnZUV2ZW50VHlwZS5PUklHSU5fUkVRVUVTVCxcbiAgICAgICAgZnVuY3Rpb25WZXJzaW9uOiBlZGdlRm4uY3VycmVudFZlcnNpb24sXG4gICAgICAgIGluY2x1ZGVCb2R5OiB0cnVlLFxuICAgICAgfSxcbiAgICBdO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlU3RhdGljQmVoYXZpb3JPcHRpb25zKCk6IEJlaGF2aW9yT3B0aW9ucyB7XG4gICAgY29uc3Qgc3RhdGljQmVoYXZpb3JPcHRpb25zID0gdGhpcy5wcm9wcy5vdmVycmlkZXM/LnN0YXRpY0JlaGF2aW9yT3B0aW9ucztcbiAgICBjb25zdCByZXNwb25zZUhlYWRlcnNQb2xpY3kgPVxuICAgICAgc3RhdGljQmVoYXZpb3JPcHRpb25zPy5yZXNwb25zZUhlYWRlcnNQb2xpY3kgPz9cbiAgICAgIG5ldyBSZXNwb25zZUhlYWRlcnNQb2xpY3kodGhpcywgXCJTdGF0aWNSZXNwb25zZUhlYWRlcnNQb2xpY3lcIiwge1xuICAgICAgICBzZWN1cml0eUhlYWRlcnNCZWhhdmlvcjogdGhpcy5jb21tb25TZWN1cml0eUhlYWRlcnNCZWhhdmlvcixcbiAgICAgICAgY29tbWVudDogYE5leHRqcyBTdGF0aWMgUmVzcG9uc2UgSGVhZGVycyBQb2xpY3kgZm9yICR7U3RhY2sub2YodGhpcykuc3RhY2tOYW1lfWAsXG4gICAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5zdGF0aWNSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcyxcbiAgICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIGNhY2hlZE1ldGhvZHM6IENhY2hlZE1ldGhvZHMuQ0FDSEVfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIGNhY2hlUG9saWN5OiBDYWNoZVBvbGljeS5DQUNISU5HX09QVElNSVpFRCxcbiAgICAgIG9yaWdpbjogdGhpcy5zdGF0aWNPcmlnaW4sXG4gICAgICByZXNwb25zZUhlYWRlcnNQb2xpY3ksXG4gICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICAuLi5zdGF0aWNCZWhhdmlvck9wdGlvbnMsXG4gICAgfTtcbiAgfVxuICBwcml2YXRlIGNyZWF0ZUR5bmFtaWNCZWhhdmlvck9wdGlvbnMoKTogQmVoYXZpb3JPcHRpb25zIHtcbiAgICBjb25zdCBkeW5hbWljQmVoYXZpb3JPcHRpb25zID0gdGhpcy5wcm9wcy5vdmVycmlkZXM/LmR5bmFtaWNCZWhhdmlvck9wdGlvbnM7XG4gICAgLy8gY3JlYXRlIGRlZmF1bHQgY2FjaGUgcG9saWN5IGlmIG5vdCBwcm92aWRlZFxuICAgIGNvbnN0IGNhY2hlUG9saWN5ID1cbiAgICAgIGR5bmFtaWNCZWhhdmlvck9wdGlvbnM/LmNhY2hlUG9saWN5ID8/XG4gICAgICBuZXcgQ2FjaGVQb2xpY3kodGhpcywgXCJEeW5hbWljQ2FjaGVQb2xpY3lcIiwge1xuICAgICAgICBxdWVyeVN0cmluZ0JlaGF2aW9yOiBDYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IuYWxsKCksXG4gICAgICAgIGhlYWRlckJlaGF2aW9yOiBDYWNoZUhlYWRlckJlaGF2aW9yLmFsbG93TGlzdChcbiAgICAgICAgICBcImFjY2VwdFwiLFxuICAgICAgICAgIFwicnNjXCIsXG4gICAgICAgICAgXCJuZXh0LXJvdXRlci1wcmVmZXRjaFwiLFxuICAgICAgICAgIFwibmV4dC1yb3V0ZXItc3RhdGUtdHJlZVwiLFxuICAgICAgICAgIFwibmV4dC11cmxcIixcbiAgICAgICAgICBcIngtcHJlcmVuZGVyLXJldmFsaWRhdGVcIixcbiAgICAgICAgKSxcbiAgICAgICAgY29va2llQmVoYXZpb3I6IENhY2hlQ29va2llQmVoYXZpb3IuYWxsKCksXG4gICAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nQnJvdGxpOiB0cnVlLFxuICAgICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0d6aXA6IHRydWUsXG4gICAgICAgIGNvbW1lbnQ6IGBOZXh0anMgRHluYW1pYyBDYWNoZSBQb2xpY3kgZm9yICR7U3RhY2sub2YodGhpcykuc3RhY2tOYW1lfWAsXG4gICAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5keW5hbWljQ2FjaGVQb2xpY3lQcm9wcyxcbiAgICAgIH0pO1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVyc1BvbGljeSA9XG4gICAgICBkeW5hbWljQmVoYXZpb3JPcHRpb25zPy5yZXNwb25zZUhlYWRlcnNQb2xpY3kgPz9cbiAgICAgIG5ldyBSZXNwb25zZUhlYWRlcnNQb2xpY3kodGhpcywgXCJEeW5hbWljUmVzcG9uc2VIZWFkZXJzUG9saWN5XCIsIHtcbiAgICAgICAgc2VjdXJpdHlIZWFkZXJzQmVoYXZpb3I6IHRoaXMuY29tbW9uU2VjdXJpdHlIZWFkZXJzQmVoYXZpb3IsXG4gICAgICAgIGNvbW1lbnQ6IGBOZXh0anMgRHluYW1pYyBSZXNwb25zZSBIZWFkZXJzIFBvbGljeSBmb3IgJHtTdGFjay5vZih0aGlzKS5zdGFja05hbWV9YCxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmR5bmFtaWNCZWhhdmlvck9wdGlvbnM/LnJlc3BvbnNlSGVhZGVyc1BvbGljeSxcbiAgICAgIH0pO1xuICAgIGNvbnN0IGJlaGF2aW9yT3B0aW9uczogQmVoYXZpb3JPcHRpb25zID0ge1xuICAgICAgYWxsb3dlZE1ldGhvZHM6IEFsbG93ZWRNZXRob2RzLkFMTE9XX0FMTCxcbiAgICAgIGNhY2hlUG9saWN5LFxuICAgICAgZWRnZUxhbWJkYXM6IHRoaXMuZWRnZUxhbWJkYXMsXG4gICAgICBmdW5jdGlvbkFzc29jaWF0aW9uczogdGhpcy5keW5hbWljQ2xvdWRGcm9udEZ1bmN0aW9uQXNzb2NpYXRpb25zLFxuICAgICAgb3JpZ2luOiB0aGlzLmR5bmFtaWNPcmlnaW4sXG4gICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiB0aGlzLmR5bmFtaWNPcmlnaW5SZXNwb25zZVBvbGljeSxcbiAgICAgIHJlc3BvbnNlSGVhZGVyc1BvbGljeSxcbiAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgIC4uLmR5bmFtaWNCZWhhdmlvck9wdGlvbnMsXG4gICAgfTtcbiAgICByZXR1cm4gYmVoYXZpb3JPcHRpb25zO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlSW1hZ2VCZWhhdmlvck9wdGlvbnMoKTogQmVoYXZpb3JPcHRpb25zIHtcbiAgICBjb25zdCBpbWFnZUJlaGF2aW9yT3B0aW9ucyA9IHRoaXMucHJvcHMub3ZlcnJpZGVzPy5pbWFnZUJlaGF2aW9yT3B0aW9ucztcbiAgICAvLyBhZGQgZGVmYXVsdCBjYWNoZSBwb2xpY3kgaWYgbm90IHByb3ZpZGVkXG4gICAgY29uc3QgY2FjaGVQb2xpY3kgPVxuICAgICAgaW1hZ2VCZWhhdmlvck9wdGlvbnM/LmNhY2hlUG9saWN5ID8/XG4gICAgICBuZXcgQ2FjaGVQb2xpY3kodGhpcywgXCJJbWFnZUNhY2hlUG9saWN5XCIsIHtcbiAgICAgICAgLy8gU0VDVVJJVFkgTk9URTogYnkgZGVmYXVsdCB3ZSBkb24ndCBpbmNsdWRlIGNvb2tpZXMgaW4gY2FjaGUgZm9yXG4gICAgICAgIC8vIGltYWdlcyBiL2MgaXQgc2lnbmlmaWNhbnRseSBpbXByb3ZlcyBpbWFnZSBwZXJmIGZvciBtb3N0IHNpdGVzIEJVVFxuICAgICAgICAvLyBpZiB5b3UgaGF2ZSBwcml2YXRlIGltYWdlcyBsb2NrZWQgYmVoaW5kIGF1dGggaW1wbGVtZW50ZWQgd2l0aCBjb29raWVzXG4gICAgICAgIC8vIHlvdSBuZWVkIHRvIG92ZXJyaWRlIHRoaXMuXG4gICAgICAgIHF1ZXJ5U3RyaW5nQmVoYXZpb3I6IENhY2hlUXVlcnlTdHJpbmdCZWhhdmlvci5hbGwoKSxcbiAgICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KFwiYWNjZXB0XCIpLFxuICAgICAgICBjb29raWVCZWhhdmlvcjogQ2FjaGVDb29raWVCZWhhdmlvci5ub25lKCksXG4gICAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nQnJvdGxpOiB0cnVlLFxuICAgICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0d6aXA6IHRydWUsXG4gICAgICAgIGNvbW1lbnQ6IGBOZXh0anMgSW1hZ2UgQ2FjaGUgUG9saWN5IGZvciAke1N0YWNrLm9mKHRoaXMpLnN0YWNrTmFtZX1gLFxuICAgICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uaW1hZ2VDYWNoZVBvbGljeVByb3BzLFxuICAgICAgfSk7XG4gICAgLy8gYWRkIGRlZmF1bHQgcmVzcG9uc2UgaGVhZGVycyBwb2xpY3kgaWYgbm90IHByb3ZpZGVkXG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzUG9saWN5ID1cbiAgICAgIGltYWdlQmVoYXZpb3JPcHRpb25zPy5yZXNwb25zZUhlYWRlcnNQb2xpY3kgPz9cbiAgICAgIG5ldyBSZXNwb25zZUhlYWRlcnNQb2xpY3kodGhpcywgXCJJbWFnZVJlc3BvbnNlSGVhZGVyc1BvbGljeVwiLCB7XG4gICAgICAgIHNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yOiB0aGlzLmNvbW1vblNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yLFxuICAgICAgICBjb21tZW50OiBgTmV4dGpzIEltYWdlIFJlc3BvbnNlIEhlYWRlcnMgUG9saWN5IGZvciAke1N0YWNrLm9mKHRoaXMpLnN0YWNrTmFtZX1gLFxuICAgICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uaW1hZ2VSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcyxcbiAgICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIGNhY2hlZE1ldGhvZHM6IENhY2hlZE1ldGhvZHMuQ0FDSEVfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIGVkZ2VMYW1iZGFzOiB0aGlzLmVkZ2VMYW1iZGFzLFxuICAgICAgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IHRoaXMuZHluYW1pY0Nsb3VkRnJvbnRGdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgIG9yaWdpbjogdGhpcy5keW5hbWljT3JpZ2luLFxuICAgICAgb3JpZ2luUmVxdWVzdFBvbGljeTogdGhpcy5keW5hbWljT3JpZ2luUmVzcG9uc2VQb2xpY3ksXG4gICAgICBjYWNoZVBvbGljeSxcbiAgICAgIHJlc3BvbnNlSGVhZGVyc1BvbGljeSxcbiAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgIC4uLmltYWdlQmVoYXZpb3JPcHRpb25zLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIENyZWF0ZXMgb3IgdXNlcyB1c2VyIHNwZWNpZmllZCBDbG91ZEZyb250IERpc3RyaWJ1dGlvblxuICAgKi9cbiAgcHJpdmF0ZSBnZXREaXN0cmlidXRpb24oKTogRGlzdHJpYnV0aW9uIHtcbiAgICBsZXQgZGlzdHJpYnV0aW9uOiBEaXN0cmlidXRpb247XG4gICAgaWYgKHRoaXMucHJvcHMuZGlzdHJpYnV0aW9uKSB7XG4gICAgICBkaXN0cmlidXRpb24gPSB0aGlzLnByb3BzLmRpc3RyaWJ1dGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlzdHJpYnV0aW9uID0gbmV3IERpc3RyaWJ1dGlvbih0aGlzLCBcIkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIG1pbmltdW1Qcm90b2NvbFZlcnNpb246IFNlY3VyaXR5UG9saWN5UHJvdG9jb2wuVExTX1YxXzJfMjAyMSxcbiAgICAgICAgZGVmYXVsdEJlaGF2aW9yOiB0aGlzLmR5bmFtaWNCZWhhdmlvck9wdGlvbnMsXG4gICAgICAgIC8vIGJlc3QgdG8gdXNlIEhUVFAgMiBhbmQgMyBmb3IgY29tcGF0YWJpbGl0eSAoSFRUUCAyKSBhbmQgcGVyZm9ybWFuY2UgKEhUVFAzKVxuICAgICAgICAvLyBDbG91ZEZyb250IHdpbGwgY2hvb3NlIGJlc3Qgb3B0aW9uIGZvciBjbGllbnRcbiAgICAgICAgaHR0cFZlcnNpb246IEh0dHBWZXJzaW9uLkhUVFAyX0FORF8zLFxuICAgICAgICBjb21tZW50OiBgY2RrLW5leHRqcyBEaXN0cmlidXRpb24gZm9yICR7U3RhY2sub2YodGhpcykuc3RhY2tOYW1lfWAsXG4gICAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5kaXN0cmlidXRpb25Qcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZGlzdHJpYnV0aW9uO1xuICB9XG4gIHByaXZhdGUgYWRkRHluYW1pY0JlaGF2aW9ycygpIHtcbiAgICAvLyBJbWFnZSBCZWhhdmlvclxuICAgIHRoaXMuZGlzdHJpYnV0aW9uLmFkZEJlaGF2aW9yKFxuICAgICAgdGhpcy5nZXRQYXRoUGF0dGVybihcIl9uZXh0L2ltYWdlKlwiKSxcbiAgICAgIHRoaXMuaW1hZ2VCZWhhdmlvck9wdGlvbnMub3JpZ2luLFxuICAgICAgdGhpcy5pbWFnZUJlaGF2aW9yT3B0aW9ucyxcbiAgICApO1xuICAgIC8vIFJvb3QgUGF0aCBCZWhhdmlvcnNcbiAgICBpZiAodGhpcy5wcm9wcy5iYXNlUGF0aCkge1xuICAgICAgLy8gYmVjYXVzZSB3ZSBhbHJlYWR5IGhhdmUgYSBiYXNlUGF0aCB3ZSBkb24ndCB1c2UgLyBpbnN0ZWFkIHdlIHVzZSAvYmFzZS1wYXRoXG4gICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihcbiAgICAgICAgdGhpcy5wcm9wcy5iYXNlUGF0aCxcbiAgICAgICAgdGhpcy5keW5hbWljQmVoYXZpb3JPcHRpb25zLm9yaWdpbixcbiAgICAgICAgdGhpcy5keW5hbWljQmVoYXZpb3JPcHRpb25zLFxuICAgICAgKTtcbiAgICAgIC8vIHdoZW4gYmFzZVBhdGggaXMgc2V0LCB3ZSBlbXVsYXRlIHRoZSBcImRlZmF1bHQgYmVoYXZpb3JcIiAoKikgZm9yIHRoZSBzaXRlIGFzIGAvYmFzZS1wYXRoLypgXG4gICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihcbiAgICAgICAgdGhpcy5nZXRQYXRoUGF0dGVybihcIipcIiksXG4gICAgICAgIHRoaXMuZHluYW1pY0JlaGF2aW9yT3B0aW9ucy5vcmlnaW4sXG4gICAgICAgIHRoaXMuZHluYW1pY0JlaGF2aW9yT3B0aW9ucyxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIG5vIGJhc2UgcGF0aCwgdGhlbiBkZWZhdWx0IGJlaGF2aW9yIHdpbGwgaGFuZGxlIGFsbCBvdGhlciBwYXRoc1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGFkZFN0YXRpY0JlaGF2aW9ycygpIHtcbiAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihcbiAgICAgIFwiX25leHQvc3RhdGljKlwiLFxuICAgICAgdGhpcy5zdGF0aWNPcmlnaW4sXG4gICAgICB0aGlzLnN0YXRpY0JlaGF2aW9yT3B0aW9ucyxcbiAgICApO1xuICAgIC8vIDIyID0gMjUgKG1heCkgLSAxIChfbmV4dC9pbWFnZSkgLSAxIChfbmV4dC9zdGF0aWMpIC0gMSAoKilcbiAgICBpZiAodGhpcy5wcm9wcy5wdWJsaWNEaXJFbnRyaWVzLmxlbmd0aCA+PSAyMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVG9vIG1hbnkgcHVibGljLyBmaWxlcyBpbiBOZXh0LmpzIGJ1aWxkLiBDbG91ZEZyb250IGxpbWl0cyBEaXN0cmlidXRpb25zIHRvIDI1IENhY2hlIEJlaGF2aW9ycy4gU2VlIGRvY3VtZW50ZWQgbGltaXQgaGVyZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkRnJvbnQvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Nsb3VkZnJvbnQtbGltaXRzLmh0bWwjbGltaXRzLXdlYi1kaXN0cmlidXRpb25zLiBUcnkgaW5jbHVkaW5nIGFsbCBwdWJsaWMgZmlsZXMgaW50byAxIHRvcCBsZXZlbCBkaXJlY3RvcnkgKGkuZS4gc3RhdGljLyopLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHB1YmxpY0ZpbGUgb2YgdGhpcy5wcm9wcy5wdWJsaWNEaXJFbnRyaWVzKSB7XG4gICAgICBjb25zdCBwYXRoUGF0dGVybiA9IHB1YmxpY0ZpbGUuaXNEaXJlY3RvcnlcbiAgICAgICAgPyBgJHtwdWJsaWNGaWxlLm5hbWV9LypgXG4gICAgICAgIDogcHVibGljRmlsZS5uYW1lO1xuICAgICAgaWYgKCEvXlthLXpBLVowLTlfXFwtLiokL35cIidAOis/Jl0rJC8udGVzdChwYXRoUGF0dGVybikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBJbnZhbGlkIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIENhY2hlIEJlaGF2aW9yIFBhdGggUGF0dGVybjogJHtwYXRoUGF0dGVybn0uIFBsZWFzZSBzZWUgZG9jdW1lbnRhdGlvbiBoZXJlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZGlzdHJpYnV0aW9uLXdlYi12YWx1ZXMtc3BlY2lmeS5odG1sI0Rvd25sb2FkRGlzdFZhbHVlc1BhdGhQYXR0ZXJuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbmFsUGF0aFBhdHRlcm4gPSB0aGlzLmdldFBhdGhQYXR0ZXJuKHBhdGhQYXR0ZXJuKTtcbiAgICAgIHRoaXMuZGlzdHJpYnV0aW9uLmFkZEJlaGF2aW9yKFxuICAgICAgICBmaW5hbFBhdGhQYXR0ZXJuLFxuICAgICAgICB0aGlzLnN0YXRpY09yaWdpbixcbiAgICAgICAgdGhpcy5zdGF0aWNCZWhhdmlvck9wdGlvbnMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogT3B0aW9uYWxseSBwcmVwZW5kcyBiYXNlIHBhdGggdG8gZ2l2ZW4gcGF0aCBwYXR0ZXJuLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQYXRoUGF0dGVybihwYXRoUGF0dGVybjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMucHJvcHMuYmFzZVBhdGgpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnByb3BzLmJhc2VQYXRofS8ke3BhdGhQYXR0ZXJufWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYXRoUGF0dGVybjtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,42 @@
1
+ import { Connections, IVpc } from "aws-cdk-lib/aws-ec2";
2
+ import { AccessPoint, AccessPointProps, FileSystem, FileSystemProps } from "aws-cdk-lib/aws-efs";
3
+ import { IRole } from "aws-cdk-lib/aws-iam";
4
+ import { Construct } from "constructs";
5
+ export interface NextjsFileSystemOverrides {
6
+ readonly fileSystemProps?: FileSystemProps;
7
+ readonly accessPointProps?: AccessPointProps;
8
+ }
9
+ export interface NextjsFileSystemProps {
10
+ readonly overrides?: NextjsFileSystemOverrides;
11
+ readonly vpc: IVpc;
12
+ }
13
+ export interface AllowComputeProps {
14
+ readonly connections: Connections;
15
+ readonly role: IRole;
16
+ }
17
+ /**
18
+ * Next.js Network File System enabling sharing of image optimization cache,
19
+ * data cach, and pages cache.
20
+ */
21
+ export declare class NextjsFileSystem extends Construct {
22
+ fileSystem: FileSystem;
23
+ accessPoint: AccessPoint;
24
+ private props;
25
+ constructor(scope: Construct, id: string, props: NextjsFileSystemProps);
26
+ /**
27
+ * Creates EFS File System
28
+ *
29
+ * Note, the resource policy for the File System will include the boolean
30
+ * condition, `"elasticfilesystem:AccessedViaMountTarget": "true"` which from
31
+ * CDK [docs](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_efs-readme.html#permissions)
32
+ * says, "only allow access to clients using IAM authentication and deny access
33
+ * to anonymous clients".
34
+ * @see https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html
35
+ *
36
+ * Ideally we could add IAM string condition `elasticfilesystem:AccessPointArn`
37
+ * to the resource policy but this causes circular dependency.
38
+ */
39
+ private createFileSystem;
40
+ private createAccessPoint;
41
+ allowCompute({ connections, role }: AllowComputeProps): void;
42
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.NextjsFileSystem = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const aws_efs_1 = require("aws-cdk-lib/aws-efs");
8
+ const constructs_1 = require("constructs");
9
+ /**
10
+ * Next.js Network File System enabling sharing of image optimization cache,
11
+ * data cach, and pages cache.
12
+ */
13
+ class NextjsFileSystem extends constructs_1.Construct {
14
+ constructor(scope, id, props) {
15
+ super(scope, id);
16
+ this.props = props;
17
+ this.fileSystem = this.createFileSystem();
18
+ this.accessPoint = this.createAccessPoint();
19
+ }
20
+ /**
21
+ * Creates EFS File System
22
+ *
23
+ * Note, the resource policy for the File System will include the boolean
24
+ * condition, `"elasticfilesystem:AccessedViaMountTarget": "true"` which from
25
+ * CDK [docs](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_efs-readme.html#permissions)
26
+ * says, "only allow access to clients using IAM authentication and deny access
27
+ * to anonymous clients".
28
+ * @see https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html
29
+ *
30
+ * Ideally we could add IAM string condition `elasticfilesystem:AccessPointArn`
31
+ * to the resource policy but this causes circular dependency.
32
+ */
33
+ createFileSystem() {
34
+ const fileSystem = new aws_efs_1.FileSystem(this, "FileSystem", {
35
+ encrypted: true,
36
+ lifecyclePolicy: aws_efs_1.LifecyclePolicy.AFTER_30_DAYS,
37
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
38
+ vpc: this.props.vpc,
39
+ allowAnonymousAccess: false,
40
+ ...this.props.overrides?.fileSystemProps,
41
+ });
42
+ return fileSystem;
43
+ }
44
+ createAccessPoint() {
45
+ const uid = "1001";
46
+ const gid = "1001";
47
+ const accessPoint = new aws_efs_1.AccessPoint(this, "AccessPoint", {
48
+ // as /next/cache doesn't exist in a new efs filesystem, the efs will
49
+ // create the directory with the following options
50
+ createAcl: {
51
+ ownerGid: gid,
52
+ ownerUid: uid,
53
+ permissions: "755",
54
+ },
55
+ fileSystem: this.fileSystem,
56
+ path: "/next/cache",
57
+ // enforce POSIX identity so container wil access file system with this identity
58
+ posixUser: {
59
+ gid,
60
+ uid,
61
+ },
62
+ ...this.props.overrides?.accessPointProps,
63
+ });
64
+ return accessPoint;
65
+ }
66
+ allowCompute({ connections, role }) {
67
+ this.fileSystem.connections.allowDefaultPortFrom(connections);
68
+ this.fileSystem.grantReadWrite(role);
69
+ }
70
+ }
71
+ exports.NextjsFileSystem = NextjsFileSystem;
72
+ _a = JSII_RTTI_SYMBOL_1;
73
+ NextjsFileSystem[_a] = { fqn: "cdk-nextjs.NextjsFileSystem", version: "0.1.1" };
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWZpbGUtc3lzdGVtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1maWxlLXN5c3RlbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUE0QztBQUU1QyxpREFNNkI7QUFFN0IsMkNBQXVDO0FBaUJ2Qzs7O0dBR0c7QUFDSCxNQUFhLGdCQUFpQixTQUFRLHNCQUFTO0lBSzdDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBNEI7UUFDcEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUNEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNLLGdCQUFnQjtRQUN0QixNQUFNLFVBQVUsR0FBRyxJQUFJLG9CQUFVLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRTtZQUNwRCxTQUFTLEVBQUUsSUFBSTtZQUNmLGVBQWUsRUFBRSx5QkFBZSxDQUFDLGFBQWE7WUFDOUMsYUFBYSxFQUFFLDJCQUFhLENBQUMsT0FBTztZQUNwQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHO1lBQ25CLG9CQUFvQixFQUFFLEtBQUs7WUFDM0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxlQUFlO1NBQ3pDLENBQUMsQ0FBQztRQUNILE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFDTyxpQkFBaUI7UUFDdkIsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDO1FBQ25CLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUNuQixNQUFNLFdBQVcsR0FBRyxJQUFJLHFCQUFXLENBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRTtZQUN2RCxxRUFBcUU7WUFDckUsa0RBQWtEO1lBQ2xELFNBQVMsRUFBRTtnQkFDVCxRQUFRLEVBQUUsR0FBRztnQkFDYixRQUFRLEVBQUUsR0FBRztnQkFDYixXQUFXLEVBQUUsS0FBSzthQUNuQjtZQUNELFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtZQUMzQixJQUFJLEVBQUUsYUFBYTtZQUNuQixnRkFBZ0Y7WUFDaEYsU0FBUyxFQUFFO2dCQUNULEdBQUc7Z0JBQ0gsR0FBRzthQUNKO1lBQ0QsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxnQkFBZ0I7U0FDMUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUNELFlBQVksQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQXFCO1FBQ25ELElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7O0FBNURILDRDQTZEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlbW92YWxQb2xpY3kgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IENvbm5lY3Rpb25zLCBJVnBjIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7XG4gIEFjY2Vzc1BvaW50LFxuICBBY2Nlc3NQb2ludFByb3BzLFxuICBGaWxlU3lzdGVtLFxuICBGaWxlU3lzdGVtUHJvcHMsXG4gIExpZmVjeWNsZVBvbGljeSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lZnNcIjtcbmltcG9ydCB7IElSb2xlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzRmlsZVN5c3RlbU92ZXJyaWRlcyB7XG4gIHJlYWRvbmx5IGZpbGVTeXN0ZW1Qcm9wcz86IEZpbGVTeXN0ZW1Qcm9wcztcbiAgcmVhZG9ubHkgYWNjZXNzUG9pbnRQcm9wcz86IEFjY2Vzc1BvaW50UHJvcHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzRmlsZVN5c3RlbVByb3BzIHtcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzRmlsZVN5c3RlbU92ZXJyaWRlcztcbiAgcmVhZG9ubHkgdnBjOiBJVnBjO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFsbG93Q29tcHV0ZVByb3BzIHtcbiAgcmVhZG9ubHkgY29ubmVjdGlvbnM6IENvbm5lY3Rpb25zO1xuICByZWFkb25seSByb2xlOiBJUm9sZTtcbn1cblxuLyoqXG4gKiBOZXh0LmpzIE5ldHdvcmsgRmlsZSBTeXN0ZW0gZW5hYmxpbmcgc2hhcmluZyBvZiBpbWFnZSBvcHRpbWl6YXRpb24gY2FjaGUsXG4gKiBkYXRhIGNhY2gsIGFuZCBwYWdlcyBjYWNoZS5cbiAqL1xuZXhwb3J0IGNsYXNzIE5leHRqc0ZpbGVTeXN0ZW0gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBmaWxlU3lzdGVtOiBGaWxlU3lzdGVtO1xuICBhY2Nlc3NQb2ludDogQWNjZXNzUG9pbnQ7XG4gIHByaXZhdGUgcHJvcHM6IE5leHRqc0ZpbGVTeXN0ZW1Qcm9wcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzRmlsZVN5c3RlbVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gICAgdGhpcy5maWxlU3lzdGVtID0gdGhpcy5jcmVhdGVGaWxlU3lzdGVtKCk7XG4gICAgdGhpcy5hY2Nlc3NQb2ludCA9IHRoaXMuY3JlYXRlQWNjZXNzUG9pbnQoKTtcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlcyBFRlMgRmlsZSBTeXN0ZW1cbiAgICpcbiAgICogTm90ZSwgdGhlIHJlc291cmNlIHBvbGljeSBmb3IgdGhlIEZpbGUgU3lzdGVtIHdpbGwgaW5jbHVkZSB0aGUgYm9vbGVhblxuICAgKiBjb25kaXRpb24sIGBcImVsYXN0aWNmaWxlc3lzdGVtOkFjY2Vzc2VkVmlhTW91bnRUYXJnZXRcIjogXCJ0cnVlXCJgIHdoaWNoIGZyb21cbiAgICogQ0RLIFtkb2NzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2RrL2FwaS92Mi9kb2NzL2F3cy1jZGstbGliLmF3c19lZnMtcmVhZG1lLmh0bWwjcGVybWlzc2lvbnMpXG4gICAqIHNheXMsIFwib25seSBhbGxvdyBhY2Nlc3MgdG8gY2xpZW50cyB1c2luZyBJQU0gYXV0aGVudGljYXRpb24gYW5kIGRlbnkgYWNjZXNzXG4gICAqIHRvIGFub255bW91cyBjbGllbnRzXCIuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvYWNjZXNzLWNvbnRyb2wtYmxvY2stcHVibGljLWFjY2Vzcy5odG1sXG4gICAqXG4gICAqIElkZWFsbHkgd2UgY291bGQgYWRkIElBTSBzdHJpbmcgY29uZGl0aW9uIGBlbGFzdGljZmlsZXN5c3RlbTpBY2Nlc3NQb2ludEFybmBcbiAgICogdG8gdGhlIHJlc291cmNlIHBvbGljeSBidXQgdGhpcyBjYXVzZXMgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRmlsZVN5c3RlbSgpIHtcbiAgICBjb25zdCBmaWxlU3lzdGVtID0gbmV3IEZpbGVTeXN0ZW0odGhpcywgXCJGaWxlU3lzdGVtXCIsIHtcbiAgICAgIGVuY3J5cHRlZDogdHJ1ZSxcbiAgICAgIGxpZmVjeWNsZVBvbGljeTogTGlmZWN5Y2xlUG9saWN5LkFGVEVSXzMwX0RBWVMsXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICB2cGM6IHRoaXMucHJvcHMudnBjLFxuICAgICAgYWxsb3dBbm9ueW1vdXNBY2Nlc3M6IGZhbHNlLFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmZpbGVTeXN0ZW1Qcm9wcyxcbiAgICB9KTtcbiAgICByZXR1cm4gZmlsZVN5c3RlbTtcbiAgfVxuICBwcml2YXRlIGNyZWF0ZUFjY2Vzc1BvaW50KCkge1xuICAgIGNvbnN0IHVpZCA9IFwiMTAwMVwiO1xuICAgIGNvbnN0IGdpZCA9IFwiMTAwMVwiO1xuICAgIGNvbnN0IGFjY2Vzc1BvaW50ID0gbmV3IEFjY2Vzc1BvaW50KHRoaXMsIFwiQWNjZXNzUG9pbnRcIiwge1xuICAgICAgLy8gYXMgL25leHQvY2FjaGUgZG9lc24ndCBleGlzdCBpbiBhIG5ldyBlZnMgZmlsZXN5c3RlbSwgdGhlIGVmcyB3aWxsXG4gICAgICAvLyBjcmVhdGUgdGhlIGRpcmVjdG9yeSB3aXRoIHRoZSBmb2xsb3dpbmcgb3B0aW9uc1xuICAgICAgY3JlYXRlQWNsOiB7XG4gICAgICAgIG93bmVyR2lkOiBnaWQsXG4gICAgICAgIG93bmVyVWlkOiB1aWQsXG4gICAgICAgIHBlcm1pc3Npb25zOiBcIjc1NVwiLFxuICAgICAgfSxcbiAgICAgIGZpbGVTeXN0ZW06IHRoaXMuZmlsZVN5c3RlbSxcbiAgICAgIHBhdGg6IFwiL25leHQvY2FjaGVcIixcbiAgICAgIC8vIGVuZm9yY2UgUE9TSVggaWRlbnRpdHkgc28gY29udGFpbmVyIHdpbCBhY2Nlc3MgZmlsZSBzeXN0ZW0gd2l0aCB0aGlzIGlkZW50aXR5XG4gICAgICBwb3NpeFVzZXI6IHtcbiAgICAgICAgZ2lkLFxuICAgICAgICB1aWQsXG4gICAgICB9LFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmFjY2Vzc1BvaW50UHJvcHMsXG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY2Vzc1BvaW50O1xuICB9XG4gIGFsbG93Q29tcHV0ZSh7IGNvbm5lY3Rpb25zLCByb2xlIH06IEFsbG93Q29tcHV0ZVByb3BzKSB7XG4gICAgdGhpcy5maWxlU3lzdGVtLmNvbm5lY3Rpb25zLmFsbG93RGVmYXVsdFBvcnRGcm9tKGNvbm5lY3Rpb25zKTtcbiAgICB0aGlzLmZpbGVTeXN0ZW0uZ3JhbnRSZWFkV3JpdGUocm9sZSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,19 @@
1
+ import { IDistribution } from "aws-cdk-lib/aws-cloudfront";
2
+ import { AwsCustomResourceProps } from "aws-cdk-lib/custom-resources";
3
+ import { Construct } from "constructs";
4
+ export interface NextjsInvalidationOverrides {
5
+ readonly awsCustomResourceProps?: AwsCustomResourceProps;
6
+ }
7
+ export interface NextjsInvalidationProps {
8
+ /**
9
+ * CloudFront Distribution to invalidate
10
+ */
11
+ readonly distribution: IDistribution;
12
+ /**
13
+ * Override props for every construct.
14
+ */
15
+ readonly overrides?: NextjsInvalidationOverrides;
16
+ }
17
+ export declare class NextjsInvalidation extends Construct {
18
+ constructor(scope: Construct, id: string, props: NextjsInvalidationProps);
19
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.NextjsInvalidation = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
8
+ const custom_resources_1 = require("aws-cdk-lib/custom-resources");
9
+ const constructs_1 = require("constructs");
10
+ class NextjsInvalidation extends constructs_1.Construct {
11
+ constructor(scope, id, props) {
12
+ super(scope, id);
13
+ const awsSdkCall = {
14
+ // make `physicalResourceId` change each time to invalidate CloudFront
15
+ // distribution on each change
16
+ physicalResourceId: custom_resources_1.PhysicalResourceId.of(`${props.distribution.distributionId}-${Date.now()}`),
17
+ action: "CreateInvalidationCommand",
18
+ service: "@aws-sdk/client-cloudfront",
19
+ parameters: {
20
+ DistributionId: props.distribution.distributionId,
21
+ InvalidationBatch: {
22
+ CallerReference: new Date().toISOString(),
23
+ Paths: {
24
+ Quantity: 1,
25
+ Items: ["/*"],
26
+ },
27
+ },
28
+ },
29
+ };
30
+ new custom_resources_1.AwsCustomResource(this, "AwsCR", {
31
+ onCreate: awsSdkCall,
32
+ onUpdate: awsSdkCall,
33
+ policy: custom_resources_1.AwsCustomResourcePolicy.fromStatements([
34
+ new aws_iam_1.PolicyStatement({
35
+ actions: ["cloudfront:CreateInvalidation"],
36
+ resources: [
37
+ aws_cdk_lib_1.Stack.of(this).formatArn({
38
+ resource: `distribution/${props.distribution.distributionId}`,
39
+ service: "cloudfront",
40
+ region: "",
41
+ }),
42
+ ],
43
+ }),
44
+ ]),
45
+ ...props.overrides?.awsCustomResourceProps,
46
+ });
47
+ }
48
+ }
49
+ exports.NextjsInvalidation = NextjsInvalidation;
50
+ _a = JSII_RTTI_SYMBOL_1;
51
+ NextjsInvalidation[_a] = { fqn: "cdk-nextjs.NextjsInvalidation", version: "0.1.1" };
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWludmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXh0anMtaW52YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBQW9DO0FBRXBDLGlEQUFzRDtBQUN0RCxtRUFNc0M7QUFDdEMsMkNBQXVDO0FBaUJ2QyxNQUFhLGtCQUFtQixTQUFRLHNCQUFTO0lBQy9DLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBOEI7UUFDdEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixNQUFNLFVBQVUsR0FBZTtZQUM3QixzRUFBc0U7WUFDdEUsOEJBQThCO1lBQzlCLGtCQUFrQixFQUFFLHFDQUFrQixDQUFDLEVBQUUsQ0FDdkMsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDckQ7WUFDRCxNQUFNLEVBQUUsMkJBQTJCO1lBQ25DLE9BQU8sRUFBRSw0QkFBNEI7WUFDckMsVUFBVSxFQUFFO2dCQUNWLGNBQWMsRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWM7Z0JBQ2pELGlCQUFpQixFQUFFO29CQUNqQixlQUFlLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7b0JBQ3pDLEtBQUssRUFBRTt3QkFDTCxRQUFRLEVBQUUsQ0FBQzt3QkFDWCxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUM7cUJBQ2Q7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7UUFDRixJQUFJLG9DQUFpQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUU7WUFDbkMsUUFBUSxFQUFFLFVBQVU7WUFDcEIsUUFBUSxFQUFFLFVBQVU7WUFDcEIsTUFBTSxFQUFFLDBDQUF1QixDQUFDLGNBQWMsQ0FBQztnQkFDN0MsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUUsQ0FBQywrQkFBK0IsQ0FBQztvQkFDMUMsU0FBUyxFQUFFO3dCQUNULG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQzs0QkFDdkIsUUFBUSxFQUFFLGdCQUFnQixLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRTs0QkFDN0QsT0FBTyxFQUFFLFlBQVk7NEJBQ3JCLE1BQU0sRUFBRSxFQUFFO3lCQUNYLENBQUM7cUJBQ0g7aUJBQ0YsQ0FBQzthQUNILENBQUM7WUFDRixHQUFHLEtBQUssQ0FBQyxTQUFTLEVBQUUsc0JBQXNCO1NBQzNDLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBdkNILGdEQXdDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBJRGlzdHJpYnV0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCI7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHtcbiAgQXdzQ3VzdG9tUmVzb3VyY2UsXG4gIEF3c1Nka0NhbGwsXG4gIEF3c0N1c3RvbVJlc291cmNlUG9saWN5LFxuICBQaHlzaWNhbFJlc291cmNlSWQsXG4gIEF3c0N1c3RvbVJlc291cmNlUHJvcHMsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5leHRqc0ludmFsaWRhdGlvbk92ZXJyaWRlcyB7XG4gIHJlYWRvbmx5IGF3c0N1c3RvbVJlc291cmNlUHJvcHM/OiBBd3NDdXN0b21SZXNvdXJjZVByb3BzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5leHRqc0ludmFsaWRhdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIHRvIGludmFsaWRhdGVcbiAgICovXG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbjogSURpc3RyaWJ1dGlvbjtcbiAgLyoqXG4gICAqIE92ZXJyaWRlIHByb3BzIGZvciBldmVyeSBjb25zdHJ1Y3QuXG4gICAqL1xuICByZWFkb25seSBvdmVycmlkZXM/OiBOZXh0anNJbnZhbGlkYXRpb25PdmVycmlkZXM7XG59XG5cbmV4cG9ydCBjbGFzcyBOZXh0anNJbnZhbGlkYXRpb24gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzSW52YWxpZGF0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIGNvbnN0IGF3c1Nka0NhbGw6IEF3c1Nka0NhbGwgPSB7XG4gICAgICAvLyBtYWtlIGBwaHlzaWNhbFJlc291cmNlSWRgIGNoYW5nZSBlYWNoIHRpbWUgdG8gaW52YWxpZGF0ZSBDbG91ZEZyb250XG4gICAgICAvLyBkaXN0cmlidXRpb24gb24gZWFjaCBjaGFuZ2VcbiAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogUGh5c2ljYWxSZXNvdXJjZUlkLm9mKFxuICAgICAgICBgJHtwcm9wcy5kaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWR9LSR7RGF0ZS5ub3coKX1gLFxuICAgICAgKSxcbiAgICAgIGFjdGlvbjogXCJDcmVhdGVJbnZhbGlkYXRpb25Db21tYW5kXCIsXG4gICAgICBzZXJ2aWNlOiBcIkBhd3Mtc2RrL2NsaWVudC1jbG91ZGZyb250XCIsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIERpc3RyaWJ1dGlvbklkOiBwcm9wcy5kaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWQsXG4gICAgICAgIEludmFsaWRhdGlvbkJhdGNoOiB7XG4gICAgICAgICAgQ2FsbGVyUmVmZXJlbmNlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgUGF0aHM6IHtcbiAgICAgICAgICAgIFF1YW50aXR5OiAxLFxuICAgICAgICAgICAgSXRlbXM6IFtcIi8qXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gICAgbmV3IEF3c0N1c3RvbVJlc291cmNlKHRoaXMsIFwiQXdzQ1JcIiwge1xuICAgICAgb25DcmVhdGU6IGF3c1Nka0NhbGwsXG4gICAgICBvblVwZGF0ZTogYXdzU2RrQ2FsbCxcbiAgICAgIHBvbGljeTogQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVN0YXRlbWVudHMoW1xuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJjbG91ZGZyb250OkNyZWF0ZUludmFsaWRhdGlvblwiXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICAgIFN0YWNrLm9mKHRoaXMpLmZvcm1hdEFybih7XG4gICAgICAgICAgICAgIHJlc291cmNlOiBgZGlzdHJpYnV0aW9uLyR7cHJvcHMuZGlzdHJpYnV0aW9uLmRpc3RyaWJ1dGlvbklkfWAsXG4gICAgICAgICAgICAgIHNlcnZpY2U6IFwiY2xvdWRmcm9udFwiLFxuICAgICAgICAgICAgICByZWdpb246IFwiXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSxcbiAgICAgIF0pLFxuICAgICAgLi4ucHJvcHMub3ZlcnJpZGVzPy5hd3NDdXN0b21SZXNvdXJjZVByb3BzLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,30 @@
1
+ import { Function as LambdaFunction } from "aws-cdk-lib/aws-lambda";
2
+ import { SqsEventSourceProps } from "aws-cdk-lib/aws-lambda-event-sources";
3
+ import { Queue, QueueProps } from "aws-cdk-lib/aws-sqs";
4
+ import { Construct } from "constructs";
5
+ import { OptionalFunctionProps } from "./generated-structs/OptionalFunctionProps";
6
+ export interface NextjsRevalidationOverrides {
7
+ readonly queueProps?: QueueProps;
8
+ readonly functionProps?: OptionalFunctionProps;
9
+ readonly sqsEventSourceProps?: SqsEventSourceProps;
10
+ }
11
+ export interface NextjsRevalidationProps {
12
+ readonly fn: LambdaFunction;
13
+ readonly overrides?: NextjsRevalidationOverrides;
14
+ readonly previewModeId: string;
15
+ }
16
+ /**
17
+ * [On-Demand Revalidation](https://nextjs.org/docs/app/building-your-application/caching#on-demand-revalidation)
18
+ * (i.e. `revalidateTag`, `revlidatePath`) doesn't work by default in Lambda
19
+ * environment because it tries to run every request completes when Lambda
20
+ * spins down. Therefore, we use a SQS Queue and Lambda function to run
21
+ * revalidation async.
22
+ */
23
+ export declare class NextjsRevalidation extends Construct {
24
+ queue: Queue;
25
+ fn: LambdaFunction;
26
+ private props;
27
+ constructor(scope: Construct, id: string, props: NextjsRevalidationProps);
28
+ private createQueue;
29
+ private createFunction;
30
+ }