UNPKG

@aws-cdk/aws-cloudfront

Version:

The CDK Construct Library for AWS::CloudFront

216 lines 31.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.EdgeFunction = void 0; const jsiiDeprecationWarnings = require("../../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = require("path"); const iam = require("@aws-cdk/aws-iam"); const lambda = require("@aws-cdk/aws-lambda"); const ssm = require("@aws-cdk/aws-ssm"); const core_1 = require("@aws-cdk/core"); /** * A Lambda@Edge function. * * Convenience resource for requesting a Lambda function in the 'us-east-1' region for use with Lambda@Edge. * Implements several restrictions enforced by Lambda@Edge. * * Note that this construct requires that the 'us-east-1' region has been bootstrapped. * See https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html or 'cdk bootstrap --help' for options. * * @resource AWS::Lambda::Function */ class EdgeFunction extends core_1.Resource { constructor(scope, id, props) { super(scope, id); this.isBoundToVpc = false; try { jsiiDeprecationWarnings._aws_cdk_aws_cloudfront_experimental_EdgeFunctionProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.constructor); } throw error; } // Create a simple Function if we're already in us-east-1; otherwise create a cross-region stack. const regionIsUsEast1 = !core_1.Token.isUnresolved(this.env.region) && this.env.region === 'us-east-1'; const { edgeFunction, edgeArn } = regionIsUsEast1 ? this.createInRegionFunction(props) : this.createCrossRegionFunction(id, props); this.edgeArn = edgeArn; this.functionArn = edgeArn; this._edgeFunction = edgeFunction; this.functionName = this._edgeFunction.functionName; this.grantPrincipal = this._edgeFunction.role; this.permissionsNode = this._edgeFunction.permissionsNode; this.version = lambda.extractQualifierFromArn(this.functionArn); this.architecture = this._edgeFunction.architecture; this.resourceArnsForGrantInvoke = this._edgeFunction.resourceArnsForGrantInvoke; this.node.defaultChild = this._edgeFunction; } get lambda() { return this._edgeFunction; } /** * Convenience method to make `EdgeFunction` conform to the same interface as `Function`. */ get currentVersion() { return this; } addAlias(aliasName, options = {}) { return new lambda.Alias(this._edgeFunction, `Alias${aliasName}`, { aliasName, version: this._edgeFunction.currentVersion, ...options, }); } /** * Not supported. Connections are only applicable to VPC-enabled functions. */ get connections() { throw new Error('Lambda@Edge does not support connections'); } get latestVersion() { throw new Error('$LATEST function version cannot be used for Lambda@Edge'); } addEventSourceMapping(id, options) { return this.lambda.addEventSourceMapping(id, options); } addPermission(id, permission) { return this.lambda.addPermission(id, permission); } addToRolePolicy(statement) { return this.lambda.addToRolePolicy(statement); } grantInvoke(identity) { return this.lambda.grantInvoke(identity); } grantInvokeUrl(identity) { return this.lambda.grantInvokeUrl(identity); } metric(metricName, props) { return this.lambda.metric(metricName, { ...props, region: EdgeFunction.EDGE_REGION }); } metricDuration(props) { return this.lambda.metricDuration({ ...props, region: EdgeFunction.EDGE_REGION }); } metricErrors(props) { return this.lambda.metricErrors({ ...props, region: EdgeFunction.EDGE_REGION }); } metricInvocations(props) { return this.lambda.metricInvocations({ ...props, region: EdgeFunction.EDGE_REGION }); } metricThrottles(props) { return this.lambda.metricThrottles({ ...props, region: EdgeFunction.EDGE_REGION }); } /** Adds an event source to this function. */ addEventSource(source) { return this.lambda.addEventSource(source); } configureAsyncInvoke(options) { return this.lambda.configureAsyncInvoke(options); } addFunctionUrl(options) { return this.lambda.addFunctionUrl(options); } /** Create a function in-region */ createInRegionFunction(props) { const edgeFunction = new lambda.Function(this, 'Fn', props); addEdgeLambdaToRoleTrustStatement(edgeFunction.role); return { edgeFunction, edgeArn: edgeFunction.currentVersion.edgeArn }; } /** Create a support stack and function in us-east-1, and a SSM reader in-region */ createCrossRegionFunction(id, props) { const parameterNamePrefix = 'cdk/EdgeFunctionArn'; if (core_1.Token.isUnresolved(this.env.region)) { throw new Error('stacks which use EdgeFunctions must have an explicitly set region'); } // SSM parameter names must only contain letters, numbers, ., _, -, or /. const sanitizedPath = this.node.path.replace(/[^\/\w.-]/g, '_'); const parameterName = `/${parameterNamePrefix}/${this.env.region}/${sanitizedPath}`; const functionStack = this.edgeStack(props.stackId); const edgeFunction = new lambda.Function(functionStack, id, props); addEdgeLambdaToRoleTrustStatement(edgeFunction.role); // Store the current version's ARN to be retrieved by the cross region reader below. const version = edgeFunction.currentVersion; new ssm.StringParameter(edgeFunction, 'Parameter', { parameterName, stringValue: version.edgeArn, }); const edgeArn = this.createCrossRegionArnReader(parameterNamePrefix, parameterName, version); return { edgeFunction, edgeArn }; } createCrossRegionArnReader(parameterNamePrefix, parameterName, version) { // Prefix of the parameter ARN that applies to all EdgeFunctions. // This is necessary because the `CustomResourceProvider` is a singleton, and the `policyStatement` // must work for multiple EdgeFunctions. const parameterArnPrefix = this.stack.formatArn({ service: 'ssm', region: EdgeFunction.EDGE_REGION, resource: 'parameter', resourceName: parameterNamePrefix + '/*', }); const resourceType = 'Custom::CrossRegionStringParameterReader'; const serviceToken = core_1.CustomResourceProvider.getOrCreate(this, resourceType, { codeDirectory: path.join(__dirname, 'edge-function'), runtime: core_1.CustomResourceProviderRuntime.NODEJS_12_X, policyStatements: [{ Effect: 'Allow', Resource: parameterArnPrefix, Action: ['ssm:GetParameter'], }], }); const resource = new core_1.CustomResource(this, 'ArnReader', { resourceType: resourceType, serviceToken, properties: { Region: EdgeFunction.EDGE_REGION, ParameterName: parameterName, // This is used to determine when the function has changed, to refresh the ARN from the custom resource. // // Use the logical id of the function version. Whenever a function version changes, the logical id must be // changed for it to take effect - a good candidate for RefreshToken. RefreshToken: core_1.Lazy.uncachedString({ produce: () => { const cfn = version.node.defaultChild; return this.stack.resolve(cfn.logicalId); }, }), }, }); return resource.getAttString('FunctionArn'); } edgeStack(stackId) { const stage = core_1.Stage.of(this); if (!stage) { throw new Error('stacks which use EdgeFunctions must be part of a CDK app or stage'); } const edgeStackId = stackId !== null && stackId !== void 0 ? stackId : `edge-lambda-stack-${this.stack.node.addr}`; let edgeStack = stage.node.tryFindChild(edgeStackId); if (!edgeStack) { edgeStack = new core_1.Stack(stage, edgeStackId, { env: { region: EdgeFunction.EDGE_REGION, account: core_1.Stack.of(this).account, }, }); } this.stack.addDependency(edgeStack); return edgeStack; } } exports.EdgeFunction = EdgeFunction; _a = JSII_RTTI_SYMBOL_1; EdgeFunction[_a] = { fqn: "@aws-cdk/aws-cloudfront.experimental.EdgeFunction", version: "1.157.0" }; EdgeFunction.EDGE_REGION = 'us-east-1'; function addEdgeLambdaToRoleTrustStatement(role) { if (role instanceof iam.Role && role.assumeRolePolicy) { const statement = new iam.PolicyStatement(); const edgeLambdaServicePrincipal = new iam.ServicePrincipal('edgelambda.amazonaws.com'); statement.addPrincipals(edgeLambdaServicePrincipal); statement.addActions(edgeLambdaServicePrincipal.assumeRoleAction); role.assumeRolePolicy.addStatements(statement); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS1mdW5jdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVkZ2UtZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsNkJBQTZCO0FBRzdCLHdDQUF3QztBQUN4Qyw4Q0FBOEM7QUFDOUMsd0NBQXdDO0FBQ3hDLHdDQUl1QjtBQWV2Qjs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsZUFBUTtJQWlCeEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUNoRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBVkgsaUJBQVksR0FBRyxLQUFLLENBQUM7Ozs7Ozs7Ozs7UUFZbkMsaUdBQWlHO1FBQ2pHLE1BQU0sZUFBZSxHQUFHLENBQUMsWUFBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQztRQUNoRyxNQUFNLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxHQUFHLGVBQWU7WUFDL0MsQ0FBQyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUM7WUFDcEMsQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFOUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFFdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxZQUFZLENBQUM7UUFDbEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQztRQUNwRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSyxDQUFDO1FBQy9DLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFl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QUksU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBVSxDQUFDO1FBQzlELElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDZCxTQUFTLEdBQUcsSUFBSSxZQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtnQkFDeEMsR0FBRyxFQUFFO29CQUNILE1BQU0sRUFBRSxZQUFZLENBQUMsV0FBVztvQkFDaEMsT0FBTyxFQUFFLFlBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTztpQkFDaEM7YUFDRixDQUFDLENBQUM7U0FDSjtRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sU0FBUyxDQUFDO0tBQ2xCOztBQTdNSCxvQ0E4TUM7OztBQTVNeUIsd0JBQVcsR0FBVyxXQUFXLENBQUM7QUFvTjVELFNBQVMsaUNBQWlDLENBQUMsSUFBZTtJQUN4RCxJQUFJLElBQUksWUFBWSxHQUFHLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtRQUNyRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM1QyxNQUFNLDBCQUEwQixHQUFHLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDeEYsU0FBUyxDQUFDLGFBQWEsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3BELFNBQVMsQ0FBQyxVQUFVLENBQUMsMEJBQTBCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0tBQ2hEO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBjbG91ZHdhdGNoIGZyb20gJ0Bhd3MtY2RrL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdAYXdzLWNkay9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdAYXdzLWNkay9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIHNzbSBmcm9tICdAYXdzLWNkay9hd3Mtc3NtJztcbmltcG9ydCB7XG4gIENmblJlc291cmNlLCBDb25zdHJ1Y3ROb2RlLFxuICBDdXN0b21SZXNvdXJjZSwgQ3VzdG9tUmVzb3VyY2VQcm92aWRlciwgQ3VzdG9tUmVzb3VyY2VQcm92aWRlclJ1bnRpbWUsXG4gIExhenksIFJlc291cmNlLCBTdGFjaywgU3RhZ2UsIFRva2VuLFxufSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGEgTGFtYmRhQEVkZ2UgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFZGdlRnVuY3Rpb25Qcm9wcyBleHRlbmRzIGxhbWJkYS5GdW5jdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBzdGFjayBJRCBvZiBMYW1iZGFARWRnZSBmdW5jdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBgZWRnZS1sYW1iZGEtc3RhY2stJHtyZWdpb259YFxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tJZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIExhbWJkYUBFZGdlIGZ1bmN0aW9uLlxuICpcbiAqIENvbnZlbmllbmNlIHJlc291cmNlIGZvciByZXF1ZXN0aW5nIGEgTGFtYmRhIGZ1bmN0aW9uIGluIHRoZSAndXMtZWFzdC0xJyByZWdpb24gZm9yIHVzZSB3aXRoIExhbWJkYUBFZGdlLlxuICogSW1wbGVtZW50cyBzZXZlcmFsIHJlc3RyaWN0aW9ucyBlbmZvcmNlZCBieSBMYW1iZGFARWRnZS5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBjb25zdHJ1Y3QgcmVxdWlyZXMgdGhhdCB0aGUgJ3VzLWVhc3QtMScgcmVnaW9uIGhhcyBiZWVuIGJvb3RzdHJhcHBlZC5cbiAqIFNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2RrL2xhdGVzdC9ndWlkZS9ib290c3RyYXBwaW5nLmh0bWwgb3IgJ2NkayBib290c3RyYXAgLS1oZWxwJyBmb3Igb3B0aW9ucy5cbiAqXG4gKiBAcmVzb3VyY2UgQVdTOjpMYW1iZGE6OkZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBFZGdlRnVuY3Rpb24gZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIGxhbWJkYS5JVmVyc2lvbiB7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgRURHRV9SRUdJT046IHN0cmluZyA9ICd1cy1lYXN0LTEnO1xuXG4gIHB1YmxpYyByZWFkb25seSBlZGdlQXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbk5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGZ1bmN0aW9uQXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBncmFudFByaW5jaXBhbDogaWFtLklQcmluY2lwYWw7XG4gIHB1YmxpYyByZWFkb25seSBpc0JvdW5kVG9WcGMgPSBmYWxzZTtcbiAgcHVibGljIHJlYWRvbmx5IHBlcm1pc3Npb25zTm9kZTogQ29uc3RydWN0Tm9kZTtcbiAgcHVibGljIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG4gIHB1YmxpYyByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBhcmNoaXRlY3R1cmU6IGxhbWJkYS5BcmNoaXRlY3R1cmU7XG4gIHB1YmxpYyByZWFkb25seSByZXNvdXJjZUFybnNGb3JHcmFudEludm9rZTogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZWRnZUZ1bmN0aW9uOiBsYW1iZGEuRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEVkZ2VGdW5jdGlvblByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8vIENyZWF0ZSBhIHNpbXBsZSBGdW5jdGlvbiBpZiB3ZSdyZSBhbHJlYWR5IGluIHVzLWVhc3QtMTsgb3RoZXJ3aXNlIGNyZWF0ZSBhIGNyb3NzLXJlZ2lvbiBzdGFjay5cbiAgICBjb25zdCByZWdpb25Jc1VzRWFzdDEgPSAhVG9rZW4uaXNVbnJlc29sdmVkKHRoaXMuZW52LnJlZ2lvbikgJiYgdGhpcy5lbnYucmVnaW9uID09PSAndXMtZWFzdC0xJztcbiAgICBjb25zdCB7IGVkZ2VGdW5jdGlvbiwgZWRnZUFybiB9ID0gcmVnaW9uSXNVc0Vhc3QxXG4gICAgICA/IHRoaXMuY3JlYXRlSW5SZWdpb25GdW5jdGlvbihwcm9wcylcbiAgICAgIDogdGhpcy5jcmVhdGVDcm9zc1JlZ2lvbkZ1bmN0aW9uKGlkLCBwcm9wcyk7XG5cbiAgICB0aGlzLmVkZ2VBcm4gPSBlZGdlQXJuO1xuXG4gICAgdGhpcy5mdW5jdGlvbkFybiA9IGVkZ2VBcm47XG4gICAgdGhpcy5fZWRnZUZ1bmN0aW9uID0gZWRnZUZ1bmN0aW9uO1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lID0gdGhpcy5fZWRnZUZ1bmN0aW9uLmZ1bmN0aW9uTmFtZTtcbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gdGhpcy5fZWRnZUZ1bmN0aW9uLnJvbGUhO1xuICAgIHRoaXMucGVybWlzc2lvbnNOb2RlID0gdGhpcy5fZWRnZUZ1bmN0aW9uLnBlcm1pc3Npb25zTm9kZTtcbiAgICB0aGlzLnZlcnNpb24gPSBsYW1iZGEuZXh0cmFjdFF1YWxpZmllckZyb21Bcm4odGhpcy5mdW5jdGlvbkFybik7XG4gICAgdGhpcy5hcmNoaXRlY3R1cmUgPSB0aGlzLl9lZGdlRnVuY3Rpb24uYXJjaGl0ZWN0dXJlO1xuICAgIHRoaXMucmVzb3VyY2VBcm5zRm9yR3JhbnRJbnZva2UgPSB0aGlzLl9lZGdlRnVuY3Rpb24ucmVzb3VyY2VBcm5zRm9yR3JhbnRJbnZva2U7XG5cbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5fZWRnZUZ1bmN0aW9uO1xuICB9XG5cbiAgcHVibGljIGdldCBsYW1iZGEoKTogbGFtYmRhLklGdW5jdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VkZ2VGdW5jdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gbWFrZSBgRWRnZUZ1bmN0aW9uYCBjb25mb3JtIHRvIHRoZSBzYW1lIGludGVyZmFjZSBhcyBgRnVuY3Rpb25gLlxuICAgKi9cbiAgcHVibGljIGdldCBjdXJyZW50VmVyc2lvbigpOiBsYW1iZGEuSVZlcnNpb24ge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFkZEFsaWFzKGFsaWFzTmFtZTogc3RyaW5nLCBvcHRpb25zOiBsYW1iZGEuQWxpYXNPcHRpb25zID0ge30pOiBsYW1iZGEuQWxpYXMge1xuICAgIHJldHVybiBuZXcgbGFtYmRhLkFsaWFzKHRoaXMuX2VkZ2VGdW5jdGlvbiwgYEFsaWFzJHthbGlhc05hbWV9YCwge1xuICAgICAgYWxpYXNOYW1lLFxuICAgICAgdmVyc2lvbjogdGhpcy5fZWRnZUZ1bmN0aW9uLmN1cnJlbnRWZXJzaW9uLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3Qgc3VwcG9ydGVkLiBDb25uZWN0aW9ucyBhcmUgb25seSBhcHBsaWNhYmxlIHRvIFZQQy1lbmFibGVkIGZ1bmN0aW9ucy5cbiAgICovXG4gIHB1YmxpYyBnZXQgY29ubmVjdGlvbnMoKTogZWMyLkNvbm5lY3Rpb25zIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xhbWJkYUBFZGdlIGRvZXMgbm90IHN1cHBvcnQgY29ubmVjdGlvbnMnKTtcbiAgfVxuICBwdWJsaWMgZ2V0IGxhdGVzdFZlcnNpb24oKTogbGFtYmRhLklWZXJzaW9uIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJyRMQVRFU1QgZnVuY3Rpb24gdmVyc2lvbiBjYW5ub3QgYmUgdXNlZCBmb3IgTGFtYmRhQEVkZ2UnKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRFdmVudFNvdXJjZU1hcHBpbmcoaWQ6IHN0cmluZywgb3B0aW9uczogbGFtYmRhLkV2ZW50U291cmNlTWFwcGluZ09wdGlvbnMpOiBsYW1iZGEuRXZlbnRTb3VyY2VNYXBwaW5nIHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGEuYWRkRXZlbnRTb3VyY2VNYXBwaW5nKGlkLCBvcHRpb25zKTtcbiAgfVxuICBwdWJsaWMgYWRkUGVybWlzc2lvbihpZDogc3RyaW5nLCBwZXJtaXNzaW9uOiBsYW1iZGEuUGVybWlzc2lvbik6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5hZGRQZXJtaXNzaW9uKGlkLCBwZXJtaXNzaW9uKTtcbiAgfVxuICBwdWJsaWMgYWRkVG9Sb2xlUG9saWN5KHN0YXRlbWVudDogaWFtLlBvbGljeVN0YXRlbWVudCk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5hZGRUb1JvbGVQb2xpY3koc3RhdGVtZW50KTtcbiAgfVxuICBwdWJsaWMgZ3JhbnRJbnZva2UoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50IHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGEuZ3JhbnRJbnZva2UoaWRlbnRpdHkpO1xuICB9XG4gIHB1YmxpYyBncmFudEludm9rZVVybChpZGVudGl0eTogaWFtLklHcmFudGFibGUpOiBpYW0uR3JhbnQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5ncmFudEludm9rZVVybChpZGVudGl0eSk7XG4gIH1cbiAgcHVibGljIG1ldHJpYyhtZXRyaWNOYW1lOiBzdHJpbmcsIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWMobWV0cmljTmFtZSwgeyAuLi5wcm9wcywgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04gfSk7XG4gIH1cbiAgcHVibGljIG1ldHJpY0R1cmF0aW9uKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNEdXJhdGlvbih7IC4uLnByb3BzLCByZWdpb246IEVkZ2VGdW5jdGlvbi5FREdFX1JFR0lPTiB9KTtcbiAgfVxuICBwdWJsaWMgbWV0cmljRXJyb3JzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNFcnJvcnMoeyAuLi5wcm9wcywgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04gfSk7XG4gIH1cbiAgcHVibGljIG1ldHJpY0ludm9jYXRpb25zKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNJbnZvY2F0aW9ucyh7IC4uLnByb3BzLCByZWdpb246IEVkZ2VGdW5jdGlvbi5FREdFX1JFR0lPTiB9KTtcbiAgfVxuICBwdWJsaWMgbWV0cmljVGhyb3R0bGVzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNUaHJvdHRsZXMoeyAuLi5wcm9wcywgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04gfSk7XG4gIH1cbiAgLyoqIEFkZHMgYW4gZXZlbnQgc291cmNlIHRvIHRoaXMgZnVuY3Rpb24uICovXG4gIHB1YmxpYyBhZGRFdmVudFNvdXJjZShzb3VyY2U6IGxhbWJkYS5JRXZlbnRTb3VyY2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGEuYWRkRXZlbnRTb3VyY2Uoc291cmNlKTtcbiAgfVxuICBwdWJsaWMgY29uZmlndXJlQXN5bmNJbnZva2Uob3B0aW9uczogbGFtYmRhLkV2ZW50SW52b2tlQ29uZmlnT3B0aW9ucyk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5jb25maWd1cmVBc3luY0ludm9rZShvcHRpb25zKTtcbiAgfVxuICBwdWJsaWMgYWRkRnVuY3Rpb25Vcmwob3B0aW9ucz86IGxhbWJkYS5GdW5jdGlvblVybE9wdGlvbnMpOiBsYW1iZGEuRnVuY3Rpb25Vcmwge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5hZGRGdW5jdGlvblVybChvcHRpb25zKTtcbiAgfVxuXG4gIC8qKiBDcmVhdGUgYSBmdW5jdGlvbiBpbi1yZWdpb24gKi9cbiAgcHJpdmF0ZSBjcmVhdGVJblJlZ2lvbkZ1bmN0aW9uKHByb3BzOiBsYW1iZGEuRnVuY3Rpb25Qcm9wcyk6IEZ1bmN0aW9uQ29uZmlnIHtcbiAgICBjb25zdCBlZGdlRnVuY3Rpb24gPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKHRoaXMsICdGbicsIHByb3BzKTtcbiAgICBhZGRFZGdlTGFtYmRhVG9Sb2xlVHJ1c3RTdGF0ZW1lbnQoZWRnZUZ1bmN0aW9uLnJvbGUhKTtcblxuICAgIHJldHVybiB7IGVkZ2VGdW5jdGlvbiwgZWRnZUFybjogZWRnZUZ1bmN0aW9uLmN1cnJlbnRWZXJzaW9uLmVkZ2VBcm4gfTtcbiAgfVxuXG4gIC8qKiBDcmVhdGUgYSBzdXBwb3J0IHN0YWNrIGFuZCBmdW5jdGlvbiBpbiB1cy1lYXN0LTEsIGFuZCBhIFNTTSByZWFkZXIgaW4tcmVnaW9uICovXG4gIHByaXZhdGUgY3JlYXRlQ3Jvc3NSZWdpb25GdW5jdGlvbihpZDogc3RyaW5nLCBwcm9wczogRWRnZUZ1bmN0aW9uUHJvcHMpOiBGdW5jdGlvbkNvbmZpZyB7XG4gICAgY29uc3QgcGFyYW1ldGVyTmFtZVByZWZpeCA9ICdjZGsvRWRnZUZ1bmN0aW9uQXJuJztcbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKHRoaXMuZW52LnJlZ2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3RhY2tzIHdoaWNoIHVzZSBFZGdlRnVuY3Rpb25zIG11c3QgaGF2ZSBhbiBleHBsaWNpdGx5IHNldCByZWdpb24nKTtcbiAgICB9XG4gICAgLy8gU1NNIHBhcmFtZXRlciBuYW1lcyBtdXN0IG9ubHkgY29udGFpbiBsZXR0ZXJzLCBudW1iZXJzLCAuLCBfLCAtLCBvciAvLlxuICAgIGNvbnN0IHNhbml0aXplZFBhdGggPSB0aGlzLm5vZGUucGF0aC5yZXBsYWNlKC9bXlxcL1xcdy4tXS9nLCAnXycpO1xuICAgIGNvbnN0IHBhcmFtZXRlck5hbWUgPSBgLyR7cGFyYW1ldGVyTmFtZVByZWZpeH0vJHt0aGlzLmVudi5yZWdpb259LyR7c2FuaXRpemVkUGF0aH1gO1xuICAgIGNvbnN0IGZ1bmN0aW9uU3RhY2sgPSB0aGlzLmVkZ2VTdGFjayhwcm9wcy5zdGFja0lkKTtcblxuICAgIGNvbnN0IGVkZ2VGdW5jdGlvbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24oZnVuY3Rpb25TdGFjaywgaWQsIHByb3BzKTtcbiAgICBhZGRFZGdlTGFtYmRhVG9Sb2xlVHJ1c3RTdGF0ZW1lbnQoZWRnZUZ1bmN0aW9uLnJvbGUhKTtcblxuICAgIC8vIFN0b3JlIHRoZSBjdXJyZW50IHZlcnNpb24ncyBBUk4gdG8gYmUgcmV0cmlldmVkIGJ5IHRoZSBjcm9zcyByZWdpb24gcmVhZGVyIGJlbG93LlxuICAgIGNvbnN0IHZlcnNpb24gPSBlZGdlRnVuY3Rpb24uY3VycmVudFZlcnNpb247XG4gICAgbmV3IHNzbS5TdHJpbmdQYXJhbWV0ZXIoZWRnZUZ1bmN0aW9uLCAnUGFyYW1ldGVyJywge1xuICAgICAgcGFyYW1ldGVyTmFtZSxcbiAgICAgIHN0cmluZ1ZhbHVlOiB2ZXJzaW9uLmVkZ2VBcm4sXG4gICAgfSk7XG5cbiAgICBjb25zdCBlZGdlQXJuID0gdGhpcy5jcmVhdGVDcm9zc1JlZ2lvbkFyblJlYWRlcihwYXJhbWV0ZXJOYW1lUHJlZml4LCBwYXJhbWV0ZXJOYW1lLCB2ZXJzaW9uKTtcblxuICAgIHJldHVybiB7IGVkZ2VGdW5jdGlvbiwgZWRnZUFybiB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDcm9zc1JlZ2lvbkFyblJlYWRlcihwYXJhbWV0ZXJOYW1lUHJlZml4OiBzdHJpbmcsIHBhcmFtZXRlck5hbWU6IHN0cmluZywgdmVyc2lvbjogbGFtYmRhLlZlcnNpb24pOiBzdHJpbmcge1xuICAgIC8vIFByZWZpeCBvZiB0aGUgcGFyYW1ldGVyIEFSTiB0aGF0IGFwcGxpZXMgdG8gYWxsIEVkZ2VGdW5jdGlvbnMuXG4gICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGUgYEN1c3RvbVJlc291cmNlUHJvdmlkZXJgIGlzIGEgc2luZ2xldG9uLCBhbmQgdGhlIGBwb2xpY3lTdGF0ZW1lbnRgXG4gICAgLy8gbXVzdCB3b3JrIGZvciBtdWx0aXBsZSBFZGdlRnVuY3Rpb25zLlxuICAgIGNvbnN0IHBhcmFtZXRlckFyblByZWZpeCA9IHRoaXMuc3RhY2suZm9ybWF0QXJuKHtcbiAgICAgIHNlcnZpY2U6ICdzc20nLFxuICAgICAgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04sXG4gICAgICByZXNvdXJjZTogJ3BhcmFtZXRlcicsXG4gICAgICByZXNvdXJjZU5hbWU6IHBhcmFtZXRlck5hbWVQcmVmaXggKyAnLyonLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2VUeXBlID0gJ0N1c3RvbTo6Q3Jvc3NSZWdpb25TdHJpbmdQYXJhbWV0ZXJSZWFkZXInO1xuICAgIGNvbnN0IHNlcnZpY2VUb2tlbiA9IEN1c3RvbVJlc291cmNlUHJvdmlkZXIuZ2V0T3JDcmVhdGUodGhpcywgcmVzb3VyY2VUeXBlLCB7XG4gICAgICBjb2RlRGlyZWN0b3J5OiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnZWRnZS1mdW5jdGlvbicpLFxuICAgICAgcnVudGltZTogQ3VzdG9tUmVzb3VyY2VQcm92aWRlclJ1bnRpbWUuTk9ERUpTXzEyX1gsXG4gICAgICBwb2xpY3lTdGF0ZW1lbnRzOiBbe1xuICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgIFJlc291cmNlOiBwYXJhbWV0ZXJBcm5QcmVmaXgsXG4gICAgICAgIEFjdGlvbjogWydzc206R2V0UGFyYW1ldGVyJ10sXG4gICAgICB9XSxcbiAgICB9KTtcbiAgICBjb25zdCByZXNvdXJjZSA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCAnQXJuUmVhZGVyJywge1xuICAgICAgcmVzb3VyY2VUeXBlOiByZXNvdXJjZVR5cGUsXG4gICAgICBzZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFJlZ2lvbjogRWRnZUZ1bmN0aW9uLkVER0VfUkVHSU9OLFxuICAgICAgICBQYXJhbWV0ZXJOYW1lOiBwYXJhbWV0ZXJOYW1lLFxuICAgICAgICAvLyBUaGlzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZW4gdGhlIGZ1bmN0aW9uIGhhcyBjaGFuZ2VkLCB0byByZWZyZXNoIHRoZSBBUk4gZnJvbSB0aGUgY3VzdG9tIHJlc291cmNlLlxuICAgICAgICAvL1xuICAgICAgICAvLyBVc2UgdGhlIGxvZ2ljYWwgaWQgb2YgdGhlIGZ1bmN0aW9uIHZlcnNpb24uIFdoZW5ldmVyIGEgZnVuY3Rpb24gdmVyc2lvbiBjaGFuZ2VzLCB0aGUgbG9naWNhbCBpZCBtdXN0IGJlXG4gICAgICAgIC8vIGNoYW5nZWQgZm9yIGl0IHRvIHRha2UgZWZmZWN0IC0gYSBnb29kIGNhbmRpZGF0ZSBmb3IgUmVmcmVzaFRva2VuLlxuICAgICAgICBSZWZyZXNoVG9rZW46IExhenkudW5jYWNoZWRTdHJpbmcoe1xuICAgICAgICAgIHByb2R1Y2U6ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNmbiA9IHZlcnNpb24ubm9kZS5kZWZhdWx0Q2hpbGQgYXMgQ2ZuUmVzb3VyY2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFjay5yZXNvbHZlKGNmbi5sb2dpY2FsSWQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiByZXNvdXJjZS5nZXRBdHRTdHJpbmcoJ0Z1bmN0aW9uQXJuJyk7XG4gIH1cblxuICBwcml2YXRlIGVkZ2VTdGFjayhzdGFja0lkPzogc3RyaW5nKTogU3RhY2sge1xuICAgIGNvbnN0IHN0YWdlID0gU3RhZ2Uub2YodGhpcyk7XG4gICAgaWYgKCFzdGFnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGFja3Mgd2hpY2ggdXNlIEVkZ2VGdW5jdGlvbnMgbXVzdCBiZSBwYXJ0IG9mIGEgQ0RLIGFwcCBvciBzdGFnZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGVkZ2VTdGFja0lkID0gc3RhY2tJZCA/PyBgZWRnZS1sYW1iZGEtc3RhY2stJHt0aGlzLnN0YWNrLm5vZGUuYWRkcn1gO1xuICAgIGxldCBlZGdlU3RhY2sgPSBzdGFnZS5ub2RlLnRyeUZpbmRDaGlsZChlZGdlU3RhY2tJZCkgYXMgU3RhY2s7XG4gICAgaWYgKCFlZGdlU3RhY2spIHtcbiAgICAgIGVkZ2VTdGFjayA9IG5ldyBTdGFjayhzdGFnZSwgZWRnZVN0YWNrSWQsIHtcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04sXG4gICAgICAgICAgYWNjb3VudDogU3RhY2sub2YodGhpcykuYWNjb3VudCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnN0YWNrLmFkZERlcGVuZGVuY3koZWRnZVN0YWNrKTtcbiAgICByZXR1cm4gZWRnZVN0YWNrO1xuICB9XG59XG5cbi8qKiBSZXN1bHQgb2YgY3JlYXRpbmcgYW4gaW4tcmVnaW9uIG9yIGNyb3NzLXJlZ2lvbiBmdW5jdGlvbiAqL1xuaW50ZXJmYWNlIEZ1bmN0aW9uQ29uZmlnIHtcbiAgcmVhZG9ubHkgZWRnZUZ1bmN0aW9uOiBsYW1iZGEuRnVuY3Rpb247XG4gIHJlYWRvbmx5IGVkZ2VBcm46IHN0cmluZztcbn1cblxuZnVuY3Rpb24gYWRkRWRnZUxhbWJkYVRvUm9sZVRydXN0U3RhdGVtZW50KHJvbGU6IGlhbS5JUm9sZSkge1xuICBpZiAocm9sZSBpbnN0YW5jZW9mIGlhbS5Sb2xlICYmIHJvbGUuYXNzdW1lUm9sZVBvbGljeSkge1xuICAgIGNvbnN0IHN0YXRlbWVudCA9IG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KCk7XG4gICAgY29uc3QgZWRnZUxhbWJkYVNlcnZpY2VQcmluY2lwYWwgPSBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2VkZ2VsYW1iZGEuYW1hem9uYXdzLmNvbScpO1xuICAgIHN0YXRlbWVudC5hZGRQcmluY2lwYWxzKGVkZ2VMYW1iZGFTZXJ2aWNlUHJpbmNpcGFsKTtcbiAgICBzdGF0ZW1lbnQuYWRkQWN0aW9ucyhlZGdlTGFtYmRhU2VydmljZVByaW5jaXBhbC5hc3N1bWVSb2xlQWN0aW9uKTtcbiAgICByb2xlLmFzc3VtZVJvbGVQb2xpY3kuYWRkU3RhdGVtZW50cyhzdGF0ZW1lbnQpO1xuICB9XG59XG4iXX0=