From 4fd0ec378885b9e42ad7aa820920ffbe16d5b852 Mon Sep 17 00:00:00 2001 From: Romain Lenzotti Date: Sun, 21 Aug 2022 12:29:52 +0200 Subject: [PATCH] fix(platform-express): prevent loosing context with express middleware --- packages/di/src/services/InjectorService.ts | 8 +++--- .../platform/platform-express/coverage.json | 6 +++++ .../platform/platform-express/jest.config.js | 7 +---- .../src/components/PlatformExpress.ts | 3 +-- .../services/PlatformExpressHandler.spec.ts | 2 +- .../src/services/PlatformExpressHandler.ts | 27 ++++++++++++++----- .../src/services/ViteServer.spec.ts | 7 ++--- 7 files changed, 35 insertions(+), 25 deletions(-) create mode 100644 packages/platform/platform-express/coverage.json diff --git a/packages/di/src/services/InjectorService.ts b/packages/di/src/services/InjectorService.ts index a695a173156..3939b2664b4 100644 --- a/packages/di/src/services/InjectorService.ts +++ b/packages/di/src/services/InjectorService.ts @@ -238,7 +238,7 @@ export class InjectorService extends Container { switch (this.scopeOf(provider)) { case ProviderScope.SINGLETON: if (provider.hooks && !options.rebuild) { - this.registerHooks(provider); + this.registerHooks(provider, instance); } if (!provider.isAsync()) { @@ -589,8 +589,6 @@ export class InjectorService extends Container { async destroy() { await this.emit("$onDestroy"); - this.#cache.clear(); - this.#hooks.destroy(); } protected ensureProvider(token: TokenProvider): Provider | undefined { @@ -740,10 +738,10 @@ export class InjectorService extends Container { }; } - private registerHooks(provider: Provider) { + private registerHooks(provider: Provider, instance: any) { if (provider.hooks) { Object.entries(provider.hooks).forEach(([event, cb]) => { - const callback = (...args: any[]) => cb(this.get(provider.token), ...args); + const callback = (...args: any[]) => cb(this.get(provider.token) || instance, ...args); this.#hooks.on(event, callback); }); diff --git a/packages/platform/platform-express/coverage.json b/packages/platform/platform-express/coverage.json new file mode 100644 index 00000000000..417ccf90808 --- /dev/null +++ b/packages/platform/platform-express/coverage.json @@ -0,0 +1,6 @@ +{ + "statements": 100, + "branches": 80.64, + "functions": 100, + "lines": 100 +} diff --git a/packages/platform/platform-express/jest.config.js b/packages/platform/platform-express/jest.config.js index 66dd0a070e8..9559b98f045 100644 --- a/packages/platform/platform-express/jest.config.js +++ b/packages/platform/platform-express/jest.config.js @@ -4,11 +4,6 @@ module.exports = { ...require("@tsed/jest-config")(__dirname, "platform-express"), coverageThreshold: { - global: { - statements: 100, - branches: 78.94, - functions: 100, - lines: 100 - } + global: require("./coverage.json") } }; diff --git a/packages/platform/platform-express/src/components/PlatformExpress.ts b/packages/platform/platform-express/src/components/PlatformExpress.ts index 106124cb25d..625b365eac8 100644 --- a/packages/platform/platform-express/src/components/PlatformExpress.ts +++ b/packages/platform/platform-express/src/components/PlatformExpress.ts @@ -170,11 +170,10 @@ export class PlatformExpress implements PlatformAdapter runInContext(undefined, () => app(req, res), this.injector); return { app, - callback: () => requestHandler + callback: () => app }; } diff --git a/packages/platform/platform-express/src/services/PlatformExpressHandler.spec.ts b/packages/platform/platform-express/src/services/PlatformExpressHandler.spec.ts index a6a2f64c975..371837caa29 100644 --- a/packages/platform/platform-express/src/services/PlatformExpressHandler.spec.ts +++ b/packages/platform/platform-express/src/services/PlatformExpressHandler.spec.ts @@ -164,7 +164,7 @@ describe("PlatformExpressHandler", () => { const handler = platformHandler.createHandler(handlerMetadata); // THEN - expect(handler).toEqual(handlerMetadata.handler); + expect(handler).toEqual(expect.any(Function)); }); }); }); diff --git a/packages/platform/platform-express/src/services/PlatformExpressHandler.ts b/packages/platform/platform-express/src/services/PlatformExpressHandler.ts index 529243f4f90..4aac4dd10fa 100644 --- a/packages/platform/platform-express/src/services/PlatformExpressHandler.ts +++ b/packages/platform/platform-express/src/services/PlatformExpressHandler.ts @@ -1,4 +1,4 @@ -import {HandlerMetadata, HandlerType, OnRequestOptions, PlatformHandler} from "@tsed/common"; +import {HandlerMetadata, HandlerType, OnRequestOptions, PlatformHandler, runInContext} from "@tsed/common"; /** * @platform @@ -6,17 +6,32 @@ import {HandlerMetadata, HandlerType, OnRequestOptions, PlatformHandler} from "@ */ export class PlatformExpressHandler extends PlatformHandler { protected createRawHandler(metadata: HandlerMetadata): Function { + if ([HandlerType.RAW_ERR_FN, HandlerType.RAW_FN].includes(metadata.type)) { + return metadata.handler; + } + + const handler = this.compileHandler(metadata); + if (metadata.type === HandlerType.ERR_MIDDLEWARE) { const handler = this.compileHandler(metadata); return async (err: any, req: any, res: any, next: any) => + runInContext(req.$ctx, () => + handler({ + err, + next, + $ctx: req.$ctx + }) + ); + } + + return async (req: any, res: any, next: any) => { + return runInContext(req.$ctx, () => handler({ - err, next, $ctx: req.$ctx - }); - } - - return super.createRawHandler(metadata); + }) + ); + }; } protected async onCtxRequest(requestOptions: OnRequestOptions): Promise { diff --git a/packages/third-parties/vite-ssr-plugin/src/services/ViteServer.spec.ts b/packages/third-parties/vite-ssr-plugin/src/services/ViteServer.spec.ts index 7d09889e25b..d22021b36b2 100644 --- a/packages/third-parties/vite-ssr-plugin/src/services/ViteServer.spec.ts +++ b/packages/third-parties/vite-ssr-plugin/src/services/ViteServer.spec.ts @@ -34,9 +34,6 @@ describe("ViteServer", () => { middlewareMode: true } }); - - // @ts-ignore - await viteDevServer.$onDestroy(); }); it("should load and close server", async () => { const viteDevServer = PlatformTest.get(VITE_SERVER); @@ -50,8 +47,8 @@ describe("ViteServer", () => { } }); - // @ts-ignore - await viteDevServer.$onDestroy(); + await PlatformTest.injector.destroy(); + expect(viteDevServer.close).toHaveBeenCalledWith(); }); });