import { type BaseEntity, Collection } from '@mikro-orm/core'; import { Entity, ManyToOne, OneToMany } from '@mikro-orm/decorators/legacy'; import type { Constructor } from '@wener/utils'; import { Feature } from '../../Feature'; import { EntityFeature } from '../enum'; import { resolveEntityRef } from '../resolveEntityRef'; import type { IdentifiableEntity } from '../types'; import type { IsHierarchyEntity } from './types'; export function withHierarchyEntity>( f: () => Constructor, ): >( Base: TBase, ) => TBase & Constructor> { return >( Base: TBase, ): TBase & Constructor> => { @Feature([EntityFeature.IsHierarchy]) @Entity({ abstract: true }) class IsHierarchyMixinEntity extends (Base as Constructor) implements IsHierarchyEntity { @ManyToOne(f, { nullable: true }) parent?: E; @OneToMany(f, (e) => e.parent) children = new Collection(this); get parentId() { return this.parent?.id; } set parentId(id: string | undefined) { this.parent = resolveEntityRef(f(), id).unwrap(); } } return IsHierarchyMixinEntity as TBase & Constructor>; }; }