typescript - Egen metoddekorerare som raderar all metadata, hur kan jag lösa det?
Jag använder NestJS och nestjs/swagger-modulen för enkel API-dokumentation, men jag har problem eftersom jag behöver validera responsen från min tjänst.
Det är därför jag skapar min egen metoddekoration, men jag har stora problem när jag använder den - all metadata från andra dekoratorer försvinner och swagger-modulen kan inte visa bra dokumentation.
Koden för min dekoratör
export function validate(classValidatorEntity: any): MethodDecorator {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
const origMethod = descriptor.value;
descriptor.value = async function() {
const result = await origMethod.apply(this, arguments);
console.log(result); // validationFunc(result) in original method
return result;
};
};
}
och ett exempel på kod för någon kontrollermetod
@Post('test')
@ApiOkResponse({
type: someResDto
})
@ResponseValidator(ActualizeFlightQueueResponseDto)
public async test(@Body() body: someReqDto): Promise<someResDto> {
return {result: true}
}
Om min dekoratör är högst upp (först) - förloras all metadata. Om min dekoratör är sist - förlorar jag data från @Body() dekoratören....
Jag vet inte vad jag ska göra, och hur jag behöver skriva om min egen dekoratör.
Svar #1
Metadata är kopplat till den specifika descriptor.value, du måste återapplicera metadata kopplat från origMethod till den nya descriptor.value
Först definiera en metadata copyMetadata-metod
const copyMetadata = (source: Object, target: Object): void => {
for (const key of Reflect.getMetadataKeys(source)) {
Reflect.defineMetadata(key, Reflect.getMetadata(key,source), target);
}
}
Applicera sedan metadata igen på den nya descriptor.value
export function validate(classValidatorEntity: any): MethodDecorator {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
const origMethod = descriptor.value;
descriptor.value = async function() {
const result = await origMethod.apply(this, arguments);
console.log(result); // validationFunc(result) in original method
return result;
};
copyMetadata(origMethod, descriptor.value);
};
}
