refactor http server

This commit is contained in:
Sergey Yarkov 2026-02-27 15:57:17 +03:00
parent 7955b224b0
commit ac7592344f
5 changed files with 44 additions and 22 deletions

9
index.d.ts vendored
View File

@ -11,8 +11,13 @@ declare global {
executorNames: string;
};
type HTTPRequest = {
parseJson: () => Promise<any>;
req: http.IncomingMessage | null;
};
type HTTPResponse = {
sendJson: (data: any, statusCode?: number = 200) => http.ServerResponse;
sendJson: (data: Record<string, unknown>, statusCode?: number = 200) => http.ServerResponse;
sendText: (text: string, statusCode?: number = 200) => http.ServerResponse;
res: http.ServerResponse | null;
};
@ -20,5 +25,5 @@ declare global {
type HTTPRoute = { method: "POST" | "GET"; handle: HTTPRouteHandler };
type HTTPRouteHandler = (ctx: HTTPContext) => Promise<void>;
type HTTPRouteMap = Record<string, HTTPRoute>;
type HTTPContext = { data: any; req: http.IncomingMessage; res: HTTPResponse };
type HTTPContext = { data: any; res: HTTPResponse; req: HTTPRequest };
}

View File

@ -4,6 +4,7 @@ import packageJson from "./package.json" with { type: "json" };
import { ctxAsyncLocalStorage } from "./context.js";
import db from "./db.js";
import response from "./response.js";
import request from "./request.js";
const SERVER_PORT = 3001;
@ -15,7 +16,8 @@ http
const url = new URL(`http://localhost:${SERVER_PORT}${req.url}`);
/** @type {HTTPContext} */
const ctx = { data: null, req, res: Object.create(response) };
const ctx = { data: null, req: Object.create(request), res: Object.create(response) };
ctx.req.req = req;
ctx.res.res = res;
ctxAsyncLocalStorage.run(ctx, () => routeHandler(url));
@ -23,6 +25,6 @@ http
console.error(error);
}
})
.listen(3001, () => {
.listen(SERVER_PORT, () => {
console.log(`Service ${packageJson.name} is running at port ${SERVER_PORT}.`);
});

19
request.js Normal file
View File

@ -0,0 +1,19 @@
/** @type {HTTPRequest} */
export default {
req: null,
async parseJson() {
return new Promise((resolve, reject) => {
let body = [];
this.req.on("data", (chunk) => body.push(chunk));
this.req.on("end", () => {
try {
const parsedJson = JSON.parse(Buffer.concat(body).toString());
resolve(parsedJson);
} catch (error) {
reject(error);
}
});
this.req.on("error", (err) => reject(err));
});
},
};

View File

@ -27,12 +27,19 @@ export async function routeHandler(url) {
try {
if (url.pathname in ROUTE_MAP) {
const route = ROUTE_MAP[url.pathname];
if (req.headers["content-type"] === "application/json") ctx.data = await getJsonData();
if (route.method === req.method) await route.handle(ctx);
if (req.req.headers["content-type"] === "application/json") {
ctx.data = await ctx.req.parseJson();
}
if (route.method === req.req.method) {
await route.handle(ctx);
}
return;
}
res.sendText("Указанный URL не имеет обработчика.", 200);
res.sendJson({ error: { message: "Указанный URL не имеет обработчика." } }, 404);
} catch (error) {
console.error(error);
res.sendJson(
@ -47,16 +54,4 @@ export async function routeHandler(url) {
}
}
function getJsonData() {
/** @type {HTTPContext} */
const { req } = ctxAsyncLocalStorage.getStore();
return new Promise((resolve, reject) => {
let body = [];
req.on("data", (chunk) => body.push(chunk));
req.on("end", () => resolve(JSON.parse(Buffer.concat(body).toString())));
req.on("error", (err) => reject(err));
});
}
export * from "./reports/parseExcel.handler.js";

View File

@ -1,14 +1,15 @@
import path from "node:path";
import xlsx from "xlsx";
import formidable from "formidable";
import db from "#root/db.js";
// import db from "#root/db.js";
/**
* Читает Excel файл отчетов и возвращает его в формате JSON
*
* @type {HTTPRouteHandler}
*/
export default async ({ req, res }) => {
export default async (ctx) => {
const { req, res } = ctx;
const sheetName = "Отчеты";
/** @type {{ markedReports: ReportModel[], reports: ReportModel[] }} */
@ -32,7 +33,7 @@ export default async ({ req, res }) => {
filter: ({ mimetype }) => mimetype && mimetype.includes("application/vnd.ms-excel"),
});
const [, files] = await form.parse(req);
const [, files] = await form.parse(req.req);
const excelFilePath = files?.report?.at(0)?.filepath;
if (excelFilePath) {