From ac7592344f26a90342dfa9aefd07fd06821b774f Mon Sep 17 00:00:00 2001 From: sergeyyarkov Date: Fri, 27 Feb 2026 15:57:17 +0300 Subject: [PATCH] refactor http server --- index.d.ts | 9 +++++++-- index.js | 6 ++++-- request.js | 19 +++++++++++++++++++ router/index.js | 25 ++++++++++--------------- router/reports/parseExcel.handler.js | 7 ++++--- 5 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 request.js diff --git a/index.d.ts b/index.d.ts index 0068031..183ec43 100644 --- a/index.d.ts +++ b/index.d.ts @@ -11,8 +11,13 @@ declare global { executorNames: string; }; + type HTTPRequest = { + parseJson: () => Promise; + req: http.IncomingMessage | null; + }; + type HTTPResponse = { - sendJson: (data: any, statusCode?: number = 200) => http.ServerResponse; + sendJson: (data: Record, 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; type HTTPRouteMap = Record; - type HTTPContext = { data: any; req: http.IncomingMessage; res: HTTPResponse }; + type HTTPContext = { data: any; res: HTTPResponse; req: HTTPRequest }; } diff --git a/index.js b/index.js index 5b60ef8..7a291d9 100644 --- a/index.js +++ b/index.js @@ -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}.`); }); diff --git a/request.js b/request.js new file mode 100644 index 0000000..82580d9 --- /dev/null +++ b/request.js @@ -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)); + }); + }, +}; diff --git a/router/index.js b/router/index.js index 1d9a0db..d6b4735 100644 --- a/router/index.js +++ b/router/index.js @@ -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"; diff --git a/router/reports/parseExcel.handler.js b/router/reports/parseExcel.handler.js index cf0e5fb..1d76420 100644 --- a/router/reports/parseExcel.handler.js +++ b/router/reports/parseExcel.handler.js @@ -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) {