Files
shop-api/src/app.ts
T
mahyargdz be82059172 first
2025-09-14 15:15:03 +03:30

160 lines
5.3 KiB
TypeScript

import compression from "compression";
import cors from "cors";
import express, { Application } from "express";
import { Container } from "inversify";
import { InversifyExpressServer } from "inversify-express-utils";
import morgan from "morgan";
import { errorHandler, lastHandler, notFoundHandler } from "./core/app/app.errorHandler";
import { appConfig } from "./core/config/app.config";
import { Logger } from "./core/logging/logger";
import { customMorganFormat, stream } from "./core/logging/morgan";
import { containerModules } from "./IOC/ioc.config";
import { IOCTYPES } from "./IOC/ioc.types";
import { PassportAuth } from "./utils/passport.service";
import { setupSwagger } from "./utils/swagger";
//controller
import "./modules/admin";
import "./modules/brand/brand.controller";
import "./modules/warranty/warranty.controller";
import "./modules/shipment/shipment.controller";
import "./modules/category/category.controller";
import "./modules/product/product.controller";
import "./modules/seller/seller.controller";
import "./modules/user/user.controller";
import "./modules/cart/cart.controller";
import "./modules/Coupon/coupon.controller";
import "./modules/order/order.controller";
import "./modules/return/return.controller";
import "./modules/blog/blog.controller";
import "./modules/landing/landing.controller";
import "./modules/ticket/ticket.controller";
import "./modules/chat/chat.controller";
import "./modules/job/job.controller";
import "./modules/faq/faq.controller";
import "./modules/notification/notification.controller";
import "./modules/wallet/wallet.controller";
import "./modules/payment/payment.controller";
import "./modules/address/address.controller";
import "./modules/newsletter/newsletter.controller";
import "./modules/contact-us/contactUs.controller";
import "./modules/cancel/cancel.controller";
import "./modules/about-us/aboutUs.controller";
import "./modules/learning/learning.controller";
import "./modules/fine/fine.controller";
import "./modules/media/media.controller";
import "./modules/site-setting/siteSetting.controller";
import "./modules/shop/shop.controller";
import "./modules/ping";
class App {
private readonly _container: Container;
// private readonly _port: number;
private logger = new Logger();
constructor(container: Container) {
this._container = container;
// this._port = port;
this.loadModules();
}
private async loadModules() {
await this._container.loadAsync(containerModules);
}
public Build(): Application {
const server = new InversifyExpressServer(this._container, null /*,{ rootPath: "/api" }*/);
return server
.setConfig(async (app) => {
await this.setMiddleware(app);
})
.setErrorConfig((app) => {
this.catchError(app);
})
.build();
// .listen(this._port, () => {
// this.logger.info(`listening on http://localhost:${this._port}`);
// });
}
private async setMiddleware(app: Application) {
//remove x-powered-by header from response
app.disable("x-powered-by");
this.logger.debug("disable the default x header of express");
/**
* trust for reverse proxy to get correct ip address of user
* Configure based on deployment environment
*/
const trustedProxies = process.env.TRUSTED_PROXIES;
const trustProxyHops = process.env.TRUST_PROXY_HOPS;
if (trustedProxies === "true") {
// recommended for production with multiple proxies/CDNs
app.set("trust proxy", 1);
this.logger.debug("trust proxy enabled for first hop only (production with CDN/proxies)");
} else if (trustProxyHops && !isNaN(parseInt(trustProxyHops))) {
// Trust specific number of proxy hops
const hops = parseInt(trustProxyHops);
app.set("trust proxy", hops);
this.logger.debug(`trust proxy enabled for ${hops} hops`);
} else if (trustedProxies && trustedProxies !== "false") {
// Trust specific proxy IPs (comma-separated list)
const proxyList = trustedProxies.split(",").map((ip) => ip.trim());
app.set("trust proxy", proxyList);
this.logger.debug(`trust proxy enabled for specific IPs: ${trustedProxies}`);
} else if (process.env.NODE_ENV === "development") {
// For development, allow localhost proxies
app.set("trust proxy", "loopback");
this.logger.debug("trust proxy enabled for development (loopback only)");
} else {
// Production without reverse proxy - don't trust any proxies
app.set("trust proxy", false);
this.logger.debug("trust proxy disabled for security");
}
// app.get("/ip", (request, response) => response.send(request.ip));
/**
* compress the response
*/
app.use(compression());
/**
* configure body parser
*/
app.use(express.json());
/**
* configure morgan for http logging
*/
app.use(morgan(customMorganFormat, { stream }));
/**
* configure cors
*/
app.use(cors(appConfig.cors));
/**
* config passport
*/
const passportAuth = this._container.get<PassportAuth>(IOCTYPES.PassportAuth);
app.use(passportAuth.initialize());
passportAuth.plug();
/**
* swagger document
*/
setupSwagger(app);
this.logger.debug("setup swagger docs");
}
private catchError(app: Application) {
app.use(notFoundHandler());
app.use(errorHandler());
app.use(lastHandler());
}
}
export { App };