diff --git a/packages/core/src/assemblers/assembler.deserializer.ts b/packages/core/src/assemblers/assembler.deserializer.ts index b8b8253c7..daa715bec 100644 --- a/packages/core/src/assemblers/assembler.deserializer.ts +++ b/packages/core/src/assemblers/assembler.deserializer.ts @@ -16,5 +16,5 @@ export function AssemblerDeserializer(deserializer: AssemblerDeserializer) } export function getAssemblerDeserializer(DTOClass: Class): MetaValue> { - return reflector.get(DTOClass); + return reflector.get(DTOClass, true); } diff --git a/packages/core/src/assemblers/assembler.factory.ts b/packages/core/src/assemblers/assembler.factory.ts index f9b74790a..2167cb3b6 100644 --- a/packages/core/src/assemblers/assembler.factory.ts +++ b/packages/core/src/assemblers/assembler.factory.ts @@ -1,21 +1,29 @@ import { Class, DeepPartial } from '../common'; -import { Assembler, getAssembler } from './assembler'; +import { Assembler, getAssemblers } from './assembler'; import { DefaultAssembler } from './default.assembler'; /** * Assembler Service used by query services to look up Assemblers. */ export class AssemblerFactory { - static getAssembler, CE = DeepPartial, U = C, UE = CE>( - FromClass: Class, - ToClass: Class, - ): Assembler { - const AssemblerClass = getAssembler(FromClass, ToClass); - if (AssemblerClass) { - return new AssemblerClass(); + static getAssembler, CE = DeepPartial, U = C, UE = CE>( + DTOClass: Class, + EntityClass: Class, + ): Assembler { + const AssemblerClasses = getAssemblers(DTOClass); + if (AssemblerClasses) { + const AssemblerClass = AssemblerClasses.get(EntityClass); + if (AssemblerClass) { + return new AssemblerClass() as Assembler; + } + const keys = [...AssemblerClasses.keys()]; + const keysWithParent = keys.filter((k) => k.prototype instanceof EntityClass); + if (keysWithParent.length === 1) { + return this.getAssembler(DTOClass, keysWithParent[0] as Class); + } } - const defaultAssember = new DefaultAssembler(FromClass, ToClass); + const defaultAssembler = new DefaultAssembler(DTOClass, EntityClass); // if its a default just assume the types can be converted for all types - return (defaultAssember as unknown) as Assembler; + return (defaultAssembler as unknown) as Assembler; } } diff --git a/packages/core/src/assemblers/assembler.serializer.ts b/packages/core/src/assemblers/assembler.serializer.ts index 30dc1d990..414e07d01 100644 --- a/packages/core/src/assemblers/assembler.serializer.ts +++ b/packages/core/src/assemblers/assembler.serializer.ts @@ -16,5 +16,5 @@ export function AssemblerSerializer(serializer: AssemblerSerializer) { } export function getAssemblerSerializer(DTOClass: Class): MetaValue> { - return reflector.get(DTOClass); + return reflector.get(DTOClass, true); } diff --git a/packages/core/src/assemblers/assembler.ts b/packages/core/src/assemblers/assembler.ts index cb0517a6c..3d61fd4a5 100644 --- a/packages/core/src/assemblers/assembler.ts +++ b/packages/core/src/assemblers/assembler.ts @@ -132,6 +132,12 @@ export function getAssembler( return reflector.get(DTOClass, EntityClass); } +export function getAssemblers( + DTOClass: Class, +): MetaValue, Class>>> { + return reflector.get(DTOClass); +} + export function getAssemblerClasses( AssemblerClass: Class>, ): MetaValue> { diff --git a/packages/core/src/assemblers/class-transformer.assembler.ts b/packages/core/src/assemblers/class-transformer.assembler.ts index fe721749b..584e84f4a 100644 --- a/packages/core/src/assemblers/class-transformer.assembler.ts +++ b/packages/core/src/assemblers/class-transformer.assembler.ts @@ -65,6 +65,12 @@ export abstract class ClassTransformerAssembler extends AbstractAss if (serializer) { return serializer(entityOrDto); } + } else if ('constructor' in entityOrDto) { + // eslint-disable-next-line @typescript-eslint/ban-types + const serializer = getAssemblerSerializer((entityOrDto as object).constructor as Class); + if (serializer) { + return serializer(entityOrDto); + } } // eslint-disable-next-line @typescript-eslint/ban-types return (entityOrDto as unknown) as object; diff --git a/packages/core/src/common/reflect.utils.ts b/packages/core/src/common/reflect.utils.ts index 822a87dcf..9ed63649e 100644 --- a/packages/core/src/common/reflect.utils.ts +++ b/packages/core/src/common/reflect.utils.ts @@ -82,8 +82,22 @@ export class MapReflector extends Reflector { this.defineMetadata(metadata, DTOClass); } - get(DTOClass: Class, key: K, includeParents = false): MetaValue { - return this.getMetadata>(DTOClass, includeParents)?.get(key); + get(DTOClass: Class, includeParents?: boolean): MetaValue>; + get(DTOClass: Class, key: K, includeParents?: boolean): MetaValue; + get( + DTOClass: Class, + key: K | boolean | undefined, + includeParents?: boolean, + ): MetaValue> { + if (typeof key === 'boolean' || typeof key === 'undefined') { + return this.getMetadata>(DTOClass, includeParents ?? false); + } + return this.getMetadata>(DTOClass, includeParents ?? false)?.get(key); + } + + getValues(DTOClass: Class, includeParents = false): MetaValue { + const values = this.getMetadata>(DTOClass, includeParents)?.values(); + return values ? [...values] : undefined; } has(DTOClass: Class, key: K): boolean {