move to #, move things to const, move types
All checks were successful
Code quality checks / biome (push) Successful in 23s
All checks were successful
Code quality checks / biome (push) Successful in 23s
This commit is contained in:
parent
908005dad5
commit
c35b767b87
9 changed files with 89 additions and 36 deletions
3
src/environment/constants/index.ts
Normal file
3
src/environment/constants/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export * from "./server";
|
||||||
|
|
||||||
|
export const requiredVariables = ["HOST", "PORT"];
|
6
src/environment/constants/server.ts
Normal file
6
src/environment/constants/server.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
const reqLoggerIgnores = {
|
||||||
|
ignoredStartsWith: ["/public"],
|
||||||
|
ignoredPaths: ["/favicon.ico"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export { reqLoggerIgnores };
|
|
@ -1,4 +1,5 @@
|
||||||
import { echo } from "@atums/echo";
|
import { echo } from "@atums/echo";
|
||||||
|
import { requiredVariables } from "#environment/constants";
|
||||||
|
|
||||||
const environment: Environment = {
|
const environment: Environment = {
|
||||||
port: Number.parseInt(process.env.PORT || "8080", 10),
|
port: Number.parseInt(process.env.PORT || "8080", 10),
|
||||||
|
@ -8,8 +9,6 @@ const environment: Environment = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function verifyRequiredVariables(): void {
|
function verifyRequiredVariables(): void {
|
||||||
const requiredVariables = ["HOST", "PORT"];
|
|
||||||
|
|
||||||
let hasError = false;
|
let hasError = false;
|
||||||
|
|
||||||
for (const key of requiredVariables) {
|
for (const key of requiredVariables) {
|
|
@ -1,7 +1,7 @@
|
||||||
import { echo } from "@atums/echo";
|
import { echo } from "@atums/echo";
|
||||||
|
|
||||||
import { verifyRequiredVariables } from "@config";
|
import { verifyRequiredVariables } from "#environment";
|
||||||
import { serverHandler } from "@server";
|
import { serverHandler } from "#server";
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
verifyRequiredVariables();
|
verifyRequiredVariables();
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import { resolve } from "node:path";
|
import { resolve } from "node:path";
|
||||||
import { Echo, echo } from "@atums/echo";
|
import { Echo, echo } from "@atums/echo";
|
||||||
import { environment } from "@config";
|
|
||||||
import { webSocketHandler } from "@websocket";
|
|
||||||
import {
|
import {
|
||||||
type BunFile,
|
type BunFile,
|
||||||
FileSystemRouter,
|
FileSystemRouter,
|
||||||
type MatchedRoute,
|
type MatchedRoute,
|
||||||
type Server,
|
type Server,
|
||||||
} from "bun";
|
} from "bun";
|
||||||
|
import { environment } from "#environment";
|
||||||
|
import { reqLoggerIgnores } from "#environment/constants";
|
||||||
|
import { webSocketHandler } from "#websocket";
|
||||||
|
|
||||||
class ServerHandler {
|
class ServerHandler {
|
||||||
private router: FileSystemRouter;
|
private router: FileSystemRouter;
|
||||||
|
@ -105,12 +106,11 @@ class ServerHandler {
|
||||||
): void {
|
): void {
|
||||||
const pathname = new URL(request.url).pathname;
|
const pathname = new URL(request.url).pathname;
|
||||||
|
|
||||||
const ignoredStartsWith: string[] = ["/public"];
|
|
||||||
const ignoredPaths: string[] = ["/favicon.ico"];
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ignoredStartsWith.some((prefix) => pathname.startsWith(prefix)) ||
|
reqLoggerIgnores.ignoredStartsWith.some((prefix) =>
|
||||||
ignoredPaths.includes(pathname)
|
pathname.startsWith(prefix),
|
||||||
|
) ||
|
||||||
|
reqLoggerIgnores.ignoredPaths.includes(pathname)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ class ServerHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
const match: MatchedRoute | null = this.router.match(request);
|
const match: MatchedRoute | null = this.router.match(request);
|
||||||
let requestBody: unknown = {};
|
let requestBody: unknown = null;
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
const { filePath, params, query } = match;
|
const { filePath, params, query } = match;
|
||||||
|
@ -185,7 +185,7 @@ class ServerHandler {
|
||||||
actualContentType === "application/json"
|
actualContentType === "application/json"
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
requestBody = await request.json();
|
requestBody = (await request.json()) as Record<string, unknown>;
|
||||||
} catch {
|
} catch {
|
||||||
requestBody = {};
|
requestBody = {};
|
||||||
}
|
}
|
||||||
|
@ -194,10 +194,49 @@ class ServerHandler {
|
||||||
actualContentType === "multipart/form-data"
|
actualContentType === "multipart/form-data"
|
||||||
) {
|
) {
|
||||||
try {
|
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 {
|
} catch {
|
||||||
requestBody = {};
|
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 (
|
if (
|
||||||
|
@ -250,7 +289,7 @@ class ServerHandler {
|
||||||
} else {
|
} else {
|
||||||
extendedRequest.params = params;
|
extendedRequest.params = params;
|
||||||
extendedRequest.query = query;
|
extendedRequest.query = query;
|
||||||
extendedRequest.body = requestBody;
|
extendedRequest.requestBody = requestBody;
|
||||||
|
|
||||||
response = await routeModule.handler(extendedRequest, server);
|
response = await routeModule.handler(extendedRequest, server);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@*": ["src/*"],
|
"#*": ["src/*"]
|
||||||
"@config": ["config/index.ts"]
|
|
||||||
},
|
},
|
||||||
"typeRoots": ["./types", "./node_modules/@types"],
|
"typeRoots": ["./types", "./node_modules/@types"],
|
||||||
"lib": ["ESNext", "DOM"],
|
"lib": ["ESNext", "DOM"],
|
||||||
|
|
0
types/config.d.ts → types/environment.d.ts
vendored
0
types/config.d.ts → types/environment.d.ts
vendored
16
types/routes.d.ts
vendored
16
types/routes.d.ts
vendored
|
@ -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
29
types/server.d.ts
vendored
|
@ -1,9 +1,32 @@
|
||||||
type Query = Record<string, string>;
|
type QueryParams = Record<string, string>;
|
||||||
type Params = Record<string, string>;
|
|
||||||
|
|
||||||
interface ExtendedRequest extends Request {
|
interface ExtendedRequest extends Request {
|
||||||
startPerf: number;
|
startPerf: number;
|
||||||
query: Query;
|
query: Query;
|
||||||
params: Params;
|
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;
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue