Uecko_ERP/apps/server/src/app.ts

101 lines
3.3 KiB
TypeScript
Raw Normal View History

2025-11-24 13:05:10 +00:00
import cors, { type CorsOptions } from "cors";
import express, { type Application } from "express";
2025-01-29 16:01:17 +00:00
import helmet from "helmet";
2025-01-30 10:45:31 +00:00
import responseTime from "response-time";
2025-11-24 13:05:10 +00:00
2026-02-12 14:46:47 +00:00
import type { ConfigType } from "./config";
// ❗️ No cargamos dotenv aquí. Debe hacerse en el entrypoint o en ./config.
// dotenv.config();
2026-02-12 14:46:47 +00:00
2025-10-30 18:26:57 +00:00
import { logger } from "./lib/logger";
2025-01-29 16:01:17 +00:00
2026-02-12 14:46:47 +00:00
export function createApp(config: ConfigType): Application {
2025-01-29 16:01:17 +00:00
const app = express();
// ───────────────────────────────────────────────────────────────────────────
// CORS
const devCors: CorsOptions = {
// En desarrollo reflejamos el Origin entrante (permite credenciales)
origin: true,
credentials: true,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
exposedHeaders: [
"Content-Disposition",
"Content-Type",
"Content-Length",
"X-Total-Count",
"Pagination-Count",
"Pagination-Page",
"Pagination-Limit",
],
};
2025-06-17 16:18:25 +00:00
const prodCors: CorsOptions = {
2026-02-12 14:46:47 +00:00
origin: config.server.frontendUrl,
credentials: true,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
exposedHeaders: [
"Content-Disposition",
"Content-Type",
"Content-Length",
"X-Total-Count",
"Pagination-Count",
"Pagination-Page",
"Pagination-Limit",
],
};
2025-06-17 16:18:25 +00:00
2026-02-12 14:46:47 +00:00
app.use(cors(config.flags.isDev ? devCors : prodCors));
app.options("*", cors(config.flags.isDev ? devCors : prodCors));
2025-11-24 13:05:10 +00:00
2026-02-12 14:46:47 +00:00
app.set("port", config.server.port ?? 3002);
2025-11-24 13:05:10 +00:00
// Oculta la cabecera x-powered-by
app.disable("x-powered-by");
// Desactiva ETag correctamente a nivel de Express
app.set("etag", false);
// ───────────────────────────────────────────────────────────────────────────
// Parsers
app.use(express.json());
app.use(express.text());
app.use(express.urlencoded({ extended: true }));
// Métrica de tiempo de respuesta
app.use(responseTime());
// ───────────────────────────────────────────────────────────────────────────
// Seguridad HTTP
2025-04-01 15:32:53 +00:00
app.use(helmet());
// ───────────────────────────────────────────────────────────────────────────
// Política de caché por defecto (no almacenamiento)
app.use((_, res, next) => {
2025-04-01 15:32:53 +00:00
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
res.setHeader("Pragma", "no-cache");
res.setHeader("Expires", "0");
next();
2025-04-01 15:32:53 +00:00
});
// Inicializar Auth Provider (placeholder)
app.use((_, __, next) => {
// authProvider.initialize();
2025-02-05 20:40:59 +00:00
next();
});
2025-02-01 21:48:13 +00:00
// Logging de cada request
2025-02-03 13:12:36 +00:00
app.use((req, _, next) => {
logger.info(`▶️ Incoming request ${req.method} to ${req.path}`);
2025-02-03 13:12:36 +00:00
next();
});
2025-11-06 16:14:49 +00:00
// Gestión global de errores.
// Siempre al final de la cadena de middlewares
// y después de las rutas.
2025-11-07 17:51:18 +00:00
//app.use(globalErrorHandler);
2025-11-06 16:14:49 +00:00
2025-01-29 16:01:17 +00:00
return app;
}