2026-03-02 16:30:21 +03:00

93 lines
2.3 KiB
JavaScript

import path from "node:path";
import formidable from "formidable";
import { ctxStorage } from "#root/context.js";
import { handlers as reportsHandlers } from "./reports/index.js";
import { BadRequestError, HttpError, NotFoundError } from "#root/errors/index.js";
import { serializeError } from "serialize-error";
/**
* @type {HTTPRouteMap}
*/
export const ROUTE_MAP = {
"/api/reports_excel_file_parse": {
method: "POST",
handle: reportsHandlers.parseExcelHandler,
incomingForm: formidable({
maxFields: 1,
maxFiles: 1,
filename: (_, ext) => `gpp-reports${ext}`,
keepExtensions: true,
uploadDir: path.join(process.cwd(), "./uploads"),
filter: ({ mimetype }) => !!mimetype && mimetype.includes("application/vnd.ms-excel")
})
},
"/api/reports_sync": {
method: "POST",
handle: reportsHandlers.syncParsedHandler
}
};
/**
* @param {URL} url
*/
export async function routeHandler(url) {
/** @type {HTTPContext} */
const ctx = ctxStorage.getStore();
const { req, res } = ctx;
try {
if (url.pathname in ROUTE_MAP) {
const route = ROUTE_MAP[url.pathname];
if (req.req.headers["content-type"] === "application/json") {
ctx.data = await ctx.req.parseJson();
}
if (req.req.headers["content-type"]?.includes("multipart/form-data")) {
if (!route.incomingForm) {
throw new BadRequestError("Request cannot be processed without defined incoming form.");
}
ctx.data = await route.incomingForm.parse(req.req);
}
if (route.method === req.req.method) {
await route.handle(ctx);
return;
}
}
throw new NotFoundError("Route not found");
} catch (error) {
console.error(error);
if (error instanceof HttpError) {
res.sendJson(
{
error: {
name: error.name,
message: error.message || "Internal Server Error",
stack: error.stack || null
}
},
error.statusCode || 500
);
return;
}
const serializedError = serializeError(error);
res.sendJson(
{
error: {
...serializedError,
stack: process.env.NODE_ENV !== "production" ? serializedError.stack : undefined
}
},
500
);
}
}
export * from "./reports/parseExcel.handler.js";