Skip to content

Commit

Permalink
feat(di): add support chain interceptor on the same method
Browse files Browse the repository at this point in the history
Closes: #2914
  • Loading branch information
Romakita committed Dec 4, 2024
1 parent 6b92cb5 commit 3729b18
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
53 changes: 49 additions & 4 deletions packages/di/src/common/decorators/intercept.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {catchError} from "@tsed/core";
import {DITest} from "../../node/index.js";
import {InterceptorContext} from "../interfaces/InterceptorContext.js";
import {InterceptorMethods} from "../interfaces/InterceptorMethods.js";
import {InjectorService} from "../services/InjectorService.js";
import {getInterceptorOptions, Intercept} from "./intercept.js";
import {Interceptor} from "./interceptor.js";
import {Service} from "./service.js";
Expand All @@ -14,7 +13,17 @@ class MyInterceptor implements InterceptorMethods {
const r = typeof context.args[0] === "string" ? undefined : new Error(`Error message`);
const retValue = context.next(r);

return `${retValue} - ${context.options || ""} - intercepted`;
return `${retValue} - ${context.options || ""} - intercepted 1`;
}
}

@Interceptor()
class MyInterceptor2 implements InterceptorMethods {
intercept(context: InterceptorContext<any>) {
const r = typeof context.args[0] === "string" ? undefined : new Error(`Error message`);
const retValue = context.next(r);

return `${retValue} - ${context.options || ""} - intercepted 2`;
}
}

Expand All @@ -24,6 +33,18 @@ class ServiceTest {
exec(param: string) {
return `Original data - ${param}`;
}

@Intercept(MyInterceptor, "options data")
@Intercept(MyInterceptor2, "options data")
chained(param: string) {
return `Chained - ${param}`;
}

@Intercept(MyInterceptor2, "options data")
@Intercept(MyInterceptor, "options data")
reverseChained(param: string) {
return `Chained - ${param}`;
}
}

@Service()
Expand All @@ -49,7 +70,31 @@ describe("@Intercept", () => {
expect(getInterceptorOptions(ServiceTest, "exec")).toEqual("options data");

// THEN
expect(result).toEqual("Original data - param data - options data - intercepted");
expect(result).toEqual("Original data - param data - options data - intercepted 1");
});
it("should chained interceptor", async () => {
// GIVEN
const serviceTest = await DITest.invoke<ServiceTest>(ServiceTest)!;

// WHEN
const result = serviceTest.chained("param data");

expect(getInterceptorOptions(ServiceTest, "chained")).toEqual("options data");

// THEN
expect(result).toEqual("Chained - param data - options data - intercepted 2 - options data - intercepted 1");
});
it("should chained interceptor (reversed)", async () => {
// GIVEN
const serviceTest = await DITest.invoke<ServiceTest>(ServiceTest)!;

// WHEN
const result = serviceTest.reverseChained("param data");

expect(getInterceptorOptions(ServiceTest, "reverseChained")).toEqual("options data");

// THEN
expect(result).toEqual("Chained - param data - options data - intercepted 1 - options data - intercepted 2");
});
it("should intercept the method and mock interceptor", async () => {
// GIVEN
Expand Down Expand Up @@ -88,7 +133,7 @@ describe("@Intercept", () => {
const result = serviceTest.exec("param data");

// THEN
expect(result).toEqual("Original data - param data - options data - intercepted");
expect(result).toEqual("Original data - param data - options data - intercepted 1");
});
it("should intercept the method and throw error", async () => {
// GIVEN
Expand Down
11 changes: 8 additions & 3 deletions packages/di/src/common/decorators/intercept.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {classOf, decorateMethodsOf, DecoratorParameters, decoratorTypeOf, DecoratorTypes, Store, Type} from "@tsed/core";
import {classOf, decorateMethodsOf, DecoratorParameters, decoratorTypeOf, DecoratorTypes, nameOf, Store, Type} from "@tsed/core";

import {DI_INTERCEPTOR_OPTIONS, DI_INVOKE_OPTIONS} from "../constants/constants.js";
import {inject} from "../fn/inject.js";
Expand All @@ -19,7 +19,7 @@ export function bindIntercept(target: any, propertyKey: string | symbol, token:

Store.fromMethod(klass, propertyKey).set(DI_INTERCEPTOR_OPTIONS, options);

descriptor!.value = function (...args: any[]) {
function newMethod(...args: any[]) {
const next = (err?: Error) => {
if (!err) {
return originalMethod.apply(this, args);
Expand Down Expand Up @@ -50,7 +50,12 @@ export function bindIntercept(target: any, propertyKey: string | symbol, token:
},
next
);
};
}

descriptor!.value = newMethod;

Reflect.deleteProperty(klass.prototype, propertyKey);
Reflect.defineProperty(klass.prototype, propertyKey, descriptor!);

return descriptor;
}
Expand Down

0 comments on commit 3729b18

Please sign in to comment.