@nodearch/express
Version:
nodearch express server
179 lines • 7.96 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import express from 'express';
import { AppContext, Logger, Service } from '@nodearch/core';
import { RouteHandler } from './route-handler.js';
import { MiddlewareFactory } from '../middleware/middleware-factory.js';
import { ExpressParser } from './express-parser.js';
import { ExpressConfig } from './express.config.js';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
let ExpressApp = class ExpressApp {
constructor(routeHandler, middlewareFactory, expressParser, expressConfig, appContext, logger) {
this.routeHandler = routeHandler;
this.middlewareFactory = middlewareFactory;
this.expressParser = expressParser;
this.expressConfig = expressConfig;
this.appContext = appContext;
this.logger = logger;
}
create() {
const app = express();
const expressInfo = this.expressParser.getExpressInfo();
this.registerResponseTimer(app);
this.registerHttpLogger(app);
this.registerParsers(app);
this.registerGlobalMiddleware(app);
this.registerStatic(app);
this.registerRouter(expressInfo, app);
return app;
}
registerResponseTimer(app) {
if (this.expressConfig.httpLogger.enable && this.expressConfig.httpLogger.showDuration) {
app.use((req, res, next) => {
const start = process.hrtime();
res.on('finish', () => {
const durationInMs = this.getDurationInMs(start);
req.nodearch = req.nodearch || {};
req.nodearch.responseTime = durationInMs;
});
next();
});
}
}
registerHttpLogger(app) {
if (this.expressConfig.httpLogger.enable) {
app.use((req, res, next) => {
res.on('finish', () => {
const message = this.getHttpLoggerMessage(req, res, this.expressConfig.httpLogger);
this.logger.info(message);
});
next();
});
}
}
getHttpLoggerMessage(req, res, config) {
let message = `[${req.method}] ${req.originalUrl}`;
if (config.showHeaders) {
message += ' - Headers: ';
message += typeof config.showHeaders === 'function' ?
config.showHeaders(req.headers) : JSON.stringify(req.headers);
}
if (config.showBody) {
message += ' - Body: ';
message += typeof config.showBody === 'function' ?
config.showBody(req.body) : JSON.stringify(req.body);
}
if (config.showQuery) {
message += ' - Query: ';
message += typeof config.showQuery === 'function' ?
config.showQuery(req.query) : JSON.stringify(req.query);
}
if (config.showParams) {
message += ' - Params: ';
message += typeof config.showParams === 'function' ?
config.showParams(req.params) : JSON.stringify(req.params);
}
if (config.showCookies) {
message += ' - Cookies: ';
message += typeof config.showCookies === 'function' ?
config.showCookies(req.cookies) : JSON.stringify(req.cookies);
}
if (config.showStatus) {
message += ` - Status: ${res.statusCode}`;
}
if (config.custom) {
message += ` - ${config.custom(req)}`;
}
if (config.showDuration) {
message += ` - Duration: ${req.nodearch.responseTime}ms`;
}
return message;
}
getDurationInMs(start) {
const NS_PER_SEC = 1e9;
const NS_TO_MS = 1e6;
const diff = process.hrtime(start);
return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS;
}
registerParsers(app) {
this.expressConfig.jsonParser.enable && app.use(express.json(this.expressConfig.jsonParser.options));
this.expressConfig.textParser.enable && app.use(express.text(this.expressConfig.textParser.options));
this.expressConfig.urlencodedParser.enable && app.use(express.urlencoded(this.expressConfig.urlencodedParser.options));
}
registerGlobalMiddleware(app) {
if (this.expressConfig.use) {
this.expressConfig.use.forEach(middleware => {
app.use(middleware);
});
}
}
registerStatic(app) {
if (this.expressConfig.static) {
const rootDirPath = fileURLToPath(this.appContext.getSettings().paths.rootDir);
this.expressConfig.static.forEach(staticItem => {
let filePath = staticItem.filePath;
if (filePath instanceof URL) {
filePath = fileURLToPath(filePath);
}
if (!path.isAbsolute(filePath)) {
filePath = path.join(rootDirPath, filePath);
}
app.use(staticItem.httpPath, express.static(filePath, staticItem.options));
this.logger.info(`Static: ${staticItem.httpPath} -> ${filePath}`);
});
}
}
registerRouter(expressInfo, app) {
expressInfo.routers.forEach(routerInfo => {
app.use(routerInfo.path, this.createRouter(routerInfo));
});
}
createRouter(routerInfo) {
const router = express.Router({ mergeParams: true });
router.use(this.middlewareFactory.defaultRouterMiddleware(routerInfo.controllerInfo));
this.middlewareFactory.createExpressMiddleware(routerInfo.middleware)
.forEach(middleware => {
router.use(middleware);
});
const controllerClass = routerInfo.controllerInfo.getClass();
routerInfo.routes.forEach(routeInfo => {
this.registerRoute(router, routerInfo, routeInfo, controllerClass);
});
return router;
}
registerRoute(router, routerInfo, routeInfo, controllerClass) {
const routeMiddleware = this.middlewareFactory.createExpressMiddleware(routeInfo.middleware);
const routeParams = [
...routeMiddleware,
this.routeHandler.create(routeInfo.controllerMethod, routeInfo.inputs)
];
router[routeInfo.method](routeInfo.path, ...routeParams);
const middlewareCount = routerInfo.middleware.length + routeMiddleware.length;
this.logger.info(this.createRouteRegisterMsg(routerInfo, routeInfo, controllerClass, middlewareCount));
}
createRouteRegisterMsg(routerInfo, routeInfo, controllerClass, middlewareCount) {
const routeMethod = `[${routeInfo.method.toUpperCase()}]`;
const routePath = `${routerInfo.path}${routeInfo.path}`;
const controllerMethod = `(${controllerClass.name}.${routeInfo.controllerMethod})`;
return `Route: ${routeMethod} ${routePath} ${controllerMethod} - Middleware: ${middlewareCount}`;
}
};
ExpressApp = __decorate([
Service(),
__metadata("design:paramtypes", [RouteHandler,
MiddlewareFactory,
ExpressParser,
ExpressConfig,
AppContext,
Logger])
], ExpressApp);
export { ExpressApp };
//# sourceMappingURL=express-app.js.map