UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

2 lines (1 loc) 5.38 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.TreeMetadata=void 0,exports.isSubtreeReference=isSubtreeReference;var fs=()=>{var tmp=require("fs");return fs=()=>tmp,tmp},path=()=>{var tmp=require("path");return path=()=>tmp,tmp},constructs_1=()=>{var tmp=require("constructs");return constructs_1=()=>tmp,tmp},runtime_info_1=()=>{var tmp=require("./runtime-info");return runtime_info_1=()=>tmp,tmp},cloud_assembly_schema_1=()=>{var tmp=require("../../../cloud-assembly-schema");return cloud_assembly_schema_1=()=>tmp,tmp},annotations_1=()=>{var tmp=require("../annotations");return annotations_1=()=>tmp,tmp},stack_1=()=>{var tmp=require("../stack");return stack_1=()=>tmp,tmp},tree_1=()=>{var tmp=require("../tree");return tree_1=()=>tmp,tmp},construct_iteration_1=()=>{var tmp=require("./construct-iteration");return construct_iteration_1=()=>tmp,tmp},errors_1=()=>{var tmp=require("../errors");return errors_1=()=>tmp,tmp};const FILE_PATH="tree.json";class TreeMetadata extends constructs_1().Construct{constructor(scope){super(scope,"Tree")}_synthesizeTree(session){const maxNodesPerTree=this.node.tryGetContext("@aws-cdk/core.TreeMetadata:maxNodes"),builder=session.assembly,writer=new FragmentedTreeWriter(builder.outdir,FILE_PATH,{maxNodesPerTree});for(const{construct,parent}of(0,construct_iteration_1().iterateBfs)(this.node.root)){const node={id:construct.node.id||"App",path:construct.node.path,constructInfo:(0,runtime_info_1().constructInfoFromConstruct)(construct)};try{node.attributes=this.synthAttributes(construct)}catch(e){annotations_1().Annotations.of(this).addWarningV2(`@aws-cdk/core:failedToRenderTreeMetadata-${construct.node.id}`,`Failed to render tree metadata for node [${construct.node.id}]. Reason: ${e}`)}writer.addNode(construct,parent,node)}const rootFilename=writer.writeForest();builder.addArtifact("Tree",{type:cloud_assembly_schema_1().ArtifactType.CDK_TREE,properties:{file:rootFilename}})}synthAttributes(construct){function canInspect(inspectable){return inspectable.inspect!==void 0}const inspector=new(tree_1()).TreeInspector;if(canInspect(construct))return construct.inspect(inspector),stack_1().Stack.of(construct).resolve(inspector.attributes)}}exports.TreeMetadata=TreeMetadata;class FragmentedTreeWriter{constructor(outdir,rootFilename,options){this.outdir=outdir,this.rootFilename=rootFilename,this.mainTreePointer={fileName:"yyy",id:"id",path:"path"},this.forest=new Array,this.constructMap=new Map,this.subtreeRoots=new Map,this.parent=new Map,this.maxNodes=options?.maxNodesPerTree??5e5}writeForest(){const forestFiles=this.allocateSubTreesToForestFiles(),mainTree=this.forest.find(t=>t.referencingNode===this.mainTreePointer);if(mainTree){const treeFile={version:"tree-0.1",tree:mainTree.root};fs().writeFileSync(path().join(this.outdir,this.rootFilename),JSON.stringify(treeFile),{encoding:"utf-8"})}for(const forestFile of forestFiles)fs().writeFileSync(path().join(this.outdir,forestFile.fileName),JSON.stringify(forestFile.file),{encoding:"utf-8"});return this.rootFilename}allocateSubTreesToForestFiles(){const ret=new Array;for(const tree of this.forest){if(tree.referencingNode===this.mainTreePointer)continue;let targetForest;ret.length===0||ret[ret.length-1].nodeCount+tree.nodes>this.maxNodes?(targetForest={fileName:`trees-${ret.length+1}.json`,file:{version:"forest-0.1",forest:{}},nodeCount:0},ret.push(targetForest)):targetForest=ret[ret.length-1];const treeId=`t${Object.keys(targetForest.file.forest).length}`;targetForest.file.forest[treeId]=tree.root,targetForest.nodeCount+=tree.nodes,tree.referencingNode.fileName=targetForest.fileName,tree.referencingNode.treeId=treeId}return ret}addNode(construct,parent,node){if(parent===void 0){if(this.forest.length>0)throw new(errors_1()).AssumptionError("Can only add exactly one node without a parent");this.addNewTree(node,this.mainTreePointer)}else{const parentNode=this.constructMap.get(parent);if(!parentNode)return;this.addToExistingTree(node,parentNode)}this.constructMap.set(construct,node)}addNewTree(root,referencingNode){const tree={root,referencingNode,nodes:nodeCount(root)};return this.forest.push(tree),this.subtreeRoots.set(root,tree),tree}addToExistingTree(node,parent){let tree=this.treeForNode(parent);if(this.isTreeFull(tree)){const grandParent=this.parent.get(parent);if(!grandParent)throw new(errors_1()).AssumptionError(`Could not find parent of ${JSON.stringify(parent)}`);const subtreeReference={id:parent.id,path:parent.path,fileName:"xxx"};tree=this.addNewTree(parent,subtreeReference),setChild(grandParent,subtreeReference),this.subtreeRoots.set(parent,tree)}setChild(parent,node),this.parent.set(node,parent),tree.nodes+=1}isTreeFull(t){return t.nodes>=this.maxNodes}treeForNode(node){const tried=new Array;let cur=node;tried.push(cur.path);let tree=this.subtreeRoots.get(cur);for(;!tree&&cur;)cur=this.parent.get(cur),tried.push(cur?.path),tree=cur&&this.subtreeRoots.get(cur);if(tree)return tree;throw new(errors_1()).AssumptionError(`Could not find tree for node: ${JSON.stringify(node)}, tried ${tried}`)}}function nodeCount(root){let ret=0;return recurse(root),ret;function recurse(x){ret+=1;for(const child of Object.values(x.children??{}))recurse(child)}}function setChild(parent,node){parent.children||(parent.children={}),parent.children[node.id]=node}function isSubtreeReference(x){return!!x.fileName}