move to #, move things to const, move types
All checks were successful
Code quality checks / biome (push) Successful in 23s

This commit is contained in:
creations 2025-06-15 17:59:18 -04:00
parent 908005dad5
commit c35b767b87
Signed by: creations
GPG key ID: 8F553AA4320FC711
9 changed files with 89 additions and 36 deletions

View file

@ -0,0 +1,3 @@
export * from "./server";
export const requiredVariables = ["HOST", "PORT"];

View file

@ -0,0 +1,6 @@
const reqLoggerIgnores = {
ignoredStartsWith: ["/public"],
ignoredPaths: ["/favicon.ico"],
};
export { reqLoggerIgnores };

View file

@ -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) {

View file

@ -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();

View file

@ -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);

View file

@ -2,8 +2,7 @@
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@*": ["src/*"],
"@config": ["config/index.ts"]
"#*": ["src/*"]
},
"typeRoots": ["./types", "./node_modules/@types"],
"lib": ["ESNext", "DOM"],

16
types/routes.d.ts vendored
View file

@ -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;
};

29
types/server.d.ts vendored
View file

@ -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;
};