UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

258 lines 33.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.errorWithCode = exports.mockResolvedEnvironment = exports.mockToolkitInfo = exports.mockBootstrapStack = exports.MockSdk = exports.MockSdkProvider = void 0; const AWS = require("aws-sdk"); const aws_auth_1 = require("../../lib/api/aws-auth"); const toolkit_info_1 = require("../../lib/api/toolkit-info"); const cloudformation_1 = require("../../lib/api/util/cloudformation"); const FAKE_CREDENTIALS = new AWS.Credentials({ accessKeyId: 'ACCESS', secretAccessKey: 'SECRET', sessionToken: 'TOKEN ' }); const FAKE_CREDENTIAL_CHAIN = new AWS.CredentialProviderChain([ () => FAKE_CREDENTIALS, ]); /** * An SDK that allows replacing (some of) the clients * * It's the responsibility of the consumer to replace all calls that * actually will be called. */ class MockSdkProvider extends aws_auth_1.SdkProvider { constructor(options = {}) { super(FAKE_CREDENTIAL_CHAIN, 'bermuda-triangle-1337', { customUserAgent: 'aws-cdk/jest' }); // SDK contains a real SDK, since some test use 'AWS-mock' to replace the underlying // AWS calls which a real SDK would do, and some tests use the 'stub' functionality below. if (options.realSdk ?? true) { this.sdk = new aws_auth_1.SDK(FAKE_CREDENTIALS, this.defaultRegion, { customUserAgent: 'aws-cdk/jest' }); } else { this.sdk = this._mockSdk = new MockSdk(); } } get mockSdk() { if (!this._mockSdk) { throw new Error('MockSdkProvider was not created with \'realSdk: false\''); } return this._mockSdk; } async baseCredentialsPartition(_environment, _mode) { return undefined; } defaultAccount() { return Promise.resolve({ accountId: '123456789012', partition: 'aws' }); } forEnvironment() { return Promise.resolve({ sdk: this.sdk, didAssumeRole: true }); } /** * Replace the CloudFormation client with the given object */ stubCloudFormation(stubs) { this.sdk.cloudFormation = jest.fn().mockReturnValue(partialAwsService(stubs)); } /** * Replace the ECR client with the given object */ stubEcr(stubs) { this.sdk.ecr = jest.fn().mockReturnValue(partialAwsService(stubs)); } stubEcs(stubs, additionalProperties = {}) { this.sdk.ecs = jest.fn().mockReturnValue(partialAwsService(stubs, additionalProperties)); } /** * Replace the S3 client with the given object */ stubS3(stubs) { this.sdk.s3 = jest.fn().mockReturnValue(partialAwsService(stubs)); } /** * Replace the STS client with the given object */ stubSTS(stubs) { this.sdk.sts = jest.fn().mockReturnValue(partialAwsService(stubs)); } /** * Replace the ELBv2 client with the given object */ stubELBv2(stubs) { this.sdk.elbv2 = jest.fn().mockReturnValue(partialAwsService(stubs)); } /** * Replace the SSM client with the given object */ stubSSM(stubs) { this.sdk.ssm = jest.fn().mockReturnValue(partialAwsService(stubs)); } stubLambda(stubs, additionalProperties = {}) { this.sdk.lambda = jest.fn().mockReturnValue(partialAwsService(stubs, additionalProperties)); } stubIam(stubs, additionalProperties = {}) { this.sdk.iam = jest.fn().mockReturnValue(partialAwsService(stubs, additionalProperties)); } stubStepFunctions(stubs) { this.sdk.stepFunctions = jest.fn().mockReturnValue(partialAwsService(stubs)); } stubCodeBuild(stubs) { this.sdk.codeBuild = jest.fn().mockReturnValue(partialAwsService(stubs)); } stubCloudWatchLogs(stubs) { this.sdk.cloudWatchLogs = jest.fn().mockReturnValue(partialAwsService(stubs)); } stubAppSync(stubs) { this.sdk.appsync = jest.fn().mockReturnValue(partialAwsService(stubs)); } stubGetEndpointSuffix(stub) { this.sdk.getEndpointSuffix = stub; } } exports.MockSdkProvider = MockSdkProvider; class MockSdk { constructor() { this.currentRegion = 'bermuda-triangle-1337'; this.lambda = jest.fn(); this.iam = jest.fn(); this.cloudFormation = jest.fn(); this.ec2 = jest.fn(); this.ssm = jest.fn(); this.s3 = jest.fn(); this.route53 = jest.fn(); this.ecr = jest.fn(); this.ecs = jest.fn(); this.elbv2 = jest.fn(); this.secretsManager = jest.fn(); this.kms = jest.fn(); this.stepFunctions = jest.fn(); this.codeBuild = jest.fn(); this.cloudWatchLogs = jest.fn(); this.appsync = jest.fn(); this.getEndpointSuffix = jest.fn(); this.appendCustomUserAgent = jest.fn(); this.removeCustomUserAgent = jest.fn(); } currentAccount() { return Promise.resolve({ accountId: '123456789012', partition: 'aws' }); } /** * Replace the CloudFormation client with the given object */ stubCloudFormation(stubs) { this.cloudFormation.mockReturnValue(partialAwsService(stubs)); } /** * Replace the CloudWatch client with the given object */ stubCloudWatchLogs(stubs) { this.cloudWatchLogs.mockReturnValue(partialAwsService(stubs)); } /** * Replace the AppSync client with the given object */ stubAppSync(stubs) { this.appsync.mockReturnValue(partialAwsService(stubs)); } /** * Replace the ECR client with the given object */ stubEcr(stubs) { this.ecr.mockReturnValue(partialAwsService(stubs)); } /** * Replace the SSM client with the given object */ stubSsm(stubs) { this.ssm.mockReturnValue(partialAwsService(stubs)); } /** * Replace the getEndpointSuffix client with the given object */ stubGetEndpointSuffix(stub) { this.getEndpointSuffix.mockReturnValue(stub()); } } exports.MockSdk = MockSdk; /** * Wrap synchronous fake handlers so that they sort-of function like a real AWS client * * For example, turns an object like this: * * ```ts * { * someCall(opts: AWS.Service.SomeCallInput): AWS.Service.SomeCallOutput { * return {...whatever...}; * } * } * ``` * * Into an object that in the type system pretends to be an 'AWS.Service' * class (even though it really isn't) and can be called like this: * * ```ts * const service = await sdk.someService(...); * const response = await service.someCall(...).promise(); * ``` * * We only implement the narrow subset of the AWS SDK API that the CDK actually * uses, and we cheat on the types to make TypeScript happy on the rest of the API. * * Most important feature of this class is that it will derive the input and output * types of the handlers on the input object from the ACTUAL AWS Service class, * so that you don't have to declare them. */ function partialAwsService(fns, additionalProperties = {}) { // Super unsafe in here because I don't know how to make TypeScript happy, // but at least the outer types make sure everything that happens in here works out. const ret = {}; for (const [key, handler] of Object.entries(fns)) { ret[key] = (args) => new FakeAWSResponse(handler(args)); } for (const [key, value] of Object.entries(additionalProperties)) { ret[key] = value; } return ret; } /** * Fake AWS response. * * We only ever 'await response.promise()' so that's the only thing we implement here. */ class FakeAWSResponse { constructor(x) { this.x = x; } promise() { return Promise.resolve(this.x); } } function mockBootstrapStack(sdk, stack) { return cloudformation_1.CloudFormationStack.fromStaticInformation((sdk ?? new MockSdk()).cloudFormation(), 'CDKToolkit', { CreationTime: new Date(), StackName: 'CDKToolkit', StackStatus: 'CREATE_COMPLETE', ...stack, Outputs: [ { OutputKey: 'BucketName', OutputValue: 'BUCKET_NAME' }, { OutputKey: 'BucketDomainName', OutputValue: 'BUCKET_ENDPOINT' }, { OutputKey: 'BootstrapVersion', OutputValue: '1' }, ...stack?.Outputs ?? [], ], }); } exports.mockBootstrapStack = mockBootstrapStack; function mockToolkitInfo(stack) { const sdk = new MockSdk(); return toolkit_info_1.ToolkitInfo.fromStack(mockBootstrapStack(sdk, stack)); } exports.mockToolkitInfo = mockToolkitInfo; function mockResolvedEnvironment() { return { account: '123456789', region: 'bermuda-triangle-1337', name: 'aws://123456789/bermuda-triangle-1337', }; } exports.mockResolvedEnvironment = mockResolvedEnvironment; function errorWithCode(code, message) { const ret = new Error(message); ret.code = code; return ret; } exports.errorWithCode = errorWithCode; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1zZGsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtb2NrLXNkay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSwrQkFBK0I7QUFDL0IscURBQTRGO0FBRTVGLDZEQUF5RDtBQUN6RCxzRUFBd0U7QUFFeEUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFFM0gsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQztJQUM1RCxHQUFHLEVBQUUsQ0FBQyxnQkFBZ0I7Q0FDdkIsQ0FBQyxDQUFDO0FBY0g7Ozs7O0dBS0c7QUFDSCxNQUFhLGVBQWdCLFNBQVEsc0JBQVc7SUFJOUMsWUFBWSxVQUFrQyxFQUFFO1FBQzlDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSx1QkFBdUIsRUFBRSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBRTNGLG9GQUFvRjtRQUNwRiwwRkFBMEY7UUFDMUYsSUFBSSxPQUFPLENBQUMsT0FBTyxJQUFJLElBQUksRUFBRTtZQUMzQixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksY0FBRyxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztTQUMvRjthQUFNO1lBQ0wsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7U0FDMUM7SUFDSCxDQUFDO0lBRUQsSUFBVyxPQUFPO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztTQUM1RTtRQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEs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U0FBZ0IsYUFBYSxDQUFDLElBQVksRUFBRSxPQUFlO0lBQ3pELE1BQU0sR0FBRyxHQUFHLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlCLEdBQVcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUpELHNDQUlDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L29yZGVyICovXG5pbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0ICogYXMgQVdTIGZyb20gJ2F3cy1zZGsnO1xuaW1wb3J0IHsgQWNjb3VudCwgSVNESywgU0RLLCBTZGtQcm92aWRlciwgU2RrRm9yRW52aXJvbm1lbnQgfSBmcm9tICcuLi8uLi9saWIvYXBpL2F3cy1hdXRoJztcbmltcG9ydCB7IE1vZGUgfSBmcm9tICcuLi8uLi9saWIvYXBpL2F3cy1hdXRoL2NyZWRlbnRpYWxzJztcbmltcG9ydCB7IFRvb2xraXRJbmZvIH0gZnJvbSAnLi4vLi4vbGliL2FwaS90b29sa2l0LWluZm8nO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25TdGFjayB9IGZyb20gJy4uLy4uL2xpYi9hcGkvdXRpbC9jbG91ZGZvcm1hdGlvbic7XG5cbmNvbnN0IEZBS0VfQ1JFREVOVElBTFMgPSBuZXcgQVdTLkNyZWRlbnRpYWxzKHsgYWNjZXNzS2V5SWQ6ICdBQ0NFU1MnLCBzZWNyZXRBY2Nlc3NLZXk6ICdTRUNSRVQnLCBzZXNzaW9uVG9rZW46ICdUT0tFTiAnIH0pO1xuXG5jb25zdCBGQUtFX0NSRURFTlRJQUxfQ0hBSU4gPSBuZXcgQVdTLkNyZWRlbnRpYWxQcm92aWRlckNoYWluKFtcbiAgKCkgPT4gRkFLRV9DUkVERU5USUFMUyxcbl0pO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1vY2tTZGtQcm92aWRlck9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciB0aGUgbW9jayBwcm92aWRlciBzaG91bGQgcHJvZHVjZSBhIHJlYWwgU0RLXG4gICAqXG4gICAqIFNvbWUgdGVzdHMgcmVxdWlyZSBhIHJlYWwgU0RLIGJlY2F1c2UgdGhleSB1c2UgYEFXUy1tb2NrYCB0byByZXBsYWNlXG4gICAqIHRoZSB1bmRlcmx5aW5nIGNhbGxzLiBPdGhlciB0ZXN0cyBkbyB0aGVpciB3b3JrIGNvbXBsZXRlbHkgdXNpbmcgamVzdC1tb2Nrcy5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVhbFNkaz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQW4gU0RLIHRoYXQgYWxsb3dzIHJlcGxhY2luZyAoc29tZSBvZikgdGhlIGNsaWVudHNcbiAqXG4gKiBJdCdzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgY29uc3VtZXIgdG8gcmVwbGFjZSBhbGwgY2FsbHMgdGhhdFxuICogYWN0dWFsbHkgd2lsbCBiZSBjYWxsZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrU2RrUHJvdmlkZXIgZXh0ZW5kcyBTZGtQcm92aWRlciB7XG4gIHB1YmxpYyByZWFkb25seSBzZGs6IElTREs7XG4gIHByaXZhdGUgcmVhZG9ubHkgX21vY2tTZGs/OiBNb2NrU2RrO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1vY2tTZGtQcm92aWRlck9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKEZBS0VfQ1JFREVOVElBTF9DSEFJTiwgJ2Jlcm11ZGEtdHJpYW5nbGUtMTMzNycsIHsgY3VzdG9tVXNlckFnZW50OiAnYXdzLWNkay9qZXN0JyB9KTtcblxuICAgIC8vIFNESyBjb250YWlucyBhIHJlYWwgU0RLLCBzaW5jZSBzb21lIHRlc3QgdXNlICdBV1MtbW9jaycgdG8gcmVwbGFjZSB0aGUgdW5kZXJseWluZ1xuICAgIC8vIEFXUyBjYWxscyB3aGljaCBhIHJlYWwgU0RLIHdvdWxkIGRvLCBhbmQgc29tZSB0ZXN0cyB1c2UgdGhlICdzdHViJyBmdW5jdGlvbmFsaXR5IGJlbG93LlxuICAgIGlmIChvcHRpb25zLnJlYWxTZGsgPz8gdHJ1ZSkge1xuICAgICAgdGhpcy5zZGsgPSBuZXcgU0RLKEZBS0VfQ1JFREVOVElBTFMsIHRoaXMuZGVmYXVsdFJlZ2lvbiwgeyBjdXN0b21Vc2VyQWdlbnQ6ICdhd3MtY2RrL2plc3QnIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNkayA9IHRoaXMuX21vY2tTZGsgPSBuZXcgTW9ja1NkaygpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXQgbW9ja1NkaygpOiBNb2NrU2RrIHtcbiAgICBpZiAoIXRoaXMuX21vY2tTZGspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1Nka1Byb3ZpZGVyIHdhcyBub3QgY3JlYXRlZCB3aXRoIFxcJ3JlYWxTZGs6IGZhbHNlXFwnJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9tb2NrU2RrO1xuICB9XG5cbiAgYXN5bmMgYmFzZUNyZWRlbnRpYWxzUGFydGl0aW9uKF9lbnZpcm9ubWVudDogY3hhcGkuRW52aXJvbm1lbnQsIF9tb2RlOiBNb2RlKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGRlZmF1bHRBY2NvdW50KCk6IFByb21pc2U8QWNjb3VudCB8IHVuZGVmaW5lZD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyBhY2NvdW50SWQ6ICcxMjM0NTY3ODkwMTInLCBwYXJ0aXRpb246ICdhd3MnIH0pO1xuICB9XG5cbiAgcHVibGljIGZvckVudmlyb25tZW50KCk6IFByb21pc2U8U2RrRm9yRW52aXJvbm1lbnQ+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgc2RrOiB0aGlzLnNkaywgZGlkQXNzdW1lUm9sZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRoZSBDbG91ZEZvcm1hdGlvbiBjbGllbnQgd2l0aCB0aGUgZ2l2ZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3R1YkNsb3VkRm9ybWF0aW9uKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5DbG91ZEZvcm1hdGlvbj4pIHtcbiAgICAodGhpcy5zZGsgYXMgYW55KS5jbG91ZEZvcm1hdGlvbiA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLkNsb3VkRm9ybWF0aW9uPihzdHVicykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIEVDUiBjbGllbnQgd2l0aCB0aGUgZ2l2ZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3R1YkVjcihzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuRUNSPikge1xuICAgICh0aGlzLnNkayBhcyBhbnkpLmVjciA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLkVDUj4oc3R1YnMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViRWNzKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5FQ1M+LCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9KSB7XG4gICAgKHRoaXMuc2RrIGFzIGFueSkuZWNzID0gamVzdC5mbigpLm1vY2tSZXR1cm5WYWx1ZShwYXJ0aWFsQXdzU2VydmljZTxBV1MuRUNTPihzdHVicywgYWRkaXRpb25hbFByb3BlcnRpZXMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRoZSBTMyBjbGllbnQgd2l0aCB0aGUgZ2l2ZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3R1YlMzKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5TMz4pIHtcbiAgICAodGhpcy5zZGsgYXMgYW55KS5zMyA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLlMzPihzdHVicykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIFNUUyBjbGllbnQgd2l0aCB0aGUgZ2l2ZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3R1YlNUUyhzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuU1RTPikge1xuICAgICh0aGlzLnNkayBhcyBhbnkpLnN0cyA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLlNUUz4oc3R1YnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRoZSBFTEJ2MiBjbGllbnQgd2l0aCB0aGUgZ2l2ZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3R1YkVMQnYyKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5FTEJ2Mj4pIHtcbiAgICAodGhpcy5zZGsgYXMgYW55KS5lbGJ2MiA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLkVMQnYyPihzdHVicykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIFNTTSBjbGllbnQgd2l0aCB0aGUgZ2l2ZW4gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3R1YlNTTShzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuU1NNPikge1xuICAgICh0aGlzLnNkayBhcyBhbnkpLnNzbSA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLlNTTT4oc3R1YnMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViTGFtYmRhKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5MYW1iZGE+LCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9KSB7XG4gICAgKHRoaXMuc2RrIGFzIGFueSkubGFtYmRhID0gamVzdC5mbigpLm1vY2tSZXR1cm5WYWx1ZShwYXJ0aWFsQXdzU2VydmljZTxBV1MuTGFtYmRhPihzdHVicywgYWRkaXRpb25hbFByb3BlcnRpZXMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViSWFtKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5JQU0+LCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9KSB7XG4gICAgKHRoaXMuc2RrIGFzIGFueSkuaWFtID0gamVzdC5mbigpLm1vY2tSZXR1cm5WYWx1ZShwYXJ0aWFsQXdzU2VydmljZTxBV1MuSUFNPihzdHVicywgYWRkaXRpb25hbFByb3BlcnRpZXMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViU3RlcEZ1bmN0aW9ucyhzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuU3RlcEZ1bmN0aW9ucz4pIHtcbiAgICAodGhpcy5zZGsgYXMgYW55KS5zdGVwRnVuY3Rpb25zID0gamVzdC5mbigpLm1vY2tSZXR1cm5WYWx1ZShwYXJ0aWFsQXdzU2VydmljZTxBV1MuU3RlcEZ1bmN0aW9ucz4oc3R1YnMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViQ29kZUJ1aWxkKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5Db2RlQnVpbGQ+KSB7XG4gICAgKHRoaXMuc2RrIGFzIGFueSkuY29kZUJ1aWxkID0gamVzdC5mbigpLm1vY2tSZXR1cm5WYWx1ZShwYXJ0aWFsQXdzU2VydmljZTxBV1MuQ29kZUJ1aWxkPihzdHVicykpO1xuICB9XG5cbiAgcHVibGljIHN0dWJDbG91ZFdhdGNoTG9ncyhzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuQ2xvdWRXYXRjaExvZ3M+KSB7XG4gICAgKHRoaXMuc2RrIGFzIGFueSkuY2xvdWRXYXRjaExvZ3MgPSBqZXN0LmZuKCkubW9ja1JldHVyblZhbHVlKHBhcnRpYWxBd3NTZXJ2aWNlPEFXUy5DbG91ZFdhdGNoTG9ncz4oc3R1YnMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViQXBwU3luYyhzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuQXBwU3luYz4pIHtcbiAgICAodGhpcy5zZGsgYXMgYW55KS5hcHBzeW5jID0gamVzdC5mbigpLm1vY2tSZXR1cm5WYWx1ZShwYXJ0aWFsQXdzU2VydmljZTxBV1MuQXBwU3luYz4oc3R1YnMpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdHViR2V0RW5kcG9pbnRTdWZmaXgoc3R1YjogKCkgPT4gc3RyaW5nKSB7XG4gICAgdGhpcy5zZGsuZ2V0RW5kcG9pbnRTdWZmaXggPSBzdHViO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNb2NrU2RrIGltcGxlbWVudHMgSVNESyB7XG4gIHB1YmxpYyByZWFkb25seSBjdXJyZW50UmVnaW9uOiBzdHJpbmcgPSAnYmVybXVkYS10cmlhbmdsZS0xMzM3JztcbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYSA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGlhbSA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGNsb3VkRm9ybWF0aW9uID0gamVzdC5mbigpO1xuICBwdWJsaWMgcmVhZG9ubHkgZWMyID0gamVzdC5mbigpO1xuICBwdWJsaWMgcmVhZG9ubHkgc3NtID0gamVzdC5mbigpO1xuICBwdWJsaWMgcmVhZG9ubHkgczMgPSBqZXN0LmZuKCk7XG4gIHB1YmxpYyByZWFkb25seSByb3V0ZTUzID0gamVzdC5mbigpO1xuICBwdWJsaWMgcmVhZG9ubHkgZWNyID0gamVzdC5mbigpO1xuICBwdWJsaWMgcmVhZG9ubHkgZWNzID0gamVzdC5mbigpO1xuICBwdWJsaWMgcmVhZG9ubHkgZWxidjIgPSBqZXN0LmZuKCk7XG4gIHB1YmxpYyByZWFkb25seSBzZWNyZXRzTWFuYWdlciA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGttcyA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IHN0ZXBGdW5jdGlvbnMgPSBqZXN0LmZuKCk7XG4gIHB1YmxpYyByZWFkb25seSBjb2RlQnVpbGQgPSBqZXN0LmZuKCk7XG4gIHB1YmxpYyByZWFkb25seSBjbG91ZFdhdGNoTG9ncyA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGFwcHN5bmMgPSBqZXN0LmZuKCk7XG4gIHB1YmxpYyByZWFkb25seSBnZXRFbmRwb2ludFN1ZmZpeCA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGFwcGVuZEN1c3RvbVVzZXJBZ2VudCA9IGplc3QuZm4oKTtcbiAgcHVibGljIHJlYWRvbmx5IHJlbW92ZUN1c3RvbVVzZXJBZ2VudCA9IGplc3QuZm4oKTtcblxuICBwdWJsaWMgY3VycmVudEFjY291bnQoKTogUHJvbWlzZTxBY2NvdW50PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGFjY291bnRJZDogJzEyMzQ1Njc4OTAxMicsIHBhcnRpdGlvbjogJ2F3cycgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZSB0aGUgQ2xvdWRGb3JtYXRpb24gY2xpZW50IHdpdGggdGhlIGdpdmVuIG9iamVjdFxuICAgKi9cbiAgcHVibGljIHN0dWJDbG91ZEZvcm1hdGlvbihzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuQ2xvdWRGb3JtYXRpb24+KSB7XG4gICAgdGhpcy5jbG91ZEZvcm1hdGlvbi5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLkNsb3VkRm9ybWF0aW9uPihzdHVicykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIENsb3VkV2F0Y2ggY2xpZW50IHdpdGggdGhlIGdpdmVuIG9iamVjdFxuICAgKi9cbiAgcHVibGljIHN0dWJDbG91ZFdhdGNoTG9ncyhzdHViczogU3luY0hhbmRsZXJTdWJzZXRPZjxBV1MuQ2xvdWRXYXRjaExvZ3M+KSB7XG4gICAgdGhpcy5jbG91ZFdhdGNoTG9ncy5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLkNsb3VkV2F0Y2hMb2dzPihzdHVicykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIEFwcFN5bmMgY2xpZW50IHdpdGggdGhlIGdpdmVuIG9iamVjdFxuICAgKi9cbiAgcHVibGljIHN0dWJBcHBTeW5jKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5BcHBTeW5jPikge1xuICAgIHRoaXMuYXBwc3luYy5tb2NrUmV0dXJuVmFsdWUocGFydGlhbEF3c1NlcnZpY2U8QVdTLkFwcFN5bmM+KHN0dWJzKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZSB0aGUgRUNSIGNsaWVudCB3aXRoIHRoZSBnaXZlbiBvYmplY3RcbiAgICovXG4gIHB1YmxpYyBzdHViRWNyKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5FQ1I+KSB7XG4gICAgdGhpcy5lY3IubW9ja1JldHVyblZhbHVlKHBhcnRpYWxBd3NTZXJ2aWNlPEFXUy5FQ1I+KHN0dWJzKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZSB0aGUgU1NNIGNsaWVudCB3aXRoIHRoZSBnaXZlbiBvYmplY3RcbiAgICovXG4gIHB1YmxpYyBzdHViU3NtKHN0dWJzOiBTeW5jSGFuZGxlclN1YnNldE9mPEFXUy5TU00+KSB7XG4gICAgdGhpcy5zc20ubW9ja1JldHVyblZhbHVlKHBhcnRpYWxBd3NTZXJ2aWNlPEFXUy5TU00+KHN0dWJzKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZSB0aGUgZ2V0RW5kcG9pbnRTdWZmaXggY2xpZW50IHdpdGggdGhlIGdpdmVuIG9iamVjdFxuICAgKi9cbiAgcHVibGljIHN0dWJHZXRFbmRwb2ludFN1ZmZpeChzdHViOiAoKSA9PiBzdHJpbmcpIHtcbiAgICB0aGlzLmdldEVuZHBvaW50U3VmZml4Lm1vY2tSZXR1cm5WYWx1ZShzdHViKCkpO1xuICB9XG59XG5cbi8qKlxuICogV3JhcCBzeW5jaHJvbm91cyBmYWtlIGhhbmRsZXJzIHNvIHRoYXQgdGhleSBzb3J0LW9mIGZ1bmN0aW9uIGxpa2UgYSByZWFsIEFXUyBjbGllbnRcbiAqXG4gKiBGb3IgZXhhbXBsZSwgdHVybnMgYW4gb2JqZWN0IGxpa2UgdGhpczpcbiAqXG4gKiBgYGB0c1xuICoge1xuICogICBzb21lQ2FsbChvcHRzOiBBV1MuU2VydmljZS5Tb21lQ2FsbElucHV0KTogQVdTLlNlcnZpY2UuU29tZUNhbGxPdXRwdXQge1xuICogICAgIHJldHVybiB7Li4ud2hhdGV2ZXIuLi59O1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBJbnRvIGFuIG9iamVjdCB0aGF0IGluIHRoZSB0eXBlIHN5c3RlbSBwcmV0ZW5kcyB0byBiZSBhbiAnQVdTLlNlcnZpY2UnXG4gKiBjbGFzcyAoZXZlbiB0aG91Z2ggaXQgcmVhbGx5IGlzbid0KSBhbmQgY2FuIGJlIGNhbGxlZCBsaWtlIHRoaXM6XG4gKlxuICogYGBgdHNcbiAqIGNvbnN0IHNlcnZpY2UgPSBhd2FpdCBzZGsuc29tZVNlcnZpY2UoLi4uKTtcbiAqIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VydmljZS5zb21lQ2FsbCguLi4pLnByb21pc2UoKTtcbiAqIGBgYFxuICpcbiAqIFdlIG9ubHkgaW1wbGVtZW50IHRoZSBuYXJyb3cgc3Vic2V0IG9mIHRoZSBBV1MgU0RLIEFQSSB0aGF0IHRoZSBDREsgYWN0dWFsbHlcbiAqIHVzZXMsIGFuZCB3ZSBjaGVhdCBvbiB0aGUgdHlwZXMgdG8gbWFrZSBUeXBlU2NyaXB0IGhhcHB5IG9uIHRoZSByZXN0IG9mIHRoZSBBUEkuXG4gKlxuICogTW9zdCBpbXBvcnRhbnQgZmVhdHVyZSBvZiB0aGlzIGNsYXNzIGlzIHRoYXQgaXQgd2lsbCBkZXJpdmUgdGhlIGlucHV0IGFuZCBvdXRwdXRcbiAqIHR5cGVzIG9mIHRoZSBoYW5kbGVycyBvbiB0aGUgaW5wdXQgb2JqZWN0IGZyb20gdGhlIEFDVFVBTCBBV1MgU2VydmljZSBjbGFzcyxcbiAqIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gZGVjbGFyZSB0aGVtLlxuICovXG5mdW5jdGlvbiBwYXJ0aWFsQXdzU2VydmljZTxTPihmbnM6IFN5bmNIYW5kbGVyU3Vic2V0T2Y8Uz4sIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge30pOiBTIHtcbiAgLy8gU3VwZXIgdW5zYWZlIGluIGhlcmUgYmVjYXVzZSBJIGRvbid0IGtub3cgaG93IHRvIG1ha2UgVHlwZVNjcmlwdCBoYXBweSxcbiAgLy8gYnV0IGF0IGxlYXN0IHRoZSBvdXRlciB0eXBlcyBtYWtlIHN1cmUgZXZlcnl0aGluZyB0aGF0IGhhcHBlbnMgaW4gaGVyZSB3b3JrcyBvdXQuXG4gIGNvbnN0IHJldDogYW55ID0ge307XG5cbiAgZm9yIChjb25zdCBba2V5LCBoYW5kbGVyXSBvZiBPYmplY3QuZW50cmllcyhmbnMpKSB7XG4gICAgcmV0W2tleV0gPSAoYXJnczogYW55KSA9PiBuZXcgRmFrZUFXU1Jlc3BvbnNlKChoYW5kbGVyIGFzIGFueSkoYXJncykpO1xuICB9XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGFkZGl0aW9uYWxQcm9wZXJ0aWVzKSkge1xuICAgIHJldFtrZXldID0gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG4vLyBCZWNhdXNlIG9mIHRoZSBvdmVybG9hZHMgYW4gQVdTIGhhbmRsZXIgdHlwZSBsb29rcyBsaWtlIHRoaXM6XG4vL1xuLy8gICB7XG4vLyAgICAgIChwYXJhbXM6IElOUFVUU1RSVUNULCBjYWxsYmFjaz86ICgoZXJyOiBBV1NFcnJvciwgZGF0YToge30pID0+IHZvaWQpIHwgdW5kZWZpbmVkKTogUmVxdWVzdDxPVVRQVVQsIC4uLj47XG4vLyAgICAgIChjYWxsYmFjaz86ICgoZXJyOiBBV1MuQVdTRXJyb3IsIGRhdGE6IHt9KSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IEFXUy5SZXF1ZXN0PC4uLj47XG4vLyAgIH1cbi8vXG4vLyBHZXQgdGhlIGZpcnN0IG92ZXJsb2FkIGFuZCBleHRyYWN0IHRoZSBpbnB1dCBhbmQgb3V0cHV0IHN0cnVjdCB0eXBlc1xudHlwZSBBd3NDYWxsSW5wdXRPdXRwdXQ8VD4gPVxuICAgIFQgZXh0ZW5kcyB7XG4gICAgICAoYXJnczogaW5mZXIgSU5QVVQsIGNhbGxiYWNrPzogKChlcnI6IEFXUy5BV1NFcnJvciwgZGF0YTogYW55KSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IEFXUy5SZXF1ZXN0PGluZmVyIE9VVFBVVCwgQVdTLkFXU0Vycm9yPjtcbiAgICAgIChjYWxsYmFjaz86ICgoZXJyOiBBV1MuQVdTRXJyb3IsIGRhdGE6IHt9KSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IEFXUy5SZXF1ZXN0PGFueSwgYW55PjtcbiAgICB9ID8gW0lOUFVULCBPVVRQVVRdIDogVDtcblxuLy8gRGV0ZXJtaW5lIHRoZSB0eXBlIG9mIHRoZSBtb2NrIGhhbmRsZXIgZnJvbSB0aGUgdHlwZSBvZiB0aGUgSW5wdXQvT3V0cHV0IHR5cGUgcGFpci5cbi8vIERvbid0IG5lZWQgdG8gd29ycnkgYWJvdXQgdGhlICduZXZlcicsIFR5cGVTY3JpcHQgd2lsbCBwcm9wYWdhdGUgaXQgdXB3YXJkcyBtYWtpbmcgaXRcbi8vIGltcG9zc2libGUgdG8gc3BlY2lmeSB0aGUgZmllbGQgdGhhdCBoYXMgJ25ldmVyJyBhbnl3aGVyZSBpbiBpdHMgdHlwZS5cbnR5cGUgTW9ja0hhbmRsZXJUeXBlPEFJPiA9XG4gICAgQUkgZXh0ZW5kcyBbYW55LCBhbnldID8gKGlucHV0OiBBSVswXSkgPT4gQUlbMV0gOiBBSTtcblxuLy8gQW55IHN1YnNldCBvZiB0aGUgZnVsbCB0eXBlIHRoYXQgc3luY2hyb25vdXNseSByZXR1cm5zIHRoZSBvdXRwdXQgc3RydWN0dXJlIGlzIG9rYXlcbmV4cG9ydCB0eXBlIFN5bmNIYW5kbGVyU3Vic2V0T2Y8Uz4gPSB7W0sgaW4ga2V5b2YgU10/OiBNb2NrSGFuZGxlclR5cGU8QXdzQ2FsbElucHV0T3V0cHV0PFNbS10+Pn07XG5cbi8qKlxuICogRmFrZSBBV1MgcmVzcG9uc2UuXG4gKlxuICogV2Ugb25seSBldmVyICdhd2FpdCByZXNwb25zZS5wcm9taXNlKCknIHNvIHRoYXQncyB0aGUgb25seSB0aGluZyB3ZSBpbXBsZW1lbnQgaGVyZS5cbiAqL1xuY2xhc3MgRmFrZUFXU1Jlc3BvbnNlPFQ+IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB4OiBUKSB7XG4gIH1cblxuICBwdWJsaWMgcHJvbWlzZSgpOiBQcm9taXNlPFQ+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMueCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1vY2tCb290c3RyYXBTdGFjayhzZGs6IElTREsgfCB1bmRlZmluZWQsIHN0YWNrPzogUGFydGlhbDxBV1MuQ2xvdWRGb3JtYXRpb24uU3RhY2s+KSB7XG4gIHJldHVybiBDbG91ZEZvcm1hdGlvblN0YWNrLmZyb21TdGF0aWNJbmZvcm1hdGlvbigoc2RrID8/IG5ldyBNb2NrU2RrKCkpLmNsb3VkRm9ybWF0aW9uKCksICdDREtUb29sa2l0Jywge1xuICAgIENyZWF0aW9uVGltZTogbmV3IERhdGUoKSxcbiAgICBTdGFja05hbWU6ICdDREtUb29sa2l0JyxcbiAgICBTdGFja1N0YXR1czogJ0NSRUFURV9DT01QTEVURScsXG4gICAgLi4uc3RhY2ssXG4gICAgT3V0cHV0czogW1xuICAgICAgeyBPdXRwdXRLZXk6ICdCdWNrZXROYW1lJywgT3V0cHV0VmFsdWU6ICdCVUNLRVRfTkFNRScgfSxcbiAgICAgIHsgT3V0cHV0S2V5OiAnQnVja2V0RG9tYWluTmFtZScsIE91dHB1dFZhbHVlOiAnQlVDS0VUX0VORFBPSU5UJyB9LFxuICAgICAgeyBPdXRwdXRLZXk6ICdCb290c3RyYXBWZXJzaW9uJywgT3V0cHV0VmFsdWU6ICcxJyB9LFxuICAgICAgLi4uc3RhY2s/Lk91dHB1dHMgPz8gW10sXG4gICAgXSxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb2NrVG9vbGtpdEluZm8oc3RhY2s/OiBQYXJ0aWFsPEFXUy5DbG91ZEZvcm1hdGlvbi5TdGFjaz4pIHtcbiAgY29uc3Qgc2RrID0gbmV3IE1vY2tTZGsoKTtcbiAgcmV0dXJuIFRvb2xraXRJbmZvLmZyb21TdGFjayhtb2NrQm9vdHN0cmFwU3RhY2soc2RrLCBzdGFjaykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbW9ja1Jlc29sdmVkRW52aXJvbm1lbnQoKTogY3hhcGkuRW52aXJvbm1lbnQge1xuICByZXR1cm4ge1xuICAgIGFjY291bnQ6ICcxMjM0NTY3ODknLFxuICAgIHJlZ2lvbjogJ2Jlcm11ZGEtdHJpYW5nbGUtMTMzNycsXG4gICAgbmFtZTogJ2F3czovLzEyMzQ1Njc4OS9iZXJtdWRhLXRyaWFuZ2xlLTEzMzcnLFxuICB9O1xufVxuXG4vLyBKZXN0IGhlbHBlcnNcblxuLy8gQW4gb2JqZWN0IG9uIHdoaWNoIGFsbCBjYWxsYWJsZXMgYXJlIEplc3QgTW9ja3NcbmV4cG9ydCB0eXBlIE1vY2tlZE9iamVjdDxTIGV4dGVuZHMgb2JqZWN0PiA9IHtbSyBpbiBrZXlvZiBTXTogTW9ja2VkRnVuY3Rpb248UmVxdWlyZWQ8Uz5bS10+fTtcblxuLy8gSWYgYSBmdW5jdGlvbiwgdGhlbiBhIG1vY2tlZCB2ZXJzaW9uIG9mIGl0LCBvdGhlcndpc2UganVzdCBUXG50eXBlIE1vY2tlZEZ1bmN0aW9uPFQ+ID0gVCBleHRlbmRzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55XG4gID8gamVzdC5Nb2NrSW5zdGFuY2U8UmV0dXJuVHlwZTxUPiwgamVzdC5BcmdzVHlwZTxUPj5cbiAgOiBUO1xuZXhwb3J0IGZ1bmN0aW9uIGVycm9yV2l0aENvZGUoY29kZTogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpIHtcbiAgY29uc3QgcmV0ID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAocmV0IGFzIGFueSkuY29kZSA9IGNvZGU7XG4gIHJldHVybiByZXQ7XG59XG4iXX0=