This commit is contained in:
Sergey Yarkov 2026-03-05 09:44:03 +03:00
parent cd0a702270
commit 37269afab1
4 changed files with 28 additions and 9 deletions

View File

@ -36,6 +36,19 @@ export class NotFoundError extends HttpError {
} }
} }
export class MethodNotAllowedError extends HttpError {
/**
* @param {string} [message]
*/
constructor(message) {
super({
name: "ERR_METHOD_NOT_ALLOWED",
message: message || "Method not allowed",
statusCode: 405
});
}
}
export class ServiceUnavailableError extends HttpError { export class ServiceUnavailableError extends HttpError {
/** /**
* @param {string} [message] * @param {string} [message]

View File

@ -13,10 +13,14 @@ export function createRequest(req) {
/** @type {Buffer[]} */ /** @type {Buffer[]} */
const body = []; const body = [];
this.req.on("data", (chunk) => body.push(chunk)); this.req.on("data", (chunk) => {
// TODO: make body size limit
body.push(chunk);
});
this.req.on("end", () => { this.req.on("end", () => {
try { try {
const parsedJson = JSON.parse(Buffer.concat(body).toString()); const buffer = Buffer.concat(body);
const parsedJson = JSON.parse(buffer.toString());
resolve(parsedJson); resolve(parsedJson);
} catch (error) { } catch (error) {
reject(error); reject(error);

View File

@ -1,6 +1,6 @@
import { serializeError } from "serialize-error"; import { serializeError } from "serialize-error";
import formidable from "formidable"; import formidable from "formidable";
import { BadRequestError, HttpError, NotFoundError } from "./errors.js"; import { BadRequestError, HttpError, MethodNotAllowedError, NotFoundError } from "./errors.js";
/** /**
* @param {URL} url * @param {URL} url
@ -15,10 +15,13 @@ export async function routeHandler(url, ctxStorage, routeMap) {
const { req, res } = ctx; const { req, res } = ctx;
try { try {
// TODO: create router based on URLPattern
if (url.pathname in routeMap) { if (url.pathname in routeMap) {
const route = routeMap[url.pathname]; const route = routeMap[url.pathname];
if (req.req.headers["content-type"] === "application/json") { if (route.method !== req.req.method) throw new MethodNotAllowedError();
if (req.req.headers["content-type"]?.includes("application/json")) {
ctx.data = await ctx.req.parseJson(); ctx.data = await ctx.req.parseJson();
} }
@ -30,10 +33,9 @@ export async function routeHandler(url, ctxStorage, routeMap) {
ctx.data = await formidable(route.incomingForm).parse(req.req); ctx.data = await formidable(route.incomingForm).parse(req.req);
} }
if (route.method === req.req.method) { await route.handle(ctx);
await route.handle(ctx);
return; return;
}
} }
throw new NotFoundError("Route not found"); throw new NotFoundError("Route not found");

View File

@ -39,7 +39,7 @@ export const routeMap = {
} }
}; };
createServer({ routeMap }).listen(SERVER_PORT, async () => { createServer({ routeMap, enableCors: true }).listen(SERVER_PORT, async () => {
console.log(`Service ${packageJson.name} is running at port ${SERVER_PORT}.`); console.log(`Service ${packageJson.name} is running at port ${SERVER_PORT}.`);
await db.connect().then(() => console.log("Database connected!")); await db.connect().then(() => console.log("Database connected!"));
}); });