From c35b767b87a1652ecf3e964c78e4469d600a963f Mon Sep 17 00:00:00 2001
From: creations <creations@creations.works>
Date: Sun, 15 Jun 2025 17:59:18 -0400
Subject: [PATCH] move to #, move things to const, move types

---
 src/environment/constants/index.ts      |  3 ++
 src/environment/constants/server.ts     |  6 +++
 {config => src/environment}/index.ts    |  3 +-
 src/index.ts                            |  4 +-
 src/server.ts                           | 61 ++++++++++++++++++++-----
 tsconfig.json                           |  3 +-
 types/{config.d.ts => environment.d.ts} |  0
 types/routes.d.ts                       | 16 -------
 types/server.d.ts                       | 29 ++++++++++--
 9 files changed, 89 insertions(+), 36 deletions(-)
 create mode 100644 src/environment/constants/index.ts
 create mode 100644 src/environment/constants/server.ts
 rename {config => src/environment}/index.ts (91%)
 rename types/{config.d.ts => environment.d.ts} (100%)
 delete mode 100644 types/routes.d.ts

diff --git a/src/environment/constants/index.ts b/src/environment/constants/index.ts
new file mode 100644
index 0000000..76a630d
--- /dev/null
+++ b/src/environment/constants/index.ts
@@ -0,0 +1,3 @@
+export * from "./server";
+
+export const requiredVariables = ["HOST", "PORT"];
diff --git a/src/environment/constants/server.ts b/src/environment/constants/server.ts
new file mode 100644
index 0000000..aedf92e
--- /dev/null
+++ b/src/environment/constants/server.ts
@@ -0,0 +1,6 @@
+const reqLoggerIgnores = {
+	ignoredStartsWith: ["/public"],
+	ignoredPaths: ["/favicon.ico"],
+};
+
+export { reqLoggerIgnores };
diff --git a/config/index.ts b/src/environment/index.ts
similarity index 91%
rename from config/index.ts
rename to src/environment/index.ts
index 543cd38..f2dc805 100644
--- a/config/index.ts
+++ b/src/environment/index.ts
@@ -1,4 +1,5 @@
 import { echo } from "@atums/echo";
