nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.07k stars 7.56k forks source link

How to integrate the context into a pipe? #2032

Closed yostools closed 5 years ago

yostools commented 5 years ago

I'm submitting a...


[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request

Current behavior

The context cannot be integrated into a pipe.

Expected behavior

The context should be integrated into the pipe via @Inject.

Minimal reproduction of the problem with instructions

I want to use a pipe to change the transferred data according to the current user. How do I integrate the context into a pipe?

To create the basic structure, I followed the instructions in the documentation:

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class CheckPipe implements PipeTransform<any> {

  /**
   * Check input
   */
  async transform(value: any, { metatype }: ArgumentMetadata) {

    // Return value if it is only a basic type (without decorator)
    if (!metatype || this.isBasicType(metatype)) {
      return value;
    }

    // Get context
    const context = ???;

    // Restrict value for current user
    if (!context.currentUser.roles.includes('admin')) {
      delete value.id
    }

    // Return value
    return value;
  }

  /**
   * Checks if it is a basic type
   */
  private isBasicType(metatype: any): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return types.includes(metatype);
  }
}

I've tried to integrate context via Injection:

@Injectable({ scope: Scope.REQUEST })
export class CheckPipe implements PipeTransform<any> {

  /**
   * Constructor to inject context
   */
  constructor(@Inject(CONTEXT) private readonly context) {}

  ...
}

And integrated the pipe into the module:

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: CheckPipe,
    },
  ],
})

But this.context in the transform method is undefined.

I am using the pipe in a GraphQL resolver:

@Resolver(of => User)
export class UserResolver {

  ...

  /**
   * Create new user
   */
  @Mutation(returns => User, { description: 'Create a new user' })
  async createUser(@Args('input') input: UserCreateInput): Promise<User> {
    return await this.usersService.create(input);
  }

  ...
}

What is the motivation/use case for changing the behavior?

I want to use a pipe to change the input data according to the current user.

Environment


Nest version: 6.1.1

For Tooling issues:
- Node version: 11.11.0
- Platform:  Mac
nartc commented 5 years ago

Can you provide a repo to reproduce?

yostools commented 5 years ago

@nartc under the following link I have provided a repository in which the problem occurs: https://github.com/yostools/nest-example

If you run npm run test:e2e you can see that during the tests a console.log was executed with the context in the pipe (src/common/pipes/check.pipe.ts:24), which is unfortunately undefined:

console.log src/common/pipes/check.pipe.ts:24
    Current context undefined
yostools commented 5 years ago

Does anyone have a clue for me as to whether this is possible or will soon be possible?

kamilmysliwiec commented 5 years ago

It seems that it's the same issue as here https://github.com/nestjs/nest/issues/1916 let's track this in a one place

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.