Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum InversifyHttpAdapterErrorKind {
invalidOperationAfterBuild,
noControllerFound,
pipeError,
requestParamIncorrectUse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ 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';
Expand All @@ -34,14 +37,36 @@ const DEFAULT_ERROR_MESSAGE: string = 'An unexpected error occurred';
export abstract class InversifyHttpAdapter<
TRequest,
TResponse,
TNextFunction extends (err?: unknown) => Promise<void> | void,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
TNextFunction extends (err?: any) => Promise<void> | 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<RequestMethodParameterType>;
readonly #container: Container;
readonly #logger: Logger;
readonly #globalPipeList: (Newable<Pipe> | Pipe)[];
#isBuilt: boolean;

constructor(
container: Container,
Expand All @@ -57,6 +82,65 @@ export abstract class InversifyHttpAdapter<
this.#logger = this.#buildLogger(httpAdapterOptions);
this.httpAdapterOptions = this.#parseHttpAdapterOptions(httpAdapterOptions);
this.#globalPipeList = [];
this.#isBuilt = false;
this.globalHandlers = {
guardList: [],
postHandlerMiddlewareList: [],
preHandlerMiddlewareList: [],
};
}

public async applyGlobalMiddleware(
...middlewareList: (Newable<Middleware> | ApplyMiddlewareOptions)[]
): Promise<void> {
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<TRequest, TResponse, TNextFunction, TResult>[],
MiddlewareHandler<TRequest, TResponse, TNextFunction, TResult>[],
] = 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<Guard<TRequest>>[]
): Promise<void> {
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);
}

public useGlobalPipe(...pipeList: (Newable<Pipe> | Pipe)[]): void {
Expand All @@ -65,6 +149,8 @@ export abstract class InversifyHttpAdapter<

protected async _buildServer(): Promise<void> {
await this.#registerControllers();

this.#isBuilt = true;
}

async #appendHandlerParam(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Request, Response, NextFunction, void>[]
| undefined = [
...routeParams.guardList,
...routeParams.preHandlerMiddlewareList,
];

const orderedPostHandlerMiddlewareList:
| MiddlewareHandler<Request, Response, NextFunction, void>[]
| 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,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Request, Response, NextFunction, void>[]
| undefined = [
...routeParams.guardList,
...routeParams.preHandlerMiddlewareList,
];

const orderedPostHandlerMiddlewareList:
| MiddlewareHandler<Request, Response, NextFunction, void>[]
| 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,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
FastifyPluginCallback,
FastifyReply,
FastifyRequest,
HookHandlerDoneFunction,
onResponseAsyncHookHandler,
preHandlerAsyncHookHandler,
RouteHandlerMethod,
Expand All @@ -24,7 +25,7 @@ import { Container } from 'inversify';
export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter<
FastifyRequest,
FastifyReply,
(err?: unknown) => void,
HookHandlerDoneFunction,
void
> {
readonly #app: FastifyInstance;
Expand Down Expand Up @@ -140,23 +141,36 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter<
_opts: Record<string, unknown>,
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),
Expand Down Expand Up @@ -238,7 +252,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter<
middlewareList: MiddlewareHandler<
FastifyRequest,
FastifyReply,
(err?: Error) => void
HookHandlerDoneFunction
>[],
): preHandlerAsyncHookHandler[] {
return middlewareList.map(
Expand All @@ -256,7 +270,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter<
middlewareList: MiddlewareHandler<
FastifyRequest,
FastifyReply,
(err?: Error) => void
HookHandlerDoneFunction
>[],
): onResponseAsyncHookHandler[] {
return middlewareList.map(
Expand All @@ -274,7 +288,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter<
middleware: MiddlewareHandler<
FastifyRequest,
FastifyReply,
(err?: Error) => void
HookHandlerDoneFunction
>,
): preHandlerAsyncHookHandler {
return async (request: FastifyRequest, reply: FastifyReply) => {
Expand All @@ -301,7 +315,7 @@ export class InversifyFastifyHttpAdapter extends InversifyHttpAdapter<
middleware: MiddlewareHandler<
FastifyRequest,
FastifyReply,
(err?: Error) => void
HookHandlerDoneFunction
>,
): onResponseAsyncHookHandler {
return async (request: FastifyRequest, reply: FastifyReply) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
Expand All @@ -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,
),
Expand Down Expand Up @@ -187,7 +198,7 @@ export class InversifyHonoHttpAdapter extends InversifyHttpAdapter<
handler(ctx.req as HonoRequest, ctx, next);
}

#buildHonoMiddlewareList(
#buildHonoPreHandlerMiddlewareList(
handlers: MiddlewareHandler<
HonoRequest,
Context,
Expand Down