Support request-scoped, global enhancers
See original GitHub issueI’m submitting a…
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Current behavior
The transform
method of global pipes is not called.
Expected behavior
The transform
method of global pipes should be called before calling a resolver method.
Minimal reproduction of the problem with instructions
core.module.ts
providers: [
{
provide: APP_PIPE,
scope: Scope.REQUEST,
useClass: CheckInputPipe,
}
]
check-input.pipe.ts
@Injectable({ scope: Scope.REQUEST })
export class CheckInputPipe implements PipeTransform<any> {
constructor(@Inject(CONTEXT) private readonly context) {}
async transform(value: any, { metatype }: ArgumentMetadata) {
console.log('Transform method is called!');
}
Console log does not occur.
To test this, you can use the following repository:
https://github.com/yostools/nest-example
clone https://github.com/yostools/nest-example.git
cd nest-example
npm i
npm run test:e2e
If everything would work, the console log Current context
should appear.
What is the motivation / use case for changing the behavior?
I would like to use a global pipe that compares the input with the rights of the current user and only passes on the inputs to which the user has authorization.
check-input.pipe.ts
import { ArgumentMetadata, BadRequestException, Inject, Injectable, PipeTransform, Scope } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';
import { plainToClass } from 'class-transformer';
import { validate, ValidationError } from 'class-validator';
import { checkRestricted } from '../decorators/restricted.decorator';
import { Context } from '../helpers/context.helper';
/**
* The CheckInputPipe checks the permissibility of individual properties of inputs for the resolvers
* in relation to the current user
*/
@Injectable({ scope: Scope.REQUEST })
export class CheckInputPipe implements PipeTransform<any> {
/**
* Constructor to inject context
*/
constructor(@Inject(CONTEXT) private readonly context) {}
/**
* Check input
*/
async transform(value: any, { metatype }: ArgumentMetadata) {
// Return value if it is only a basic type
if (!metatype || this.isBasicType(metatype)) {
return value;
}
// Remove restricted values if roles are missing
const { user }: any = Context.getData(this.context);
value = checkRestricted(value, user);
// Validate value
const plainValue = JSON.parse(JSON.stringify(value));
const object = plainToClass(metatype, plainValue);
const errors: ValidationError[] = await validate(object);
// Check errors
if (errors.length > 0) {
throw new BadRequestException('Validation failed');
}
// Everything is ok
return value;
}
/**
* Checks if it is a basic type
*/
private isBasicType(metatype: any): boolean {
const types = [String, Boolean, Number, Array, Object, Buffer, ArrayBuffer];
return types.includes(metatype);
}
}
Environment
Nest version: 6.5.2
For Tooling issues:
- Node version: 12.4.0
- Platform: Mac
Others:
The error has occurred since version 6.5.0.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:8
- Comments:17 (6 by maintainers)
Top Results From Across the Web
Enhancement Properties - Apache Stanbol
Globally defined properties use ' enhancer. ... Regardless of the defined data type Enhancement Engines that support a property MUST support to parse...
Read more >Testing | NestJS - A progressive Node.js framework
Let's introduce some more advanced capabilities that help you test applications ... to dynamically resolve scoped providers (transient or request-scoped).
Read more >NestJS inject service in guard - Stack Overflow
When now trying to inject a service, let's say AuthService ... No it is neither REQUEST scoped nor does anything inject REQUEST.
Read more >Using Hibernate ORM and JPA - Quarkus
quarkus.hibernate-orm.database.globally-quoted-identifiers ... If Hibernate ORM should create the schemas automatically (for databases supporting them).
Read more >RequestScoped (Java EE 6 ) - Oracle Help Center
Specifies that a bean is request scoped. The request scope is active: during the service() method of any servlet in the web application, ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
For anyone coming to this issue at the moment, request scoping an interceptor or guard doesn’t make much sense because they already have access to the request object. What can be done, is inject the
ModuleRef
class and get the request scoped instance of the class. A sample of this would look something likeTo make sure this works, you should also make sure to set up the context properly from the
GraphqlModule
like soThe
intercept
method is also not being called in case of anInterceptor
. I think for thegraphql
package in general the request scoped providers are not being invoked.