UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

169 lines 24.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const reference_1 = require("../reference"); const uniqueid_1 = require("./uniqueid"); const CFN_REFERENCE_SYMBOL = Symbol.for('@aws-cdk/core.CfnReference'); /** * A Token that represents a CloudFormation reference to another resource * * If these references are used in a different stack from where they are * defined, appropriate CloudFormation `Export`s and `Fn::ImportValue`s will be * synthesized automatically instead of the regular CloudFormation references. * * Additionally, the dependency between the stacks will be recorded, and the toolkit * will make sure to deploy producing stack before the consuming stack. * * This magic happens in the prepare() phase, where consuming stacks will call * `consumeFromStack` on these Tokens and if they happen to be exported by a different * Stack, we'll register the dependency. */ class CfnReference extends reference_1.Reference { constructor(value, displayName, target) { // prepend scope path to display name super(value, target); this.displayName = displayName; this.originalDisplayName = displayName; this.replacementTokens = new Map(); this.humanReadableDesc = `target = ${target.node.path}`; this.producingStack = stack_1.Stack.of(target); Object.defineProperty(this, CFN_REFERENCE_SYMBOL, { value: true }); } /** * Check whether this is actually a Reference */ static isCfnReference(x) { return CFN_REFERENCE_SYMBOL in x; } /** * Return the CfnReference for the indicated target * * Will make sure that multiple invocations for the same target and intrinsic * return the same CfnReference. Because CfnReferences accumulate state in * the prepare() phase (for the purpose of cross-stack references), it's * important that the state isn't lost if it's lazily created, like so: * * Lazy.stringValue({ produce: () => new CfnReference(...) }) */ static for(target, attribute) { return CfnReference.singletonReference(target, attribute, () => { const cfnIntrinsic = attribute === 'Ref' ? { Ref: target.logicalId } : { 'Fn::GetAtt': [target.logicalId, attribute] }; return new CfnReference(cfnIntrinsic, attribute, target); }); } /** * Return a CfnReference that references a pseudo referencd */ static forPseudo(pseudoName, scope) { return CfnReference.singletonReference(scope, `Pseudo:${pseudoName}`, () => { const cfnIntrinsic = { Ref: pseudoName }; return new CfnReference(cfnIntrinsic, pseudoName, scope); }); } /** * Get or create the table */ static singletonReference(target, attribKey, fresh) { let attribs = CfnReference.referenceTable.get(target); if (!attribs) { attribs = new Map(); CfnReference.referenceTable.set(target, attribs); } let ref = attribs.get(attribKey); if (!ref) { ref = fresh(); attribs.set(attribKey, ref); } return ref; } resolve(context) { // If we have a special token for this consuming stack, resolve that. Otherwise resolve as if // we are in the same stack. const consumingStack = stack_1.Stack.of(context.scope); const token = this.replacementTokens.get(consumingStack); if (!token && this.isCrossStackReference(consumingStack) && !context.preparing) { // tslint:disable-next-line:max-line-length throw new Error(`Cross-stack reference (${context.scope.node.path} -> ${this.target.node.path}) has not been assigned a value--call prepare() first`); } if (token) { return token.resolve(context); } else { return super.resolve(context); } } /** * Register a stack this references is being consumed from. */ consumeFromStack(consumingStack, consumingConstruct) { if (this.producingStack && consumingStack.node.root !== this.producingStack.node.root) { throw this.newError(`Cannot reference across apps. ` + `Consuming and producing stacks must be defined within the same CDK app.`); } // tslint:disable-next-line:max-line-length if (!this.replacementTokens.has(consumingStack) && this.isCrossStackReference(consumingStack)) { // We're trying to resolve a cross-stack reference consumingStack.addDependency(this.producingStack, `${consumingConstruct.node.path} -> ${this.target.node.path}.${this.originalDisplayName}`); this.replacementTokens.set(consumingStack, this.exportValue(consumingStack)); } } /** * Implementation of toString() that will use the display name */ toString() { return token_1.Token.asString(this, { displayHint: `${this.target.node.id}.${this.displayName}` }); } /** * Export a Token value for use in another stack * * Works by mutating the producing stack in-place. */ exportValue(consumingStack) { const producingStack = this.producingStack; if (producingStack.environment !== consumingStack.environment) { throw this.newError(`Can only reference cross stacks in the same region and account. ${this.humanReadableDesc}`); } // Ensure a singleton "Exports" scoping Construct // This mostly exists to trigger LogicalID munging, which would be // disabled if we parented constructs directly under Stack. // Also it nicely prevents likely construct name clashes const exportsName = 'Exports'; let stackExports = producingStack.node.tryFindChild(exportsName); if (stackExports === undefined) { stackExports = new construct_1.Construct(producingStack, exportsName); } // Ensure a singleton CfnOutput for this value const resolved = producingStack.resolve(this); const id = 'Output' + JSON.stringify(resolved); const exportName = this.generateExportName(stackExports, id); let output = stackExports.node.tryFindChild(id); if (!output) { output = new cfn_output_1.CfnOutput(stackExports, id, { value: token_1.Token.asString(this), exportName }); } // We want to return an actual FnImportValue Token here, but Fn.importValue() returns a 'string', // so construct one in-place. return new intrinsic_1.Intrinsic({ 'Fn::ImportValue': exportName }); } generateExportName(stackExports, id) { const stack = stack_1.Stack.of(stackExports); const components = [...stackExports.node.scopes.slice(2).map(c => c.node.id), id]; const prefix = stack.stackName ? stack.stackName + ':' : ''; const exportName = prefix + uniqueid_1.makeUniqueId(components); return exportName; } isCrossStackReference(consumingStack) { return this.producingStack && this.producingStack !== consumingStack; } } exports.CfnReference = CfnReference; /** * Static table where we keep singleton CfnReference instances */ CfnReference.referenceTable = new Map(); const cfn_output_1 = require("../cfn-output"); const construct_1 = require("../construct"); const stack_1 = require("../stack"); const token_1 = require("../token"); const intrinsic_1 = require("./intrinsic"); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2ZuLXJlZmVyZW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNmbi1yZWZlcmVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw0Q0FBeUM7QUFDekMseUNBQTBDO0FBRTFDLE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0FBRXRFOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFhLFlBQWEsU0FBUSxxQkFBUztJQXNFekMsWUFBc0IsS0FBVSxFQUFtQixXQUFtQixFQUFFLE1BQWtCO1FBQ3hGLHFDQUFxQztRQUNyQyxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRjRCLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1FBR3BFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxXQUFXLENBQUM7UUFDdkMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFzQixDQUFDO1FBQ3ZELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxZQUFZLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFeEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxhQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLG9CQUFvQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQTlFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBYztRQUN6QyxPQUFPLG9CQUFvQixJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFrQixFQUFFLFNBQWlCO1FBQ3JELE9BQU8sWUFBWSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQzdELE1BQU0sWUFB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Q0FBQztRQUM1RCxNQUFNLFVBQVUsR0FBRyxNQUFNLEdBQUcsdUJBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRU8scUJBQXFCLENBQUMsY0FBcUI7UUFDakQsT0FBTyxJQUFJLENBQUMsY0FBYyxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssY0FBYyxDQUFDO0lBQ3ZFLENBQUM7O0FBNUtILG9DQTZLQztBQTFJQzs7R0FFRztBQUNZLDJCQUFjLEdBQUcsSUFBSSxHQUFHLEVBQXdDLENBQUM7QUEwSWxGLDhDQUEwQztBQUMxQyw0Q0FBcUQ7QUFFckQsb0NBQWlDO0FBQ2pDLG9DQUFpQztBQUNqQywyQ0FBd0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZWZlcmVuY2UgfSBmcm9tIFwiLi4vcmVmZXJlbmNlXCI7XG5pbXBvcnQgeyBtYWtlVW5pcXVlSWQgfSBmcm9tICcuL3VuaXF1ZWlkJztcblxuY29uc3QgQ0ZOX1JFRkVSRU5DRV9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLkNmblJlZmVyZW5jZScpO1xuXG4vKipcbiAqIEEgVG9rZW4gdGhhdCByZXByZXNlbnRzIGEgQ2xvdWRGb3JtYXRpb24gcmVmZXJlbmNlIHRvIGFub3RoZXIgcmVzb3VyY2VcbiAqXG4gKiBJZiB0aGVzZSByZWZlcmVuY2VzIGFyZSB1c2VkIGluIGEgZGlmZmVyZW50IHN0YWNrIGZyb20gd2hlcmUgdGhleSBhcmVcbiAqIGRlZmluZWQsIGFwcHJvcHJpYXRlIENsb3VkRm9ybWF0aW9uIGBFeHBvcnRgcyBhbmQgYEZuOjpJbXBvcnRWYWx1ZWBzIHdpbGwgYmVcbiAqIHN5bnRoZXNpemVkIGF1dG9tYXRpY2FsbHkgaW5zdGVhZCBvZiB0aGUgcmVndWxhciBDbG91ZEZvcm1hdGlvbiByZWZlcmVuY2VzLlxuICpcbiAqIEFkZGl0aW9uYWxseSwgdGhlIGRlcGVuZGVuY3kgYmV0d2VlbiB0aGUgc3RhY2tzIHdpbGwgYmUgcmVjb3JkZWQsIGFuZCB0aGUgdG9vbGtpdFxuICogd2lsbCBtYWtlIHN1cmUgdG8gZGVwbG95IHByb2R1Y2luZyBzdGFjayBiZWZvcmUgdGhlIGNvbnN1bWluZyBzdGFjay5cbiAqXG4gKiBUaGlzIG1hZ2ljIGhhcHBlbnMgaW4gdGhlIHByZXBhcmUoKSBwaGFzZSwgd2hlcmUgY29uc3VtaW5nIHN0YWNrcyB3aWxsIGNhbGxcbiAqIGBjb25zdW1lRnJvbVN0YWNrYCBvbiB0aGVzZSBUb2tlbnMgYW5kIGlmIHRoZXkgaGFwcGVuIHRvIGJlIGV4cG9ydGVkIGJ5IGEgZGlmZmVyZW50XG4gKiBTdGFjaywgd2UnbGwgcmVnaXN0ZXIgdGhlIGRlcGVuZGVuY3kuXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5SZWZlcmVuY2UgZXh0ZW5kcyBSZWZlcmVuY2Uge1xuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciB0aGlzIGlzIGFjdHVhbGx5IGEgUmVmZXJlbmNlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGlzQ2ZuUmVmZXJlbmNlKHg6IElSZXNvbHZhYmxlKTogeCBpcyBDZm5SZWZlcmVuY2Uge1xuICAgIHJldHVybiBDRk5fUkVGRVJFTkNFX1NZTUJPTCBpbiB4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgQ2ZuUmVmZXJlbmNlIGZvciB0aGUgaW5kaWNhdGVkIHRhcmdldFxuICAgKlxuICAgKiBXaWxsIG1ha2Ugc3VyZSB0aGF0IG11bHRpcGxlIGludm9jYXRpb25zIGZvciB0aGUgc2FtZSB0YXJnZXQgYW5kIGludHJpbnNpY1xuICAgKiByZXR1cm4gdGhlIHNhbWUgQ2ZuUmVmZXJlbmNlLiBCZWNhdXNlIENmblJlZmVyZW5jZXMgYWNjdW11bGF0ZSBzdGF0ZSBpblxuICAgKiB0aGUgcHJlcGFyZSgpIHBoYXNlIChmb3IgdGhlIHB1cnBvc2Ugb2YgY3Jvc3Mtc3RhY2sgcmVmZXJlbmNlcyksIGl0J3NcbiAgICogaW1wb3J0YW50IHRoYXQgdGhlIHN0YXRlIGlzbid0IGxvc3QgaWYgaXQncyBsYXppbHkgY3JlYXRlZCwgbGlrZSBzbzpcbiAgICpcbiAgICogICAgIExhenkuc3RyaW5nVmFsdWUoeyBwcm9kdWNlOiAoKSA9PiBuZXcgQ2ZuUmVmZXJlbmNlKC4uLikgfSlcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZm9yKHRhcmdldDogQ2ZuRWxlbWVudCwgYXR0cmlidXRlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gQ2ZuUmVmZXJlbmNlLnNpbmdsZXRvblJlZmVyZW5jZSh0YXJnZXQsIGF0dHJpYnV0ZSwgKCkgPT4ge1xuICAgICAgY29uc3QgY2ZuSW50cmluc2ljID0gYXR0cmlidXRlID09PSAnUmVmJyA/IHsgUmVmOiB0YXJnZXQubG9naWNhbElkIH0gOiB7ICdGbjo6R2V0QXR0JzogWyB0YXJnZXQubG9naWNhbElkLCBhdHRyaWJ1dGUgXX07XG4gICAgICByZXR1cm4gbmV3IENmblJlZmVyZW5jZShjZm5JbnRyaW5zaWMsIGF0dHJpYnV0ZSwgdGFyZ2V0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBDZm5SZWZlcmVuY2UgdGhhdCByZWZlcmVuY2VzIGEgcHNldWRvIHJlZmVyZW5jZFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmb3JQc2V1ZG8ocHNldWRvTmFtZTogc3RyaW5nLCBzY29wZTogQ29uc3RydWN0KSB7XG4gICAgcmV0dXJuIENmblJlZmVyZW5jZS5zaW5nbGV0b25SZWZlcmVuY2Uoc2NvcGUsIGBQc2V1ZG86JHtwc2V1ZG9OYW1lfWAsICgpID0+IHtcbiAgICAgIGNvbnN0IGNmbkludHJpbnNpYyA9IHsgUmVmOiBwc2V1ZG9OYW1lIH07XG4gICAgICByZXR1cm4gbmV3IENmblJlZmVyZW5jZShjZm5JbnRyaW5zaWMsIHBzZXVkb05hbWUsIHNjb3BlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgdGFibGUgd2hlcmUgd2Uga2VlcCBzaW5nbGV0b24gQ2ZuUmVmZXJlbmNlIGluc3RhbmNlc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVmZXJlbmNlVGFibGUgPSBuZXcgTWFwPENvbnN0cnVjdCwgTWFwPHN0cmluZywgQ2ZuUmVmZXJlbmNlPj4oKTtcblxuICAvKipcbiAgICogR2V0IG9yIGNyZWF0ZSB0aGUgdGFibGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHNpbmdsZXRvblJlZmVyZW5jZSh0YXJnZXQ6IENvbnN0cnVjdCwgYXR0cmliS2V5OiBzdHJpbmcsIGZyZXNoOiAoKSA9PiBDZm5SZWZlcmVuY2UpIHtcbiAgICBsZXQgYXR0cmlicyA9IENmblJlZmVyZW5jZS5yZWZlcmVuY2VUYWJsZS5nZXQodGFyZ2V0KTtcbiAgICBpZiAoIWF0dHJpYnMpIHtcbiAgICAgIGF0dHJpYnMgPSBuZXcgTWFwKCk7XG4gICAgICBDZm5SZWZlcmVuY2UucmVmZXJlbmNlVGFibGUuc2V0KHRhcmdldCwgYXR0cmlicyk7XG4gICAgfVxuICAgIGxldCByZWYgPSBhdHRyaWJzLmdldChhdHRyaWJLZXkpO1xuICAgIGlmICghcmVmKSB7XG4gICAgICByZWYgPSBmcmVzaCgpO1xuICAgICAgYXR0cmlicy5zZXQoYXR0cmliS2V5LCByZWYpO1xuICAgIH1cbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoYXQgc3RhY2sgdGhpcyBUb2tlbiBpcyBwb2ludGluZyB0b1xuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwcm9kdWNpbmdTdGFjaz86IFN0YWNrO1xuXG4gIC8qKlxuICAgKiBUaGUgVG9rZW5zIHRoYXQgc2hvdWxkIGJlIHJldHVybmVkIGZvciBlYWNoIGNvbnN1bWluZyBzdGFjayAoYXMgZGVjaWRlZCBieSB0aGUgcHJvZHVjaW5nIFN0YWNrKVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZXBsYWNlbWVudFRva2VuczogTWFwPFN0YWNrLCBJUmVzb2x2YWJsZT47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvcmlnaW5hbERpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgaHVtYW5SZWFkYWJsZURlc2M6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IodmFsdWU6IGFueSwgcHJpdmF0ZSByZWFkb25seSBkaXNwbGF5TmFtZTogc3RyaW5nLCB0YXJnZXQ6IElDb25zdHJ1Y3QpIHtcbiAgICAvLyBwcmVwZW5kIHNjb3BlIHBhdGggdG8gZGlzcGxheSBuYW1lXG4gICAgc3VwZXIodmFsdWUsIHRhcmdldCk7XG4gICAgdGhpcy5vcmlnaW5hbERpc3BsYXlOYW1lID0gZGlzcGxheU5hbWU7XG4gICAgdGhpcy5yZXBsYWNlbWVudFRva2VucyA9IG5ldyBNYXA8U3RhY2ssIElSZXNvbHZhYmxlPigpO1xuICAgIHRoaXMuaHVtYW5SZWFkYWJsZURlc2MgPSBgdGFyZ2V0ID0gJHt0YXJnZXQubm9kZS5wYXRofWA7XG5cbiAgICB0aGlzLnByb2R1Y2luZ1N0YWNrID0gU3RhY2sub2YodGFyZ2V0KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgQ0ZOX1JFRkVSRU5DRV9TWU1CT0wsIHsgdmFsdWU6IHRydWUgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVzb2x2ZShjb250ZXh0OiBJUmVzb2x2ZUNvbnRleHQpOiBhbnkge1xuICAgIC8vIElmIHdlIGhhdmUgYSBzcGVjaWFsIHRva2VuIGZvciB0aGlzIGNvbnN1bWluZyBzdGFjaywgcmVzb2x2ZSB0aGF0LiBPdGhlcndpc2UgcmVzb2x2ZSBhcyBpZlxuICAgIC8vIHdlIGFyZSBpbiB0aGUgc2FtZSBzdGFjay5cbiAgICBjb25zdCBjb25zdW1pbmdTdGFjayA9IFN0YWNrLm9mKGNvbnRleHQuc2NvcGUpO1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy5yZXBsYWNlbWVudFRva2Vucy5nZXQoY29uc3VtaW5nU3RhY2spO1xuICAgIGlmICghdG9rZW4gJiYgdGhpcy5pc0Nyb3NzU3RhY2tSZWZlcmVuY2UoY29uc3VtaW5nU3RhY2spICYmICFjb250ZXh0LnByZXBhcmluZykge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDcm9zcy1zdGFjayByZWZlcmVuY2UgKCR7Y29udGV4dC5zY29wZS5ub2RlLnBhdGh9IC0+ICR7dGhpcy50YXJnZXQubm9kZS5wYXRofSkgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIGEgdmFsdWUtLWNhbGwgcHJlcGFyZSgpIGZpcnN0YCk7XG4gICAgfVxuXG4gICAgaWYgKHRva2VuKSB7XG4gICAgICByZXR1cm4gdG9rZW4ucmVzb2x2ZShjb250ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN1cGVyLnJlc29sdmUoY29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgc3RhY2sgdGhpcyByZWZlcmVuY2VzIGlzIGJlaW5nIGNvbnN1bWVkIGZyb20uXG4gICAqL1xuICBwdWJsaWMgY29uc3VtZUZyb21TdGFjayhjb25zdW1pbmdTdGFjazogU3RhY2ssIGNvbnN1bWluZ0NvbnN0cnVjdDogSUNvbnN0cnVjdCkge1xuICAgIGlmICh0aGlzLnByb2R1Y2luZ1N0YWNrICYmIGNvbnN1bWluZ1N0YWNrLm5vZGUucm9vdCAhPT0gdGhpcy5wcm9kdWNpbmdTdGFjay5ub2RlLnJvb3QpIHtcbiAgICAgIHRocm93IHRoaXMubmV3RXJyb3IoXG4gICAgICAgIGBDYW5ub3QgcmVmZXJlbmNlIGFjcm9zcyBhcHBzLiBgICtcbiAgICAgICAgYENvbnN1bWluZyBhbmQgcHJvZHVjaW5nIHN0YWNrcyBtdXN0IGJlIGRlZmluZWQgd2l0aGluIHRoZSBzYW1lIENESyBhcHAuYCk7XG4gICAgfVxuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgIGlmICghdGhpcy5yZXBsYWNlbWVudFRva2Vucy5oYXMoY29uc3VtaW5nU3RhY2spICYmIHRoaXMuaXNDcm9zc1N0YWNrUmVmZXJlbmNlKGNvbnN1bWluZ1N0YWNrKSkge1xuICAgICAgLy8gV2UncmUgdHJ5aW5nIHRvIHJlc29sdmUgYSBjcm9zcy1zdGFjayByZWZlcmVuY2VcbiAgICAgIGNvbnN1bWluZ1N0YWNrLmFkZERlcGVuZGVuY3kodGhpcy5wcm9kdWNpbmdTdGFjayEsIGAke2NvbnN1bWluZ0NvbnN0cnVjdC5ub2RlLnBhdGh9IC0+ICR7dGhpcy50YXJnZXQubm9kZS5wYXRofS4ke3RoaXMub3JpZ2luYWxEaXNwbGF5TmFtZX1gKTtcbiAgICAgIHRoaXMucmVwbGFjZW1lbnRUb2tlbnMuc2V0KGNvbnN1bWluZ1N0YWNrLCB0aGlzLmV4cG9ydFZhbHVlKGNvbnN1bWluZ1N0YWNrKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEltcGxlbWVudGF0aW9uIG9mIHRvU3RyaW5nKCkgdGhhdCB3aWxsIHVzZSB0aGUgZGlzcGxheSBuYW1lXG4gICAqL1xuICBwdWJsaWMgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gVG9rZW4uYXNTdHJpbmcodGhpcywge1xuICAgICAgZGlzcGxheUhpbnQ6IGAke3RoaXMudGFyZ2V0Lm5vZGUuaWR9LiR7dGhpcy5kaXNwbGF5TmFtZX1gXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IGEgVG9rZW4gdmFsdWUgZm9yIHVzZSBpbiBhbm90aGVyIHN0YWNrXG4gICAqXG4gICAqIFdvcmtzIGJ5IG11dGF0aW5nIHRoZSBwcm9kdWNpbmcgc3RhY2sgaW4tcGxhY2UuXG4gICAqL1xuICBwcml2YXRlIGV4cG9ydFZhbHVlKGNvbnN1bWluZ1N0YWNrOiBTdGFjayk6IElSZXNvbHZhYmxlIHtcbiAgICBjb25zdCBwcm9kdWNpbmdTdGFjayA9IHRoaXMucHJvZHVjaW5nU3RhY2shO1xuXG4gICAgaWYgKHByb2R1Y2luZ1N0YWNrLmVudmlyb25tZW50ICE9PSBjb25zdW1pbmdTdGFjay5lbnZpcm9ubWVudCkge1xuICAgICAgdGhyb3cgdGhpcy5uZXdFcnJvcihgQ2FuIG9ubHkgcmVmZXJlbmNlIGNyb3NzIHN0YWNrcyBpbiB0aGUgc2FtZSByZWdpb24gYW5kIGFjY291bnQuICR7dGhpcy5odW1hblJlYWRhYmxlRGVzY31gKTtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgYSBzaW5nbGV0b24gXCJFeHBvcnRzXCIgc2NvcGluZyBDb25zdHJ1Y3RcbiAgICAvLyBUaGlzIG1vc3RseSBleGlzdHMgdG8gdHJpZ2dlciBMb2dpY2FsSUQgbXVuZ2luZywgd2hpY2ggd291bGQgYmVcbiAgICAvLyBkaXNhYmxlZCBpZiB3ZSBwYXJlbnRlZCBjb25zdHJ1Y3RzIGRpcmVjdGx5IHVuZGVyIFN0YWNrLlxuICAgIC8vIEFsc28gaXQgbmljZWx5IHByZXZlbnRzIGxpa2VseSBjb25zdHJ1Y3QgbmFtZSBjbGFzaGVzXG5cbiAgICBjb25zdCBleHBvcnRzTmFtZSA9ICdFeHBvcnRzJztcbiAgICBsZXQgc3RhY2tFeHBvcnRzID0gcHJvZHVjaW5nU3RhY2subm9kZS50cnlGaW5kQ2hpbGQoZXhwb3J0c05hbWUpIGFzIENvbnN0cnVjdDtcbiAgICBpZiAoc3RhY2tFeHBvcnRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHN0YWNrRXhwb3J0cyA9IG5ldyBDb25zdHJ1Y3QocHJvZHVjaW5nU3RhY2ssIGV4cG9ydHNOYW1lKTtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgYSBzaW5nbGV0b24gQ2ZuT3V0cHV0IGZvciB0aGlzIHZhbHVlXG4gICAgY29uc3QgcmVzb2x2ZWQgPSBwcm9kdWNpbmdTdGFjay5yZXNvbHZlKHRoaXMpO1xuICAgIGNvbnN0IGlkID0gJ091dHB1dCcgKyBKU09OLnN0cmluZ2lmeShyZXNvbHZlZCk7XG4gICAgY29uc3QgZXhwb3J0TmFtZSA9IHRoaXMuZ2VuZXJhdGVFeHBvcnROYW1lKHN0YWNrRXhwb3J0cywgaWQpO1xuICAgIGxldCBvdXRwdXQgPSBzdGFja0V4cG9ydHMubm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIENmbk91dHB1dDtcbiAgICBpZiAoIW91dHB1dCkge1xuICAgICAgb3V0cHV0ID0gbmV3IENmbk91dHB1dChzdGFja0V4cG9ydHMsIGlkLCB7IHZhbHVlOiBUb2tlbi5hc1N0cmluZyh0aGlzKSwgZXhwb3J0TmFtZSB9KTtcbiAgICB9XG5cbiAgICAvLyBXZSB3YW50IHRvIHJldHVybiBhbiBhY3R1YWwgRm5JbXBvcnRWYWx1ZSBUb2tlbiBoZXJlLCBidXQgRm4uaW1wb3J0VmFsdWUoKSByZXR1cm5zIGEgJ3N0cmluZycsXG4gICAgLy8gc28gY29uc3RydWN0IG9uZSBpbi1wbGFjZS5cbiAgICByZXR1cm4gbmV3IEludHJpbnNpYyh7ICdGbjo6SW1wb3J0VmFsdWUnOiBleHBvcnROYW1lIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZUV4cG9ydE5hbWUoc3RhY2tFeHBvcnRzOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHN0YWNrRXhwb3J0cyk7XG4gICAgY29uc3QgY29tcG9uZW50cyA9IFsuLi5zdGFja0V4cG9ydHMubm9kZS5zY29wZXMuc2xpY2UoMikubWFwKGMgPT4gYy5ub2RlLmlkKSwgaWRdO1xuICAgIGNvbnN0IHByZWZpeCA9IHN0YWNrLnN0YWNrTmFtZSA/IHN0YWNrLnN0YWNrTmFtZSArICc6JyA6ICcnO1xuICAgIGNvbnN0IGV4cG9ydE5hbWUgPSBwcmVmaXggKyBtYWtlVW5pcXVlSWQoY29tcG9uZW50cyk7XG4gICAgcmV0dXJuIGV4cG9ydE5hbWU7XG4gIH1cblxuICBwcml2YXRlIGlzQ3Jvc3NTdGFja1JlZmVyZW5jZShjb25zdW1pbmdTdGFjazogU3RhY2spIHtcbiAgICByZXR1cm4gdGhpcy5wcm9kdWNpbmdTdGFjayAmJiB0aGlzLnByb2R1Y2luZ1N0YWNrICE9PSBjb25zdW1pbmdTdGFjaztcbiAgfVxufVxuXG5pbXBvcnQgeyBDZm5FbGVtZW50IH0gZnJvbSBcIi4uL2Nmbi1lbGVtZW50XCI7XG5pbXBvcnQgeyBDZm5PdXRwdXQgfSBmcm9tIFwiLi4vY2ZuLW91dHB1dFwiO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJQ29uc3RydWN0IH0gZnJvbSBcIi4uL2NvbnN0cnVjdFwiO1xuaW1wb3J0IHsgSVJlc29sdmFibGUsIElSZXNvbHZlQ29udGV4dCB9IGZyb20gXCIuLi9yZXNvbHZhYmxlXCI7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gXCIuLi9zdGFja1wiO1xuaW1wb3J0IHsgVG9rZW4gfSBmcm9tIFwiLi4vdG9rZW5cIjtcbmltcG9ydCB7IEludHJpbnNpYyB9IGZyb20gXCIuL2ludHJpbnNpY1wiO1xuIl19