Skip to content

Commit 2c46c07

Browse files
authored
Merge pull request #15 from expressots/feature/expresso-middleware
Feature/expresso middleware
2 parents b2fbce5 + 934ae17 commit 2c46c07

File tree

1 file changed

+75
-18
lines changed

1 file changed

+75
-18
lines changed

src/adapter-express/application-express.ts

+75-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import express from "express";
1+
import express, { Request, Response, NextFunction } from "express";
22
import { Container } from "inversify";
33
import { provide } from "inversify-binding-decorators";
44
import process from "process";
@@ -15,17 +15,55 @@ import { IApplicationExpress } from "./application-express.interface";
1515
import { InversifyExpressServer } from "./express-utils/inversify-express-server";
1616
import { ApplicationBase } from "./application-base";
1717

18+
/**
19+
* ExpressHandler Type
20+
*
21+
* The ExpressHandler type is a union type that represents various types of Express middleware functions.
22+
* It can be one of the following types:
23+
* - express.ErrorRequestHandler: Handles errors in the middleware pipeline.
24+
* - express.RequestParamHandler: Handles parameters in the middleware pipeline.
25+
* - express.RequestHandler: General request handler.
26+
* - undefined: Represents the absence of a handler.
27+
*/
1828
type ExpressHandler =
1929
| express.ErrorRequestHandler
2030
| express.RequestParamHandler
2131
| express.RequestHandler
2232
| undefined;
2333

34+
/**
35+
* MiddlewareConfig Interface
36+
*
37+
* The MiddlewareConfig interface specifies the structure for middleware configuration objects.
38+
* - path: Optional. The route path for which the middleware is configured.
39+
* - middlewares: An array of ExpressHandler types that make up the middleware pipeline for the route specified by 'path'.
40+
*/
2441
type MiddlewareConfig = {
2542
path?: string;
2643
middlewares: Array<ExpressHandler>;
2744
};
2845

46+
/**
47+
* Expresso middleware interface.
48+
*/
49+
interface IExpressoMiddleware {
50+
//readonly name: string;
51+
use(req: Request, res: Response, next: NextFunction): Promise<void> | void;
52+
}
53+
54+
/**
55+
* Abstract class for creating custom Expresso middleware.
56+
* Custom middleware classes should extend this class and implement the use method.
57+
*
58+
*/
59+
abstract class ExpressoMiddleware implements IExpressoMiddleware {
60+
get name(): string {
61+
return this.constructor.name;
62+
}
63+
64+
abstract use(req: Request, res: Response, next: NextFunction): Promise<void> | void;
65+
}
66+
2967
/**
3068
* Enum representing possible server environments.
3169
*/
@@ -59,6 +97,40 @@ class ApplicationExpress extends ApplicationBase implements IApplicationExpress
5997
process.exit(0);
6098
}
6199

100+
/**
101+
* Configures the Express application with the provided middleware entries.
102+
* @param app - The Express application instance.
103+
* @param middlewareEntries - An array of Express middleware entries to be applied.
104+
*/
105+
private async configureMiddleware(
106+
app: express.Application,
107+
middlewareEntries: Array<ExpressHandler | MiddlewareConfig | ExpressoMiddleware>,
108+
): Promise<void> {
109+
for (const entry of middlewareEntries) {
110+
if (typeof entry === "function") {
111+
app.use(entry as express.RequestHandler);
112+
// eslint-disable-next-line no-prototype-builtins
113+
} else if (entry?.hasOwnProperty("path")) {
114+
const { path, middlewares } = entry as MiddlewareConfig;
115+
for (const mid of middlewares) {
116+
if (path) {
117+
if (typeof mid === "function") {
118+
app.use(path, mid as express.RequestHandler);
119+
} else {
120+
const middleware = mid as unknown as ExpressoMiddleware;
121+
middleware.use = middleware.use.bind(middleware);
122+
app.use(path, middleware.use);
123+
}
124+
}
125+
}
126+
} else {
127+
const middleware = entry as ExpressoMiddleware;
128+
middleware.use = middleware.use.bind(middleware);
129+
app.use(middleware.use);
130+
}
131+
}
132+
}
133+
62134
/**
63135
* Create and configure the Express application.
64136
* @param container - The InversifyJS container.
@@ -69,35 +141,20 @@ class ApplicationExpress extends ApplicationBase implements IApplicationExpress
69141
container: Container,
70142
middlewares: Array<express.RequestHandler> = [],
71143
): Promise<ApplicationExpress> {
72-
await Promise.resolve(this.configureServices());
144+
await this.configureServices();
73145

74146
const middleware = container.get<IMiddleware>(Middleware);
75147
const sortedMiddlewarePipeline = middleware.getMiddlewarePipeline();
76148
const pipeline = sortedMiddlewarePipeline.map((entry) => entry.middleware);
77149

78150
this.middlewares.push(...middlewares, ...(pipeline as Array<ExpressHandler>));
79151

80-
const allMiddlewareEntries: Array<ExpressHandler | MiddlewareConfig> = [...this.middlewares];
81-
82152
const expressServer = new InversifyExpressServer(container, null, {
83153
rootPath: this.globalPrefix as string,
84154
});
85155

86156
expressServer.setConfig((app: express.Application) => {
87-
allMiddlewareEntries.forEach((entry) => {
88-
if (typeof entry === "function") {
89-
app.use(entry as express.RequestHandler);
90-
} else {
91-
const { path, middlewares } = entry as MiddlewareConfig;
92-
middlewares.forEach((middleware) => {
93-
if (path) {
94-
app.use(path, middleware as express.RequestHandler);
95-
} else {
96-
app.use(middleware as express.RequestHandler);
97-
}
98-
});
99-
}
100-
});
157+
this.configureMiddleware(app, this.middlewares);
101158
});
102159

103160
expressServer.setErrorConfig((app: express.Application) => {

0 commit comments

Comments
 (0)