cdk-nextjs 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +13811 -0
- package/.prettierrc +0 -0
- package/API.md +9694 -0
- package/LICENSE +202 -0
- package/README.md +137 -0
- package/THIRD-PARTY-LICENSES.md +31 -0
- package/assets/lambdas/assets-deployment/assets-deployment.lambda/assets-deployment.Dockerfile +18 -0
- package/assets/lambdas/assets-deployment/assets-deployment.lambda/index.js +8831 -0
- package/assets/lambdas/revalidate/revalidate.lambda/index.js +67 -0
- package/assets/lambdas/sign-fn-url/sign-fn-url.lambda/index.js +2002 -0
- package/examples/README.md +14 -0
- package/lib/common.d.ts +23 -0
- package/lib/common.js +28 -0
- package/lib/generated-structs/OptionalApplicationLoadBalancedTaskImageOptions.d.ts +106 -0
- package/lib/generated-structs/OptionalApplicationLoadBalancedTaskImageOptions.js +3 -0
- package/lib/generated-structs/OptionalCloudFrontFunctionProps.d.ts +43 -0
- package/lib/generated-structs/OptionalCloudFrontFunctionProps.js +3 -0
- package/lib/generated-structs/OptionalClusterProps.d.ts +49 -0
- package/lib/generated-structs/OptionalClusterProps.js +3 -0
- package/lib/generated-structs/OptionalDistributionProps.d.ts +155 -0
- package/lib/generated-structs/OptionalDistributionProps.js +3 -0
- package/lib/generated-structs/OptionalDockerImageAssetProps.d.ts +124 -0
- package/lib/generated-structs/OptionalDockerImageAssetProps.js +3 -0
- package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +399 -0
- package/lib/generated-structs/OptionalDockerImageFunctionProps.js +3 -0
- package/lib/generated-structs/OptionalEdgeFunctionProps.d.ts +428 -0
- package/lib/generated-structs/OptionalEdgeFunctionProps.js +3 -0
- package/lib/generated-structs/OptionalFunctionProps.d.ts +422 -0
- package/lib/generated-structs/OptionalFunctionProps.js +3 -0
- package/lib/generated-structs/OptionalFunctionUrlProps.d.ts +30 -0
- package/lib/generated-structs/OptionalFunctionUrlProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsAssetsDeploymentProps.d.ts +45 -0
- package/lib/generated-structs/OptionalNextjsAssetsDeploymentProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsBuildProps.d.ts +30 -0
- package/lib/generated-structs/OptionalNextjsBuildProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +43 -0
- package/lib/generated-structs/OptionalNextjsContainersProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +50 -0
- package/lib/generated-structs/OptionalNextjsDistributionProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsFileSystemProps.d.ts +15 -0
- package/lib/generated-structs/OptionalNextjsFileSystemProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsInvalidationProps.d.ts +17 -0
- package/lib/generated-structs/OptionalNextjsInvalidationProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsVpcProps.d.ts +21 -0
- package/lib/generated-structs/OptionalNextjsVpcProps.js +3 -0
- package/lib/generated-structs/OptionalS3OriginProps.d.ts +64 -0
- package/lib/generated-structs/OptionalS3OriginProps.js +3 -0
- package/lib/generated-structs/OptionalVpcProps.d.ts +224 -0
- package/lib/generated-structs/OptionalVpcProps.js +3 -0
- package/lib/index.d.ts +35 -0
- package/lib/index.js +32 -0
- package/lib/lambdas/assets-deployment/assets-deployment-function.d.ts +13 -0
- package/lib/lambdas/assets-deployment/assets-deployment-function.js +23 -0
- package/lib/lambdas/assets-deployment/assets-deployment.lambda.d.ts +2 -0
- package/lib/lambdas/assets-deployment/assets-deployment.lambda.js +62 -0
- package/lib/lambdas/assets-deployment/common.d.ts +8 -0
- package/lib/lambdas/assets-deployment/common.js +32 -0
- package/lib/lambdas/assets-deployment/fs-to-fs.d.ts +2 -0
- package/lib/lambdas/assets-deployment/fs-to-fs.js +9 -0
- package/lib/lambdas/assets-deployment/fs-to-s3.d.ts +2 -0
- package/lib/lambdas/assets-deployment/fs-to-s3.js +45 -0
- package/lib/lambdas/assets-deployment/prune-s3.d.ts +15 -0
- package/lib/lambdas/assets-deployment/prune-s3.js +42 -0
- package/lib/lambdas/assets-deployment/s3.d.ts +2 -0
- package/lib/lambdas/assets-deployment/s3.js +7 -0
- package/lib/lambdas/assets-deployment/utils.d.ts +18 -0
- package/lib/lambdas/assets-deployment/utils.js +35 -0
- package/lib/lambdas/revalidate/revalidate-function.d.ts +13 -0
- package/lib/lambdas/revalidate/revalidate-function.js +23 -0
- package/lib/lambdas/revalidate/revalidate.lambda.d.ts +2 -0
- package/lib/lambdas/revalidate/revalidate.lambda.js +53 -0
- package/lib/lambdas/sign-fn-url/sign-fn-url-function.d.ts +13 -0
- package/lib/lambdas/sign-fn-url/sign-fn-url-function.js +23 -0
- package/lib/lambdas/sign-fn-url/sign-fn-url.lambda.d.ts +9 -0
- package/lib/lambdas/sign-fn-url/sign-fn-url.lambda.js +35 -0
- package/lib/lambdas/sign-fn-url/sign-request.d.ts +28 -0
- package/lib/lambdas/sign-fn-url/sign-request.js +119 -0
- package/lib/lambdas/sign-fn-url/sign-request.test.d.ts +1 -0
- package/lib/lambdas/sign-fn-url/sign-request.test.js +129 -0
- package/lib/nextjs-assets-deployment.d.ts +116 -0
- package/lib/nextjs-assets-deployment.js +93 -0
- package/lib/nextjs-build/add-cache-handler.d.ts +1 -0
- package/lib/nextjs-build/add-cache-handler.js +23 -0
- package/lib/nextjs-build/add-cache-handler.mjs +18 -0
- package/lib/nextjs-build/builder.Dockerfile +29 -0
- package/lib/nextjs-build/cache-handler.cjs +21513 -0
- package/lib/nextjs-build/cache-handler.d.ts +6 -0
- package/lib/nextjs-build/cache-handler.js +22 -0
- package/lib/nextjs-build/global-containers.Dockerfile +45 -0
- package/lib/nextjs-build/global-functions.Dockerfile +46 -0
- package/lib/nextjs-build/nextjs-build.d.ts +150 -0
- package/lib/nextjs-build/nextjs-build.js +220 -0
- package/lib/nextjs-build/regional-containers.Dockerfile +45 -0
- package/lib/nextjs-build/symlink-full-route-cache.d.ts +1 -0
- package/lib/nextjs-build/symlink-full-route-cache.js +37 -0
- package/lib/nextjs-build/symlink-full-route-cache.mjs +23 -0
- package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +8 -0
- package/lib/nextjs-compute/nextjs-compute-base-props.js +3 -0
- package/lib/nextjs-compute/nextjs-containers.d.ts +43 -0
- package/lib/nextjs-compute/nextjs-containers.js +149 -0
- package/lib/nextjs-compute/nextjs-functions.d.ts +23 -0
- package/lib/nextjs-compute/nextjs-functions.js +57 -0
- package/lib/nextjs-distribution.d.ts +120 -0
- package/lib/nextjs-distribution.js +362 -0
- package/lib/nextjs-file-system.d.ts +42 -0
- package/lib/nextjs-file-system.js +74 -0
- package/lib/nextjs-invalidation.d.ts +19 -0
- package/lib/nextjs-invalidation.js +52 -0
- package/lib/nextjs-revalidation.d.ts +30 -0
- package/lib/nextjs-revalidation.js +65 -0
- package/lib/nextjs-static-assets.d.ts +21 -0
- package/lib/nextjs-static-assets.js +32 -0
- package/lib/nextjs-vpc.d.ts +42 -0
- package/lib/nextjs-vpc.js +64 -0
- package/lib/root-constructs/nextjs-base-overrides.d.ts +26 -0
- package/lib/root-constructs/nextjs-base-overrides.js +3 -0
- package/lib/root-constructs/nextjs-base-props.d.ts +56 -0
- package/lib/root-constructs/nextjs-base-props.js +3 -0
- package/lib/root-constructs/nextjs-global-containers.d.ts +74 -0
- package/lib/root-constructs/nextjs-global-containers.js +125 -0
- package/lib/root-constructs/nextjs-global-functions.d.ts +76 -0
- package/lib/root-constructs/nextjs-global-functions.js +131 -0
- package/lib/root-constructs/nextjs-regional-containers.d.ts +43 -0
- package/lib/root-constructs/nextjs-regional-containers.js +92 -0
- package/package.json +165 -0
|
@@ -0,0 +1,362 @@
|
|
|
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 constructs_1 = require("constructs");
|
|
11
|
+
const common_1 = require("./common");
|
|
12
|
+
const sign_fn_url_function_1 = require("./lambdas/sign-fn-url/sign-fn-url-function");
|
|
13
|
+
class NextjsDistribution extends constructs_1.Construct {
|
|
14
|
+
constructor(scope, id, props) {
|
|
15
|
+
super(scope, id);
|
|
16
|
+
/**
|
|
17
|
+
* Common security headers applied by default to all origins
|
|
18
|
+
* @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html#managed-response-headers-policies-security
|
|
19
|
+
*/
|
|
20
|
+
this.commonSecurityHeadersBehavior = {
|
|
21
|
+
contentTypeOptions: { override: false },
|
|
22
|
+
frameOptions: {
|
|
23
|
+
frameOption: aws_cloudfront_1.HeadersFrameOption.SAMEORIGIN,
|
|
24
|
+
override: false,
|
|
25
|
+
},
|
|
26
|
+
referrerPolicy: {
|
|
27
|
+
override: false,
|
|
28
|
+
referrerPolicy: aws_cloudfront_1.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
|
|
29
|
+
},
|
|
30
|
+
strictTransportSecurity: {
|
|
31
|
+
accessControlMaxAge: aws_cdk_lib_1.Duration.days(365),
|
|
32
|
+
includeSubdomains: true,
|
|
33
|
+
override: false,
|
|
34
|
+
preload: true,
|
|
35
|
+
},
|
|
36
|
+
xssProtection: { override: false, protection: true, modeBlock: true },
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Given stack id: "arn:aws:cloudformation:us-east-1:905418358903:stack/lh-stickb-idp/4bf74be0-e880-11ee-aea9-0affc6185b25",
|
|
40
|
+
* returns "4bf74be0"
|
|
41
|
+
*/
|
|
42
|
+
this.uniqueStackIdPart = aws_cdk_lib_1.Fn.select(0, aws_cdk_lib_1.Fn.split("-", aws_cdk_lib_1.Fn.select(2, aws_cdk_lib_1.Fn.split("/", `${aws_cdk_lib_1.Aws.STACK_ID}`))));
|
|
43
|
+
this.props = props;
|
|
44
|
+
this.staticOrigin = this.createStaticOrigin();
|
|
45
|
+
this.isFunctionCompute = props.nextjsType === common_1.NextjsType.GLOBAL_FUNCTIONS;
|
|
46
|
+
this.dynamicOrigin = this.createDynamicOrigin();
|
|
47
|
+
this.dynamicOriginResponsePolicy = this.createDynamicOriginRequestPolicy();
|
|
48
|
+
this.dynamicCloudFrontFunctionAssociations =
|
|
49
|
+
this.createDynamicCloudFrontFunctionAssociations();
|
|
50
|
+
if (this.isFunctionCompute) {
|
|
51
|
+
this.edgeLambdas = this.createEdgeLambdas();
|
|
52
|
+
}
|
|
53
|
+
this.staticBehaviorOptions = this.createStaticBehaviorOptions();
|
|
54
|
+
this.dynamicBehaviorOptions = this.createDynamicBehaviorOptions();
|
|
55
|
+
this.imageBehaviorOptions = this.createImageBehaviorOptions();
|
|
56
|
+
this.distribution = this.getDistribution();
|
|
57
|
+
this.addStaticBehaviors();
|
|
58
|
+
this.addDynamicBehaviors();
|
|
59
|
+
this.addS3OacAndRemoveOai();
|
|
60
|
+
if (this.isFunctionCompute) {
|
|
61
|
+
// this.addLambdaOac(); // TODO: wait for POST body encryption feature for Lambda OAC
|
|
62
|
+
}
|
|
63
|
+
new aws_cdk_lib_1.CfnOutput(this, "DistributionDomainName", {
|
|
64
|
+
value: this.distribution.domainName,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
createStaticOrigin() {
|
|
68
|
+
const s3Origin = new aws_cloudfront_origins_1.S3Origin(this.props.assetsBucket, this.props.overrides?.s3OriginProps);
|
|
69
|
+
return s3Origin;
|
|
70
|
+
}
|
|
71
|
+
createDynamicOrigin() {
|
|
72
|
+
let protocolPolicy;
|
|
73
|
+
if (this.isFunctionCompute) {
|
|
74
|
+
protocolPolicy = aws_cloudfront_1.OriginProtocolPolicy.HTTPS_ONLY;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
protocolPolicy = this.props.certificate
|
|
78
|
+
? aws_cloudfront_1.OriginProtocolPolicy.HTTPS_ONLY
|
|
79
|
+
: aws_cloudfront_1.OriginProtocolPolicy.HTTP_ONLY;
|
|
80
|
+
}
|
|
81
|
+
return new aws_cloudfront_origins_1.HttpOrigin(aws_cdk_lib_1.Fn.parseDomainName(this.props.dynamicUrl), {
|
|
82
|
+
protocolPolicy,
|
|
83
|
+
...this.props.overrides?.dynamicHttpOriginProps,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Lambda Function URLs "expect the `Host` header to contain the origin domain
|
|
88
|
+
* name, not the domain name of the CloudFront distribution."
|
|
89
|
+
* @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-except-host-header
|
|
90
|
+
*/
|
|
91
|
+
createDynamicOriginRequestPolicy() {
|
|
92
|
+
return this.isFunctionCompute
|
|
93
|
+
? aws_cloudfront_1.OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER
|
|
94
|
+
: aws_cloudfront_1.OriginRequestPolicy.ALL_VIEWER;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Ensures Next.js `request.url` will be correct domain instead of URL of
|
|
98
|
+
* compute option (App Runner, Fargate, or Lambda)
|
|
99
|
+
* @see https://open-next.js.org/advanced/workaround#workaround-set-x-forwarded-host-header-aws-specific
|
|
100
|
+
*/
|
|
101
|
+
createDynamicCloudFrontFunctionAssociations() {
|
|
102
|
+
const associations = [];
|
|
103
|
+
if (this.isFunctionCompute) {
|
|
104
|
+
const cloudFrontFn = new aws_cloudfront_1.Function(this, "CloudFrontFn", {
|
|
105
|
+
code: aws_cloudfront_1.FunctionCode.fromInline(`
|
|
106
|
+
function handler(event) {
|
|
107
|
+
var request = event.request;
|
|
108
|
+
request.headers["x-forwarded-host"] = request.headers.host;
|
|
109
|
+
return request;
|
|
110
|
+
}
|
|
111
|
+
`),
|
|
112
|
+
});
|
|
113
|
+
associations.push({
|
|
114
|
+
eventType: aws_cloudfront_1.FunctionEventType.VIEWER_REQUEST,
|
|
115
|
+
function: cloudFrontFn,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return associations;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Required to sign requests so that we can use IAM_AUTH for Lambda Function URL
|
|
122
|
+
* to prevent public access. Once CloudFront Lambda OAC is released, we can
|
|
123
|
+
* use infra configuration for this instead of custom code.
|
|
124
|
+
*/
|
|
125
|
+
createEdgeLambdas() {
|
|
126
|
+
if (!this.props.functionArn)
|
|
127
|
+
throw new Error("functionArn is required");
|
|
128
|
+
const edgeFn = new sign_fn_url_function_1.SignFnUrlFunction(this, "SignFnUrl", {
|
|
129
|
+
currentVersionOptions: {
|
|
130
|
+
retryAttempts: 0, // fail fast when trying to delete b/c replicated functions take long time to delete
|
|
131
|
+
},
|
|
132
|
+
initialPolicy: [
|
|
133
|
+
new aws_iam_1.PolicyStatement({
|
|
134
|
+
actions: ["lambda:InvokeFunctionUrl"],
|
|
135
|
+
resources: [this.props.functionArn],
|
|
136
|
+
}),
|
|
137
|
+
],
|
|
138
|
+
...this.props.overrides?.edgeFunctionProps,
|
|
139
|
+
});
|
|
140
|
+
edgeFn.currentVersion.grantInvoke(new aws_iam_1.ServicePrincipal("edgelambda.amazonaws.com"));
|
|
141
|
+
edgeFn.currentVersion.grantInvoke(new aws_iam_1.ServicePrincipal("lambda.amazonaws.com"));
|
|
142
|
+
// retain on delete b/c they take too long to delete resulting in stack failure
|
|
143
|
+
edgeFn.applyRemovalPolicy(aws_cdk_lib_1.RemovalPolicy.RETAIN);
|
|
144
|
+
return [
|
|
145
|
+
{
|
|
146
|
+
eventType: aws_cloudfront_1.LambdaEdgeEventType.ORIGIN_REQUEST,
|
|
147
|
+
functionVersion: edgeFn.currentVersion,
|
|
148
|
+
includeBody: true,
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
createStaticBehaviorOptions() {
|
|
153
|
+
const staticBehaviorOptions = this.props.overrides?.staticBehaviorOptions;
|
|
154
|
+
const responseHeadersPolicy = staticBehaviorOptions?.responseHeadersPolicy ??
|
|
155
|
+
new aws_cloudfront_1.ResponseHeadersPolicy(this, "StaticResponseHeadersPolicy", {
|
|
156
|
+
securityHeadersBehavior: this.commonSecurityHeadersBehavior,
|
|
157
|
+
comment: `Nextjs Static Response Headers Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
|
|
158
|
+
...this.props.overrides?.staticResponseHeadersPolicyProps,
|
|
159
|
+
});
|
|
160
|
+
return {
|
|
161
|
+
allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
|
|
162
|
+
cachedMethods: aws_cloudfront_1.CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
163
|
+
cachePolicy: aws_cloudfront_1.CachePolicy.CACHING_OPTIMIZED,
|
|
164
|
+
origin: this.staticOrigin,
|
|
165
|
+
responseHeadersPolicy,
|
|
166
|
+
viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
167
|
+
...staticBehaviorOptions,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
createDynamicBehaviorOptions() {
|
|
171
|
+
const dynamicBehaviorOptions = this.props.overrides?.dynamicBehaviorOptions;
|
|
172
|
+
// create default cache policy if not provided
|
|
173
|
+
const cachePolicy = dynamicBehaviorOptions?.cachePolicy ??
|
|
174
|
+
new aws_cloudfront_1.CachePolicy(this, "DynamicCachePolicy", {
|
|
175
|
+
queryStringBehavior: aws_cloudfront_1.CacheQueryStringBehavior.all(),
|
|
176
|
+
headerBehavior: aws_cloudfront_1.CacheHeaderBehavior.allowList("accept", "rsc", "next-router-prefetch", "next-router-state-tree", "next-url", "x-prerender-revalidate"),
|
|
177
|
+
cookieBehavior: aws_cloudfront_1.CacheCookieBehavior.all(),
|
|
178
|
+
enableAcceptEncodingBrotli: true,
|
|
179
|
+
enableAcceptEncodingGzip: true,
|
|
180
|
+
comment: `Nextjs Dynamic Cache Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
|
|
181
|
+
...this.props.overrides?.dynamicCachePolicyProps,
|
|
182
|
+
});
|
|
183
|
+
const responseHeadersPolicy = dynamicBehaviorOptions?.responseHeadersPolicy ??
|
|
184
|
+
new aws_cloudfront_1.ResponseHeadersPolicy(this, "DynamicResponseHeadersPolicy", {
|
|
185
|
+
securityHeadersBehavior: this.commonSecurityHeadersBehavior,
|
|
186
|
+
comment: `Nextjs Dynamic Response Headers Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
|
|
187
|
+
...this.props.overrides?.dynamicBehaviorOptions?.responseHeadersPolicy,
|
|
188
|
+
});
|
|
189
|
+
const behaviorOptions = {
|
|
190
|
+
allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_ALL,
|
|
191
|
+
cachePolicy,
|
|
192
|
+
edgeLambdas: this.edgeLambdas,
|
|
193
|
+
functionAssociations: this.dynamicCloudFrontFunctionAssociations,
|
|
194
|
+
origin: this.dynamicOrigin,
|
|
195
|
+
originRequestPolicy: this.dynamicOriginResponsePolicy,
|
|
196
|
+
responseHeadersPolicy,
|
|
197
|
+
viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
198
|
+
...dynamicBehaviorOptions,
|
|
199
|
+
};
|
|
200
|
+
return behaviorOptions;
|
|
201
|
+
}
|
|
202
|
+
createImageBehaviorOptions() {
|
|
203
|
+
const imageBehaviorOptions = this.props.overrides?.imageBehaviorOptions;
|
|
204
|
+
// add default cache policy if not provided
|
|
205
|
+
const cachePolicy = imageBehaviorOptions?.cachePolicy ??
|
|
206
|
+
new aws_cloudfront_1.CachePolicy(this, "ImageCachePolicy", {
|
|
207
|
+
queryStringBehavior: aws_cloudfront_1.CacheQueryStringBehavior.all(),
|
|
208
|
+
headerBehavior: aws_cloudfront_1.CacheHeaderBehavior.allowList("accept"),
|
|
209
|
+
cookieBehavior: aws_cloudfront_1.CacheCookieBehavior.none(),
|
|
210
|
+
enableAcceptEncodingBrotli: true,
|
|
211
|
+
enableAcceptEncodingGzip: true,
|
|
212
|
+
comment: `Nextjs Image Cache Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
|
|
213
|
+
...this.props.overrides?.imageCachePolicyProps,
|
|
214
|
+
});
|
|
215
|
+
// add default response headers policy if not provided
|
|
216
|
+
const responseHeadersPolicy = imageBehaviorOptions?.responseHeadersPolicy ??
|
|
217
|
+
new aws_cloudfront_1.ResponseHeadersPolicy(this, "ImageResponseHeadersPolicy", {
|
|
218
|
+
securityHeadersBehavior: this.commonSecurityHeadersBehavior,
|
|
219
|
+
comment: `Nextjs Image Response Headers Policy for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
|
|
220
|
+
...this.props.overrides?.imageResponseHeadersPolicyProps,
|
|
221
|
+
});
|
|
222
|
+
return {
|
|
223
|
+
allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
|
|
224
|
+
cachedMethods: aws_cloudfront_1.CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
225
|
+
edgeLambdas: this.edgeLambdas,
|
|
226
|
+
functionAssociations: this.dynamicCloudFrontFunctionAssociations,
|
|
227
|
+
origin: this.dynamicOrigin,
|
|
228
|
+
originRequestPolicy: this.dynamicOriginResponsePolicy,
|
|
229
|
+
cachePolicy,
|
|
230
|
+
responseHeadersPolicy,
|
|
231
|
+
viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
232
|
+
...imageBehaviorOptions,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Creates or uses user specified CloudFront Distribution
|
|
237
|
+
*/
|
|
238
|
+
getDistribution() {
|
|
239
|
+
let distribution;
|
|
240
|
+
if (this.props.distribution) {
|
|
241
|
+
distribution = this.props.distribution;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
distribution = new aws_cloudfront_1.Distribution(this, "Distribution", {
|
|
245
|
+
minimumProtocolVersion: aws_cloudfront_1.SecurityPolicyProtocol.TLS_V1_2_2021,
|
|
246
|
+
defaultBehavior: this.dynamicBehaviorOptions,
|
|
247
|
+
httpVersion: aws_cloudfront_1.HttpVersion.HTTP2, // HTTP2_AND_3 causes timeout issues with Lambda Function URLs!
|
|
248
|
+
comment: `cdk-nextjs Distribution for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
|
|
249
|
+
...this.props.overrides?.distributionProps,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
return distribution;
|
|
253
|
+
}
|
|
254
|
+
addDynamicBehaviors() {
|
|
255
|
+
// Image Behavior
|
|
256
|
+
this.distribution.addBehavior(this.getPathPattern("_next/image*"), this.imageBehaviorOptions.origin, this.imageBehaviorOptions);
|
|
257
|
+
// Root Path Behaviors
|
|
258
|
+
if (this.props.basePath) {
|
|
259
|
+
// because we already have a basePath we don't use / instead we use /base-path
|
|
260
|
+
this.distribution.addBehavior(this.props.basePath, this.dynamicBehaviorOptions.origin, this.dynamicBehaviorOptions);
|
|
261
|
+
// when basePath is set, we emulate the "default behavior" (*) for the site as `/base-path/*`
|
|
262
|
+
this.distribution.addBehavior(this.getPathPattern("*"), this.dynamicBehaviorOptions.origin, this.dynamicBehaviorOptions);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
// if no base path, then default behavior will handle all other paths
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
addStaticBehaviors() {
|
|
269
|
+
this.distribution.addBehavior("_next/static*", this.staticOrigin, this.staticBehaviorOptions);
|
|
270
|
+
// 22 = 25 (max) - 1 (_next/image) - 1 (_next/static) - 1 (*)
|
|
271
|
+
if (this.props.publicDirEntries.length >= 22) {
|
|
272
|
+
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/*).`);
|
|
273
|
+
}
|
|
274
|
+
for (const publicFile of this.props.publicDirEntries) {
|
|
275
|
+
const pathPattern = publicFile.isDirectory
|
|
276
|
+
? `${publicFile.name}/*`
|
|
277
|
+
: publicFile.name;
|
|
278
|
+
if (!/^[a-zA-Z0-9_\-.*$/~"'@:+?&]+$/.test(pathPattern)) {
|
|
279
|
+
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`);
|
|
280
|
+
}
|
|
281
|
+
const finalPathPattern = this.getPathPattern(pathPattern);
|
|
282
|
+
this.distribution.addBehavior(finalPathPattern, this.staticOrigin, this.staticBehaviorOptions);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Optionally prepends base path to given path pattern.
|
|
287
|
+
*/
|
|
288
|
+
getPathPattern(pathPattern) {
|
|
289
|
+
if (this.props.basePath) {
|
|
290
|
+
return `${this.props.basePath}/${pathPattern}`;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
return pathPattern;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Add Origin Access Control (OAC) to CloudFront Distribution which is preferred
|
|
298
|
+
* way to secure access from Distribution to S3. Remove legacy OAI.
|
|
299
|
+
*
|
|
300
|
+
* When CDK releases L2 support for this, please remove this code.
|
|
301
|
+
* @see https://github.com/aws/aws-cdk/issues/21771#issuecomment-1567647338
|
|
302
|
+
*/
|
|
303
|
+
addS3OacAndRemoveOai() {
|
|
304
|
+
const s3Oac = new aws_cloudfront_1.CfnOriginAccessControl(this, "OAC", {
|
|
305
|
+
originAccessControlConfig: {
|
|
306
|
+
name: `OAC-S3-${this.uniqueStackIdPart}`,
|
|
307
|
+
originAccessControlOriginType: "s3",
|
|
308
|
+
signingBehavior: "always",
|
|
309
|
+
signingProtocol: "sigv4",
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
// add OAC to CloudFront Distribution
|
|
313
|
+
const cfnDistribution = this.distribution.node
|
|
314
|
+
.defaultChild;
|
|
315
|
+
cfnDistribution.addOverride("Properties.DistributionConfig.Origins.1.S3OriginConfig.OriginAccessIdentity", "");
|
|
316
|
+
cfnDistribution.addPropertyOverride("DistributionConfig.Origins.1.OriginAccessControlId", s3Oac.getAtt("Id"));
|
|
317
|
+
// add IAM Policy Statement to allow OAC access to Bucket
|
|
318
|
+
const oacBucketStatement = new aws_iam_1.PolicyStatement({
|
|
319
|
+
sid: "AllowS3OacAccess",
|
|
320
|
+
principals: [new aws_iam_1.ServicePrincipal("cloudfront.amazonaws.com")],
|
|
321
|
+
actions: ["s3:GetObject"],
|
|
322
|
+
resources: [this.props.assetsBucket.bucketArn + "/*"],
|
|
323
|
+
conditions: {
|
|
324
|
+
StringEquals: {
|
|
325
|
+
"aws:sourceArn": aws_cdk_lib_1.Stack.of(this).formatArn({
|
|
326
|
+
service: "cloudfront",
|
|
327
|
+
region: "",
|
|
328
|
+
resource: "distribution",
|
|
329
|
+
resourceName: this.distribution.distributionId,
|
|
330
|
+
arnFormat: aws_cdk_lib_1.ArnFormat.SLASH_RESOURCE_NAME,
|
|
331
|
+
}),
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
this.props.assetsBucket.addToResourcePolicy(oacBucketStatement);
|
|
336
|
+
// Remove OAI IAM Policy Statement from Bucket Policy
|
|
337
|
+
const bucketPolicyJson = this.props.assetsBucket.policy?.document.toJSON();
|
|
338
|
+
const updatedBucketPolicyJson = {
|
|
339
|
+
Version: "2012-10-17",
|
|
340
|
+
Statement: [],
|
|
341
|
+
};
|
|
342
|
+
for (const statement of bucketPolicyJson.Statement) {
|
|
343
|
+
if (!("CanonicalUser" in statement.Principal)) {
|
|
344
|
+
updatedBucketPolicyJson.Statement.push(statement);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const bucketPolicy = this.props.assetsBucket.node.findChild("Policy").node
|
|
348
|
+
.defaultChild;
|
|
349
|
+
bucketPolicy.addOverride("Properties.PolicyDocument", updatedBucketPolicyJson);
|
|
350
|
+
// Remove S3 Origin Resource
|
|
351
|
+
const distributionChildren = this.distribution.node.findAll();
|
|
352
|
+
for (const child of distributionChildren) {
|
|
353
|
+
if (child.node.id === "S3Origin") {
|
|
354
|
+
child.node.tryRemoveChild("Resource");
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
exports.NextjsDistribution = NextjsDistribution;
|
|
360
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
361
|
+
NextjsDistribution[_a] = { fqn: "cdk-nextjs.NextjsDistribution", version: "0.0.0" };
|
|
362
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWRpc3RyaWJ1dGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXh0anMtZGlzdHJpYnV0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBUXFCO0FBRXJCLCtEQTZCb0M7QUFDcEMsK0VBSTRDO0FBQzVDLGlEQUF3RTtBQUV4RSwyQ0FBdUM7QUFDdkMscUNBQXNDO0FBSXRDLHFGQUErRTtBQWtEL0UsTUFBYSxrQkFBbUIsU0FBUSxzQkFBUztJQTZDL0MsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE4QjtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBMUNuQjs7O1dBR0c7UUFDSyxrQ0FBNkIsR0FBb0M7WUFDdkUsa0JBQWtCLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFO1lBQ3ZDLFlBQVksRUFBRTtnQkFDWixXQUFXLEVBQUUsbUNBQWtCLENBQUMsVUFBVTtnQkFDMUMsUUFBUSxFQUFFLEtBQUs7YUFDaEI7WUFDRCxjQUFjLEVBQUU7Z0JBQ2QsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsY0FBYyxFQUFFLHNDQUFxQixDQUFDLCtCQUErQjthQUN0RTtZQUVELHVCQUF1QixFQUFFO2dCQUN2QixtQkFBbUIsRUFBRSxzQkFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7Z0JBQ3ZDLGlCQUFpQixFQUFFLElBQUk7Z0JBQ3ZCLFFBQVEsRUFBRSxLQUFLO2dCQUNmLE9BQU8sRUFBRSxJQUFJO2FBQ2Q7WUFDRCxhQUFhLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRTtTQUN0RSxDQUFDO1FBVUY7OztXQUdHO1FBQ0ssc0JBQWlCLEdBQUcsZ0JBQUUsQ0FBQyxNQUFNLENBQ25DLENBQUMsRUFDRCxnQkFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsZ0JBQUUsQ0FBQyxNQUFN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SyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUk7YUFDdkUsWUFBK0IsQ0FBQztRQUNuQyxZQUFZLENBQUMsV0FBVyxDQUN0QiwyQkFBMkIsRUFDM0IsdUJBQXVCLENBQ3hCLENBQUM7UUFFRiw0QkFBNEI7UUFDNUIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM5RCxLQUFLLE1BQU0sS0FBSyxJQUFJLG9CQUFvQixFQUFFLENBQUM7WUFDekMsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDakMsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOztBQTNaSCxnREE4YUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBcm5Gb3JtYXQsXG4gIEF3cyxcbiAgQ2ZuT3V0cHV0LFxuICBEdXJhdGlvbixcbiAgRm4sXG4gIFJlbW92YWxQb2xpY3ksXG4gIFN0YWNrLFxufSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IElDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBBZGRCZWhhdmlvck9wdGlvbnMsXG4gIEFsbG93ZWRNZXRob2RzLFxuICBCZWhhdmlvck9wdGlvbnMsXG4gIENhY2hlQ29va2llQmVoYXZpb3IsXG4gIENhY2hlSGVhZGVyQmVoYXZpb3IsXG4gIENhY2hlUG9saWN5LFxuICBDYWNoZVBvbGljeVByb3BzLFxuICBDYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IsXG4gIENhY2hlZE1ldGhvZHMsXG4gIENmbkRpc3RyaWJ1dGlvbixcbiAgQ2ZuT3JpZ2luQWNjZXNzQ29udHJvbCxcbiAgRnVuY3Rpb24gYXMgQ2xvdWRGcm9udEZ1bmN0aW9uLFxuICBEaXN0cmlidXRpb24sXG4gIEZ1bmN0aW9uQXNzb2NpYXRpb24sXG4gIEZ1bmN0aW9uQ29kZSxcbiAgRnVuY3Rpb25FdmVudFR5cGUsXG4gIEhlYWRlcnNGcmFtZU9wdGlvbixcbiAgSGVhZGVyc1JlZmVycmVyUG9saWN5LFxuICBIdHRwVmVyc2lvbixcbiAgSU9yaWdpblJlcXVlc3RQb2xpY3ksXG4gIExhbWJkYUVkZ2VFdmVudFR5cGUsXG4gIE9yaWdpblByb3RvY29sUG9saWN5LFxuICBPcmlnaW5SZXF1ZXN0UG9saWN5LFxuICBSZXNwb25zZUhlYWRlcnNQb2xpY3ksXG4gIFJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzLFxuICBSZXNwb25zZVNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yLFxuICBTZWN1cml0eVBvbGljeVByb3RvY29sLFxuICBWaWV3ZXJQcm90b2NvbFBvbGljeSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCI7XG5pbXBvcnQge1xuICBIdHRwT3JpZ2luLFxuICBIdHRwT3JpZ2luUHJvcHMsXG4gIFMzT3JpZ2luLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQtb3JpZ2luc1wiO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBTZXJ2aWNlUHJpbmNpcGFsIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IENmbkJ1Y2tldFBvbGljeSwgSUJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBOZXh0anNUeXBlIH0gZnJvbSBcIi4vY29tbW9uXCI7XG5pbXBvcnQgeyBPcHRpb25hbERpc3RyaWJ1dGlvblByb3BzIH0gZnJvbSBcIi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxEaXN0cmlidXRpb25Qcm9wc1wiO1xuaW1wb3J0IHsgT3B0aW9uYWxGdW5jdGlvblByb3BzIH0gZnJvbSBcIi4vZ2VuZXJhdGVkLXN0cnVjdHMvT3B0aW9uYWxGdW5jdGlvblByb3BzXCI7XG5pbXBvcnQgeyBPcHRpb25hbFMzT3JpZ2luUHJvcHMgfSBmcm9tIFwiLi9nZW5lcmF0ZWQtc3RydWN0cy9PcHRpb25hbFMzT3JpZ2luUHJvcHNcIjtcbmltcG9ydCB7IFNpZ25GblVybEZ1bmN0aW9uIH0gZnJvbSBcIi4vbGFtYmRhcy9zaWduLWZuLXVybC9zaWduLWZuLXVybC1mdW5jdGlvblwiO1xuaW1wb3J0IHsgUHVibGljRGlyRW50cnkgfSBmcm9tIFwiLi9uZXh0anMtYnVpbGQvbmV4dGpzLWJ1aWxkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzRGlzdHJpYnV0aW9uT3ZlcnJpZGVzIHtcbiAgcmVhZG9ubHkgZWRnZUZ1bmN0aW9uUHJvcHM/OiBPcHRpb25hbEZ1bmN0aW9uUHJvcHM7XG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvblByb3BzPzogT3B0aW9uYWxEaXN0cmlidXRpb25Qcm9wcztcbiAgcmVhZG9ubHkgaW1hZ2VCZWhhdmlvck9wdGlvbnM/OiBBZGRCZWhhdmlvck9wdGlvbnM7XG4gIHJlYWRvbmx5IGltYWdlQ2FjaGVQb2xpY3lQcm9wcz86IENhY2hlUG9saWN5UHJvcHM7XG4gIHJlYWRvbmx5IGltYWdlUmVzcG9uc2VIZWFkZXJzUG9saWN5UHJvcHM/OiBSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcztcbiAgcmVhZG9ubHkgZHluYW1pY0JlaGF2aW9yT3B0aW9ucz86IEFkZEJlaGF2aW9yT3B0aW9ucztcbiAgcmVhZG9ubHkgZHluYW1pY0NhY2hlUG9saWN5UHJvcHM/OiBDYWNoZVBvbGljeVByb3BzO1xuICByZWFkb25seSBkeW5hbWljUmVzcG9uc2VIZWFkZXJzUG9saWN5UHJvcHM/OiBSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcztcbiAgcmVhZG9ubHkgZHluYW1pY0h0dHBPcmlnaW5Qcm9wcz86IEh0dHBPcmlnaW5Qcm9wcztcbiAgcmVhZG9ubHkgc3RhdGljQmVoYXZpb3JPcHRpb25zPzogQWRkQmVoYXZpb3JPcHRpb25zO1xuICByZWFkb25seSBzdGF0aWNSZXNwb25zZUhlYWRlcnNQb2xpY3lQcm9wcz86IFJlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzO1xuICByZWFkb25seSBzM09yaWdpblByb3BzPzogT3B0aW9uYWxTM09yaWdpblByb3BzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5leHRqc0Rpc3RyaWJ1dGlvblByb3BzIHtcbiAgLyoqXG4gICAqIEJ1Y2tldCBjb250YWluaW5nIHN0YXRpYyBhc3NldHMuXG4gICAqIE11c3QgYmUgcHJvdmlkZWQgaWYgeW91IHdhbnQgdG8gc2VydmUgc3RhdGljIGZpbGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgYXNzZXRzQnVja2V0OiBJQnVja2V0O1xuICByZWFkb25seSBiYXNlUGF0aD86IHN0cmluZztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGJ1dCBvbmx5IGFwcGxpY2FibGUgZm9yIGBOZXh0anNUeXBlLkdMT0JBTF9DT05UQUlORVJTYFxuICAgKi9cbiAgcmVhZG9ubHkgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGU7XG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbj86IERpc3RyaWJ1dGlvbjtcbiAgLyoqXG4gICAqIER5bmFtaWMgKE5leHQuanMgc2VydmVyKSBVUkwgdG8gYWRkIGJlaGF2aW9yIHRvIGRpc3RyaWJ1dGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZHluYW1pY1VybDogc3RyaW5nO1xuICAvKipcbiAgICogUmVxdWlyZWQgaWYgYE5leHRqc1R5cGUuR0xPQkFMX0ZVTkNUSU9OU2BcbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uQXJuPzogc3RyaW5nO1xuICByZWFkb25seSBuZXh0anNUeXBlOiBOZXh0anNUeXBlO1xuICAvKipcbiAgICogT3ZlcnJpZGUgcHJvcHMgZm9yIGV2ZXJ5IGNvbnN0cnVjdC5cbiAgICovXG4gIHJlYWRvbmx5IG92ZXJyaWRlcz86IE5leHRqc0Rpc3RyaWJ1dGlvbk92ZXJyaWRlcztcbiAgLyoqXG4gICAqIFBhdGggdG8gZGlyZWN0b3J5IG9mIE5leHQuanMgYXBwJ3MgcHVibGljIGRpcmVjdG9yeS4gVXNlZCB0byBhZGQgc3RhdGljXG4gICAqIGJlaGF2aW9ycyB0byBkaXN0cmlidXRpb24uXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNEaXJFbnRyaWVzOiBQdWJsaWNEaXJFbnRyeVtdO1xufVxuXG5leHBvcnQgY2xhc3MgTmV4dGpzRGlzdHJpYnV0aW9uIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgZGlzdHJpYnV0aW9uOiBEaXN0cmlidXRpb247XG5cbiAgcHJpdmF0ZSBwcm9wczogTmV4dGpzRGlzdHJpYnV0aW9uUHJvcHM7XG4gIC8qKlxuICAgKiBDb21tb24gc2VjdXJpdHkgaGVhZGVycyBhcHBsaWVkIGJ5IGRlZmF1bHQgdG8gYWxsIG9yaWdpbnNcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvdXNpbmctbWFuYWdlZC1yZXNwb25zZS1oZWFkZXJzLXBvbGljaWVzLmh0bWwjbWFuYWdlZC1yZXNwb25zZS1oZWFkZXJzLXBvbGljaWVzLXNlY3VyaXR5XG4gICAqL1xuICBwcml2YXRlIGNvbW1vblNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yOiBSZXNwb25zZVNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yID0ge1xuICAgIGNvbnRlbnRUeXBlT3B0aW9uczogeyBvdmVycmlkZTogZmFsc2UgfSxcbiAgICBmcmFtZU9wdGlvbnM6IHtcbiAgICAgIGZyYW1lT3B0aW9uOiBIZWFkZXJzRnJhbWVPcHRpb24uU0FNRU9SSUdJTixcbiAgICAgIG92ZXJyaWRlOiBmYWxzZSxcbiAgICB9LFxuICAgIHJlZmVycmVyUG9saWN5OiB7XG4gICAgICBvdmVycmlkZTogZmFsc2UsXG4gICAgICByZWZlcnJlclBvbGljeTogSGVhZGVyc1JlZmVycmVyUG9saWN5LlNUUklDVF9PUklHSU5fV0hFTl9DUk9TU19PUklHSU4sXG4gICAgfSxcblxuICAgIHN0cmljdFRyYW5zcG9ydFNlY3VyaXR5OiB7XG4gICAgICBhY2Nlc3NDb250cm9sTWF4QWdlOiBEdXJhdGlvbi5kYXlzKDM2NSksXG4gICAgICBpbmNsdWRlU3ViZG9tYWluczogdHJ1ZSxcbiAgICAgIG92ZXJyaWRlOiBmYWxzZSxcbiAgICAgIHByZWxvYWQ6IHRydWUsXG4gICAgfSxcbiAgICB4c3NQcm90ZWN0aW9uOiB7IG92ZXJyaWRlOiBmYWxzZSwgcHJvdGVjdGlvbjogdHJ1ZSwgbW9kZUJsb2NrOiB0cnVlIH0sXG4gIH07XG4gIHByaXZhdGUgc3RhdGljT3JpZ2luOiBTM09yaWdpbjtcbiAgcHJpdmF0ZSBkeW5hbWljT3JpZ2luOiBIdHRwT3JpZ2luO1xuICBwcml2YXRlIGR5bmFtaWNPcmlnaW5SZXNwb25zZVBvbGljeTogSU9yaWdpblJlcXVlc3RQb2xpY3k7XG4gIHByaXZhdGUgZHluYW1pY0Nsb3VkRnJvbnRGdW5jdGlvbkFzc29jaWF0aW9uczogRnVuY3Rpb25Bc3NvY2lhdGlvbltdO1xuICBwcml2YXRlIGVkZ2VMYW1iZGFzPzogQWRkQmVoYXZpb3JPcHRpb25zW1wiZWRnZUxhbWJkYXNcIl07XG4gIHByaXZhdGUgaXNGdW5jdGlvbkNvbXB1dGU6IGJvb2xlYW47XG4gIHByaXZhdGUgc3RhdGljQmVoYXZpb3JPcHRpb25zOiBCZWhhdmlvck9wdGlvbnM7XG4gIHByaXZhdGUgZHluYW1pY0JlaGF2aW9yT3B0aW9uczogQmVoYXZpb3JPcHRpb25zO1xuICBwcml2YXRlIGltYWdlQmVoYXZpb3JPcHRpb25zOiBCZWhhdmlvck9wdGlvbnM7XG4gIC8qKlxuICAgKiBHaXZlbiBzdGFjayBpZDogXCJhcm46YXdzOmNsb3VkZm9ybWF0aW9uOnVzLWVhc3QtMTo5MDU0MTgzNTg5MDM6c3RhY2svbGgtc3RpY2tiLWlkcC80YmY3NGJlMC1lODgwLTExZWUtYWVhOS0wYWZmYzYxODViMjVcIixcbiAgICogcmV0dXJucyBcIjRiZjc0YmUwXCJcbiAgICovXG4gIHByaXZhdGUgdW5pcXVlU3RhY2tJZFBhcnQgPSBGbi5zZWxlY3QoXG4gICAgMCxcbiAgICBGbi5zcGxpdChcIi1cIiwgRm4uc2VsZWN0KDIsIEZuLnNwbGl0KFwiL1wiLCBgJHtBd3MuU1RBQ0tfSUR9YCkpKSxcbiAgKTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzRGlzdHJpYnV0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLnN0YXRpY09yaWdpbiA9IHRoaXMuY3JlYXRlU3RhdGljT3JpZ2luKCk7XG4gICAgdGhpcy5pc0Z1bmN0aW9uQ29tcHV0ZSA9IHByb3BzLm5leHRqc1R5cGUgPT09IE5leHRqc1R5cGUuR0xPQkFMX0ZVTkNUSU9OUztcbiAgICB0aGlzLmR5bmFtaWNPcmlnaW4gPSB0aGlzLmNyZWF0ZUR5bmFtaWNPcmlnaW4oKTtcbiAgICB0aGlzLmR5bmFtaWNPcmlnaW5SZXNwb25zZVBvbGljeSA9IHRoaXMuY3JlYXRlRHluYW1pY09yaWdpblJlcXVlc3RQb2xpY3koKTtcbiAgICB0aGlzLmR5bmFtaWNDbG91ZEZyb250RnVuY3Rpb25Bc3NvY2lhdGlvbnMgPVxuICAgICAgdGhpcy5jcmVhdGVEeW5hbWljQ2xvdWRGcm9udEZ1bmN0aW9uQXNzb2NpYXRpb25zKCk7XG4gICAgaWYgKHRoaXMuaXNGdW5jdGlvbkNvbXB1dGUpIHtcbiAgICAgIHRoaXMuZWRnZUxhbWJkYXMgPSB0aGlzLmNyZWF0ZUVkZ2VMYW1iZGFzKCk7XG4gICAgfVxuICAgIHRoaXMuc3RhdGljQmVoYXZpb3JPcHRpb25zID0gdGhpcy5jcmVhdGVTdGF0aWNCZWhhdmlvck9wdGlvbnMoKTtcbiAgICB0aGlzLmR5bmFtaWNCZWhhdmlvck9wdGlvbnMgPSB0aGlzLmNyZWF0ZUR5bmFtaWNCZWhhdmlvck9wdGlvbnMoKTtcbiAgICB0aGlzLmltYWdlQmVoYXZpb3JPcHRpb25zID0gdGhpcy5jcmVhdGVJbWFnZUJlaGF2aW9yT3B0aW9ucygpO1xuICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gdGhpcy5nZXREaXN0cmlidXRpb24oKTtcbiAgICB0aGlzLmFkZFN0YXRpY0JlaGF2aW9ycygpO1xuICAgIHRoaXMuYWRkRHluYW1pY0JlaGF2aW9ycygpO1xuICAgIHRoaXMuYWRkUzNPYWNBbmRSZW1vdmVPYWkoKTtcbiAgICBpZiAodGhpcy5pc0Z1bmN0aW9uQ29tcHV0ZSkge1xuICAgICAgLy8gdGhpcy5hZGRMYW1iZGFPYWMoKTsgLy8gVE9ETzogd2FpdCBmb3IgUE9TVCBib2R5IGVuY3J5cHRpb24gZmVhdHVyZSBmb3IgTGFtYmRhIE9BQ1xuICAgIH1cbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIFwiRGlzdHJpYnV0aW9uRG9tYWluTmFtZVwiLCB7XG4gICAgICB2YWx1ZTogdGhpcy5kaXN0cmlidXRpb24uZG9tYWluTmFtZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU3RhdGljT3JpZ2luKCk6IFMzT3JpZ2luIHtcbiAgICBjb25zdCBzM09yaWdpbiA9IG5ldyBTM09yaWdpbihcbiAgICAgIHRoaXMucHJvcHMuYXNzZXRzQnVja2V0LFxuICAgICAgdGhpcy5wcm9wcy5vdmVycmlkZXM/LnMzT3JpZ2luUHJvcHMsXG4gICAgKTtcbiAgICByZXR1cm4gczNPcmlnaW47XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVEeW5hbWljT3JpZ2luKCk6IEh0dHBPcmlnaW4ge1xuICAgIGxldCBwcm90b2NvbFBvbGljeTogT3JpZ2luUHJvdG9jb2xQb2xpY3k7XG4gICAgaWYgKHRoaXMuaXNGdW5jdGlvbkNvbXB1dGUpIHtcbiAgICAgIHByb3RvY29sUG9saWN5ID0gT3JpZ2luUHJvdG9jb2xQb2xpY3kuSFRUUFNfT05MWTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvdG9jb2xQb2xpY3kgPSB0aGlzLnByb3BzLmNlcnRpZmljYXRlXG4gICAgICAgID8gT3JpZ2luUHJvdG9jb2xQb2xpY3kuSFRUUFNfT05MWVxuICAgICAgICA6IE9yaWdpblByb3RvY29sUG9saWN5LkhUVFBfT05MWTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBIdHRwT3JpZ2luKEZuLnBhcnNlRG9tYWluTmFtZSh0aGlzLnByb3BzLmR5bmFtaWNVcmwpLCB7XG4gICAgICBwcm90b2NvbFBvbGljeSxcbiAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5keW5hbWljSHR0cE9yaWdpblByb3BzLFxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBMYW1iZGEgRnVuY3Rpb24gVVJMcyBcImV4cGVjdCB0aGUgYEhvc3RgIGhlYWRlciB0byBjb250YWluIHRoZSBvcmlnaW4gZG9tYWluXG4gICAqIG5hbWUsIG5vdCB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlwiXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkRnJvbnQvbGF0ZXN0L0RldmVsb3Blckd1aWRlL3VzaW5nLW1hbmFnZWQtb3JpZ2luLXJlcXVlc3QtcG9saWNpZXMuaHRtbCNtYW5hZ2VkLW9yaWdpbi1yZXF1ZXN0LXBvbGljeS1hbGwtdmlld2VyLWV4Y2VwdC1ob3N0LWhlYWRlclxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEeW5hbWljT3JpZ2luUmVxdWVzdFBvbGljeSgpOiBJT3JpZ2luUmVxdWVzdFBvbGljeSB7XG4gICAgcmV0dXJuIHRoaXMuaXNGdW5jdGlvbkNvbXB1dGVcbiAgICAgID8gT3JpZ2luUmVxdWVzdFBvbGljeS5BTExfVklFV0VSX0VYQ0VQVF9IT1NUX0hFQURFUlxuICAgICAgOiBPcmlnaW5SZXF1ZXN0UG9saWN5LkFMTF9WSUVXRVI7XG4gIH1cbiAgLyoqXG4gICAqIEVuc3VyZXMgTmV4dC5qcyBgcmVxdWVzdC51cmxgIHdpbGwgYmUgY29ycmVjdCBkb21haW4gaW5zdGVhZCBvZiBVUkwgb2ZcbiAgICogY29tcHV0ZSBvcHRpb24gKEFwcCBSdW5uZXIsIEZhcmdhdGUsIG9yIExhbWJkYSlcbiAgICogQHNlZSBodHRwczovL29wZW4tbmV4dC5qcy5vcmcvYWR2YW5jZWQvd29ya2Fyb3VuZCN3b3JrYXJvdW5kLXNldC14LWZvcndhcmRlZC1ob3N0LWhlYWRlci1hd3Mtc3BlY2lmaWNcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRHluYW1pY0Nsb3VkRnJvbnRGdW5jdGlvbkFzc29jaWF0aW9ucygpOiBGdW5jdGlvbkFzc29jaWF0aW9uW10ge1xuICAgIGNvbnN0IGFzc29jaWF0aW9uczogRnVuY3Rpb25Bc3NvY2lhdGlvbltdID0gW107XG4gICAgaWYgKHRoaXMuaXNGdW5jdGlvbkNvbXB1dGUpIHtcbiAgICAgIGNvbnN0IGNsb3VkRnJvbnRGbiA9IG5ldyBDbG91ZEZyb250RnVuY3Rpb24odGhpcywgXCJDbG91ZEZyb250Rm5cIiwge1xuICAgICAgICBjb2RlOiBGdW5jdGlvbkNvZGUuZnJvbUlubGluZShgXG4gICAgICAgICAgZnVuY3Rpb24gaGFuZGxlcihldmVudCkge1xuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSBldmVudC5yZXF1ZXN0O1xuICAgICAgICAgICAgcmVxdWVzdC5oZWFkZXJzW1wieC1mb3J3YXJkZWQtaG9zdFwiXSA9IHJlcXVlc3QuaGVhZGVycy5ob3N0O1xuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgICAgICAgfVxuICAgICAgICAgIGApLFxuICAgICAgfSk7XG4gICAgICBhc3NvY2lhdGlvbnMucHVzaCh7XG4gICAgICAgIGV2ZW50VHlwZTogRnVuY3Rpb25FdmVudFR5cGUuVklFV0VSX1JFUVVFU1QsXG4gICAgICAgIGZ1bmN0aW9uOiBjbG91ZEZyb250Rm4sXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGFzc29jaWF0aW9ucztcbiAgfVxuICAvKipcbiAgICogUmVxdWlyZWQgdG8gc2lnbiByZXF1ZXN0cyBzbyB0aGF0IHdlIGNhbiB1c2UgSUFNX0FVVEggZm9yIExhbWJkYSBGdW5jdGlvbiBVUkxcbiAgICogdG8gcHJldmVudCBwdWJsaWMgYWNjZXNzLiBPbmNlIENsb3VkRnJvbnQgTGFtYmRhIE9BQyBpcyByZWxlYXNlZCwgd2UgY2FuXG4gICAqIHVzZSBpbmZyYSBjb25maWd1cmF0aW9uIGZvciB0aGlzIGluc3RlYWQgb2YgY3VzdG9tIGNvZGUuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUVkZ2VMYW1iZGFzKCk6IEFkZEJlaGF2aW9yT3B0aW9uc1tcImVkZ2VMYW1iZGFzXCJdIHtcbiAgICBpZiAoIXRoaXMucHJvcHMuZnVuY3Rpb25Bcm4pIHRocm93IG5ldyBFcnJvcihcImZ1bmN0aW9uQXJuIGlzIHJlcXVpcmVkXCIpO1xuICAgIGNvbnN0IGVkZ2VGbiA9IG5ldyBTaWduRm5VcmxGdW5jdGlvbih0aGlzLCBcIlNpZ25GblVybFwiLCB7XG4gICAgICBjdXJyZW50VmVyc2lvbk9wdGlvbnM6IHtcbiAgICAgICAgcmV0cnlBdHRlbXB0czogMCwgLy8gZmFpbCBmYXN0IHdoZW4gdHJ5aW5nIHRvIGRlbGV0ZSBiL2MgcmVwbGljYXRlZCBmdW5jdGlvbnMgdGFrZSBsb25nIHRpbWUgdG8gZGVsZXRlXG4gICAgICB9LFxuICAgICAgaW5pdGlhbFBvbGljeTogW1xuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJsYW1iZGE6SW52b2tlRnVuY3Rpb25VcmxcIl0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbdGhpcy5wcm9wcy5mdW5jdGlvbkFybl0sXG4gICAgICAgIH0pLFxuICAgICAgXSxcbiAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5lZGdlRnVuY3Rpb25Qcm9wcyxcbiAgICB9KTtcbiAgICBlZGdlRm4uY3VycmVudFZlcnNpb24uZ3JhbnRJbnZva2UoXG4gICAgICBuZXcgU2VydmljZVByaW5jaXBhbChcImVkZ2VsYW1iZGEuYW1hem9uYXdzLmNvbVwiKSxcbiAgICApO1xuICAgIGVkZ2VGbi5jdXJyZW50VmVyc2lvbi5ncmFudEludm9rZShcbiAgICAgIG5ldyBTZXJ2aWNlUHJpbmNpcGFsKFwibGFtYmRhLmFtYXpvbmF3cy5jb21cIiksXG4gICAgKTtcbiAgICAvLyByZXRhaW4gb24gZGVsZXRlIGIvYyB0aGV5IHRha2UgdG9vIGxvbmcgdG8gZGVsZXRlIHJlc3VsdGluZyBpbiBzdGFjayBmYWlsdXJlXG4gICAgZWRnZUZuLmFwcGx5UmVtb3ZhbFBvbGljeShSZW1vdmFsUG9saWN5LlJFVEFJTik7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgZXZlbnRUeXBlOiBMYW1iZGFFZGdlRXZlbnRUeXBlLk9SSUdJTl9SRVFVRVNULFxuICAgICAgICBmdW5jdGlvblZlcnNpb246IGVkZ2VGbi5jdXJyZW50VmVyc2lvbixcbiAgICAgICAgaW5jbHVkZUJvZHk6IHRydWUsXG4gICAgICB9LFxuICAgIF07XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVTdGF0aWNCZWhhdmlvck9wdGlvbnMoKTogQmVoYXZpb3JPcHRpb25zIHtcbiAgICBjb25zdCBzdGF0aWNCZWhhdmlvck9wdGlvbnMgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uc3RhdGljQmVoYXZpb3JPcHRpb25zO1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVyc1BvbGljeSA9XG4gICAgICBzdGF0aWNCZWhhdmlvck9wdGlvbnM/LnJlc3BvbnNlSGVhZGVyc1BvbGljeSA/P1xuICAgICAgbmV3IFJlc3BvbnNlSGVhZGVyc1BvbGljeSh0aGlzLCBcIlN0YXRpY1Jlc3BvbnNlSGVhZGVyc1BvbGljeVwiLCB7XG4gICAgICAgIHNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yOiB0aGlzLmNvbW1vblNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yLFxuICAgICAgICBjb21tZW50OiBgTmV4dGpzIFN0YXRpYyBSZXNwb25zZSBIZWFkZXJzIFBvbGljeSBmb3IgJHtTdGFjay5vZih0aGlzKS5zdGFja05hbWV9YCxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LnN0YXRpY1Jlc3BvbnNlSGVhZGVyc1BvbGljeVByb3BzLFxuICAgICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFsbG93ZWRNZXRob2RzOiBBbGxvd2VkTWV0aG9kcy5BTExPV19HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgY2FjaGVkTWV0aG9kczogQ2FjaGVkTWV0aG9kcy5DQUNIRV9HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgY2FjaGVQb2xpY3k6IENhY2hlUG9saWN5LkNBQ0hJTkdfT1BUSU1JWkVELFxuICAgICAgb3JpZ2luOiB0aGlzLnN0YXRpY09yaWdpbixcbiAgICAgIHJlc3BvbnNlSGVhZGVyc1BvbGljeSxcbiAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgIC4uLnN0YXRpY0JlaGF2aW9yT3B0aW9ucyxcbiAgICB9O1xuICB9XG4gIHByaXZhdGUgY3JlYXRlRHluYW1pY0JlaGF2aW9yT3B0aW9ucygpOiBCZWhhdmlvck9wdGlvbnMge1xuICAgIGNvbnN0IGR5bmFtaWNCZWhhdmlvck9wdGlvbnMgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uZHluYW1pY0JlaGF2aW9yT3B0aW9ucztcbiAgICAvLyBjcmVhdGUgZGVmYXVsdCBjYWNoZSBwb2xpY3kgaWYgbm90IHByb3ZpZGVkXG4gICAgY29uc3QgY2FjaGVQb2xpY3kgPVxuICAgICAgZHluYW1pY0JlaGF2aW9yT3B0aW9ucz8uY2FjaGVQb2xpY3kgPz9cbiAgICAgIG5ldyBDYWNoZVBvbGljeSh0aGlzLCBcIkR5bmFtaWNDYWNoZVBvbGljeVwiLCB7XG4gICAgICAgIHF1ZXJ5U3RyaW5nQmVoYXZpb3I6IENhY2hlUXVlcnlTdHJpbmdCZWhhdmlvci5hbGwoKSxcbiAgICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KFxuICAgICAgICAgIFwiYWNjZXB0XCIsXG4gICAgICAgICAgXCJyc2NcIixcbiAgICAgICAgICBcIm5leHQtcm91dGVyLXByZWZldGNoXCIsXG4gICAgICAgICAgXCJuZXh0LXJvdXRlci1zdGF0ZS10cmVlXCIsXG4gICAgICAgICAgXCJuZXh0LXVybFwiLFxuICAgICAgICAgIFwieC1wcmVyZW5kZXItcmV2YWxpZGF0ZVwiLFxuICAgICAgICApLFxuICAgICAgICBjb29raWVCZWhhdmlvcjogQ2FjaGVDb29raWVCZWhhdmlvci5hbGwoKSxcbiAgICAgICAgZW5hYmxlQWNjZXB0RW5jb2RpbmdCcm90bGk6IHRydWUsXG4gICAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nR3ppcDogdHJ1ZSxcbiAgICAgICAgY29tbWVudDogYE5leHRqcyBEeW5hbWljIENhY2hlIFBvbGljeSBmb3IgJHtTdGFjay5vZih0aGlzKS5zdGFja05hbWV9YCxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmR5bmFtaWNDYWNoZVBvbGljeVByb3BzLFxuICAgICAgfSk7XG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzUG9saWN5ID1cbiAgICAgIGR5bmFtaWNCZWhhdmlvck9wdGlvbnM/LnJlc3BvbnNlSGVhZGVyc1BvbGljeSA/P1xuICAgICAgbmV3IFJlc3BvbnNlSGVhZGVyc1BvbGljeSh0aGlzLCBcIkR5bmFtaWNSZXNwb25zZUhlYWRlcnNQb2xpY3lcIiwge1xuICAgICAgICBzZWN1cml0eUhlYWRlcnNCZWhhdmlvcjogdGhpcy5jb21tb25TZWN1cml0eUhlYWRlcnNCZWhhdmlvcixcbiAgICAgICAgY29tbWVudDogYE5leHRqcyBEeW5hbWljIFJlc3BvbnNlIEhlYWRlcnMgUG9saWN5IGZvciAke1N0YWNrLm9mKHRoaXMpLnN0YWNrTmFtZX1gLFxuICAgICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uZHluYW1pY0JlaGF2aW9yT3B0aW9ucz8ucmVzcG9uc2VIZWFkZXJzUG9saWN5LFxuICAgICAgfSk7XG4gICAgY29uc3QgYmVoYXZpb3JPcHRpb25zOiBCZWhhdmlvck9wdGlvbnMgPSB7XG4gICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfQUxMLFxuICAgICAgY2FjaGVQb2xpY3ksXG4gICAgICBlZGdlTGFtYmRhczogdGhpcy5lZGdlTGFtYmRhcyxcbiAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiB0aGlzLmR5bmFtaWNDbG91ZEZyb250RnVuY3Rpb25Bc3NvY2lhdGlvbnMsXG4gICAgICBvcmlnaW46IHRoaXMuZHluYW1pY09yaWdpbixcbiAgICAgIG9yaWdpblJlcXVlc3RQb2xpY3k6IHRoaXMuZHluYW1pY09yaWdpblJlc3BvbnNlUG9saWN5LFxuICAgICAgcmVzcG9uc2VIZWFkZXJzUG9saWN5LFxuICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IFZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgLi4uZHluYW1pY0JlaGF2aW9yT3B0aW9ucyxcbiAgICB9O1xuICAgIHJldHVybiBiZWhhdmlvck9wdGlvbnM7XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVJbWFnZUJlaGF2aW9yT3B0aW9ucygpOiBCZWhhdmlvck9wdGlvbnMge1xuICAgIGNvbnN0IGltYWdlQmVoYXZpb3JPcHRpb25zID0gdGhpcy5wcm9wcy5vdmVycmlkZXM/LmltYWdlQmVoYXZpb3JPcHRpb25zO1xuICAgIC8vIGFkZCBkZWZhdWx0IGNhY2hlIHBvbGljeSBpZiBub3QgcHJvdmlkZWRcbiAgICBjb25zdCBjYWNoZVBvbGljeSA9XG4gICAgICBpbWFnZUJlaGF2aW9yT3B0aW9ucz8uY2FjaGVQb2xpY3kgPz9cbiAgICAgIG5ldyBDYWNoZVBvbGljeSh0aGlzLCBcIkltYWdlQ2FjaGVQb2xpY3lcIiwge1xuICAgICAgICBxdWVyeVN0cmluZ0JlaGF2aW9yOiBDYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IuYWxsKCksXG4gICAgICAgIGhlYWRlckJlaGF2aW9yOiBDYWNoZUhlYWRlckJlaGF2aW9yLmFsbG93TGlzdChcImFjY2VwdFwiKSxcbiAgICAgICAgY29va2llQmVoYXZpb3I6IENhY2hlQ29va2llQmVoYXZpb3Iubm9uZSgpLFxuICAgICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0Jyb3RsaTogdHJ1ZSxcbiAgICAgICAgZW5hYmxlQWNjZXB0RW5jb2RpbmdHemlwOiB0cnVlLFxuICAgICAgICBjb21tZW50OiBgTmV4dGpzIEltYWdlIENhY2hlIFBvbGljeSBmb3IgJHtTdGFjay5vZih0aGlzKS5zdGFja05hbWV9YCxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmltYWdlQ2FjaGVQb2xpY3lQcm9wcyxcbiAgICAgIH0pO1xuICAgIC8vIGFkZCBkZWZhdWx0IHJlc3BvbnNlIGhlYWRlcnMgcG9saWN5IGlmIG5vdCBwcm92aWRlZFxuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVyc1BvbGljeSA9XG4gICAgICBpbWFnZUJlaGF2aW9yT3B0aW9ucz8ucmVzcG9uc2VIZWFkZXJzUG9saWN5ID8/XG4gICAgICBuZXcgUmVzcG9uc2VIZWFkZXJzUG9saWN5KHRoaXMsIFwiSW1hZ2VSZXNwb25zZUhlYWRlcnNQb2xpY3lcIiwge1xuICAgICAgICBzZWN1cml0eUhlYWRlcnNCZWhhdmlvcjogdGhpcy5jb21tb25TZWN1cml0eUhlYWRlcnNCZWhhdmlvcixcbiAgICAgICAgY29tbWVudDogYE5leHRqcyBJbWFnZSBSZXNwb25zZSBIZWFkZXJzIFBvbGljeSBmb3IgJHtTdGFjay5vZih0aGlzKS5zdGFja05hbWV9YCxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmltYWdlUmVzcG9uc2VIZWFkZXJzUG9saWN5UHJvcHMsXG4gICAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgYWxsb3dlZE1ldGhvZHM6IEFsbG93ZWRNZXRob2RzLkFMTE9XX0dFVF9IRUFEX09QVElPTlMsXG4gICAgICBjYWNoZWRNZXRob2RzOiBDYWNoZWRNZXRob2RzLkNBQ0hFX0dFVF9IRUFEX09QVElPTlMsXG4gICAgICBlZGdlTGFtYmRhczogdGhpcy5lZGdlTGFtYmRhcyxcbiAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiB0aGlzLmR5bmFtaWNDbG91ZEZyb250RnVuY3Rpb25Bc3NvY2lhdGlvbnMsXG4gICAgICBvcmlnaW46IHRoaXMuZHluYW1pY09yaWdpbixcbiAgICAgIG9yaWdpblJlcXVlc3RQb2xpY3k6IHRoaXMuZHluYW1pY09yaWdpblJlc3BvbnNlUG9saWN5LFxuICAgICAgY2FjaGVQb2xpY3ksXG4gICAgICByZXNwb25zZUhlYWRlcnNQb2xpY3ksXG4gICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICAuLi5pbWFnZUJlaGF2aW9yT3B0aW9ucyxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiBDcmVhdGVzIG9yIHVzZXMgdXNlciBzcGVjaWZpZWQgQ2xvdWRGcm9udCBEaXN0cmlidXRpb25cbiAgICovXG4gIHByaXZhdGUgZ2V0RGlzdHJpYnV0aW9uKCk6IERpc3RyaWJ1dGlvbiB7XG4gICAgbGV0IGRpc3RyaWJ1dGlvbjogRGlzdHJpYnV0aW9uO1xuICAgIGlmICh0aGlzLnByb3BzLmRpc3RyaWJ1dGlvbikge1xuICAgICAgZGlzdHJpYnV0aW9uID0gdGhpcy5wcm9wcy5kaXN0cmlidXRpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpc3RyaWJ1dGlvbiA9IG5ldyBEaXN0cmlidXRpb24odGhpcywgXCJEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBtaW5pbXVtUHJvdG9jb2xWZXJzaW9uOiBTZWN1cml0eVBvbGljeVByb3RvY29sLlRMU19WMV8yXzIwMjEsXG4gICAgICAgIGRlZmF1bHRCZWhhdmlvcjogdGhpcy5keW5hbWljQmVoYXZpb3JPcHRpb25zLFxuICAgICAgICBodHRwVmVyc2lvbjogSHR0cFZlcnNpb24uSFRUUDIsIC8vIEhUVFAyX0FORF8zIGNhdXNlcyB0aW1lb3V0IGlzc3VlcyB3aXRoIExhbWJkYSBGdW5jdGlvbiBVUkxzIVxuICAgICAgICBjb21tZW50OiBgY2RrLW5leHRqcyBEaXN0cmlidXRpb24gZm9yICR7U3RhY2sub2YodGhpcykuc3RhY2tOYW1lfWAsXG4gICAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5kaXN0cmlidXRpb25Qcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZGlzdHJpYnV0aW9uO1xuICB9XG4gIHByaXZhdGUgYWRkRHluYW1pY0JlaGF2aW9ycygpIHtcbiAgICAvLyBJbWFnZSBCZWhhdmlvclxuICAgIHRoaXMuZGlzdHJpYnV0aW9uLmFkZEJlaGF2aW9yKFxuICAgICAgdGhpcy5nZXRQYXRoUGF0dGVybihcIl9uZXh0L2ltYWdlKlwiKSxcbiAgICAgIHRoaXMuaW1hZ2VCZWhhdmlvck9wdGlvbnMub3JpZ2luLFxuICAgICAgdGhpcy5pbWFnZUJlaGF2aW9yT3B0aW9ucyxcbiAgICApO1xuICAgIC8vIFJvb3QgUGF0aCBCZWhhdmlvcnNcbiAgICBpZiAodGhpcy5wcm9wcy5iYXNlUGF0aCkge1xuICAgICAgLy8gYmVjYXVzZSB3ZSBhbHJlYWR5IGhhdmUgYSBiYXNlUGF0aCB3ZSBkb24ndCB1c2UgLyBpbnN0ZWFkIHdlIHVzZSAvYmFzZS1wYXRoXG4gICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihcbiAgICAgICAgdGhpcy5wcm9wcy5iYXNlUGF0aCxcbiAgICAgICAgdGhpcy5keW5hbWljQmVoYXZpb3JPcHRpb25zLm9yaWdpbixcbiAgICAgICAgdGhpcy5keW5hbWljQmVoYXZpb3JPcHRpb25zLFxuICAgICAgKTtcbiAgICAgIC8vIHdoZW4gYmFzZVBhdGggaXMgc2V0LCB3ZSBlbXVsYXRlIHRoZSBcImRlZmF1bHQgYmVoYXZpb3JcIiAoKikgZm9yIHRoZSBzaXRlIGFzIGAvYmFzZS1wYXRoLypgXG4gICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihcbiAgICAgICAgdGhpcy5nZXRQYXRoUGF0dGVybihcIipcIiksXG4gICAgICAgIHRoaXMuZHluYW1pY0JlaGF2aW9yT3B0aW9ucy5vcmlnaW4sXG4gICAgICAgIHRoaXMuZHluYW1pY0JlaGF2aW9yT3B0aW9ucyxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIG5vIGJhc2UgcGF0aCwgdGhlbiBkZWZhdWx0IGJlaGF2aW9yIHdpbGwgaGFuZGxlIGFsbCBvdGhlciBwYXRoc1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGFkZFN0YXRpY0JlaGF2aW9ycygpIHtcbiAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihcbiAgICAgIFwiX25leHQvc3RhdGljKlwiLFxuICAgICAgdGhpcy5zdGF0aWNPcmlnaW4sXG4gICAgICB0aGlzLnN0YXRpY0JlaGF2aW9yT3B0aW9ucyxcbiAgICApO1xuICAgIC8vIDIyID0gMjUgKG1heCkgLSAxIChfbmV4dC9pbWFnZSkgLSAxIChfbmV4dC9zdGF0aWMpIC0gMSAoKilcbiAgICBpZiAodGhpcy5wcm9wcy5wdWJsaWNEaXJFbnRyaWVzLmxlbmd0aCA+PSAyMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVG9vIG1hbnkgcHVibGljLyBmaWxlcyBpbiBOZXh0LmpzIGJ1aWxkLiBDbG91ZEZyb250IGxpbWl0cyBEaXN0cmlidXRpb25zIHRvIDI1IENhY2hlIEJlaGF2aW9ycy4gU2VlIGRvY3VtZW50ZWQgbGltaXQgaGVyZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkRnJvbnQvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Nsb3VkZnJvbnQtbGltaXRzLmh0bWwjbGltaXRzLXdlYi1kaXN0cmlidXRpb25zLiBUcnkgaW5jbHVkaW5nIGFsbCBwdWJsaWMgZmlsZXMgaW50byAxIHRvcCBsZXZlbCBkaXJlY3RvcnkgKGkuZS4gc3RhdGljLyopLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHB1YmxpY0ZpbGUgb2YgdGhpcy5wcm9wcy5wdWJsaWNEaXJFbnRyaWVzKSB7XG4gICAgICBjb25zdCBwYXRoUGF0dGVybiA9IHB1YmxpY0ZpbGUuaXNEaXJlY3RvcnlcbiAgICAgICAgPyBgJHtwdWJsaWNGaWxlLm5hbWV9LypgXG4gICAgICAgIDogcHVibGljRmlsZS5uYW1lO1xuICAgICAgaWYgKCEvXlthLXpBLVowLTlfXFwtLiokL35cIidAOis/Jl0rJC8udGVzdChwYXRoUGF0dGVybikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBJbnZhbGlkIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIENhY2hlIEJlaGF2aW9yIFBhdGggUGF0dGVybjogJHtwYXRoUGF0dGVybn0uIFBsZWFzZSBzZWUgZG9jdW1lbnRhdGlvbiBoZXJlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZGlzdHJpYnV0aW9uLXdlYi12YWx1ZXMtc3BlY2lmeS5odG1sI0Rvd25sb2FkRGlzdFZhbHVlc1BhdGhQYXR0ZXJuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbmFsUGF0aFBhdHRlcm4gPSB0aGlzLmdldFBhdGhQYXR0ZXJuKHBhdGhQYXR0ZXJuKTtcbiAgICAgIHRoaXMuZGlzdHJpYnV0aW9uLmFkZEJlaGF2aW9yKFxuICAgICAgICBmaW5hbFBhdGhQYXR0ZXJuLFxuICAgICAgICB0aGlzLnN0YXRpY09yaWdpbixcbiAgICAgICAgdGhpcy5zdGF0aWNCZWhhdmlvck9wdGlvbnMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogT3B0aW9uYWxseSBwcmVwZW5kcyBiYXNlIHBhdGggdG8gZ2l2ZW4gcGF0aCBwYXR0ZXJuLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQYXRoUGF0dGVybihwYXRoUGF0dGVybjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMucHJvcHMuYmFzZVBhdGgpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnByb3BzLmJhc2VQYXRofS8ke3BhdGhQYXR0ZXJufWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYXRoUGF0dGVybjtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEFkZCBPcmlnaW4gQWNjZXNzIENvbnRyb2wgKE9BQykgdG8gQ2xvdWRGcm9udCBEaXN0cmlidXRpb24gd2hpY2ggaXMgcHJlZmVycmVkXG4gICAqIHdheSB0byBzZWN1cmUgYWNjZXNzIGZyb20gRGlzdHJpYnV0aW9uIHRvIFMzLiBSZW1vdmUgbGVnYWN5IE9BSS5cbiAgICpcbiAgICogV2hlbiBDREsgcmVsZWFzZXMgTDIgc3VwcG9ydCBmb3IgdGhpcywgcGxlYXNlIHJlbW92ZSB0aGlzIGNvZGUuXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8yMTc3MSNpc3N1ZWNvbW1lbnQtMTU2NzY0NzMzOFxuICAgKi9cbiAgcHJpdmF0ZSBhZGRTM09hY0FuZFJlbW92ZU9haSgpIHtcbiAgICBjb25zdCBzM09hYyA9IG5ldyBDZm5PcmlnaW5BY2Nlc3NDb250cm9sKHRoaXMsIFwiT0FDXCIsIHtcbiAgICAgIG9yaWdpbkFjY2Vzc0NvbnRyb2xDb25maWc6IHtcbiAgICAgICAgbmFtZTogYE9BQy1TMy0ke3RoaXMudW5pcXVlU3RhY2tJZFBhcnR9YCxcbiAgICAgICAgb3JpZ2luQWNjZXNzQ29udHJvbE9yaWdpblR5cGU6IFwiczNcIixcbiAgICAgICAgc2lnbmluZ0JlaGF2aW9yOiBcImFsd2F5c1wiLFxuICAgICAgICBzaWduaW5nUHJvdG9jb2w6IFwic2lndjRcIixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgLy8gYWRkIE9BQyB0byBDbG91ZEZyb250IERpc3RyaWJ1dGlvblxuICAgIGNvbnN0IGNmbkRpc3RyaWJ1dGlvbiA9IHRoaXMuZGlzdHJpYnV0aW9uLm5vZGVcbiAgICAgIC5kZWZhdWx0Q2hpbGQgYXMgQ2ZuRGlzdHJpYnV0aW9uO1xuICAgIGNmbkRpc3RyaWJ1dGlvbi5hZGRPdmVycmlkZShcbiAgICAgIFwiUHJvcGVydGllcy5EaXN0cmlidXRpb25Db25maWcuT3JpZ2lucy4xLlMzT3JpZ2luQ29uZmlnLk9yaWdpbkFjY2Vzc0lkZW50aXR5XCIsXG4gICAgICBcIlwiLFxuICAgICk7XG4gICAgY2ZuRGlzdHJpYnV0aW9uLmFkZFByb3BlcnR5T3ZlcnJpZGUoXG4gICAgICBcIkRpc3RyaWJ1dGlvbkNvbmZpZy5PcmlnaW5zLjEuT3JpZ2luQWNjZXNzQ29udHJvbElkXCIsXG4gICAgICBzM09hYy5nZXRBdHQoXCJJZFwiKSxcbiAgICApO1xuXG4gICAgLy8gYWRkIElBTSBQb2xpY3kgU3RhdGVtZW50IHRvIGFsbG93IE9BQyBhY2Nlc3MgdG8gQnVja2V0XG4gICAgY29uc3Qgb2FjQnVja2V0U3RhdGVtZW50ID0gbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6IFwiQWxsb3dTM09hY0FjY2Vzc1wiLFxuICAgICAgcHJpbmNpcGFsczogW25ldyBTZXJ2aWNlUHJpbmNpcGFsKFwiY2xvdWRmcm9udC5hbWF6b25hd3MuY29tXCIpXSxcbiAgICAgIGFjdGlvbnM6IFtcInMzOkdldE9iamVjdFwiXSxcbiAgICAgIHJlc291cmNlczogW3RoaXMucHJvcHMuYXNzZXRzQnVja2V0LmJ1Y2tldEFybiArIFwiLypcIl0sXG4gICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgIFwiYXdzOnNvdXJjZUFyblwiOiBTdGFjay5vZih0aGlzKS5mb3JtYXRBcm4oe1xuICAgICAgICAgICAgc2VydmljZTogXCJjbG91ZGZyb250XCIsXG4gICAgICAgICAgICByZWdpb246IFwiXCIsXG4gICAgICAgICAgICByZXNvdXJjZTogXCJkaXN0cmlidXRpb25cIixcbiAgICAgICAgICAgIHJlc291cmNlTmFtZTogdGhpcy5kaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWQsXG4gICAgICAgICAgICBhcm5Gb3JtYXQ6IEFybkZvcm1hdC5TTEFTSF9SRVNPVVJDRV9OQU1FLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLnByb3BzLmFzc2V0c0J1Y2tldC5hZGRUb1Jlc291cmNlUG9saWN5KG9hY0J1Y2tldFN0YXRlbWVudCk7XG4gICAgLy8gUmVtb3ZlIE9BSSBJQU0gUG9saWN5IFN0YXRlbWVudCBmcm9tIEJ1Y2tldCBQb2xpY3lcbiAgICBjb25zdCBidWNrZXRQb2xpY3lKc29uID0gdGhpcy5wcm9wcy5hc3NldHNCdWNrZXQucG9saWN5Py5kb2N1bWVudC50b0pTT04oKTtcbiAgICBjb25zdCB1cGRhdGVkQnVja2V0UG9saWN5SnNvbiA9IHtcbiAgICAgIFZlcnNpb246IFwiMjAxMi0xMC0xN1wiLFxuICAgICAgU3RhdGVtZW50OiBbXSBhcyB1bmtub3duW10sXG4gICAgfTtcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBidWNrZXRQb2xpY3lKc29uLlN0YXRlbWVudCkge1xuICAgICAgaWYgKCEoXCJDYW5vbmljYWxVc2VyXCIgaW4gc3RhdGVtZW50LlByaW5jaXBhbCkpIHtcbiAgICAgICAgdXBkYXRlZEJ1Y2tldFBvbGljeUpzb24uU3RhdGVtZW50LnB1c2goc3RhdGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgYnVja2V0UG9saWN5ID0gdGhpcy5wcm9wcy5hc3NldHNCdWNrZXQubm9kZS5maW5kQ2hpbGQoXCJQb2xpY3lcIikubm9kZVxuICAgICAgLmRlZmF1bHRDaGlsZCBhcyBDZm5CdWNrZXRQb2xpY3k7XG4gICAgYnVja2V0UG9saWN5LmFkZE92ZXJyaWRlKFxuICAgICAgXCJQcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50XCIsXG4gICAgICB1cGRhdGVkQnVja2V0UG9saWN5SnNvbixcbiAgICApO1xuXG4gICAgLy8gUmVtb3ZlIFMzIE9yaWdpbiBSZXNvdXJjZVxuICAgIGNvbnN0IGRpc3RyaWJ1dGlvbkNoaWxkcmVuID0gdGhpcy5kaXN0cmlidXRpb24ubm9kZS5maW5kQWxsKCk7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBkaXN0cmlidXRpb25DaGlsZHJlbikge1xuICAgICAgaWYgKGNoaWxkLm5vZGUuaWQgPT09IFwiUzNPcmlnaW5cIikge1xuICAgICAgICBjaGlsZC5ub2RlLnRyeVJlbW92ZUNoaWxkKFwiUmVzb3VyY2VcIik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIHdoZW4gUE9TVCBib2R5IGVuY3J5cHRpb24gZmVhdHVyZSBpcyBhZGRlZCBmb3IgTGFtYmRhIE9BQ1xuICAvLyBwcml2YXRlIGFkZExhbWJkYU9hYygpIHtcbiAgLy8gICBjb25zdCBsYW1iZGFPYWMgPSBuZXcgQ2ZuT3JpZ2luQWNjZXNzQ29udHJvbCh0aGlzLCBcIk9BQ1wiLCB7XG4gIC8vICAgICBvcmlnaW5BY2Nlc3NDb250cm9sQ29uZmlnOiB7XG4gIC8vICAgICAgIG5hbWU6IGBPQUMtTGFtYmRhLSR7dGhpcy51bmlxdWVTdGFja0lkUGFydH1gLFxuICAvLyAgICAgICBvcmlnaW5BY2Nlc3NDb250cm9sT3JpZ2luVHlwZTogXCJsYW1iZGFcIixcbiAgLy8gICAgICAgc2lnbmluZ0JlaGF2aW9yOiBcImFsd2F5c1wiLFxuICAvLyAgICAgICBzaWduaW5nUHJvdG9jb2w6IFwic2lndjRcIixcbiAgLy8gICAgIH0sXG4gIC8vICAgfSk7XG4gIC8vICAgY29uc3QgY2ZuRGlzdHJpYnV0aW9uID0gdGhpcy5kaXN0cmlidXRpb24ubm9kZVxuICAvLyAgICAgLmRlZmF1bHRDaGlsZCBhcyBDZm5EaXN0cmlidXRpb247XG4gIC8vICAgY2ZuRGlzdHJpYnV0aW9uLmFkZFByb3BlcnR5T3ZlcnJpZGUoXG4gIC8vICAgICBcIkRpc3RyaWJ1dGlvbkNvbmZpZy5PcmlnaW5zLjAuT3JpZ2luQWNjZXNzQ29udHJvbElkXCIsXG4gIC8vICAgICBsYW1iZGFPYWMuZ2V0QXR0KFwiSWRcIiksXG4gIC8vICAgKTtcbiAgLy8gfVxufVxuIl19
|
|
@@ -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.0.0" };
|
|
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
|
+
}
|