Files
api-duneawa/src/app.js
2026-05-10 21:40:51 +02:00

94 lines
2.4 KiB
JavaScript

const cors = require("cors");
const express = require("express");
const fs = require("fs");
const path = require("path");
const swaggerUi = require("swagger-ui-express");
const { config } = require("./config");
const { pingMongo } = require("./db/client");
const { router: apiRouter } = require("./routes/api");
const { openApiDocument } = require("./swagger/openapi");
const skillFilePaths = [
path.join(__dirname, "SKILL.md"),
path.join(__dirname, "..", ".idea", "SKILL.md"),
path.join(__dirname, "..", ".ai", "SKILL.md"),
];
function getSkillFilePath() {
return skillFilePaths.find((filePath) => fs.existsSync(filePath));
}
function createApp() {
const app = express();
app.set("trust proxy", true);
app.use(cors());
app.use(express.json({ limit: "2mb" }));
app.use((request, response, next) => {
const forwardedProto = request.get("x-forwarded-proto");
const isSecure = request.secure || forwardedProto === "https";
const isLocalhost = ["localhost", "127.0.0.1", "::1"].includes(
request.hostname,
);
if (config.public.forceHttps && !isSecure && !isLocalhost) {
const baseUrl =
request.hostname === "ui.dune.api.coppnic.cc"
? config.public.uiUrl
: config.public.apiUrl;
response.redirect(308, new URL(request.originalUrl, baseUrl).toString());
return;
}
next();
});
app.get("/", (request, response) => {
response.redirect(308, `${config.public.uiUrl}/docs`);
});
app.get("/health", async (request, response) => {
try {
await pingMongo();
response.json({ ok: true, mongo: "connected" });
} catch (error) {
response
.status(503)
.json({ ok: false, mongo: "unavailable", error: error.message });
}
});
app.get("/openapi.json", (request, response) => {
response.json(openApiDocument);
});
app.get(["/SKILL.md", "/skill.md"], (request, response) => {
const skillFilePath = getSkillFilePath();
if (!skillFilePath) {
response.status(404).json({ error: "SKILL.md not found" });
return;
}
response.type("text/markdown");
response.sendFile(skillFilePath);
});
app.use("/docs", swaggerUi.serve, swaggerUi.setup(openApiDocument));
app.use("/api", apiRouter);
app.use((request, response) => {
response.status(404).json({ error: "Not found" });
});
app.use((error, request, response, next) => {
const status = error.status || 500;
response
.status(status)
.json({ error: error.message || "Internal server error" });
});
return app;
}
module.exports = { createApp };