From d2613136e5aa950999dca338c6195eb454184f81 Mon Sep 17 00:00:00 2001 From: Adrianmjim Date: Sun, 27 Apr 2025 10:23:36 +0200 Subject: [PATCH 1/5] feat(http-core): add invalidOperationAfterBuild error kind to InversifyHttpAdapterErrorKind enum --- .../core/src/error/models/InversifyHttpAdapterErrorKind.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/http/libraries/core/src/error/models/InversifyHttpAdapterErrorKind.ts b/packages/http/libraries/core/src/error/models/InversifyHttpAdapterErrorKind.ts index 1a56a2bde..c73d70d85 100644 --- a/packages/http/libraries/core/src/error/models/InversifyHttpAdapterErrorKind.ts +++ b/packages/http/libraries/core/src/error/models/InversifyHttpAdapterErrorKind.ts @@ -1,4 +1,5 @@ export enum InversifyHttpAdapterErrorKind { + invalidOperationAfterBuild, noControllerFound, requestParamIncorrectUse, } From 9bd4d0c33224d38df2620702889705d3b35d6fad Mon Sep 17 00:00:00 2001 From: Adrianmjim Date: Sun, 27 Apr 2025 10:24:17 +0200 Subject: [PATCH 2/5] feat(http-core): implement global middleware and guard application methods in InversifyHttpAdapter --- .../src/http/adapter/InversifyHttpAdapter.ts | 92 ++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/packages/http/libraries/core/src/http/adapter/InversifyHttpAdapter.ts b/packages/http/libraries/core/src/http/adapter/InversifyHttpAdapter.ts index d1f236044..f53597767 100644 --- a/packages/http/libraries/core/src/http/adapter/InversifyHttpAdapter.ts +++ b/packages/http/libraries/core/src/http/adapter/InversifyHttpAdapter.ts @@ -1,14 +1,19 @@ import { Readable } from 'node:stream'; import { ConsoleLogger, Logger } from '@inversifyjs/logger'; -import { Container } from 'inversify'; +import { Container, Newable } from 'inversify'; +import { InversifyHttpAdapterError } from '../../error/models/InversifyHttpAdapterError'; +import { InversifyHttpAdapterErrorKind } from '../../error/models/InversifyHttpAdapterErrorKind'; +import { buildMiddlewareOptionsFromApplyMiddlewareOptions } from '../../routerExplorer/calculations/buildMiddlewareOptionsFromApplyMiddlewareOptions'; import { buildRouterExplorerControllerMetadataList } from '../../routerExplorer/calculations/buildRouterExplorerControllerMetadataList'; import { ControllerMethodParameterMetadata } from '../../routerExplorer/model/ControllerMethodParameterMetadata'; +import { MiddlewareOptions } from '../../routerExplorer/model/MiddlewareOptions'; import { RouterExplorerControllerMetadata } from '../../routerExplorer/model/RouterExplorerControllerMetadata'; import { RouterExplorerControllerMethodMetadata } from '../../routerExplorer/model/RouterExplorerControllerMethodMetadata'; import { Guard } from '../guard/model/Guard'; import { Middleware } from '../middleware/model/Middleware'; +import { ApplyMiddlewareOptions } from '../models/ApplyMiddlewareOptions'; import { Controller } from '../models/Controller'; import { ControllerResponse } from '../models/ControllerResponse'; import { HttpAdapterOptions } from '../models/HttpAdapterOptions'; @@ -28,13 +33,35 @@ const DEFAULT_ERROR_MESSAGE: string = 'An unexpected error occurred'; export abstract class InversifyHttpAdapter< TRequest, TResponse, - TNextFunction extends (err?: unknown) => Promise | void, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + TNextFunction extends (err?: any) => Promise | void, TResult, > { protected readonly httpAdapterOptions: InternalHttpAdapterOptions; + protected readonly globalHandlers: { + preHandlerMiddlewareList: MiddlewareHandler< + TRequest, + TResponse, + TNextFunction, + TResult + >[]; + postHandlerMiddlewareList: MiddlewareHandler< + TRequest, + TResponse, + TNextFunction, + TResult + >[]; + guardList: MiddlewareHandler< + TRequest, + TResponse, + TNextFunction, + TResult | undefined + >[]; + }; readonly #awaitableRequestMethodParamTypes: Set; readonly #container: Container; readonly #logger: Logger; + #isBuilt: boolean; constructor( container: Container, @@ -49,10 +76,71 @@ export abstract class InversifyHttpAdapter< this.#container = container; this.#logger = this.#buildLogger(httpAdapterOptions); this.httpAdapterOptions = this.#parseHttpAdapterOptions(httpAdapterOptions); + this.#isBuilt = false; + this.globalHandlers = { + guardList: [], + postHandlerMiddlewareList: [], + preHandlerMiddlewareList: [], + }; + } + + public async applyGlobalMiddleware( + ...middlewareList: (Newable | ApplyMiddlewareOptions)[] + ): Promise { + if (this.#isBuilt) { + throw new InversifyHttpAdapterError( + InversifyHttpAdapterErrorKind.invalidOperationAfterBuild, + 'Cannot apply global middleware after the server has been built', + ); + } + + const middlewareOptions: MiddlewareOptions = + buildMiddlewareOptionsFromApplyMiddlewareOptions(middlewareList); + + const [preHandlerMiddlewareList, postHandlerMiddlewareList]: [ + MiddlewareHandler[], + MiddlewareHandler[], + ] = await Promise.all([ + this.#getMiddlewareHandlerFromMetadata( + middlewareOptions.preHandlerMiddlewareList, + ), + this.#getMiddlewareHandlerFromMetadata( + middlewareOptions.postHandlerMiddlewareList, + ), + ]); + + this.globalHandlers.preHandlerMiddlewareList.push( + ...preHandlerMiddlewareList, + ); + this.globalHandlers.postHandlerMiddlewareList.push( + ...postHandlerMiddlewareList, + ); + } + + public async applyGlobalGuards( + ...guardList: Newable>[] + ): Promise { + if (this.#isBuilt) { + throw new InversifyHttpAdapterError( + InversifyHttpAdapterErrorKind.invalidOperationAfterBuild, + 'Cannot apply global guard after the server has been built', + ); + } + + const guardHandlerList: MiddlewareHandler< + TRequest, + TResponse, + TNextFunction, + TResult | undefined + >[] = await this.#getGuardHandlerFromMetadata(guardList); + + this.globalHandlers.guardList.push(...guardHandlerList); } protected async _buildServer(): Promise { await this.#registerControllers(); + + this.#isBuilt = true; } async #appendHandlerParam( From 698dbf84857e9e9baf22516ee383b139240292d1 Mon Sep 17 00:00:00 2001 From: Adrianmjim Date: Sun, 27 Apr 2025 10:33:36 +0200 Subject: [PATCH 3/5] feat(http-core): incorporate global handlers in InversifyExpressHttpAdapter --- .../adapter/InversifyExpressHttpAdapter.ts | 31 ++++++++++++------- .../adapter/InversifyExpressHttpAdapter.ts | 31 ++++++++++++------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/http/libraries/express-v4/src/adapter/InversifyExpressHttpAdapter.ts b/packages/http/libraries/express-v4/src/adapter/InversifyExpressHttpAdapter.ts index a0ea30df5..e4ec3527b 100644 --- a/packages/http/libraries/express-v4/src/adapter/InversifyExpressHttpAdapter.ts +++ b/packages/http/libraries/express-v4/src/adapter/InversifyExpressHttpAdapter.ts @@ -51,23 +51,32 @@ export class InversifyExpressHttpAdapter extends InversifyHttpAdapter< Response, NextFunction, void - >[] = [...routerParams.guardList, ...routerParams.preHandlerMiddlewareList]; + >[] = [ + ...this.globalHandlers.guardList, + ...routerParams.guardList, + ...this.globalHandlers.preHandlerMiddlewareList, + ...routerParams.preHandlerMiddlewareList, + ]; if (orderedMiddlewareList.length > 0) { router.use(orderedMiddlewareList); } for (const routeParams of routerParams.routeParamsList) { - const orderedPreHandlerMiddlewareList: - | MiddlewareHandler[] - | undefined = [ - ...routeParams.guardList, - ...routeParams.preHandlerMiddlewareList, - ]; - - const orderedPostHandlerMiddlewareList: - | MiddlewareHandler[] - | undefined = [ + const orderedPreHandlerMiddlewareList: MiddlewareHandler< + Request, + Response, + NextFunction, + void + >[] = [...routeParams.guardList, ...routeParams.preHandlerMiddlewareList]; + + const orderedPostHandlerMiddlewareList: MiddlewareHandler< + Request, + Response, + NextFunction, + void + >[] = [ + ...this.globalHandlers.postHandlerMiddlewareList, ...routerParams.postHandlerMiddlewareList, ...routeParams.postHandlerMiddlewareList, ]; diff --git a/packages/http/libraries/express/src/adapter/InversifyExpressHttpAdapter.ts b/packages/http/libraries/express/src/adapter/InversifyExpressHttpAdapter.ts index a0ea30df5..e4ec3527b 100644 --- a/packages/http/libraries/express/src/adapter/InversifyExpressHttpAdapter.ts +++ b/packages/http/libraries/express/src/adapter/InversifyExpressHttpAdapter.ts @@ -51,23 +51,32 @@ export class InversifyExpressHttpAdapter extends InversifyHttpAdapter< Response, NextFunction, void - >[] = [...routerParams.guardList, ...routerParams.preHandlerMiddlewareList]; + >[] = [ + ...this.globalHandlers.guardList, + ...routerParams.guardList, + ...this.globalHandlers.preHandlerMiddlewareList, + ...routerParams.preHandlerMiddlewareList, + ]; if (orderedMiddlewareList.length > 0) { router.use(orderedMiddlewareList); } for (const routeParams of routerParams.routeParamsList) { - const orderedPreHandlerMiddlewareList: - | MiddlewareHandler[] - | undefined = [ - ...routeParams.guardList, - ...routeParams.preHandlerMiddlewareList, - ]; - - const orderedPostHandlerMiddlewareList: - | MiddlewareHandler[] - | undefined = [ + const orderedPreHandlerMiddlewareList: MiddlewareHandler< + Request, + Response, + NextFunction, + void + >[] = [...routeParams.guardList, ...routeParams.preHandlerMiddlewareList]; + + const orderedPostHandlerMiddlewareList: MiddlewareHandler< + Request, + Response, + NextFunction, + void + >[] = [ + ...this.globalHandlers.postHandlerMiddlewareList, ...routerParams.postHandlerMiddlewareList, ...routeParams.postHandlerMiddlewareList, ]; From ae981fd947379ee4fc2c96964861778185990730 Mon Sep 17 00:00:00 2001 From: Adrianmjim Date: Sun, 27 Apr 2025 10:34:32 +0200 Subject: [PATCH 4/5] feat(http-fastify): incorporate global handlers in InversifyFastifyHttpAdapter --- .../adapter/InversifyFastifyHttpAdapter.ts | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/http/libraries/fastify/src/adapter/InversifyFastifyHttpAdapter.ts b/packages/http/libraries/fastify/src/adapter/InversifyFastifyHttpAdapter.ts index ce981540c..4f3a83950 100644 --- a/packages/http/libraries/fastify/src/adapter/InversifyFastifyHttpAdapter.ts +++ b/packages/http/libraries/fastify/src/adapter/InversifyFastifyHttpAdapter.ts @@ -15,6 +15,7 @@ import { FastifyPluginCallback, FastifyReply, FastifyRequest, + HookHandlerDoneFunction, onResponseAsyncHookHandler, preHandlerAsyncHookHandler, RouteHandlerMethod, @@ -24,7 +25,7 @@ import { Container } from 'inversify'; export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter< FastifyRequest, FastifyReply, - (err?: unknown) => void, + HookHandlerDoneFunction, void > { readonly #app: FastifyInstance; @@ -140,23 +141,36 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter< _opts: Record, done: () => void, ) => { - const orderedMiddlewareList: MiddlewareHandler< + const orderedPreHandlerMiddlewareList: MiddlewareHandler< FastifyRequest, FastifyReply, - (err?: Error) => void + (err?: Error) => void, + void >[] = [ + ...this.globalHandlers.preHandlerMiddlewareList, ...routerParams.guardList, + ...this.globalHandlers.preHandlerMiddlewareList, ...routerParams.preHandlerMiddlewareList, ]; - for (const middleware of orderedMiddlewareList) { + const orderedPostHandlerMiddlewareList: MiddlewareHandler< + FastifyRequest, + FastifyReply, + (err?: Error) => void, + void + >[] = [ + ...this.globalHandlers.postHandlerMiddlewareList, + ...routerParams.postHandlerMiddlewareList, + ]; + + for (const middleware of orderedPreHandlerMiddlewareList) { fastifyInstance.addHook( 'preHandler', this.#buildFastifyPreHandlerAsyncMiddleware(middleware), ); } - for (const middleware of routerParams.postHandlerMiddlewareList) { + for (const middleware of orderedPostHandlerMiddlewareList) { fastifyInstance.addHook( 'onResponse', this.#buildFastifyOnResponseAsyncMiddleware(middleware), @@ -238,7 +252,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter< middlewareList: MiddlewareHandler< FastifyRequest, FastifyReply, - (err?: Error) => void + HookHandlerDoneFunction >[], ): preHandlerAsyncHookHandler[] { return middlewareList.map( @@ -256,7 +270,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter< middlewareList: MiddlewareHandler< FastifyRequest, FastifyReply, - (err?: Error) => void + HookHandlerDoneFunction >[], ): onResponseAsyncHookHandler[] { return middlewareList.map( @@ -274,7 +288,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter< middleware: MiddlewareHandler< FastifyRequest, FastifyReply, - (err?: Error) => void + HookHandlerDoneFunction >, ): preHandlerAsyncHookHandler { return async (request: FastifyRequest, reply: FastifyReply) => { @@ -301,7 +315,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter< middleware: MiddlewareHandler< FastifyRequest, FastifyReply, - (err?: Error) => void + HookHandlerDoneFunction >, ): onResponseAsyncHookHandler { return async (request: FastifyRequest, reply: FastifyReply) => { From 5a4310d3de37bb08dd45806a05b005ab55983126 Mon Sep 17 00:00:00 2001 From: Adrianmjim Date: Sun, 27 Apr 2025 10:35:39 +0200 Subject: [PATCH 5/5] feat(http-hono): incorporate global handlers in InversifyHonoHttpAdapter --- .../src/adapter/InversifyHonoHttpAdapter.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/http/libraries/hono/src/adapter/InversifyHonoHttpAdapter.ts b/packages/http/libraries/hono/src/adapter/InversifyHonoHttpAdapter.ts index d953409ee..eeb4e909e 100644 --- a/packages/http/libraries/hono/src/adapter/InversifyHonoHttpAdapter.ts +++ b/packages/http/libraries/hono/src/adapter/InversifyHonoHttpAdapter.ts @@ -57,8 +57,17 @@ export class InversifyHonoHttpAdapter extends InversifyHttpAdapter< const router: Hono = new Hono(); const routerHonoMiddlewareList: HonoMiddlewareHandler[] = [ - ...this.#buildHonoMiddlewareList(routerParams.guardList), - ...this.#buildHonoMiddlewareList(routerParams.preHandlerMiddlewareList), + ...this.#buildHonoPreHandlerMiddlewareList(this.globalHandlers.guardList), + ...this.#buildHonoPreHandlerMiddlewareList(routerParams.guardList), + ...this.#buildHonoPreHandlerMiddlewareList( + this.globalHandlers.preHandlerMiddlewareList, + ), + ...this.#buildHonoPreHandlerMiddlewareList( + routerParams.preHandlerMiddlewareList, + ), + ...this.#buildHonoPostHandlerMiddlewareList( + this.globalHandlers.postHandlerMiddlewareList, + ), ...this.#buildHonoPostHandlerMiddlewareList( routerParams.postHandlerMiddlewareList, ), @@ -70,8 +79,10 @@ export class InversifyHonoHttpAdapter extends InversifyHttpAdapter< for (const routeParams of routerParams.routeParamsList) { const routeHonoMiddlewareList: HonoMiddlewareHandler[] = [ - ...this.#buildHonoMiddlewareList(routeParams.guardList), - ...this.#buildHonoMiddlewareList(routeParams.preHandlerMiddlewareList), + ...this.#buildHonoPreHandlerMiddlewareList(routeParams.guardList), + ...this.#buildHonoPreHandlerMiddlewareList( + routeParams.preHandlerMiddlewareList, + ), ...this.#buildHonoPostHandlerMiddlewareList( routeParams.postHandlerMiddlewareList, ), @@ -187,7 +198,7 @@ export class InversifyHonoHttpAdapter extends InversifyHttpAdapter< handler(ctx.req as HonoRequest, ctx, next); } - #buildHonoMiddlewareList( + #buildHonoPreHandlerMiddlewareList( handlers: MiddlewareHandler< HonoRequest, Context,