import { CacheService } from './cache.service' ; import { CacheManagerOptions , InternalServerErrorException } from '@nestjs/common' ; import 'reflect-metadata' ; import { tap , switchMap } from 'rxjs/operators' ; import { from , Observable , of } from 'rxjs' ; type Cacheable < T > = ( ... args ) => Observable < T > ; export function Cache < T > ( options ? ) { return ( target , methodName , descriptor ) => { const originalMethod = descriptor . value ; const className = target . constructor . name ; descriptor . value = function ( ... args ) { const cache = this . cacheService ; if ( ! cache || ! ( cache instanceof CacheService ) ) { throw new InternalServerErrorException ( 'Target Class should inject CacheService' ) ; } else { const cacheKey = `${ className }:${ methodName }:${ args . map ( ( a ) => JSON . stringify ( a ) ) . join ( ) }` ; return from ( cache . get < T > ( cacheKey ) ) . pipe ( switchMap ( ( res ) => res ? of ( res ) : originalMethod . apply ( this , args ) . pipe ( tap ( ( methodResult ) => cache . set < T > ( cacheKey , methodResult , options ) ) ) ) ) ; } } ; return descriptor ; } ; } export function CacheBuster < T > ( cacheKey ) { return ( target , methodName , descriptor ) => { const originalMethod = descriptor . value ; descriptor . value = function ( ... args ) { return originalMethod . apply ( this , args ) . pipe ( tap ( this . cacheService . del ( cacheKey ) ) ) ; } ; return descriptor ; } ; }