Skip to content

Instantly share code, notes, and snippets.

@yayajacky
Created February 5, 2020 06:49
Show Gist options
  • Save yayajacky/807843ff546aa696058278ba6392e309 to your computer and use it in GitHub Desktop.
Save yayajacky/807843ff546aa696058278ba6392e309 to your computer and use it in GitHub Desktop.
NestJS MergePipe Utility
import {
ArgumentMetadata,
Injectable,
mixin,
PipeTransform,
Type,
} from '@nestjs/common'
import { ModuleRef } from '@nestjs/core'
/**
* Takes multiple pipe in a map and apply them to the same argument.
* Example:
* Assuming you have 3 models, User has many Book and Post:
* Instead of having 3 pipes, you can now use one MergePipe to extract all 3 pieces of information.
*
* @CurrentUserId(IdToUserTransform, MergePipe({
* books: UserToBooksTransform,
* posts: UserToPostsTransform
* }) extracted: {
* books: Book[]
* posts: Post[],
* identity: User
* }
*/
@Injectable()
export class MergePipeTransform implements PipeTransform {
protected readonly transformIdentity: boolean
protected readonly transformMap: { [key: string]: Type<PipeTransform> }
constructor(private readonly moduleRef: ModuleRef) {}
async transform(
val: any,
metadata: ArgumentMetadata
): Promise<{ [key: string]: any }> {
const result = {}
for (const key in this.transformMap) {
const transformClass = this.transformMap[key]
const tmp = this.moduleRef.get(transformClass).transform(val, metadata)
result[key] = await Promise.resolve(tmp)
}
if (this.transformIdentity) {
result['identity'] = val
}
return result
}
}
/**
* Take a map of property field name and transforms
* Return a pipe that create the mapped values, kind of like combineReducer from redux
* @param map
* @param identity
* @constructor
*/
export function MergePipe(
map: { [key: string]: Type<PipeTransform> },
identity: boolean = true
) {
return mixin(
class CustomMergePipe extends MergePipeTransform {
protected readonly transformMap = map
protected readonly transformIdentity = identity
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment