Improve dependency injection through import function calls

This commit is contained in:
Vasco-jofra
2025-06-15 00:47:34 +02:00
parent 9019879d99
commit 6920430073
6 changed files with 62 additions and 12 deletions

View File

@@ -510,15 +510,36 @@ module NestJS {
* ```
*/
private DataFlow::Node providerTuple() {
result =
DataFlow::moduleImport("@nestjs/common")
.getAPropertyRead("Module")
.getACall()
.getOptionArgument(0, "providers")
.getALocalSource()
.(DataFlow::ArrayCreationNode)
.getAnElement()
exists(DataFlow::CallNode moduleCall |
moduleCall = DataFlow::moduleImport("@nestjs/common").getAPropertyRead("Module").getACall() and
result = providerTupleAux(moduleCall.getArgument(0).getALocalSource())
)
}
private DataFlow::Node providerTupleAux(DataFlow::ObjectLiteralNode o) {
(
result =
o.getAPropertyWrite("providers")
.getRhs()
.getALocalSource()
.(DataFlow::ArrayCreationNode)
.getAnElement()
or
result =
providerTupleAux(o.getAPropertyWrite("imports")
.getRhs()
.getALocalSource()
.(DataFlow::ArrayCreationNode)
.getAnElement()
.(DataFlow::CallNode)
.getCalleeNode()
.getAFunctionValue()
.getFunction()
.getAReturnedExpr()
.flow())
)
}
private DataFlow::Node getConcreteClassFromProviderTuple(DataFlow::SourceNode tuple) {
result = tuple.getAPropertyWrite("useClass").getRhs()
or

View File

@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { Controller } from './validation';
import { Imports } from './imports';
import { Foo, Foo2, Foo3 } from './foo.interface';
import { FooImpl, Foo2Impl, Foo3Impl } from './foo.impl';
@@ -7,6 +8,7 @@ const foo3 = new Foo3Impl()
@Module({
controllers: [Controller],
imports: [Imports.forRoot()],
providers: [
{
provide: Foo,

View File

@@ -1,4 +1,4 @@
import { Foo , Foo2 } from "./foo.interface";
import { Foo, Foo2, Foo3, Foo4 } from "./foo.interface";
export class FooImpl extends Foo {
fooMethod(x: string) {
@@ -12,7 +12,13 @@ export class Foo2Impl extends Foo2 {
}
}
export class Foo3Impl extends Foo2 {
export class Foo3Impl extends Foo3 {
fooMethod(x: string) {
sink(x); // $ hasValueFlow=x
}
}
export class Foo4Impl extends Foo4 {
fooMethod(x: string) {
sink(x); // $ hasValueFlow=x
}

View File

@@ -9,3 +9,7 @@ export abstract class Foo2 {
export abstract class Foo3 {
abstract fooMethod(x: string): void;
}
export abstract class Foo4 {
abstract fooMethod(x: string): void;
}

View File

@@ -0,0 +1,16 @@
import { DynamicModule } from '@nestjs/common';
import { Foo4Impl } from './foo.impl';
import { Foo4 } from './foo.interface';
export class Imports {
static forRoot(): DynamicModule {
return {
providers: [
{
provide: Foo4,
useClass: Foo4Impl,
},
],
};
}
}

View File

@@ -1,10 +1,10 @@
import { Get, Query } from '@nestjs/common';
import { IsIn } from 'class-validator';
import { Foo, Foo2, Foo3 } from './foo.interface';
import { Foo, Foo2, Foo3, Foo4 } from './foo.interface';
export class Controller {
constructor(
private readonly foo: Foo, private readonly foo2: Foo2, private readonly foo3: Foo3
private readonly foo: Foo, private readonly foo2: Foo2, private readonly foo3: Foo3, private readonly foo4: Foo4
) { }
@Get()
@@ -18,6 +18,7 @@ export class Controller {
this.foo.fooMethod(x);
this.foo2.fooMethod(x);
this.foo3.fooMethod(x);
this.foo4.fooMethod(x);
}
}