import { inspect } from 'util' ; import type { EntityManager } from '../EntityManager' ; import type { AnyEntity , Dictionary , EntityData , EntityDictionary , EntityMetadata , Populate , PopulateOptions , Primary } from '../typings' ; import type { IdentifiedReference } from './Reference' ; import { Reference } from './Reference' ; import type { SerializationContext } from './EntityTransformer' ; import { EntityTransformer } from './EntityTransformer' ; import type { AssignOptions } from './EntityAssigner' ; import { EntityAssigner } from './EntityAssigner' ; import { Utils } from '../utils/Utils' ; import type { LockMode } from '../enums' ; import { ValidationError } from '../errors' ; import type { EntityIdentifier } from './EntityIdentifier' ; export class WrappedEntity < T extends AnyEntity < T > , PK extends keyof T > { __initialized = true ; __touched = false ; __populated ? : boolean ; __lazyInitialized ? : boolean ; __managed ? : boolean ; __onLoadFired ? : boolean ; __schema ? : string ; __em ? : EntityManager ; __serializationContext : { root ? : SerializationContext < T > ; populate ? : PopulateOptions < T > [ ] ; } = { } ; __loadedProperties = new Set < string > ( ) ; __data : Dictionary = { } ; /** holds last entity data snapshot so we can compute changes when persisting managed entities */ __originalEntityData ? : EntityData < T > ; /** holds wrapped primary key so we can compute change set without eager commit */ __identifier ? : EntityIdentifier ; constructor ( private readonly entity , private readonly pkGetter ? , private readonly pkSerializer ? , private readonly pkGetterConverted ? ) { } isInitialized ( ) { return this . __initialized ; } isTouched ( ) { return this . __touched ; } populated ( populated = true ) { this . __populated = populated ; this . __lazyInitialized = false ; } toReference ( ) { return Reference . create < T , PK > ( this . entity ) ; } toObject ( ignoreFields = [ ] ) { return EntityTransformer . toObject ( this . entity , ignoreFields ) as EntityData < T > ; } toPOJO ( ) { return EntityTransformer . toObject ( this . entity , [ ] , true ) ; } toJSON ( ... args ) { return ( this . entity as Dictionary ) . toJSON ( ... args ) ; } assign ( data , options ? ) { if ( 'assign' in this . entity ) { return ( this . entity as Dictionary ) . assign ( data , options ) ; } return EntityAssigner . assign ( this . entity , data , options ) ; } async init < P extends Populate < T > = Populate < T > > ( populated = true , populate ? , lockMode ? ) { if ( ! this . __em ) { throw ValidationError . entityNotManaged ( this . entity ) ; } await this . __em . findOne ( this . entity . constructor . name , this . entity , { refresh : true , lockMode , populate } ) ; this . populated ( populated ) ; this . __lazyInitialized = true ; return this . entity ; } hasPrimaryKey ( ) { const pk = this . getPrimaryKey ( ) ; return pk !== undefined && pk !== null ; } getPrimaryKey ( convertCustomTypes = false ) { if ( convertCustomTypes ) { return this . pkGetterConverted ! ( this . entity ) ; } return this . pkGetter ! ( this . entity ) ; } getPrimaryKeys ( convertCustomTypes = false ) { const pk = this . getPrimaryKey ( convertCustomTypes ) ; if ( ! pk ) { return null ; } if ( this . __meta . compositePK ) { return this . __meta . primaryKeys . reduce ( ( ret , pk ) => { const child = this . entity [ pk ] as AnyEntity < T > | Primary < unknown > ; if ( Utils . isEntity ( child , true ) ) { const childPk = child . __helper ! . getPrimaryKeys ( convertCustomTypes ) ; ret . push ( ... childPk ! ) ; } else { ret . push ( child as Primary < unknown > ) ; } return ret ; } , [ ] as Primary < T > [ ] ) ; } return [ pk ] ; } getSchema ( ) { return this . __schema ; } setSchema ( schema ? ) { this . __schema = schema ; } setPrimaryKey ( id ) { this . entity [ this . entity . __meta ! . primaryKeys [ 0 ] as string ] = id ; } getSerializedPrimaryKey ( ) { return this . pkSerializer ! ( this . entity ) ; } get __meta ( ) : EntityMetadata < T > { return this . entity . __meta ! ; } get __platform ( ) { return this . entity . __platform ! ; } get __primaryKeys ( ) : Primary < T > [ ] { return Utils . getPrimaryKeyValues ( this . entity , this . entity . __meta ! . primaryKeys ) ; } get __primaryKeyCond ( ) : Primary < T > | Primary < T > [ ] | null { if ( this . entity . __meta ! . compositePK ) { return this . __primaryKeys ; } return this . getPrimaryKey ( ) ; } [ inspect . custom ] ( ) { return `[WrappedEntity<${ this . entity . __meta ! . className }>]` ; } }