+import { requiredVariables } from "#environment/constants";
 
 const environment: Environment = {
 	port: Number.parseInt(process.env.PORT || "8080", 10),
@@ -8,8 +9,6 @@ const environment: Environment = {
 };
 
 function verifyRequiredVariables(): void {
-	const requiredVariables = ["HOST", "PORT"];
-
 	let hasError = false;
 
 	for (const key of requiredVariables) {
diff --git a/src/index.ts b/src/index.ts
index f095bcd..835ac45 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,7 +1,7 @@
 import { echo } from "@atums/echo";
 
-import { verifyRequiredVariables } from "@config";
-import { serverHandler } from "@server";
+import { verifyRequiredVariables } from "#environment";
+import { serverHandler } from "#server";
 
 async function main(): Promise<void> {
 	verifyRequiredVariables();
diff --git a/src/server.ts b/src/server.ts
index 192af15..3ef678f 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -1,13 +1,14 @@
 import { resolve } from "node:path";
 import { Echo, echo } from "@atums/echo";
-import { environment } from "@config";
-import { webSocketHandler } from "@websocket";
 import {
 	type BunFile,
 	FileSystemRouter,
 	type MatchedRoute,
 	type Server,
 } from "bun";
+import { environment } from "#environment";
+import { reqLoggerIgnores } from "#environment/constants";
+import { webSocketHandler } from "#websocket";
 
 class ServerHandler {
 	private router: FileSystemRouter;
@@ -105,12 +106,11 @@ class ServerHandler {
 	): void {
 		const pathname = new URL(request.url).pathname;
 
-		const ignoredStartsWith: string[] = ["/public"];
-		const ignoredPaths: string[] = ["/favicon.ico"];
-
 		if (
-			ignoredStartsWith.some((prefix) => pathname.startsWith(prefix)) ||
-			ignoredPaths.includes(pathname)
+			reqLoggerIgnores.ignoredStartsWith.some((prefix) =>
+				pathname.startsWith(prefix),
+			) ||
+			reqLoggerIgnores.ignoredPaths.includes(pathname)
 		) {
 			return;
 		}
@@ -168,7 +168,7 @@ class ServerHandler {
 		}
 
 		const match: MatchedRoute | null = this.router.match(request);
-		let requestBody: unknown = {};
+		let requestBody: unknown = null;
 
 		if (match) {
 			const { filePath, params, query } = match;
@@ -185,7 +185,7 @@ class ServerHandler {
 					actualContentType === "application/json"
 				) {
 					try {
-						requestBody = await request.json();
+						requestBody = (await request.json()) as Record<string, unknown>;
 					} catch {
 						requestBody = {};
 					}
@@ -194,10 +194,49 @@ class ServerHandler {
 					actualContentType === "multipart/form-data"
 				) {
 					try {
-						requestBody = await request.formData();
+						requestBody = (await request.formData()) as FormData;
+					} catch {
+						requestBody = new FormData();
+					}
+				} else if (
+					routeModule.routeDef.needsBody === "urlencoded" &&
+					actualContentType === "application/x-www-form-urlencoded"
+				) {
+					try {
+						const formData = await request.formData();
+						requestBody = Object.fromEntries(formData.entries()) as Record<
+							string,
+							string
+						>;
 					} catch {
 						requestBody = {};
 					}
+				} else if (
+					routeModule.routeDef.needsBody === "text" &&
+					actualContentType?.startsWith("text/")
+				) {
+					try {
+						requestBody = (await request.text()) as string;
+					} catch {
+						requestBody = "";
+					}
+				} else if (
+					routeModule.routeDef.needsBody === "raw" ||
+					routeModule.routeDef.needsBody === "buffer"
+				) {
+					try {
+						requestBody = (await request.arrayBuffer()) as ArrayBuffer;
+					} catch {
+						requestBody = new ArrayBuffer(0);
+					}
+				} else if (routeModule.routeDef.needsBody === "blob") {
+					try {
+						requestBody = (await request.blob()) as Blob;
+					} catch {
+						requestBody = new Blob();
+					}
+				} else if (routeModule.routeDef.needsBody) {
+					requestBody = null;
 				}
 
 				if (
@@ -250,7 +289,7 @@ class ServerHandler {
 					} else {
 						extendedRequest.params = params;
 						extendedRequest.query = query;
-						extendedRequest.body = requestBody;
+						extendedRequest.requestBody = requestBody;
 
 						response = await routeModule.handler(extendedRequest, server);
 
diff --git a/tsconfig.json b/tsconfig.json
index cf343ea..32b9468 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,8 +2,7 @@
 	"compilerOptions": {
 		"baseUrl": "./",
 		"paths": {
-			"@*": ["src/*"],
-			"@config": ["config/index.ts"]
+			"#*": ["src/*"]
 		},
 		"typeRoots": ["./types", "./node_modules/@types"],
 		"lib": ["ESNext", "DOM"],
diff --git a/types/config.d.ts b/types/environment.d.ts
similarity index 100%
rename from types/config.d.ts
rename to types/environment.d.ts
diff --git a/types/routes.d.ts b/types/routes.d.ts
deleted file mode 100644
index d2a8633..0000000
--- a/types/routes.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-type RouteDef = {
-	method: string | string[];
-	accepts: string | null | string[];
-	returns: string;
-	needsBody?: "multipart" | "json";
-};
-
-type handler = (
-	request: Request | ExtendedRequest,
-	server: Server,
-) => Promise<Response> | Response;
-
-type RouteModule = {
-	handler: handler;
-	routeDef: RouteDef;
-};
diff --git a/types/server.d.ts b/types/server.d.ts
index 85a4839..796cd74 100644
--- a/types/server.d.ts
+++ b/types/server.d.ts
@@ -1,9 +1,32 @@
-type Query = Record<string, string>;
-type Params = Record<string, string>;
+type QueryParams = Record<string, string>;
 
 interface ExtendedRequest extends Request {
 	startPerf: number;
 	query: Query;
 	params: Params;
-	body: unknown;
+	requestBody: unknown;
 }
+
+type RouteDef = {
+	method: string | string[];
+	accepts: string | null | string[];
+	returns: string;
+	needsBody?:
+		| "multipart"
+		| "json"
+		| "urlencoded"
+		| "text"
+		| "raw"
+		| "buffer"
+		| "blob";
+};
+
+type Handler = (
+	request: ExtendedRequest,
+	server: Server,
+) => Promise<Response> | Response;
+
+type RouteModule = {
+	handler: Handler;
+	routeDef: RouteDef;
+};
-- 
GitLab