UNPKG

@aws-cdk/integ-tests-alpha

Version:

CDK Integration Testing Constructs

232 lines 27.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.AssertionsProvider = void 0; const jsiiDeprecationWarnings = require("../../../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = require("path"); const core_1 = require("aws-cdk-lib/core"); const constructs_1 = require("constructs"); const helpers_internal_1 = require("aws-cdk-lib/custom-resources/lib/helpers-internal"); /** * integ-tests can only depend on '@aws-cdk/core' so * this construct creates a lambda function provider using * only CfnResource */ class LambdaFunctionProvider extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); this.policies = []; const staging = new core_1.AssetStaging(this, 'Staging', { sourcePath: path.join(__dirname, 'lambda-handler.bundle'), }); const stack = core_1.Stack.of(this); const asset = stack.synthesizer.addFileAsset({ fileName: staging.relativeStagedPath(stack), sourceHash: staging.assetHash, packaging: core_1.FileAssetPackaging.ZIP_DIRECTORY, }); const role = new core_1.CfnResource(this, 'Role', { type: 'AWS::IAM::Role', properties: { AssumeRolePolicyDocument: { Version: '2012-10-17', Statement: [{ Action: 'sts:AssumeRole', Effect: 'Allow', Principal: { Service: 'lambda.amazonaws.com' } }], }, ManagedPolicyArns: [ { 'Fn::Sub': 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' }, ], Policies: core_1.Lazy.any({ produce: () => { const policies = this.policies.length > 0 ? [ { PolicyName: 'Inline', PolicyDocument: { Version: '2012-10-17', Statement: this.policies, }, }, ] : undefined; return policies; }, }), }, }); const functionProperties = { Runtime: (0, core_1.determineLatestNodeRuntimeName)(this), Code: { S3Bucket: asset.bucketName, S3Key: asset.objectKey, }, Timeout: core_1.Duration.minutes(2).toSeconds(), Handler: props?.handler ?? 'index.handler', Role: role.getAtt('Arn'), }; if (props?.logRetention) { const logGroup = new core_1.CfnResource(this, 'LogGroup', { type: 'AWS::Logs::LogGroup', properties: { LogGroupName: `/aws/lambda/${id}`, RetentionInDays: props.logRetention, }, }); functionProperties.LoggingConfig = { LogGroup: logGroup.ref, }; } const handler = new core_1.CfnResource(this, 'Handler', { type: 'AWS::Lambda::Function', properties: functionProperties, }); this.serviceToken = core_1.Token.asString(handler.getAtt('Arn')); this.roleArn = role.getAtt('Arn'); } addPolicies(policies) { this.policies.push(...policies); } } /** * Mimic the singletonfunction construct in '@aws-cdk/aws-lambda' */ class SingletonFunction extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); this.lambdaFunction = this.ensureFunction(props); this.serviceToken = this.lambdaFunction.serviceToken; } ensureFunction(props) { const constructName = 'SingletonFunction' + slugify(props.uuid); const existing = core_1.Stack.of(this).node.tryFindChild(constructName); if (existing) { return existing; } return new LambdaFunctionProvider(core_1.Stack.of(this), constructName, { handler: props.handler, logRetention: props.logRetention, }); } /** * Add an IAM policy statement to the inline policy of the * lambdas function's role * * **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement` * object like you will see in the rest of the CDK. * * * singleton.addToRolePolicy({ * Effect: 'Allow', * Action: 's3:GetObject', * Resources: '*', * }); */ addToRolePolicy(statement) { this.lambdaFunction.addPolicies([statement]); } /** * Create a policy statement from a specific api call */ addPolicyStatementFromSdkCall(service, api, resources) { this.lambdaFunction.addPolicies([{ Action: [(0, helpers_internal_1.awsSdkToIamAction)(service, api)], Effect: 'Allow', Resource: resources || ['*'], }]); } } /** * Represents an assertions provider. The creates a singletone * Lambda Function that will create a single function per stack * that serves as the custom resource provider for the various * assertion providers */ class AssertionsProvider extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); try { jsiiDeprecationWarnings._aws_cdk_integ_tests_alpha_AssertionsProviderProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, AssertionsProvider); } throw error; } this.handler = new SingletonFunction(this, 'AssertionsProvider', { handler: props?.handler, uuid: props?.uuid ?? '1488541a-7b23-4664-81b6-9b4408076b81', logRetention: props?.logRetention, }); this.handlerRoleArn = this.handler.lambdaFunction.roleArn; this.serviceToken = this.handler.serviceToken; } /** * Encode an object so it can be passed * as custom resource parameters. Custom resources will convert * all input parameters to strings so we encode non-strings here * so we can then decode them correctly in the provider function */ encode(obj) { if (!obj) { return obj; } return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, encodeValue(value)])); function encodeValue(value) { if (ArrayBuffer.isView(value)) { return { $type: 'ArrayBufferView', string: new TextDecoder().decode(value), }; } return JSON.stringify(value); } } /** * Create a policy statement from a specific api call */ addPolicyStatementFromSdkCall(service, api, resources) { this.handler.addPolicyStatementFromSdkCall(service, api, resources); } /** * Add an IAM policy statement to the inline policy of the * lambdas function's role * * **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement` * object like you will see in the rest of the CDK. * * * @example * declare const provider: AssertionsProvider; * provider.addToRolePolicy({ * Effect: 'Allow', * Action: ['s3:GetObject'], * Resource: ['*'], * }); */ addToRolePolicy(statement) { this.handler.addToRolePolicy(statement); } /** * Grant a principal access to invoke the assertion provider * lambda function * * @param principalArn the ARN of the principal that should be given * permission to invoke the assertion provider */ grantInvoke(principalArn) { new core_1.CfnResource(this, 'Invoke', { type: 'AWS::Lambda::Permission', properties: { Action: 'lambda:InvokeFunction', FunctionName: this.serviceToken, Principal: principalArn, }, }); } } exports.AssertionsProvider = AssertionsProvider; _a = JSII_RTTI_SYMBOL_1; AssertionsProvider[_a] = { fqn: "@aws-cdk/integ-tests-alpha.AssertionsProvider", version: "2.190.0-alpha.0" }; function slugify(x) { return x.replace(/[^a-zA-Z0-9]/g, ''); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IsMkNBVTBCO0FBQzFCLDJDQUF1QztBQUN2Qyx3RkFBc0Y7QUFzQnRGOzs7O0dBSUc7QUFDSCxNQUFNLHNCQUF1QixTQUFRLHNCQUFTO0lBYzVDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBbUM7UUFDM0UsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUhGLGFBQVEsR0FBVSxFQUFFLENBQUM7UUFLcEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxtQkFBWSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDaEQsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLHVCQUF1QixDQUFDO1NBQzFELENBQUMsQ0FBQztRQUVILE1BQU0sS0FBSyxHQUFHLFlBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUM7WUFDM0MsUUFBUSxFQUFFLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7WUFDM0MsVUFBVSxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzdCLFNBQVMsRUFBRSx5QkFBa0IsQ0FBQyxhQUFhO1NBQzVDLENBQUMsQ0FBQztRQUVILE1BQU0sSUFBSSxHQUFHLElBQUksa0JBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFO1lBQ3pDLElBQUksRUFBRSxnQkFBZ0I7WUFDdEIsVUFBVSxFQUFFO2dCQUNWLHdCQUF3QixFQUFFO29CQUN4QixPQUFPLEVBQUUsWUFBWTtvQkFDckIsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsRUFBRSxPQUFPLEVBQUUsc0JB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RUQ7Ozs7OztPQU1HO0lBQ0ksV0FBVyxDQUFDLFlBQW9CO1FBQ3JDLElBQUksa0JBQVcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQzlCLElBQUksRUFBRSx5QkFBeUI7WUFDL0IsVUFBVSxFQUFFO2dCQUNWLE1BQU0sRUFBRSx1QkFBdUI7Z0JBQy9CLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtnQkFDL0IsU0FBUyxFQUFFLFlBQVk7YUFDeEI7U0FDRixDQUFDLENBQUM7S0FDSjs7QUEvRkgsZ0RBZ0dDOzs7QUFFRCxTQUFTLE9BQU8sQ0FBQyxDQUFTO0lBQ3hCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDeEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQge1xuICBEdXJhdGlvbixcbiAgQ2ZuUmVzb3VyY2UsXG4gIEFzc2V0U3RhZ2luZyxcbiAgU3RhY2ssXG4gIEZpbGVBc3NldFBhY2thZ2luZyxcbiAgVG9rZW4sXG4gIExhenksXG4gIFJlZmVyZW5jZSxcbiAgZGV0ZXJtaW5lTGF0ZXN0Tm9kZVJ1bnRpbWVOYW1lLFxufSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgYXdzU2RrVG9JYW1BY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzL2xpYi9oZWxwZXJzLWludGVybmFsJztcbmltcG9ydCB7IFJldGVudGlvbkRheXMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYSBsYW1iZGEgZnVuY3Rpb24gcHJvdmlkZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYW1iZGFGdW5jdGlvblByb3ZpZGVyUHJvcHMge1xuICAvKipcbiAgICogVGhlIGhhbmRsZXIgdG8gdXNlIGZvciB0aGUgbGFtYmRhIGZ1bmN0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IGluZGV4LmhhbmRsZXJcbiAgICovXG4gIHJlYWRvbmx5IGhhbmRsZXI/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyBsb25nLCBpbiBkYXlzLCB0aGUgbG9nIGNvbnRlbnRzIHdpbGwgYmUgcmV0YWluZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcmV0ZW50aW9uIGRheXMgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBsb2dSZXRlbnRpb24/OiBSZXRlbnRpb25EYXlzO1xufVxuXG4vKipcbiAqIGludGVnLXRlc3RzIGNhbiBvbmx5IGRlcGVuZCBvbiAnQGF3cy1jZGsvY29yZScgc29cbiAqIHRoaXMgY29uc3RydWN0IGNyZWF0ZXMgYSBsYW1iZGEgZnVuY3Rpb24gcHJvdmlkZXIgdXNpbmdcbiAqIG9ubHkgQ2ZuUmVzb3VyY2VcbiAqL1xuY2xhc3MgTGFtYmRhRnVuY3Rpb25Qcm92aWRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBsYW1iZGEgZnVuY3Rpb24gd2hpY2ggY2FuIGJlIHVzZWRcbiAgICogYXMgYSBzZXJ2aWNlVG9rZW4gdG8gYSBDdXN0b21SZXNvdXJjZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VUb2tlbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIFJlZmVyZW5jZSB0byB0aGUgcHJvdmlkZXIgbGFtYmRhIGV4ZXVjdGlvbiByb2xlIEFSTlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGVBcm46IFJlZmVyZW5jZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBvbGljaWVzOiBhbnlbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzPzogTGFtYmRhRnVuY3Rpb25Qcm92aWRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHN0YWdpbmcgPSBuZXcgQXNzZXRTdGFnaW5nKHRoaXMsICdTdGFnaW5nJywge1xuICAgICAgc291cmNlUGF0aDogcGF0aC5qb2luKF9fZGlybmFtZSwgJ2xhbWJkYS1oYW5kbGVyLmJ1bmRsZScpLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICBjb25zdCBhc3NldCA9IHN0YWNrLnN5bnRoZXNpemVyLmFkZEZpbGVBc3NldCh7XG4gICAgICBmaWxlTmFtZTogc3RhZ2luZy5yZWxhdGl2ZVN0YWdlZFBhdGgoc3RhY2spLFxuICAgICAgc291cmNlSGFzaDogc3RhZ2luZy5hc3NldEhhc2gsXG4gICAgICBwYWNrYWdpbmc6IEZpbGVBc3NldFBhY2thZ2luZy5aSVBfRElSRUNUT1JZLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgcm9sZSA9IG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAnUm9sZScsIHtcbiAgICAgIHR5cGU6ICdBV1M6OklBTTo6Um9sZScsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIEFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgIFZlcnNpb246ICcyMDEyLTEwLTE3JyxcbiAgICAgICAgICBTdGF0ZW1lbnQ6IFt7IEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJywgRWZmZWN0OiAnQWxsb3cnLCBQcmluY2lwYWw6IHsgU2VydmljZTogJ2xhbWJkYS5hbWF6b25hd3MuY29tJyB9IH1dLFxuICAgICAgICB9LFxuICAgICAgICBNYW5hZ2VkUG9saWN5QXJuczogW1xuICAgICAgICAgIHsgJ0ZuOjpTdWInOiAnYXJuOiR7QVdTOjpQYXJ0aXRpb259OmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJyB9LFxuICAgICAgICBdLFxuICAgICAgICBQb2xpY2llczogTGF6eS5hbnkoe1xuICAgICAgICAgIHByb2R1Y2U6ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBvbGljaWVzID0gdGhpcy5wb2xpY2llcy5sZW5ndGggPiAwID8gW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgUG9saWN5TmFtZTogJ0lubGluZScsXG4gICAgICAgICAgICAgICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAgIFZlcnNpb246ICcyMDEyLTEwLTE3JyxcbiAgICAgICAgICAgICAgICAgIFN0YXRlbWVudDogdGhpcy5wb2xpY2llcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiBwb2xpY2llcztcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBmdW5jdGlvblByb3BlcnRpZXM6IGFueSA9IHtcbiAgICAgIFJ1bnRpbWU6IGRldGVybWluZUxhdGVzdE5vZGVSdW50aW1lTmFtZSh0aGlzKSxcbiAgICAgIENvZGU6IHtcbiAgICAgICAgUzNCdWNrZXQ6IGFzc2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgIFMzS2V5OiBhc3NldC5vYmplY3RLZXksXG4gICAgICB9LFxuICAgICAgVGltZW91dDogRHVyYXRpb24ubWludXRlcygyKS50b1NlY29uZHMoKSxcbiAgICAgIEhhbmRsZXI6IHByb3BzPy5oYW5kbGVyID8/ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIFJvbGU6IHJvbGUuZ2V0QXR0KCdBcm4nKSxcbiAgICB9O1xuXG4gICAgaWYgKHByb3BzPy5sb2dSZXRlbnRpb24pIHtcbiAgICAgIGNvbnN0IGxvZ0dyb3VwID0gbmV3IENmblJlc291cmNlKHRoaXMsICdMb2dHcm91cCcsIHtcbiAgICAgICAgdHlwZTogJ0FXUzo6TG9nczo6TG9nR3JvdXAnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgTG9nR3JvdXBOYW1lOiBgL2F3cy9sYW1iZGEvJHtpZH1gLFxuICAgICAgICAgIFJldGVudGlvbkluRGF5czogcHJvcHMubG9nUmV0ZW50aW9uLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGZ1bmN0aW9uUHJvcGVydGllcy5Mb2dnaW5nQ29uZmlnID0ge1xuICAgICAgICBMb2dHcm91cDogbG9nR3JvdXAucmVmLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IENmblJlc291cmNlKHRoaXMsICdIYW5kbGVyJywge1xuICAgICAgdHlwZTogJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsXG4gICAgICBwcm9wZXJ0aWVzOiBmdW5jdGlvblByb3BlcnRpZXMsXG4gICAgfSk7XG5cbiAgICB0aGlzLnNlcnZpY2VUb2tlbiA9IFRva2VuLmFzU3RyaW5nKGhhbmRsZXIuZ2V0QXR0KCdBcm4nKSk7XG4gICAgdGhpcy5yb2xlQXJuID0gcm9sZS5nZXRBdHQoJ0FybicpO1xuICB9XG5cbiAgcHVibGljIGFkZFBvbGljaWVzKHBvbGljaWVzOiBhbnlbXSk6IHZvaWQge1xuICAgIHRoaXMucG9saWNpZXMucHVzaCguLi5wb2xpY2llcyk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFNpbmdsZXRvbkZ1bmN0aW9uUHJvcHMgZXh0ZW5kcyBMYW1iZGFGdW5jdGlvblByb3ZpZGVyUHJvcHMge1xuICAvKipcbiAgICogQSB1bmlxdWUgaWRlbnRpZmllciB0byBpZGVudGlmeSB0aGlzIGxhbWJkYVxuICAgKlxuICAgKiBUaGUgaWRlbnRpZmllciBzaG91bGQgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY3VzdG9tIHJlc291cmNlIHByb3ZpZGVycy5cbiAgICogV2UgcmVjb21tZW5kIGdlbmVyYXRpbmcgYSBVVUlEIHBlciBwcm92aWRlci5cbiAgICovXG4gIHJlYWRvbmx5IHV1aWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBNaW1pYyB0aGUgc2luZ2xldG9uZnVuY3Rpb24gY29uc3RydWN0IGluICdAYXdzLWNkay9hd3MtbGFtYmRhJ1xuICovXG5jbGFzcyBTaW5nbGV0b25GdW5jdGlvbiBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlVG9rZW46IHN0cmluZztcblxuICBwdWJsaWMgcmVhZG9ubHkgbGFtYmRhRnVuY3Rpb246IExhbWJkYUZ1bmN0aW9uUHJvdmlkZXI7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTaW5nbGV0b25GdW5jdGlvblByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uID0gdGhpcy5lbnN1cmVGdW5jdGlvbihwcm9wcyk7XG4gICAgdGhpcy5zZXJ2aWNlVG9rZW4gPSB0aGlzLmxhbWJkYUZ1bmN0aW9uLnNlcnZpY2VUb2tlbjtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlRnVuY3Rpb24ocHJvcHM6IFNpbmdsZXRvbkZ1bmN0aW9uUHJvcHMpOiBMYW1iZGFGdW5jdGlvblByb3ZpZGVyIHtcbiAgICBjb25zdCBjb25zdHJ1Y3ROYW1lID0gJ1NpbmdsZXRvbkZ1bmN0aW9uJyArIHNsdWdpZnkocHJvcHMudXVpZCk7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBTdGFjay5vZih0aGlzKS5ub2RlLnRyeUZpbmRDaGlsZChjb25zdHJ1Y3ROYW1lKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHJldHVybiBleGlzdGluZyBhcyBMYW1iZGFGdW5jdGlvblByb3ZpZGVyO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTGFtYmRhRnVuY3Rpb25Qcm92aWRlcihTdGFjay5vZih0aGlzKSwgY29uc3RydWN0TmFtZSwge1xuICAgICAgaGFuZGxlcjogcHJvcHMuaGFuZGxlcixcbiAgICAgIGxvZ1JldGVudGlvbjogcHJvcHMubG9nUmV0ZW50aW9uLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBJQU0gcG9saWN5IHN0YXRlbWVudCB0byB0aGUgaW5saW5lIHBvbGljeSBvZiB0aGVcbiAgICogbGFtYmRhcyBmdW5jdGlvbidzIHJvbGVcbiAgICpcbiAgICogKipQbGVhc2Ugbm90ZSoqOiB0aGlzIGlzIGEgZGlyZWN0IElBTSBKU09OIHBvbGljeSBibG9iLCAqbm90KiBhIGBpYW0uUG9saWN5U3RhdGVtZW50YFxuICAgKiBvYmplY3QgbGlrZSB5b3Ugd2lsbCBzZWUgaW4gdGhlIHJlc3Qgb2YgdGhlIENESy5cbiAgICpcbiAgICpcbiAgICogc2luZ2xldG9uLmFkZFRvUm9sZVBvbGljeSh7XG4gICAqICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgKiAgIEFjdGlvbjogJ3MzOkdldE9iamVjdCcsXG4gICAqICAgUmVzb3VyY2VzOiAnKicsXG4gICAqIH0pO1xuICAgKi9cbiAgcHVibGljIGFkZFRvUm9sZVBvbGljeShzdGF0ZW1lbnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMubGFtYmRhRnVuY3Rpb24uYWRkUG9saWNpZXMoW3N0YXRlbWVudF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHBvbGljeSBzdGF0ZW1lbnQgZnJvbSBhIHNwZWNpZmljIGFwaSBjYWxsXG4gICAqL1xuICBwdWJsaWMgYWRkUG9saWN5U3RhdGVtZW50RnJvbVNka0NhbGwoc2VydmljZTogc3RyaW5nLCBhcGk6IHN0cmluZywgcmVzb3VyY2VzPzogc3RyaW5nW10pOiB2b2lkIHtcbiAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uLmFkZFBvbGljaWVzKFt7XG4gICAgICBBY3Rpb246IFthd3NTZGtUb0lhbUFjdGlvbihzZXJ2aWNlLCBhcGkpXSxcbiAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgIFJlc291cmNlOiByZXNvdXJjZXMgfHwgWycqJ10sXG4gICAgfV0pO1xuICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYW4gQXNzZXJ0aW9uc1Byb3ZpZGVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXNzZXJ0aW9uc1Byb3ZpZGVyUHJvcHMgZXh0ZW5kcyBMYW1iZGFGdW5jdGlvblByb3ZpZGVyUHJvcHMge1xuICAvKipcbiAgICogVGhpcyBkZXRlcm1pbmVzIHRoZSB1bmlxdWVuZXNzIG9mIGVhY2ggQXNzZXJ0aW9uc1Byb3ZpZGVyLlxuICAgKiBZb3Ugc2hvdWxkIG9ubHkgbmVlZCB0byBwcm92aWRlIHNvbWV0aGluZyBkaWZmZXJlbnQgaGVyZSBpZiB5b3VcbiAgICogX2tub3dfIHRoYXQgeW91IG5lZWQgYSBzZXBhcmF0ZSBwcm92aWRlclxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRoZSBkZWZhdWx0IHV1aWQgaXMgdXNlZFxuICAgKi9cbiAgcmVhZG9ubHkgdXVpZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGFzc2VydGlvbnMgcHJvdmlkZXIuIFRoZSBjcmVhdGVzIGEgc2luZ2xldG9uZVxuICogTGFtYmRhIEZ1bmN0aW9uIHRoYXQgd2lsbCBjcmVhdGUgYSBzaW5nbGUgZnVuY3Rpb24gcGVyIHN0YWNrXG4gKiB0aGF0IHNlcnZlcyBhcyB0aGUgY3VzdG9tIHJlc291cmNlIHByb3ZpZGVyIGZvciB0aGUgdmFyaW91c1xuICogYXNzZXJ0aW9uIHByb3ZpZGVyc1xuICovXG5leHBvcnQgY2xhc3MgQXNzZXJ0aW9uc1Byb3ZpZGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIGxhbWJkYSBmdW5jdGlvbiB3aGljaCBjYW4gYmUgdXNlZFxuICAgKiBhcyBhIHNlcnZpY2VUb2tlbiB0byBhIEN1c3RvbVJlc291cmNlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmljZVRva2VuOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgcHJvdmlkZXIgTGFtYmRhIEZ1bmN0aW9uXG4gICAqIGV4ZWN1dGlvbiBSb2xlIEFSTlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGhhbmRsZXJSb2xlQXJuOiBSZWZlcmVuY2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBoYW5kbGVyOiBTaW5nbGV0b25GdW5jdGlvbjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IEFzc2VydGlvbnNQcm92aWRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuaGFuZGxlciA9IG5ldyBTaW5nbGV0b25GdW5jdGlvbih0aGlzLCAnQXNzZXJ0aW9uc1Byb3ZpZGVyJywge1xuICAgICAgaGFuZGxlcjogcHJvcHM/LmhhbmRsZXIsXG4gICAgICB1dWlkOiBwcm9wcz8udXVpZCA/PyAnMTQ4ODU0MWEtN2IyMy00NjY0LTgxYjYtOWI0NDA4MDc2YjgxJyxcbiAgICAgIGxvZ1JldGVudGlvbjogcHJvcHM/LmxvZ1JldGVudGlvbixcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlclJvbGVBcm4gPSB0aGlzLmhhbmRsZXIubGFtYmRhRnVuY3Rpb24ucm9sZUFybjtcblxuICAgIHRoaXMuc2VydmljZVRva2VuID0gdGhpcy5oYW5kbGVyLnNlcnZpY2VUb2tlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNvZGUgYW4gb2JqZWN0IHNvIGl0IGNhbiBiZSBwYXNzZWRcbiAgICogYXMgY3VzdG9tIHJlc291cmNlIHBhcmFtZXRlcnMuIEN1c3RvbSByZXNvdXJjZXMgd2lsbCBjb252ZXJ0XG4gICAqIGFsbCBpbnB1dCBwYXJhbWV0ZXJzIHRvIHN0cmluZ3Mgc28gd2UgZW5jb2RlIG5vbi1zdHJpbmdzIGhlcmVcbiAgICogc28gd2UgY2FuIHRoZW4gZGVjb2RlIHRoZW0gY29ycmVjdGx5IGluIHRoZSBwcm92aWRlciBmdW5jdGlvblxuICAgKi9cbiAgcHVibGljIGVuY29kZShvYmo6IGFueSk6IGFueSB7XG4gICAgaWYgKCFvYmopIHtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMob2JqKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW2tleSwgZW5jb2RlVmFsdWUodmFsdWUpXSkpO1xuXG4gICAgZnVuY3Rpb24gZW5jb2RlVmFsdWUodmFsdWU6IGFueSk6IGFueSB7XG4gICAgICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICR0eXBlOiAnQXJyYXlCdWZmZXJWaWV3JyxcbiAgICAgICAgICBzdHJpbmc6IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZSh2YWx1ZSBhcyBVaW50OEFycmF5KSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcG9saWN5IHN0YXRlbWVudCBmcm9tIGEgc3BlY2lmaWMgYXBpIGNhbGxcbiAgICovXG4gIHB1YmxpYyBhZGRQb2xpY3lTdGF0ZW1lbnRGcm9tU2RrQ2FsbChzZXJ2aWNlOiBzdHJpbmcsIGFwaTogc3RyaW5nLCByZXNvdXJjZXM/OiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5hZGRQb2xpY3lTdGF0ZW1lbnRGcm9tU2RrQ2FsbChzZXJ2aWNlLCBhcGksIHJlc291cmNlcyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIElBTSBwb2xpY3kgc3RhdGVtZW50IHRvIHRoZSBpbmxpbmUgcG9saWN5IG9mIHRoZVxuICAgKiBsYW1iZGFzIGZ1bmN0aW9uJ3Mgcm9sZVxuICAgKlxuICAgKiAqKlBsZWFzZSBub3RlKio6IHRoaXMgaXMgYSBkaXJlY3QgSUFNIEpTT04gcG9saWN5IGJsb2IsICpub3QqIGEgYGlhbS5Qb2xpY3lTdGF0ZW1lbnRgXG4gICAqIG9iamVjdCBsaWtlIHlvdSB3aWxsIHNlZSBpbiB0aGUgcmVzdCBvZiB0aGUgQ0RLLlxuICAgKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBkZWNsYXJlIGNvbnN0IHByb3ZpZGVyOiBBc3NlcnRpb25zUHJvdmlkZXI7XG4gICAqIHByb3ZpZGVyLmFkZFRvUm9sZVBvbGljeSh7XG4gICAqICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgKiAgIEFjdGlvbjogWydzMzpHZXRPYmplY3QnXSxcbiAgICogICBSZXNvdXJjZTogWycqJ10sXG4gICAqIH0pO1xuICAgKi9cbiAgcHVibGljIGFkZFRvUm9sZVBvbGljeShzdGF0ZW1lbnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5hZGRUb1JvbGVQb2xpY3koc3RhdGVtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudCBhIHByaW5jaXBhbCBhY2Nlc3MgdG8gaW52b2tlIHRoZSBhc3NlcnRpb24gcHJvdmlkZXJcbiAgICogbGFtYmRhIGZ1bmN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBwcmluY2lwYWxBcm4gdGhlIEFSTiBvZiB0aGUgcHJpbmNpcGFsIHRoYXQgc2hvdWxkIGJlIGdpdmVuXG4gICAqICBwZXJtaXNzaW9uIHRvIGludm9rZSB0aGUgYXNzZXJ0aW9uIHByb3ZpZGVyXG4gICAqL1xuICBwdWJsaWMgZ3JhbnRJbnZva2UocHJpbmNpcGFsQXJuOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBuZXcgQ2ZuUmVzb3VyY2UodGhpcywgJ0ludm9rZScsIHtcbiAgICAgIHR5cGU6ICdBV1M6OkxhbWJkYTo6UGVybWlzc2lvbicsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIEFjdGlvbjogJ2xhbWJkYTpJbnZva2VGdW5jdGlvbicsXG4gICAgICAgIEZ1bmN0aW9uTmFtZTogdGhpcy5zZXJ2aWNlVG9rZW4sXG4gICAgICAgIFByaW5jaXBhbDogcHJpbmNpcGFsQXJuLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzbHVnaWZ5KHg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB4LnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCAnJyk7XG59XG4iXX0=