Last active
January 22, 2024 20:47
-
-
Save EndyKaufman/aa8a7ebb750540217a08fac72292a9c2 to your computer and use it in GitHub Desktop.
CoreClassSerializerInterceptor.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { CallHandler, ClassSerializerInterceptor, ExecutionContext, Injectable, Logger, Module, PlainLiteralObject, SetMetadata, Type } from '@nestjs/common'; | |
import { APP_INTERCEPTOR, Reflector } from '@nestjs/core'; | |
import { ClassTransformOptions, plainToClass } from 'class-transformer'; | |
import { Observable } from 'rxjs'; | |
import { map } from 'rxjs/operators'; | |
export const GQL_RETURN_TYPE = 'GQL_RETURN_TYPE'; | |
export const GqlReturn = (type: Type<any>) => SetMetadata('GQL_RETURN_TYPE', type); | |
@Resolver() | |
export class PaymentBalanceResolver { | |
@GqlReturn(BalanceDto) | |
@Query(() => BalanceDto, { | |
nullable: false, | |
}) | |
getUserBalance(@CurrentUser() currentUser: CurrentUserType): Observable<BalanceDto> { | |
return this.paymentBalanceService.getUserBalance(currentUser.id); | |
} | |
} | |
@Module({ | |
providers: [ | |
{ | |
provide: APP_INTERCEPTOR, | |
useFactory: (reflector: any): ClassSerializerInterceptor => new ClassSerializerInterceptor(reflector), | |
inject: [Reflector], | |
}, | |
PaymentBalanceResolver, | |
], | |
}) | |
export class AppModule {} | |
@Injectable() | |
export class CoreClassSerializerInterceptor extends ClassSerializerInterceptor { | |
private readonly logger = new Logger(CoreClassSerializerInterceptor.name); | |
constructor(protected readonly reflector: any, defaultOptions?: ClassTransformOptions) { | |
super(reflector, defaultOptions); | |
this.logger.log('create'); | |
} | |
intercept(context: ExecutionContext, next: CallHandler): Observable<any> { | |
if ((context.getType() as string) === 'graphql') { | |
const op = context.getArgByIndex(3).operation.operation; | |
if (op === 'subscription') { | |
return next.handle(); | |
} | |
const contextOptions = this.getContextOptions(context); | |
const options = { | |
...this.defaultOptions, | |
...contextOptions, | |
}; | |
return next | |
.handle() | |
.pipe( | |
map((res: PlainLiteralObject | Array<PlainLiteralObject>) => | |
this.serialize(res, { ...options, returnClass: Reflect.getMetadata(GQL_RETURN_TYPE, context.getHandler()) }) | |
) | |
); | |
} | |
return next.handle(); | |
} | |
serialize( | |
response: PlainLiteralObject | Array<PlainLiteralObject>, | |
options: ClassTransformOptions & { returnClass: any } | |
): PlainLiteralObject | Array<PlainLiteralObject> { | |
try { | |
const result = super.serialize(options.returnClass ? plainToClass(options.returnClass, response) : response, options); | |
return result; | |
} catch (err) { | |
this.logger.debug(response); | |
this.logger.error(err); | |
throw err; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment