cdk-nextjs
Version:
Deploy Next.js apps on AWS with CDK
173 lines • 25 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NextjsApi = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const constructs_1 = require("constructs");
/**
* Creates an API Gateway REST API for Next.js applications
*/
class NextjsApi extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
this.props = props;
this.validateProps(props);
this.api = this.createRestApi();
this.baseResource = this.createBaseResource(props.basePath);
this.staticIntegrationRole = this.createStaticIntegrationRole();
this.createStaticIntegrations();
if (props.serverFunction) {
this.createDynamicIntegration(props.serverFunction);
}
else if (props.vpc) {
// [Future] create integration with ECS via VPC Link and ECS Service Discovery
}
}
validateProps(props) {
if (!props.serverFunction && !props.vpc) {
throw new Error("serverFunction or vpc must be set in NextjsApiProps");
}
}
createRestApi() {
return new aws_apigateway_1.RestApi(this, "RestApi", {
binaryMediaTypes: ["*/*"],
description: `cdk-nextjs REST API for ${aws_cdk_lib_1.Stack.of(this).stackName}`,
endpointTypes: [aws_apigateway_1.EndpointType.REGIONAL],
minCompressionSize: aws_cdk_lib_1.Size.bytes(0), // compress all responses for better perf
...this.props.overrides?.restApiProps,
});
}
/**
* Create base resource path if needed. Important if `basePath` is set.
*/
createBaseResource(basePath) {
// Create base resource path if needed
let baseResource = this.api.root;
if (basePath) {
const _basePath = basePath.startsWith("/")
? basePath.substring(1)
: basePath;
baseResource = this.api.root.addResource(_basePath);
}
return baseResource;
}
createStaticIntegrationRole() {
// Create S3 integration role
const staticIntegrationRole = new aws_iam_1.Role(this, "StaticIntegrationRole", {
assumedBy: new aws_iam_1.ServicePrincipal("apigateway.amazonaws.com"),
});
staticIntegrationRole.addToPolicy(new aws_iam_1.PolicyStatement({
actions: ["s3:GetObject", "s3:ListBucket"],
resources: [
this.props.staticAssetsBucket.bucketArn,
`${this.props.staticAssetsBucket.bucketArn}/*`,
],
}));
return staticIntegrationRole;
}
createStaticIntegrations() {
// Add static assets route (_next/static/*)
this.baseResource
.addResource("_next")
.addResource("static")
.addResource("{proxy+}")
.addMethod("GET", this.createS3Integration({ key: "_next/static/{key}" }), this.getStaticMethodOptions({ proxy: true }));
// add public directory files/directories that exist at top level but need to go to S3.
for (const publicDirEntry of this.props.publicDirEntries) {
if (publicDirEntry.isDirectory) {
this.baseResource
.addResource(publicDirEntry.name)
.addResource("{proxy+}")
.addMethod("GET", this.createS3Integration({ key: `${publicDirEntry.name}/{key}` }), this.getStaticMethodOptions({ proxy: true }));
}
else {
this.baseResource
.addResource(publicDirEntry.name)
.addMethod("GET", this.createS3Integration({ key: publicDirEntry.name }), this.getStaticMethodOptions());
}
}
}
/**
* Maps API request to S3 request.
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-parameter-mapping-sources.html
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html#api-items-in-folder-as-s3-objects-in-bucket
*/
createS3Integration({ key }) {
const s3Integration = new aws_apigateway_1.AwsIntegration({
service: "s3",
integrationHttpMethod: "GET",
path: `${this.props.staticAssetsBucket.bucketName}/${key}`,
options: {
credentialsRole: this.staticIntegrationRole,
passthroughBehavior: aws_apigateway_1.PassthroughBehavior.WHEN_NO_TEMPLATES, // recommended
requestParameters: key.includes("{key}")
? {
"integration.request.path.key": "method.request.path.proxy",
}
: undefined,
integrationResponses: [
{
statusCode: "200",
responseParameters: {
"method.response.header.Content-Type": "integration.response.header.Content-Type",
"method.response.header.Content-Length": "integration.response.header.Content-Length",
"method.response.header.Cache-Control": "integration.response.header.Cache-Control",
"method.response.header.ETag": "integration.response.header.ETag",
"method.response.header.Last-Modified": "integration.response.header.Last-Modified",
},
},
{
statusCode: "404",
selectionPattern: "404",
},
],
},
...this.props.overrides?.staticIntegrationProps,
});
return s3Integration;
}
getStaticMethodOptions({ proxy } = { proxy: false }) {
return {
requestParameters: proxy
? {
"method.request.path.proxy": true,
}
: undefined,
methodResponses: [
{
statusCode: "200",
responseParameters: {
"method.response.header.Content-Type": true,
"method.response.header.Content-Length": true,
"method.response.header.Cache-Control": true,
"method.response.header.ETag": true,
"method.response.header.Last-Modified": true,
},
},
{
statusCode: "404",
},
],
...this.props.overrides?.s3MethodOptions,
};
}
/**
* Create Lambda Proxy integration for all other routes
*/
createDynamicIntegration(serverFunction) {
const lambdaIntegration = new aws_apigateway_1.LambdaIntegration(serverFunction, {
...this.props.overrides?.dynamicIntegrationProps,
});
// Add catch-all route for server-side rendering
this.baseResource.addMethod("ANY", lambdaIntegration);
const proxyResource = this.baseResource.addResource("{proxy+}");
proxyResource.addMethod("ANY", lambdaIntegration);
}
}
exports.NextjsApi = NextjsApi;
_a = JSII_RTTI_SYMBOL_1;
NextjsApi[_a] = { fqn: "cdk-nextjs.NextjsApi", version: "0.4.14" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXh0anMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBQTBDO0FBQzFDLCtEQVdvQztBQUVwQyxpREFLNkI7QUFHN0IsMkNBQXVDO0FBc0N2Qzs7R0FFRztBQUNILE1BQWEsU0FBVSxTQUFRLHNCQUFTO0lBVXRDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBcUI7UUFDN0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUVuQixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7UUFDaEUsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDaEMsSUFBSSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN0RCxDQUFDO2FBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDckIsOEVBQThFO1FBQ2hGLENBQUM7SUFDSCxDQUFDO0lBRU8sYUFBYSxDQUFDLEtBQXFCO1FBQ3pDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQztRQUN6RSxDQUFDO0lBQ0gsQ0FBQztJQUVPLGFB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ImltcG9ydCB7IFNpemUsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBSZXN0QXBpLFxuICBMYW1iZGFJbnRlZ3JhdGlvbixcbiAgQXdzSW50ZWdyYXRpb24sXG4gIE1ldGhvZE9wdGlvbnMsXG4gIElSZXNvdXJjZSxcbiAgRW5kcG9pbnRUeXBlLFxuICBSZXN0QXBpUHJvcHMsXG4gIEF3c0ludGVncmF0aW9uUHJvcHMsXG4gIExhbWJkYUludGVncmF0aW9uT3B0aW9ucyxcbiAgUGFzc3Rocm91Z2hCZWhhdmlvcixcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5XCI7XG5pbXBvcnQgeyBJVnBjIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7XG4gIFJvbGUsXG4gIFNlcnZpY2VQcmluY2lwYWwsXG4gIFBvbGljeVN0YXRlbWVudCxcbiAgSVJvbGUsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyBJRnVuY3Rpb24gfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgSUJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBQdWJsaWNEaXJFbnRyeSB9IGZyb20gXCIuL25leHRqcy1idWlsZC9uZXh0anMtYnVpbGRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNBcGlPdmVycmlkZXMge1xuICByZWFkb25seSByZXN0QXBpUHJvcHM/OiBSZXN0QXBpUHJvcHM7XG4gIHJlYWRvbmx5IHN0YXRpY0ludGVncmF0aW9uUHJvcHM/OiBBd3NJbnRlZ3JhdGlvblByb3BzO1xuICByZWFkb25seSBzM01ldGhvZE9wdGlvbnM/OiBNZXRob2RPcHRpb25zO1xuICByZWFkb25seSBkeW5hbWljSW50ZWdyYXRpb25Qcm9wcz86IExhbWJkYUludGVncmF0aW9uT3B0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNBcGlQcm9wcyB7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBiYXNlIHBhdGggZm9yIHRoZSBhcHBsaWNhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgYmFzZVBhdGg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBPdmVycmlkZSBwcm9wcyBmb3IgZXZlcnkgY29uc3RydWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzQXBpT3ZlcnJpZGVzO1xuICAvKipcbiAgICogUGF0aCB0byBkaXJlY3Rvcnkgb2YgTmV4dC5qcyBhcHAncyBwdWJsaWMgZGlyZWN0b3J5LiBVc2VkIHRvIGFkZCByZXNvdXJjZXNcbiAgICogdG8gQVBJIEdhdGV3YXkgUkVTVCBBUEkgZm9yIHB1YmxpYyBkaXJlY3RvcnkgdG8gZ28gZGlyZWN0bHkgdG8gUzMuXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNEaXJFbnRyaWVzOiBQdWJsaWNEaXJFbnRyeVtdO1xuICAvKipcbiAgICogUmVxdWlyZWQgaWYgYE5leHRqc1JlZ2lvbmFsRnVuY3Rpb25zYC4gVGhlIExhbWJkYSBmdW5jdGlvbiBmb3Igc2VydmVyLXNpZGUgcmVuZGVyaW5nXG4gICAqL1xuICByZWFkb25seSBzZXJ2ZXJGdW5jdGlvbj86IElGdW5jdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBTMyBidWNrZXQgY29udGFpbmluZyBzdGF0aWMgYXNzZXRzXG4gICAqL1xuICByZWFkb25seSBzdGF0aWNBc3NldHNCdWNrZXQ6IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBbRnV0dXJlXSBSZXF1aXJlZCBpZiBgTmV4dGpzUmVnaW9uYWxDb250YWluZXJzYC4gVlBDIHRvIGNyZWF0ZSBWUEMgTGluayBhbmQgRUNTIFNlcnZpY2UgRGlzY292ZXJ5XG4gICAqL1xuICByZWFkb25seSB2cGM/OiBJVnBjO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gQVBJIEdhdGV3YXkgUkVTVCBBUEkgZm9yIE5leHQuanMgYXBwbGljYXRpb25zXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXh0anNBcGkgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEFQSSBHYXRld2F5IFJFU1QgQVBJXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXBpOiBSZXN0QXBpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZVJlc291cmNlOiBJUmVzb3VyY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IE5leHRqc0FwaVByb3BzO1xuICBwcml2YXRlIHN0YXRpY0ludGVncmF0aW9uUm9sZTogSVJvbGU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE5leHRqc0FwaVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG5cbiAgICB0aGlzLnZhbGlkYXRlUHJvcHMocHJvcHMpO1xuICAgIHRoaXMuYXBpID0gdGhpcy5jcmVhdGVSZXN0QXBpKCk7XG4gICAgdGhpcy5iYXNlUmVzb3VyY2UgPSB0aGlzLmNyZWF0ZUJhc2VSZXNvdXJjZShwcm9wcy5iYXNlUGF0aCk7XG4gICAgdGhpcy5zdGF0aWNJbnRlZ3JhdGlvblJvbGUgPSB0aGlzLmNyZWF0ZVN0YXRpY0ludGVncmF0aW9uUm9sZSgpO1xuICAgIHRoaXMuY3JlYXRlU3RhdGljSW50ZWdyYXRpb25zKCk7XG4gICAgaWYgKHByb3BzLnNlcnZlckZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLmNyZWF0ZUR5bmFtaWNJbnRlZ3JhdGlvbihwcm9wcy5zZXJ2ZXJGdW5jdGlvbik7XG4gICAgfSBlbHNlIGlmIChwcm9wcy52cGMpIHtcbiAgICAgIC8vIFtGdXR1cmVdIGNyZWF0ZSBpbnRlZ3JhdGlvbiB3aXRoIEVDUyB2aWEgVlBDIExpbmsgYW5kIEVDUyBTZXJ2aWNlIERpc2NvdmVyeVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVQcm9wcyhwcm9wczogTmV4dGpzQXBpUHJvcHMpIHtcbiAgICBpZiAoIXByb3BzLnNlcnZlckZ1bmN0aW9uICYmICFwcm9wcy52cGMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInNlcnZlckZ1bmN0aW9uIG9yIHZwYyBtdXN0IGJlIHNldCBpbiBOZXh0anNBcGlQcm9wc1wiKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVJlc3RBcGkoKTogUmVzdEFwaSB7XG4gICAgcmV0dXJuIG5ldyBSZXN0QXBpKHRoaXMsIFwiUmVzdEFwaVwiLCB7XG4gICAgICBiaW5hcnlNZWRpYVR5cGVzOiBbXCIqLypcIl0sXG4gICAgICBkZXNjcmlwdGlvbjogYGNkay1uZXh0anMgUkVTVCBBUEkgZm9yICR7U3RhY2sub2YodGhpcykuc3RhY2tOYW1lfWAsXG4gICAgICBlbmRwb2ludFR5cGVzOiBbRW5kcG9pbnRUeXBlLlJFR0lPTkFMXSxcbiAgICAgIG1pbkNvbXByZXNzaW9uU2l6ZTogU2l6ZS5ieXRlcygwKSwgLy8gY29tcHJlc3MgYWxsIHJlc3BvbnNlcyBmb3IgYmV0dGVyIHBlcmZcbiAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5yZXN0QXBpUHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGJhc2UgcmVzb3VyY2UgcGF0aCBpZiBuZWVkZWQuIEltcG9ydGFudCBpZiBgYmFzZVBhdGhgIGlzIHNldC5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQmFzZVJlc291cmNlKGJhc2VQYXRoPzogc3RyaW5nKTogSVJlc291cmNlIHtcbiAgICAvLyBDcmVhdGUgYmFzZSByZXNvdXJjZSBwYXRoIGlmIG5lZWRlZFxuICAgIGxldCBiYXNlUmVzb3VyY2UgPSB0aGlzLmFwaS5yb290O1xuICAgIGlmIChiYXNlUGF0aCkge1xuICAgICAgY29uc3QgX2Jhc2VQYXRoID0gYmFzZVBhdGguc3RhcnRzV2l0aChcIi9cIilcbiAgICAgICAgPyBiYXNlUGF0aC5zdWJzdHJpbmcoMSlcbiAgICAgICAgOiBiYXNlUGF0aDtcblxuICAgICAgYmFzZVJlc291cmNlID0gdGhpcy5hcGkucm9vdC5hZGRSZXNvdXJjZShfYmFzZVBhdGgpO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZVJlc291cmNlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTdGF0aWNJbnRlZ3JhdGlvblJvbGUoKSB7XG4gICAgLy8gQ3JlYXRlIFMzIGludGVncmF0aW9uIHJvbGVcbiAgICBjb25zdCBzdGF0aWNJbnRlZ3JhdGlvblJvbGUgPSBuZXcgUm9sZSh0aGlzLCBcIlN0YXRpY0ludGVncmF0aW9uUm9sZVwiLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBTZXJ2aWNlUHJpbmNpcGFsKFwiYXBpZ2F0ZXdheS5hbWF6b25hd3MuY29tXCIpLFxuICAgIH0pO1xuXG4gICAgc3RhdGljSW50ZWdyYXRpb25Sb2xlLmFkZFRvUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcInMzOkdldE9iamVjdFwiLCBcInMzOkxpc3RCdWNrZXRcIl0sXG4gICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgIHRoaXMucHJvcHMuc3RhdGljQXNzZXRzQnVja2V0LmJ1Y2tldEFybixcbiAgICAgICAgICBgJHt0aGlzLnByb3BzLnN0YXRpY0Fzc2V0c0J1Y2tldC5idWNrZXRBcm59LypgLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gc3RhdGljSW50ZWdyYXRpb25Sb2xlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTdGF0aWNJbnRlZ3JhdGlvbnMoKSB7XG4gICAgLy8gQWRkIHN0YXRpYyBhc3NldHMgcm91dGUgKF9uZXh0L3N0YXRpYy8qKVxuICAgIHRoaXMuYmFzZVJlc291cmNlXG4gICAgICAuYWRkUmVzb3VyY2UoXCJfbmV4dFwiKVxuICAgICAgLmFkZFJlc291cmNlKFwic3RhdGljXCIpXG4gICAgICAuYWRkUmVzb3VyY2UoXCJ7cHJveHkrfVwiKVxuICAgICAgLmFkZE1ldGhvZChcbiAgICAgICAgXCJHRVRcIixcbiAgICAgICAgdGhpcy5jcmVhdGVTM0ludGVncmF0aW9uKHsga2V5OiBcIl9uZXh0L3N0YXRpYy97a2V5fVwiIH0pLFxuICAgICAgICB0aGlzLmdldFN0YXRpY01ldGhvZE9wdGlvbnMoeyBwcm94eTogdHJ1ZSB9KSxcbiAgICAgICk7XG4gICAgLy8gYWRkIHB1YmxpYyBkaXJlY3RvcnkgZmlsZXMvZGlyZWN0b3JpZXMgdGhhdCBleGlzdCBhdCB0b3AgbGV2ZWwgYnV0IG5lZWQgdG8gZ28gdG8gUzMuXG4gICAgZm9yIChjb25zdCBwdWJsaWNEaXJFbnRyeSBvZiB0aGlzLnByb3BzLnB1YmxpY0RpckVudHJpZXMpIHtcbiAgICAgIGlmIChwdWJsaWNEaXJFbnRyeS5pc0RpcmVjdG9yeSkge1xuICAgICAgICB0aGlzLmJhc2VSZXNvdXJjZVxuICAgICAgICAgIC5hZGRSZXNvdXJjZShwdWJsaWNEaXJFbnRyeS5uYW1lKVxuICAgICAgICAgIC5hZGRSZXNvdXJjZShcIntwcm94eSt9XCIpXG4gICAgICAgICAgLmFkZE1ldGhvZChcbiAgICAgICAgICAgIFwiR0VUXCIsXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVMzSW50ZWdyYXRpb24oeyBrZXk6IGAke3B1YmxpY0RpckVudHJ5Lm5hbWV9L3trZXl9YCB9KSxcbiAgICAgICAgICAgIHRoaXMuZ2V0U3RhdGljTWV0aG9kT3B0aW9ucyh7IHByb3h5OiB0cnVlIH0pLFxuICAgICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmJhc2VSZXNvdXJjZVxuICAgICAgICAgIC5hZGRSZXNvdXJjZShwdWJsaWNEaXJFbnRyeS5uYW1lKVxuICAgICAgICAgIC5hZGRNZXRob2QoXG4gICAgICAgICAgICBcIkdFVFwiLFxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTM0ludGVncmF0aW9uKHsga2V5OiBwdWJsaWNEaXJFbnRyeS5uYW1lIH0pLFxuICAgICAgICAgICAgdGhpcy5nZXRTdGF0aWNNZXRob2RPcHRpb25zKCksXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFwcyBBUEkgcmVxdWVzdCB0byBTMyByZXF1ZXN0LlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hcGlnYXRld2F5L2xhdGVzdC9kZXZlbG9wZXJndWlkZS9yZXN0LWFwaS1wYXJhbWV0ZXItbWFwcGluZy1zb3VyY2VzLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvaW50ZWdyYXRpbmctYXBpLXdpdGgtYXdzLXNlcnZpY2VzLXMzLmh0bWwjYXBpLWl0ZW1zLWluLWZvbGRlci1hcy1zMy1vYmplY3RzLWluLWJ1Y2tldFxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVTM0ludGVncmF0aW9uKHsga2V5IH06IHsga2V5OiBzdHJpbmcgfSkge1xuICAgIGNvbnN0IHMzSW50ZWdyYXRpb24gPSBuZXcgQXdzSW50ZWdyYXRpb24oe1xuICAgICAgc2VydmljZTogXCJzM1wiLFxuICAgICAgaW50ZWdyYXRpb25IdHRwTWV0aG9kOiBcIkdFVFwiLFxuICAgICAgcGF0aDogYCR7dGhpcy5wcm9wcy5zdGF0aWNBc3NldHNCdWNrZXQuYnVja2V0TmFtZX0vJHtrZXl9YCxcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgY3JlZGVudGlhbHNSb2xlOiB0aGlzLnN0YXRpY0ludGVncmF0aW9uUm9sZSxcbiAgICAgICAgcGFzc3Rocm91Z2hCZWhhdmlvcjogUGFzc3Rocm91Z2hCZWhhdmlvci5XSEVOX05PX1RFTVBMQVRFUywgLy8gcmVjb21tZW5kZWRcbiAgICAgICAgcmVxdWVzdFBhcmFtZXRlcnM6IGtleS5pbmNsdWRlcyhcIntrZXl9XCIpXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIFwiaW50ZWdyYXRpb24ucmVxdWVzdC5wYXRoLmtleVwiOiBcIm1ldGhvZC5yZXF1ZXN0LnBhdGgucHJveHlcIixcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgaW50ZWdyYXRpb25SZXNwb25zZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBcIjIwMFwiLFxuICAgICAgICAgICAgcmVzcG9uc2VQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIFwibWV0aG9kLnJlc3BvbnNlLmhlYWRlci5Db250ZW50LVR5cGVcIjpcbiAgICAgICAgICAgICAgICBcImludGVncmF0aW9uLnJlc3BvbnNlLmhlYWRlci5Db250ZW50LVR5cGVcIixcbiAgICAgICAgICAgICAgXCJtZXRob2QucmVzcG9uc2UuaGVhZGVyLkNvbnRlbnQtTGVuZ3RoXCI6XG4gICAgICAgICAgICAgICAgXCJpbnRlZ3JhdGlvbi5yZXNwb25zZS5oZWFkZXIuQ29udGVudC1MZW5ndGhcIixcbiAgICAgICAgICAgICAgXCJtZXRob2QucmVzcG9uc2UuaGVhZGVyLkNhY2hlLUNvbnRyb2xcIjpcbiAgICAgICAgICAgICAgICBcImludGVncmF0aW9uLnJlc3BvbnNlLmhlYWRlci5DYWNoZS1Db250cm9sXCIsXG4gICAgICAgICAgICAgIFwibWV0aG9kLnJlc3BvbnNlLmhlYWRlci5FVGFnXCI6IFwiaW50ZWdyYXRpb24ucmVzcG9uc2UuaGVhZGVyLkVUYWdcIixcbiAgICAgICAgICAgICAgXCJtZXRob2QucmVzcG9uc2UuaGVhZGVyLkxhc3QtTW9kaWZpZWRcIjpcbiAgICAgICAgICAgICAgICBcImludGVncmF0aW9uLnJlc3BvbnNlLmhlYWRlci5MYXN0LU1vZGlmaWVkXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgc3RhdHVzQ29kZTogXCI0MDRcIixcbiAgICAgICAgICAgIHNlbGVjdGlvblBhdHRlcm46IFwiNDA0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uc3RhdGljSW50ZWdyYXRpb25Qcm9wcyxcbiAgICB9KTtcbiAgICByZXR1cm4gczNJbnRlZ3JhdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RhdGljTWV0aG9kT3B0aW9ucyh7IHByb3h5IH0gPSB7IHByb3h5OiBmYWxzZSB9KTogTWV0aG9kT3B0aW9ucyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzOiBwcm94eVxuICAgICAgICA/IHtcbiAgICAgICAgICAgIFwibWV0aG9kLnJlcXVlc3QucGF0aC5wcm94eVwiOiB0cnVlLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICBtZXRob2RSZXNwb25zZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IFwiMjAwXCIsXG4gICAgICAgICAgcmVzcG9uc2VQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBcIm1ldGhvZC5yZXNwb25zZS5oZWFkZXIuQ29udGVudC1UeXBlXCI6IHRydWUsXG4gICAgICAgICAgICBcIm1ldGhvZC5yZXNwb25zZS5oZWFkZXIuQ29udGVudC1MZW5ndGhcIjogdHJ1ZSxcbiAgICAgICAgICAgIFwibWV0aG9kLnJlc3BvbnNlLmhlYWRlci5DYWNoZS1Db250cm9sXCI6IHRydWUsXG4gICAgICAgICAgICBcIm1ldGhvZC5yZXNwb25zZS5oZWFkZXIuRVRhZ1wiOiB0cnVlLFxuICAgICAgICAgICAgXCJtZXRob2QucmVzcG9uc2UuaGVhZGVyLkxhc3QtTW9kaWZpZWRcIjogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogXCI0MDRcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uczNNZXRob2RPcHRpb25zLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIExhbWJkYSBQcm94eSBpbnRlZ3JhdGlvbiBmb3IgYWxsIG90aGVyIHJvdXRlc1xuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEeW5hbWljSW50ZWdyYXRpb24oc2VydmVyRnVuY3Rpb246IElGdW5jdGlvbikge1xuICAgIGNvbnN0IGxhbWJkYUludGVncmF0aW9uID0gbmV3IExhbWJkYUludGVncmF0aW9uKHNlcnZlckZ1bmN0aW9uLCB7XG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uZHluYW1pY0ludGVncmF0aW9uUHJvcHMsXG4gICAgfSk7XG4gICAgLy8gQWRkIGNhdGNoLWFsbCByb3V0ZSBmb3Igc2VydmVyLXNpZGUgcmVuZGVyaW5nXG4gICAgdGhpcy5iYXNlUmVzb3VyY2UuYWRkTWV0aG9kKFwiQU5ZXCIsIGxhbWJkYUludGVncmF0aW9uKTtcbiAgICBjb25zdCBwcm94eVJlc291cmNlID0gdGhpcy5iYXNlUmVzb3VyY2UuYWRkUmVzb3VyY2UoXCJ7cHJveHkrfVwiKTtcbiAgICBwcm94eVJlc291cmNlLmFkZE1ldGhvZChcIkFOWVwiLCBsYW1iZGFJbnRlZ3JhdGlvbik7XG4gIH1cbn1cbiJdfQ==