UNPKG

turbo-remote-cache-construct

Version:

A Turborepo Remote Cache implementation using AWS API Gateway, Lambda, S3, and DynamoDB.

74 lines 12.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TurboRemoteCache = void 0; const constructs_1 = require("constructs"); const s3 = require("aws-cdk-lib/aws-s3"); const dynamodb = require("aws-cdk-lib/aws-dynamodb"); const iam = require("aws-cdk-lib/aws-iam"); const cdk = require("aws-cdk-lib"); const lambda_1 = require("./lambda"); const api_1 = require("./api"); class TurboRemoteCache extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const artifactsBucket = new s3.Bucket(this, 'ArtifactsBucket', { versioned: false, bucketName: 'turbo-remote-cache-artifacts', encryption: s3.BucketEncryption.S3_MANAGED, lifecycleRules: [ { expiration: cdk.Duration.days(30), }, ], cors: [ { allowedHeaders: ['*'], allowedMethods: [s3.HttpMethods.GET, s3.HttpMethods.PUT, s3.HttpMethods.HEAD], allowedOrigins: ['*'], exposedHeaders: [ 'User-Agent', 'Content-Type', 'Content-Length', 'x-artifact-duration', 'x-artifact-tag', ], } ], removalPolicy: cdk.RemovalPolicy.DESTROY, ...props.artifactsBucketProps, }); const s3Credentials = new iam.Role(this, 'S3CredentialsRole', { assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess'), ], }); artifactsBucket.grantReadWrite(s3Credentials); const eventsTable = new dynamodb.Table(this, 'EventsTable', { tableName: 'turbo-remote-cache-events', partitionKey: { name: 'hash', type: dynamodb.AttributeType.STRING }, sortKey: { name: 'sessionId', type: dynamodb.AttributeType.STRING }, billingMode: dynamodb.BillingMode.PROVISIONED, readCapacity: 5, writeCapacity: 5, timeToLiveAttribute: 'ttl', removalPolicy: cdk.RemovalPolicy.DESTROY, ...props.eventsTableProps, }); const lambdaFunctions = new lambda_1.LambdaFunctions(this, 'LambdaFunctions', { artifactsBucket, eventsTable, lambdaProps: props.lambdaProps, authorizerFunction: props.authorizerFunction, userInfoFunction: props.userInfoFunction, }); const api = new api_1.APIGateway(this, 'APIGateway', { lambdaFunctions, artifactsBucket, s3Credentials, apiProps: props.apiProps, }); } } exports.TurboRemoteCache = TurboRemoteCache; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBQ3ZDLHlDQUF5QztBQUN6QyxxREFBcUQ7QUFFckQsMkNBQTJDO0FBQzNDLG1DQUFtQztBQUNuQyxxQ0FBMkM7QUFDM0MsK0JBQW1DO0FBdUZuQyxNQUFhLGdCQUFpQixTQUFRLHNCQUFTO0lBQzdDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBNEI7UUFDcEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLGVBQWUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLGlCQUFpQixFQUFFO1lBQzdELFNBQVMsRUFBRSxLQUFLO1lBQ2hCLFVBQVUsRUFBRSw4QkFBOEI7WUFDMUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVO1lBQzFDLGNBQWMsRUFBRTtnQkFDZDtvQkFDRSxVQUFVLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2lCQUNsQzthQUNGO1lBQ0QsSUFBSSxFQUFFO2dCQUNKO29CQUNFLGNBQWMsRUFBRSxDQUFDLEdBQUcsQ0FBQztvQkFDckIsY0FBYyxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7b0JBQzdFLGNBQWMsRUFBRSxDQUFDLEdBQUcsQ0FBQztvQkFDckIsY0FBYyxFQUFFO3dCQUNkLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxnQkFBZ0I7d0JBQ2hCLHFCQUFxQjt3QkFDckIsZ0JBQWdCO3FCQUNqQjtpQkFDRjthQUNGO1lBQ0QsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsT0FBTztZQUN4QyxHQUFHLEtBQUssQ0FBQyxvQkFBb0I7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRTtZQUM1RCxTQUFTLEVBQUUsSUFBSSxHQUFHLENBQUMsZ0JBQWdCLENBQUMsMEJBQTBCLENBQUM7WUFDL0QsZUFBZSxFQUFFO2dCQUNmLEdBQUcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsb0JBQW9CLENBQUM7YUFDakU7U0FDRixDQUFDLENBQUM7UUFFSCxlQUFlLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTlDLE1BQU0sV0FBVyxHQUFHLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFO1lBQzFELFNBQVMsRUFBRSwyQkFBMkI7WUFDdEMsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUU7WUFDbkUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUU7WUFDbkUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsV0FBVztZQUM3QyxZQUFZLEVBQUUsQ0FBQztZQUNmLGFBQWEsRUFBRSxDQUFDO1lBQ2hCLG1CQUFtQixFQUFFLEtBQUs7WUFDMUIsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsT0FBTztZQUN4QyxHQUFHLEtBQUssQ0FBQyxnQkFBZ0I7U0FDMUIsQ0FBQyxDQUFDO1FBR0gsTUFBTSxlQUFlLEdBQUcsSUFBSSx3QkFBZSxDQUFDLElBQUksRUFBRSxpQkFBaUIsRUFBRTtZQUNuRSxlQUFlO1lBQ2YsV0FBVztZQUNYLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM5QixrQkFBa0IsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1lBQzVDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7U0FDekMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxHQUFHLEdBQUcsSUFBSSxnQkFBVSxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUU7WUFDN0MsZUFBZTtZQUNmLGVBQWU7WUFDZixhQUFhO1lBQ2IsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1NBQ3pCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXBFRCw0Q0FvRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCAqIGFzIHMzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgKiBhcyBkeW5hbW9kYiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZHluYW1vZGInO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IExhbWJkYUZ1bmN0aW9ucyB9IGZyb20gJy4vbGFtYmRhJztcbmltcG9ydCB7IEFQSUdhdGV3YXkgfSBmcm9tICcuL2FwaSc7XG5pbXBvcnQgKiBhcyBhcGlnYXRld2F5IGZyb20gJ2F3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5JztcbmV4cG9ydCBpbnRlcmZhY2UgVHVyYm9SZW1vdGVDYWNoZVByb3BzIHtcbiAgLyoqXG4gICAqIFR1cmJvIFRva2VuXG4gICAqIEBkZXByZWNhdGVkIFVzZSBhdXRob3JpemVyRnVuY3Rpb24gaW5zdGVhZCBmb3IgYXV0aGVudGljYXRpb25cbiAgICogVXNlZCBvbmx5IGlmIGN1c3RvbSBhdXRob3JpemVyIGlzIG5vdCBwcm92aWRlZFxuICAgKiBAZXhhbXBsZSBnZW5lcmF0ZSBhIHJhbmRvbSBzdHJpbmcgdXNpbmcgYG9wZW5zc2wgcmFuZCAtYmFzZTY0IDMyYFxuICAgKi9cbiAgdHVyYm9Ub2tlbj86IHN0cmluZztcblxuICAvKipcbiAgICogQ3VzdG9tIGF1dGhvcml6ZXIgbGFtYmRhIGZ1bmN0aW9uIGZvciBBUEkgYXV0aGVudGljYXRpb25cbiAgICogVGhpcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHRoZSB0ZWFtSWQgaW4gdGhlIGF1dGhvcml6ZXIgY29udGV4dFxuICAgKiBSZXBsYWNlcyB0aGUgZGVwcmVjYXRlZCB0dXJib1Rva2VuIGF1dGhlbnRpY2F0aW9uXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmV3IFR1cmJvUmVtb3RlQ2FjaGUodGhpcywgJ0NhY2hlJywge1xuICAgKiAgIGF1dGhvcml6ZXJGdW5jdGlvbjogbXlDdXN0b21BdXRob3JpemVyLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhdXRob3JpemVyRnVuY3Rpb24/OiBsYW1iZGEuRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIEN1c3RvbSB1c2VyIGluZm8gbGFtYmRhIGZ1bmN0aW9uXG4gICAqIEltcGxlbWVudHMgdGhlIC92Mi91c2VyIGVuZHBvaW50IGZvciByZXRyaWV2aW5nIGF1dGhlbnRpY2F0ZWQgdXNlciBpbmZvcm1hdGlvblxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIG5ldyBUdXJib1JlbW90ZUNhY2hlKHRoaXMsICdDYWNoZScsIHtcbiAgICogICB1c2VySW5mb0Z1bmN0aW9uOiBteVVzZXJJbmZvRnVuY3Rpb24sXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIHVzZXJJbmZvRnVuY3Rpb24/OiBsYW1iZGEuRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIEFQSSBHYXRld2F5IHByb3BzXG4gICAqIEBkZWZhdWx0XG4gICAqICByZXN0QXBpTmFtZTogJ1R1cmJvcmVwbyBSZW1vdGUgQ2FjaGUgQVBJJyxcbiAgICogIGRlc2NyaXB0aW9uOiAnVHVyYm9yZXBvIGlzIGFuIGludGVsbGlnZW50IGJ1aWxkIHN5c3RlbSBvcHRpbWl6ZWQgZm9yIEphdmFTY3JpcHQgYW5kIFR5cGVTY3JpcHQgY29kZWJhc2VzLicsXG4gICAqICBjbG91ZFdhdGNoUm9sZTogdHJ1ZSxcbiAgICogIGRlcGxveU9wdGlvbnM6IHtcbiAgICogICAgZG9jdW1lbnRhdGlvblZlcnNpb246ICc4LjAuMCcsXG4gICAqICAgIGxvZ2dpbmdMZXZlbDogYXBpZ2F0ZXdheS5NZXRob2RMb2dnaW5nTGV2ZWwuSU5GTyxcbiAgICogICAgYWNjZXNzTG9nRGVzdGluYXRpb246IG5ldyBhcGlnYXRld2F5LkxvZ0dyb3VwTG9nRGVzdGluYXRpb24obG9nR3JvdXApLFxuICAgKiAgICBhY2Nlc3NMb2dGb3JtYXQ6IGFwaWdhdGV3YXkuQWNjZXNzTG9nRm9ybWF0Lmpzb25XaXRoU3RhbmRhcmRGaWVsZHMoKSxcbiAgICogICAgZGF0YVRyYWNlRW5hYmxlZDogdHJ1ZSxcbiAgICogICAgdHJhY2luZ0VuYWJsZWQ6IHRydWUsXG4gICAqICB9LFxuICAgKiAgYmluYXJ5TWVkaWFUeXBlczogWydhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nXSxcbiAgICovXG4gIGFwaVByb3BzPzogUGFydGlhbDxhcGlnYXRld2F5LlJlc3RBcGlQcm9wcz47XG5cbiAgLyoqXG4gICAqIFMzIGJ1Y2tldCBwcm9wcyBmb3IgdGhlIGFydGlmYWN0cyBidWNrZXRcbiAgICogQGRlZmF1bHRcbiAgICogIGJ1Y2tldE5hbWU6ICd0dXJiby1yZW1vdGUtY2FjaGUtYXJ0aWZhY3RzJyxcbiAgICogIGxpZmVjeWNsZVJ1bGVzOiBbeyBleHBpcmF0aW9uOiBjZGsuRHVyYXRpb24uZGF5cygzMCkgfV0sXG4gICAqICBjb3JzOiBbe1xuICAgKiAgICBhbGxvd2VkSGVhZGVyczogWycqJ10sXG4gICAqICAgIGFsbG93ZWRNZXRob2RzOiBbczMuSHR0cE1ldGhvZHMuR0VULCBzMy5IdHRwTWV0aG9kcy5QVVQsIHMzLkh0dHBNZXRob2RzLkhFQURdLFxuICAgKiAgICBhbGxvd2VkT3JpZ2luczogWycqJ10sXG4gICAqICAgIGV4cG9zZWRIZWFkZXJzOiBbJ1VzZXItQWdlbnQnLCAnQ29udGVudC1UeXBlJywgJ0NvbnRlbnQtTGVuZ3RoJywgJ3gtYXJ0aWZhY3QtZHVyYXRpb24nLCAneC1hcnRpZmFjdC10YWcnXSxcbiAgICogIH1dLFxuICAgKiAgcmVtb3ZhbFBvbGljeTogY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICovXG4gIGFydGlmYWN0c0J1Y2tldFByb3BzPzogUGFydGlhbDxzMy5CdWNrZXRQcm9wcz47XG5cbiAgLyoqXG4gICAqIER5bmFtb0RCIHRhYmxlIHByb3BzIGZvciB0aGUgZXZlbnRzIHRhYmxlXG4gICAqIEBkZWZhdWx0XG4gICAqICB0YWJsZU5hbWU6ICd0dXJiby1yZW1vdGUtY2FjaGUtZXZlbnRzJyxcbiAgICogIGJpbGxpbmdNb2RlOiBkeW5hbW9kYi5CaWxsaW5nTW9kZS5QUk9WSVNJT05FRCxcbiAgICogIHJlYWRDYXBhY2l0eTogNSxcbiAgICogIHdyaXRlQ2FwYWNpdHk6IDUsXG4gICAqICB0aW1lVG9MaXZlQXR0cmlidXRlOiAndHRsJyxcbiAgICogIHJlbW92YWxQb2xpY3k6IGNkay5SZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAqL1xuICBldmVudHNUYWJsZVByb3BzPzogUGFydGlhbDxkeW5hbW9kYi5UYWJsZVByb3BzPjtcblxuICAvKipcbiAgICogQ29tbW9uIGxhbWJkYSBmdW5jdGlvbiBwcm9wcyBmb3IgYWxsIGxhbWJkYSBmdW5jdGlvbnNcbiAgICovXG4gIGxhbWJkYVByb3BzPzogUGFydGlhbDxsYW1iZGEuRnVuY3Rpb25Qcm9wcz47XG59XG5cbmV4cG9ydCBjbGFzcyBUdXJib1JlbW90ZUNhY2hlIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFR1cmJvUmVtb3RlQ2FjaGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBhcnRpZmFjdHNCdWNrZXQgPSBuZXcgczMuQnVja2V0KHRoaXMsICdBcnRpZmFjdHNCdWNrZXQnLCB7XG4gICAgICB2ZXJzaW9uZWQ6IGZhbHNlLFxuICAgICAgYnVja2V0TmFtZTogJ3R1cmJvLXJlbW90ZS1jYWNoZS1hcnRpZmFjdHMnLFxuICAgICAgZW5jcnlwdGlvbjogczMuQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VELFxuICAgICAgbGlmZWN5Y2xlUnVsZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGV4cGlyYXRpb246IGNkay5EdXJhdGlvbi5kYXlzKDMwKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBjb3JzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhbGxvd2VkSGVhZGVyczogWycqJ10sXG4gICAgICAgICAgYWxsb3dlZE1ldGhvZHM6IFtzMy5IdHRwTWV0aG9kcy5HRVQsIHMzLkh0dHBNZXRob2RzLlBVVCwgczMuSHR0cE1ldGhvZHMuSEVBRF0sXG4gICAgICAgICAgYWxsb3dlZE9yaWdpbnM6IFsnKiddLFxuICAgICAgICAgIGV4cG9zZWRIZWFkZXJzOiBbXG4gICAgICAgICAgICAnVXNlci1BZ2VudCcsXG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJyxcbiAgICAgICAgICAgICdDb250ZW50LUxlbmd0aCcsXG4gICAgICAgICAgICAneC1hcnRpZmFjdC1kdXJhdGlvbicsXG4gICAgICAgICAgICAneC1hcnRpZmFjdC10YWcnLFxuICAgICAgICAgIF0sXG4gICAgICAgIH1cbiAgICAgIF0sXG4gICAgICByZW1vdmFsUG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgLi4ucHJvcHMuYXJ0aWZhY3RzQnVja2V0UHJvcHMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzM0NyZWRlbnRpYWxzID0gbmV3IGlhbS5Sb2xlKHRoaXMsICdTM0NyZWRlbnRpYWxzUm9sZScsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdhcGlnYXRld2F5LmFtYXpvbmF3cy5jb20nKSxcbiAgICAgIG1hbmFnZWRQb2xpY2llczogW1xuICAgICAgICBpYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoJ0FtYXpvblMzRnVsbEFjY2VzcycpLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIGFydGlmYWN0c0J1Y2tldC5ncmFudFJlYWRXcml0ZShzM0NyZWRlbnRpYWxzKTtcblxuICAgIGNvbnN0IGV2ZW50c1RhYmxlID0gbmV3IGR5bmFtb2RiLlRhYmxlKHRoaXMsICdFdmVudHNUYWJsZScsIHtcbiAgICAgIHRhYmxlTmFtZTogJ3R1cmJvLXJlbW90ZS1jYWNoZS1ldmVudHMnLFxuICAgICAgcGFydGl0aW9uS2V5OiB7IG5hbWU6ICdoYXNoJywgdHlwZTogZHluYW1vZGIuQXR0cmlidXRlVHlwZS5TVFJJTkcgfSxcbiAgICAgIHNvcnRLZXk6IHsgbmFtZTogJ3Nlc3Npb25JZCcsIHR5cGU6IGR5bmFtb2RiLkF0dHJpYnV0ZVR5cGUuU1RSSU5HIH0sXG4gICAgICBiaWxsaW5nTW9kZTogZHluYW1vZGIuQmlsbGluZ01vZGUuUFJPVklTSU9ORUQsXG4gICAgICByZWFkQ2FwYWNpdHk6IDUsXG4gICAgICB3cml0ZUNhcGFjaXR5OiA1LFxuICAgICAgdGltZVRvTGl2ZUF0dHJpYnV0ZTogJ3R0bCcsXG4gICAgICByZW1vdmFsUG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgLi4ucHJvcHMuZXZlbnRzVGFibGVQcm9wcyxcbiAgICB9KTtcblxuXG4gICAgY29uc3QgbGFtYmRhRnVuY3Rpb25zID0gbmV3IExhbWJkYUZ1bmN0aW9ucyh0aGlzLCAnTGFtYmRhRnVuY3Rpb25zJywge1xuICAgICAgYXJ0aWZhY3RzQnVja2V0LFxuICAgICAgZXZlbnRzVGFibGUsXG4gICAgICBsYW1iZGFQcm9wczogcHJvcHMubGFtYmRhUHJvcHMsXG4gICAgICBhdXRob3JpemVyRnVuY3Rpb246IHByb3BzLmF1dGhvcml6ZXJGdW5jdGlvbixcbiAgICAgIHVzZXJJbmZvRnVuY3Rpb246IHByb3BzLnVzZXJJbmZvRnVuY3Rpb24sXG4gICAgfSk7XG5cbiAgICBjb25zdCBhcGkgPSBuZXcgQVBJR2F0ZXdheSh0aGlzLCAnQVBJR2F0ZXdheScsIHtcbiAgICAgIGxhbWJkYUZ1bmN0aW9ucyxcbiAgICAgIGFydGlmYWN0c0J1Y2tldCxcbiAgICAgIHMzQ3JlZGVudGlhbHMsXG4gICAgICBhcGlQcm9wczogcHJvcHMuYXBpUHJvcHMsXG4gICAgfSk7XG4gIH1cbn0iXX0=