re-vibecode

This commit is contained in:
Debian
2026-03-30 13:57:39 +00:00
parent 09d76c044b
commit bb8497d33d
29 changed files with 1040 additions and 1622 deletions
+88 -47
View File
@@ -1,77 +1,118 @@
import { ZodError, type ZodSchema } from "zod";
import { config } from "./config";
import { HttpError, isHttpError } from "./errors";
import { buildResponseHeaders } from "./security";
import { HttpError } from "./errors";
export const jsonResponse = (request: Request, status: number, payload: unknown, init?: HeadersInit): Response =>
const allowedOrigin = (request: Request): string | null => {
const origin = request.headers.get("origin");
if (!origin) {
return null;
}
return config.appOrigins.includes(origin.toLowerCase()) ? origin : null;
};
const securityHeaders = (): Record<string, string> => ({
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"Referrer-Policy": "no-referrer"
});
const mergeHeaders = (request: Request, headers?: HeadersInit): Headers => {
const result = new Headers(headers);
const origin = allowedOrigin(request);
for (const [key, value] of Object.entries(securityHeaders())) {
result.set(key, value);
}
result.set("Vary", "Origin");
if (origin) {
result.set("Access-Control-Allow-Origin", origin);
result.set("Access-Control-Allow-Credentials", "true");
result.set("Access-Control-Allow-Headers", "Content-Type");
result.set("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,OPTIONS");
}
return result;
};
export const assertAllowedOrigin = (request: Request): void => {
const origin = request.headers.get("origin");
if (!origin) {
return;
}
if (!config.appOrigins.includes(origin.toLowerCase())) {
throw new HttpError(403, "Origin is not allowed.");
}
};
export const jsonResponse = (
request: Request,
status: number,
payload: unknown,
headers?: HeadersInit
): Response =>
new Response(JSON.stringify(payload), {
status,
headers: buildResponseHeaders(request, {
"Content-Type": "application/json; charset=utf-8",
...init
headers: mergeHeaders(request, {
"content-type": "application/json; charset=utf-8",
...headers
})
});
export const emptyResponse = (request: Request, status = 204, init?: HeadersInit): Response =>
export const emptyResponse = (request: Request, status = 204, headers?: HeadersInit): Response =>
new Response(null, {
status,
headers: buildResponseHeaders(request, init)
headers: mergeHeaders(request, headers)
});
export const fileResponse = (request: Request, body: Blob | Uint8Array, contentType: string, init?: HeadersInit): Response =>
new Response(body as BodyInit, {
status: 200,
headers: buildResponseHeaders(request, {
"Content-Type": contentType,
"Cache-Control": "private, max-age=300",
...init
})
});
export const optionsResponse = (request: Request): Response =>
emptyResponse(request, 204);
export const parseJson = async <T>(request: Request, schema: { parse(data: unknown): T }): Promise<T> => {
const contentType = request.headers.get("content-type") ?? "";
if (!contentType.toLowerCase().includes("application/json")) {
throw new HttpError(415, "Expected application/json request body.");
}
export const parseJson = async <T>(request: Request, schema: ZodSchema<T>): Promise<T> => {
let body: unknown;
let payload: unknown;
try {
payload = await request.json();
body = await request.json();
} catch {
throw new HttpError(400, "Malformed JSON request body.");
throw new HttpError(400, "Request body must be valid JSON.");
}
try {
return schema.parse(payload);
return schema.parse(body);
} catch (error) {
throw new HttpError(400, "Request validation failed.", { details: error });
if (error instanceof ZodError) {
throw new HttpError(400, error.issues[0]?.message ?? "Invalid request body.");
}
throw error;
}
};
export const errorResponse = (request: Request, error: unknown): Response => {
if (isHttpError(error)) {
const retryAfterMs =
typeof error.details === "object" &&
error.details !== null &&
"retryAfterMs" in error.details &&
typeof (error.details as { retryAfterMs?: unknown }).retryAfterMs === "number"
? Math.ceil(((error.details as { retryAfterMs: number }).retryAfterMs ?? 0) / 1000)
: undefined;
return jsonResponse(
request,
error.status,
{
error: error.expose ? error.message : "An internal server error occurred."
},
retryAfterMs ? { "Retry-After": String(retryAfterMs) } : undefined
);
if (error instanceof HttpError) {
return jsonResponse(request, error.status, {
error: {
message: error.message
}
});
}
if (config.nodeEnv !== "production") {
console.error(error);
if (error instanceof ZodError) {
return jsonResponse(request, 400, {
error: {
message: error.issues[0]?.message ?? "Invalid request."
}
});
}
console.error(error);
return jsonResponse(request, 500, {
error: "An internal server error occurred."
error: {
message: "Unexpected server error."
}
});
};