import { MetadataManager , MissingRequiredTableConfig , Table , } from '@typedorm/common' ; import { AttributeMetadataType , EntityMetadata , } from '../metadata/entity-metadata' ; import { AttributesMetadataBuilder } from './attribute-metadata-builder' ; import { Connection } from './connection' ; export class EntityMetadataBuilder { table : Table ; private attributesMetadataBuilder : AttributesMetadataBuilder ; constructor ( private connection ) { this . attributesMetadataBuilder = new AttributesMetadataBuilder ( ) ; } build ( entityClasses ) { return entityClasses . map ( decoratedEntityClass => { const { target , table , name , primaryKey , indexes , } = MetadataManager . metadataStorage . getRawEntityByTarget ( decoratedEntityClass ) ; if ( table ) { this . table = table ; } else { this . table = this . connection . table ; } if ( ! this . table ) { throw new MissingRequiredTableConfig ( decoratedEntityClass . name ) ; } const inheritedClasses = this . recursiveGetInheritanceTree ( decoratedEntityClass ) ; const inheritedEntitiesAttributesMetadata = inheritedClasses . map ( derivedClass => this . attributesMetadataBuilder . build ( this . table , derivedClass , decoratedEntityClass ) ) . reverse ( ) ; const deNormalizedAttributesMap = inheritedEntitiesAttributesMetadata . flat ( ) . reduce ( ( acc , current ) => { acc . set ( current . name , current ) ; return acc ; } , new Map < string , AttributeMetadataType > ( ) ) ; const allAttributesForEntity = Array . from ( deNormalizedAttributesMap . values ( ) ) . reverse ( ) ; return new EntityMetadata ( { connection : this . connection , table : this . table , target , attributes : allAttributesForEntity , name , primaryKey , indexes , } ) ; } ) ; } param entityClass param tree returns private recursiveGetInheritanceTree ( entityClass , tree = [ ] ) { tree . push ( entityClass ) ; const proto = Object . getPrototypeOf ( entityClass ) ; if ( proto && proto . name ) { return this . recursiveGetInheritanceTree ( proto , tree ) ; } return tree ; } }