UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

167 lines 24.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkGraphBuilder = void 0; const cxapi = require("@aws-cdk/cx-api"); const cdk_assets_1 = require("cdk-assets"); const content_hash_1 = require("./content-hash"); const work_graph_1 = require("./work-graph"); const work_graph_types_1 = require("./work-graph-types"); const error_1 = require("../toolkit/error"); class WorkGraphBuilder { constructor(prebuildAssets, idPrefix = '') { this.prebuildAssets = prebuildAssets; this.idPrefix = idPrefix; this.graph = new work_graph_1.WorkGraph(); } addStack(artifact) { this.graph.addNodes({ type: 'stack', id: `${this.idPrefix}${artifact.id}`, dependencies: new Set(this.stackArtifactIds(onlyStacks(artifact.dependencies))), stack: artifact, deploymentState: work_graph_types_1.DeploymentState.PENDING, priority: WorkGraphBuilder.PRIORITIES.stack, }); } /** * Oof, see this parameter list */ // eslint-disable-next-line max-len addAsset(parentStack, assetManifestArtifact, assetManifest, asset) { // Just the artifact identifier const assetId = asset.id.assetId; const buildId = `build-${assetId}-${(0, content_hash_1.contentHashAny)([assetId, asset.genericSource]).substring(0, 10)}`; const publishId = `publish-${assetId}-${(0, content_hash_1.contentHashAny)([assetId, asset.genericDestination]).substring(0, 10)}`; // Build node only gets added once because they are all the same if (!this.graph.tryGetNode(buildId)) { const node = { type: 'asset-build', id: buildId, note: assetId, dependencies: new Set([ ...this.stackArtifactIds(assetManifestArtifact.dependencies), // If we disable prebuild, then assets inherit (stack) dependencies from their parent stack ...!this.prebuildAssets ? this.stackArtifactIds(onlyStacks(parentStack.dependencies)) : [], ]), parentStack: parentStack, assetManifestArtifact, assetManifest, asset, deploymentState: work_graph_types_1.DeploymentState.PENDING, priority: WorkGraphBuilder.PRIORITIES['asset-build'], }; this.graph.addNodes(node); } const publishNode = this.graph.tryGetNode(publishId); if (!publishNode) { this.graph.addNodes({ type: 'asset-publish', id: publishId, note: `${asset.id}`, dependencies: new Set([ buildId, ]), parentStack, assetManifestArtifact, assetManifest, asset, deploymentState: work_graph_types_1.DeploymentState.PENDING, priority: WorkGraphBuilder.PRIORITIES['asset-publish'], }); } for (const inheritedDep of this.stackArtifactIds(onlyStacks(parentStack.dependencies))) { // The asset publish step also depends on the stacks that the parent depends on. // This is purely cosmetic: if we don't do this, the progress printing of asset publishing // is going to interfere with the progress bar of the stack deployment. We could remove this // for overall faster deployments if we ever have a better method of progress displaying. // Note: this may introduce a cycle if one of the parent's dependencies is another stack that // depends on this asset. To workaround this we remove these cycles once all nodes have // been added to the graph. this.graph.addDependency(publishId, inheritedDep); } // This will work whether the stack node has been added yet or not this.graph.addDependency(`${this.idPrefix}${parentStack.id}`, publishId); } build(artifacts) { const parentStacks = stacksFromAssets(artifacts); for (const artifact of artifacts) { if (cxapi.CloudFormationStackArtifact.isCloudFormationStackArtifact(artifact)) { this.addStack(artifact); } else if (cxapi.AssetManifestArtifact.isAssetManifestArtifact(artifact)) { const manifest = cdk_assets_1.AssetManifest.fromFile(artifact.file); for (const entry of manifest.entries) { const parentStack = parentStacks.get(artifact); if (parentStack === undefined) { throw new error_1.ToolkitError('Found an asset manifest that is not associated with a stack'); } this.addAsset(parentStack, artifact, manifest, entry); } } else if (cxapi.NestedCloudAssemblyArtifact.isNestedCloudAssemblyArtifact(artifact)) { const assembly = new cxapi.CloudAssembly(artifact.fullPath, { topoSort: false }); const nestedGraph = new WorkGraphBuilder(this.prebuildAssets, `${this.idPrefix}${artifact.id}.`).build(assembly.artifacts); this.graph.absorb(nestedGraph); } else { // Ignore whatever else } } this.graph.removeUnavailableDependencies(); // Remove any potentially introduced cycles between asset publishing and the stacks that depend on them. this.removeStackPublishCycles(); return this.graph; } stackArtifactIds(deps) { return deps.flatMap((d) => cxapi.CloudFormationStackArtifact.isCloudFormationStackArtifact(d) ? [this.stackArtifactId(d)] : []); } stackArtifactId(artifact) { if (!cxapi.CloudFormationStackArtifact.isCloudFormationStackArtifact(artifact)) { throw new error_1.ToolkitError(`Can only call this on CloudFormationStackArtifact, got: ${artifact.constructor.name}`); } return `${this.idPrefix}${artifact.id}`; } /** * We may have accidentally introduced cycles in an attempt to make the messages printed to the * console not interfere with each other too much. Remove them again. */ removeStackPublishCycles() { const publishSteps = this.graph.nodesOfType('asset-publish'); for (const publishStep of publishSteps) { for (const dep of publishStep.dependencies) { if (this.graph.reachable(dep, publishStep.id)) { publishStep.dependencies.delete(dep); } } } } } exports.WorkGraphBuilder = WorkGraphBuilder; /** * Default priorities for nodes * * Assets builds have higher priority than the other two operations, to make good on our promise that * '--prebuild-assets' will actually do assets before stacks (if it can). Unfortunately it is the * default :( * * But between stack dependencies and publish dependencies, stack dependencies go first */ WorkGraphBuilder.PRIORITIES = { 'asset-build': 10, 'asset-publish': 0, 'stack': 5, }; function stacksFromAssets(artifacts) { const ret = new Map(); for (const stack of artifacts.filter(cxapi.CloudFormationStackArtifact.isCloudFormationStackArtifact)) { const assetArtifacts = stack.dependencies.filter(cxapi.AssetManifestArtifact.isAssetManifestArtifact); for (const art of assetArtifacts) { ret.set(art, stack); } } return ret; } function onlyStacks(artifacts) { return artifacts.filter(cxapi.CloudFormationStackArtifact.isCloudFormationStackArtifact); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29yay1ncmFwaC1idWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid29yay1ncmFwaC1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUF5QztBQUN6QywyQ0FBZ0U7QUFDaEUsaURBQWdEO0FBQ2hELDZDQUF5QztBQUN6Qyx5REFBK0U7QUFDL0UsNENBQWdEO0FBRWhELE1BQWEsZ0JBQWdCO0lBaUIzQixZQUE2QixjQUF1QixFQUFtQixXQUFXLEVBQUU7UUFBdkQsbUJBQWMsR0FBZCxjQUFjLENBQVM7UUFBbUIsYUFBUSxHQUFSLFFBQVEsQ0FBSztRQUZuRSxVQUFLLEdBQUcsSUFBSSxzQkFBUyxFQUFFLENBQUM7SUFFK0MsQ0FBQztJQUVqRixRQUFRLENBQUMsUUFBMkM7UUFDMUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7WUFDbEIsSUFBSSxFQUFFLE9BQU87WUFDYixFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxFQUFFLEVBQUU7WUFDcEMsWUFBWSxFQUFFLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDL0UsS0FBSyxFQUFFLFFBQVE7WUFDZixlQUFlLEVBQUUsa0NBQWUsQ0FBQyxPQUFPO1lBQ3hDLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsS0FBSztTQUM1QyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxtQ0FBbUM7SUFDM0IsUUFBUSxDQUFDLFdBQThDLEVBQUUscUJBQWtELEVBQUUsYUFBNEIsRUFBRSxLQUFxQjtRQUN0SywrQkFBK0I7UUFDL0IsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUM7UUFFakMsTUFBTSxPQUFPLEdBQUcsU0FBUyxPQUFPLElBQUksSUFBQSw2QkFBYyxFQUFD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QyxZQUFZLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN2QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOztBQXhKSCw0Q0F5SkM7QUF4SkM7Ozs7Ozs7O0dBUUc7QUFDVywyQkFBVSxHQUFxQztJQUMzRCxhQUFhLEVBQUUsRUFBRTtJQUNqQixlQUFlLEVBQUUsQ0FBQztJQUNsQixPQUFPLEVBQUUsQ0FBQztDQUNYLEFBSnVCLENBSXRCO0FBNklKLFNBQVMsZ0JBQWdCLENBQUMsU0FBZ0M7SUFDeEQsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQWtFLENBQUM7SUFDdEYsS0FBSyxNQUFNLEtBQUssSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyw2QkFBNkIsQ0FBQyxFQUFFLENBQUM7UUFDdEcsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDdEcsS0FBSyxNQUFNLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNqQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLFNBQWdDO0lBQ2xELE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsNkJBQTZCLENBQUMsQ0FBQztBQUMzRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB7IEFzc2V0TWFuaWZlc3QsIHR5cGUgSU1hbmlmZXN0RW50cnkgfSBmcm9tICdjZGstYXNzZXRzJztcbmltcG9ydCB7IGNvbnRlbnRIYXNoQW55IH0gZnJvbSAnLi9jb250ZW50LWhhc2gnO1xuaW1wb3J0IHsgV29ya0dyYXBoIH0gZnJvbSAnLi93b3JrLWdyYXBoJztcbmltcG9ydCB7IERlcGxveW1lbnRTdGF0ZSwgQXNzZXRCdWlsZE5vZGUsIFdvcmtOb2RlIH0gZnJvbSAnLi93b3JrLWdyYXBoLXR5cGVzJztcbmltcG9ydCB7IFRvb2xraXRFcnJvciB9IGZyb20gJy4uL3Rvb2xraXQvZXJyb3InO1xuXG5leHBvcnQgY2xhc3MgV29ya0dyYXBoQnVpbGRlciB7XG4gIC8qKlxuICAgKiBEZWZhdWx0IHByaW9yaXRpZXMgZm9yIG5vZGVzXG4gICAqXG4gICAqIEFzc2V0cyBidWlsZHMgaGF2ZSBoaWdoZXIgcHJpb3JpdHkgdGhhbiB0aGUgb3RoZXIgdHdvIG9wZXJhdGlvbnMsIHRvIG1ha2UgZ29vZCBvbiBvdXIgcHJvbWlzZSB0aGF0XG4gICAqICctLXByZWJ1aWxkLWFzc2V0cycgd2lsbCBhY3R1YWxseSBkbyBhc3NldHMgYmVmb3JlIHN0YWNrcyAoaWYgaXQgY2FuKS4gVW5mb3J0dW5hdGVseSBpdCBpcyB0aGVcbiAgICogZGVmYXVsdCA6KFxuICAgKlxuICAgKiBCdXQgYmV0d2VlbiBzdGFjayBkZXBlbmRlbmNpZXMgYW5kIHB1Ymxpc2ggZGVwZW5kZW5jaWVzLCBzdGFjayBkZXBlbmRlbmNpZXMgZ28gZmlyc3RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgUFJJT1JJVElFUzogUmVjb3JkPFdvcmtOb2RlWyd0eXBlJ10sIG51bWJlcj4gPSB7XG4gICAgJ2Fzc2V0LWJ1aWxkJzogMTAsXG4gICAgJ2Fzc2V0LXB1Ymxpc2gnOiAwLFxuICAgICdzdGFjayc6IDUsXG4gIH07XG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JhcGggPSBuZXcgV29ya0dyYXBoKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBwcmVidWlsZEFzc2V0czogYm9vbGVhbiwgcHJpdmF0ZSByZWFkb25seSBpZFByZWZpeCA9ICcnKSB7IH1cblxuICBwcml2YXRlIGFkZFN0YWNrKGFydGlmYWN0OiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpIHtcbiAgICB0aGlzLmdyYXBoLmFkZE5vZGVzKHtcbiAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICBpZDogYCR7dGhpcy5pZFByZWZpeH0ke2FydGlmYWN0LmlkfWAsXG4gICAgICBkZXBlbmRlbmNpZXM6IG5ldyBTZXQodGhpcy5zdGFja0FydGlmYWN0SWRzKG9ubHlTdGFja3MoYXJ0aWZhY3QuZGVwZW5kZW5jaWVzKSkpLFxuICAgICAgc3RhY2s6IGFydGlmYWN0LFxuICAgICAgZGVwbG95bWVudFN0YXRlOiBEZXBsb3ltZW50U3RhdGUuUEVORElORyxcbiAgICAgIHByaW9yaXR5OiBXb3JrR3JhcGhCdWlsZGVyLlBSSU9SSVRJRVMuc3RhY2ssXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogT29mLCBzZWUgdGhpcyBwYXJhbWV0ZXIgbGlzdFxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgcHJpdmF0ZSBhZGRBc3NldChwYXJlbnRTdGFjazogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LCBhc3NldE1hbmlmZXN0QXJ0aWZhY3Q6IGN4YXBpLkFzc2V0TWFuaWZlc3RBcnRpZmFjdCwgYXNzZXRNYW5pZmVzdDogQXNzZXRNYW5pZmVzdCwgYXNzZXQ6IElNYW5pZmVzdEVudHJ5KSB7XG4gICAgLy8gSnVzdCB0aGUgYXJ0aWZhY3QgaWRlbnRpZmllclxuICAgIGNvbnN0IGFzc2V0SWQgPSBhc3NldC5pZC5hc3NldElkO1xuXG4gICAgY29uc3QgYnVpbGRJZCA9IGBidWlsZC0ke2Fzc2V0SWR9LSR7Y29udGVudEhhc2hBbnkoW2Fzc2V0SWQsIGFzc2V0LmdlbmVyaWNTb3VyY2VdKS5zdWJzdHJpbmcoMCwgMTApfWA7XG4gICAgY29uc3QgcHVibGlzaElkID0gYHB1Ymxpc2gtJHthc3NldElkfS0ke2NvbnRlbnRIYXNoQW55KFthc3NldElkLCBhc3NldC5nZW5lcmljRGVzdGluYXRpb25dKS5zdWJzdHJpbmcoMCwgMTApfWA7XG5cbiAgICAvLyBCdWlsZCBub2RlIG9ubHkgZ2V0cyBhZGRlZCBvbmNlIGJlY2F1c2UgdGhleSBhcmUgYWxsIHRoZSBzYW1lXG4gICAgaWYgKCF0aGlzLmdyYXBoLnRyeUdldE5vZGUoYnVpbGRJZCkpIHtcbiAgICAgIGNvbnN0IG5vZGU6IEFzc2V0QnVpbGROb2RlID0ge1xuICAgICAgICB0eXBlOiAnYXNzZXQtYnVpbGQnLFxuICAgICAgICBpZDogYnVpbGRJZCxcbiAgICAgICAgbm90ZTogYXNzZXRJZCxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiBuZXcgU2V0KFtcbiAgICAgICAgICAuLi50aGlzLnN0YWNrQXJ0aWZhY3RJZHMoYXNzZXRNYW5pZmVzdEFydGlmYWN0LmRlcGVuZGVuY2llcyksXG4gICAgICAgICAgLy8gSWYgd2UgZGlzYWJsZSBwcmVidWlsZCwgdGhlbiBhc3NldHMgaW5oZXJpdCAoc3RhY2spIGRlcGVuZGVuY2llcyBmcm9tIHRoZWlyIHBhcmVudCBzdGFja1xuICAgICAgICAgIC4uLiF0aGlzLnByZWJ1aWxkQXNzZXRzID8gdGhpcy5zdGFja0FydGlmYWN0SWRzKG9ubHlTdGFja3MocGFyZW50U3RhY2suZGVwZW5kZW5jaWVzKSkgOiBbXSxcbiAgICAgICAgXSksXG4gICAgICAgIHBhcmVudFN0YWNrOiBwYXJlbnRTdGFjayxcbiAgICAgICAgYXNzZXRNYW5pZmVzdEFydGlmYWN0LFxuICAgICAgICBhc3NldE1hbmlmZXN0LFxuICAgICAgICBhc3NldCxcbiAgICAgICAgZGVwbG95bWVudFN0YXRlOiBEZXBsb3ltZW50U3RhdGUuUEVORElORyxcbiAgICAgICAgcHJpb3JpdHk6IFdvcmtHcmFwaEJ1aWxkZXIuUFJJT1JJVElFU1snYXNzZXQtYnVpbGQnXSxcbiAgICAgIH07XG4gICAgICB0aGlzLmdyYXBoLmFkZE5vZGVzKG5vZGUpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1Ymxpc2hOb2RlID0gdGhpcy5ncmFwaC50cnlHZXROb2RlKHB1Ymxpc2hJZCk7XG4gICAgaWYgKCFwdWJsaXNoTm9kZSkge1xuICAgICAgdGhpcy5ncmFwaC5hZGROb2Rlcyh7XG4gICAgICAgIHR5cGU6ICdhc3NldC1wdWJsaXNoJyxcbiAgICAgICAgaWQ6IHB1Ymxpc2hJZCxcbiAgICAgICAgbm90ZTogYCR7YXNzZXQuaWR9YCxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiBuZXcgU2V0KFtcbiAgICAgICAgICBidWlsZElkLFxuICAgICAgICBdKSxcbiAgICAgICAgcGFyZW50U3RhY2ssXG4gICAgICAgIGFzc2V0TWFuaWZlc3RBcnRpZmFjdCxcbiAgICAgICAgYXNzZXRNYW5pZmVzdCxcbiAgICAgICAgYXNzZXQsXG4gICAgICAgIGRlcGxveW1lbnRTdGF0ZTogRGVwbG95bWVudFN0YXRlLlBFTkRJTkcsXG4gICAgICAgIHByaW9yaXR5OiBXb3JrR3JhcGhCdWlsZGVyLlBSSU9SSVRJRVNbJ2Fzc2V0LXB1Ymxpc2gnXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgaW5oZXJpdGVkRGVwIG9mIHRoaXMuc3RhY2tBcnRpZmFjdElkcyhvbmx5U3RhY2tzKHBhcmVudFN0YWNrLmRlcGVuZGVuY2llcykpKSB7XG4gICAgICAvLyBUaGUgYXNzZXQgcHVibGlzaCBzdGVwIGFsc28gZGVwZW5kcyBvbiB0aGUgc3RhY2tzIHRoYXQgdGhlIHBhcmVudCBkZXBlbmRzIG9uLlxuICAgICAgLy8gVGhpcyBpcyBwdXJlbHkgY29zbWV0aWM6IGlmIHdlIGRvbid0IGRvIHRoaXMsIHRoZSBwcm9ncmVzcyBwcmludGluZyBvZiBhc3NldCBwdWJsaXNoaW5nXG4gICAgICAvLyBpcyBnb2luZyB0byBpbnRlcmZlcmUgd2l0aCB0aGUgcHJvZ3Jlc3MgYmFyIG9mIHRoZSBzdGFjayBkZXBsb3ltZW50LiBXZSBjb3VsZCByZW1vdmUgdGhpc1xuICAgICAgLy8gZm9yIG92ZXJhbGwgZmFzdGVyIGRlcGxveW1lbnRzIGlmIHdlIGV2ZXIgaGF2ZSBhIGJldHRlciBtZXRob2Qgb2YgcHJvZ3Jlc3MgZGlzcGxheWluZy5cbiAgICAgIC8vIE5vdGU6IHRoaXMgbWF5IGludHJvZHVjZSBhIGN5Y2xlIGlmIG9uZSBvZiB0aGUgcGFyZW50J3MgZGVwZW5kZW5jaWVzIGlzIGFub3RoZXIgc3RhY2sgdGhhdFxuICAgICAgLy8gZGVwZW5kcyBvbiB0aGlzIGFzc2V0LiBUbyB3b3JrYXJvdW5kIHRoaXMgd2UgcmVtb3ZlIHRoZXNlIGN5Y2xlcyBvbmNlIGFsbCBub2RlcyBoYXZlXG4gICAgICAvLyBiZWVuIGFkZGVkIHRvIHRoZSBncmFwaC5cbiAgICAgIHRoaXMuZ3JhcGguYWRkRGVwZW5kZW5jeShwdWJsaXNoSWQsIGluaGVyaXRlZERlcCk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyB3aWxsIHdvcmsgd2hldGhlciB0aGUgc3RhY2sgbm9kZSBoYXMgYmVlbiBhZGRlZCB5ZXQgb3Igbm90XG4gICAgdGhpcy5ncmFwaC5hZGREZXBlbmRlbmN5KGAke3RoaXMuaWRQcmVmaXh9JHtwYXJlbnRTdGFjay5pZH1gLCBwdWJsaXNoSWQpO1xuICB9XG5cbiAgcHVibGljIGJ1aWxkKGFydGlmYWN0czogY3hhcGkuQ2xvdWRBcnRpZmFjdFtdKTogV29ya0dyYXBoIHtcbiAgICBjb25zdCBwYXJlbnRTdGFja3MgPSBzdGFja3NGcm9tQXNzZXRzKGFydGlmYWN0cyk7XG5cbiAgICBmb3IgKGNvbnN0IGFydGlmYWN0IG9mIGFydGlmYWN0cykge1xuICAgICAgaWYgKGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdC5pc0Nsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdChhcnRpZmFjdCkpIHtcbiAgICAgICAgdGhpcy5hZGRTdGFjayhhcnRpZmFjdCk7XG4gICAgICB9IGVsc2UgaWYgKGN4YXBpLkFzc2V0TWFuaWZlc3RBcnRpZmFjdC5pc0Fzc2V0TWFuaWZlc3RBcnRpZmFjdChhcnRpZmFjdCkpIHtcbiAgICAgICAgY29uc3QgbWFuaWZlc3QgPSBBc3NldE1hbmlmZXN0LmZyb21GaWxlKGFydGlmYWN0LmZpbGUpO1xuXG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgbWFuaWZlc3QuZW50cmllcykge1xuICAgICAgICAgIGNvbnN0IHBhcmVudFN0YWNrID0gcGFyZW50U3RhY2tzLmdldChhcnRpZmFjdCk7XG4gICAgICAgICAgaWYgKHBhcmVudFN0YWNrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0ZvdW5kIGFuIGFzc2V0IG1hbmlmZXN0IHRoYXQgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhIHN0YWNrJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYWRkQXNzZXQocGFyZW50U3RhY2ssIGFydGlmYWN0LCBtYW5pZmVzdCwgZW50cnkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN4YXBpLk5lc3RlZENsb3VkQXNzZW1ibHlBcnRpZmFjdC5pc05lc3RlZENsb3VkQXNzZW1ibHlBcnRpZmFjdChhcnRpZmFjdCkpIHtcbiAgICAgICAgY29uc3QgYXNzZW1ibHkgPSBuZXcgY3hhcGkuQ2xvdWRBc3NlbWJseShhcnRpZmFjdC5mdWxsUGF0aCwgeyB0b3BvU29ydDogZmFsc2UgfSk7XG4gICAgICAgIGNvbnN0IG5lc3RlZEdyYXBoID0gbmV3IFdvcmtHcmFwaEJ1aWxkZXIodGhpcy5wcmVidWlsZEFzc2V0cywgYCR7dGhpcy5pZFByZWZpeH0ke2FydGlmYWN0LmlkfS5gKS5idWlsZChhc3NlbWJseS5hcnRpZmFjdHMpO1xuICAgICAgICB0aGlzLmdyYXBoLmFic29yYihuZXN0ZWRHcmFwaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZ25vcmUgd2hhdGV2ZXIgZWxzZVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZ3JhcGgucmVtb3ZlVW5hdmFpbGFibGVEZXBlbmRlbmNpZXMoKTtcblxuICAgIC8vIFJlbW92ZSBhbnkgcG90ZW50aWFsbHkgaW50cm9kdWNlZCBjeWNsZXMgYmV0d2VlbiBhc3NldCBwdWJsaXNoaW5nIGFuZCB0aGUgc3RhY2tzIHRoYXQgZGVwZW5kIG9uIHRoZW0uXG4gICAgdGhpcy5yZW1vdmVTdGFja1B1Ymxpc2hDeWNsZXMoKTtcblxuICAgIHJldHVybiB0aGlzLmdyYXBoO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFja0FydGlmYWN0SWRzKGRlcHM6IGN4YXBpLkNsb3VkQXJ0aWZhY3RbXSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gZGVwcy5mbGF0TWFwKChkKSA9PiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QuaXNDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QoZCkgPyBbdGhpcy5zdGFja0FydGlmYWN0SWQoZCldIDogW10pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFja0FydGlmYWN0SWQoYXJ0aWZhY3Q6IGN4YXBpLkNsb3VkQXJ0aWZhY3QpOiBzdHJpbmcge1xuICAgIGlmICghY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LmlzQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0KGFydGlmYWN0KSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgQ2FuIG9ubHkgY2FsbCB0aGlzIG9uIENsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCwgZ290OiAke2FydGlmYWN0LmNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLmlkUHJlZml4fSR7YXJ0aWZhY3QuaWR9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXZSBtYXkgaGF2ZSBhY2NpZGVudGFsbHkgaW50cm9kdWNlZCBjeWNsZXMgaW4gYW4gYXR0ZW1wdCB0byBtYWtlIHRoZSBtZXNzYWdlcyBwcmludGVkIHRvIHRoZVxuICAgKiBjb25zb2xlIG5vdCBpbnRlcmZlcmUgd2l0aCBlYWNoIG90aGVyIHRvbyBtdWNoLiBSZW1vdmUgdGhlbSBhZ2Fpbi5cbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlU3RhY2tQdWJsaXNoQ3ljbGVzKCkge1xuICAgIGNvbnN0IHB1Ymxpc2hTdGVwcyA9IHRoaXMuZ3JhcGgubm9kZXNPZlR5cGUoJ2Fzc2V0LXB1Ymxpc2gnKTtcbiAgICBmb3IgKGNvbnN0IHB1Ymxpc2hTdGVwIG9mIHB1Ymxpc2hTdGVwcykge1xuICAgICAgZm9yIChjb25zdCBkZXAgb2YgcHVibGlzaFN0ZXAuZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgIGlmICh0aGlzLmdyYXBoLnJlYWNoYWJsZShkZXAsIHB1Ymxpc2hTdGVwLmlkKSkge1xuICAgICAgICAgIHB1Ymxpc2hTdGVwLmRlcGVuZGVuY2llcy5kZWxldGUoZGVwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdGFja3NGcm9tQXNzZXRzKGFydGlmYWN0czogY3hhcGkuQ2xvdWRBcnRpZmFjdFtdKSB7XG4gIGNvbnN0IHJldCA9IG5ldyBNYXA8Y3hhcGkuQXNzZXRNYW5pZmVzdEFydGlmYWN0LCBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q+KCk7XG4gIGZvciAoY29uc3Qgc3RhY2sgb2YgYXJ0aWZhY3RzLmZpbHRlcihjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QuaXNDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpKSB7XG4gICAgY29uc3QgYXNzZXRBcnRpZmFjdHMgPSBzdGFjay5kZXBlbmRlbmNpZXMuZmlsdGVyKGN4YXBpLkFzc2V0TWFuaWZlc3RBcnRpZmFjdC5pc0Fzc2V0TWFuaWZlc3RBcnRpZmFjdCk7XG4gICAgZm9yIChjb25zdCBhcnQgb2YgYXNzZXRBcnRpZmFjdHMpIHtcbiAgICAgIHJldC5zZXQoYXJ0LCBzdGFjayk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb25seVN0YWNrcyhhcnRpZmFjdHM6IGN4YXBpLkNsb3VkQXJ0aWZhY3RbXSkge1xuICByZXR1cm4gYXJ0aWZhY3RzLmZpbHRlcihjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QuaXNDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpO1xufVxuIl19