const MAX_JSON_BODY_BYTES = 16 * 1024;
export class RequestBodyTooLargeError extends Error {
    constructor() {
        super("JSON request body exceeds the 16KB limit.");
        this.name = "RequestBodyTooLargeError";
    }
}
export async function readJsonBody(request) {
    const chunks = [];
    let totalBytes = 0;
    for await (const chunk of request) {
        const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
        totalBytes += buffer.byteLength;
        if (totalBytes > MAX_JSON_BODY_BYTES)
            throw new RequestBodyTooLargeError();
        chunks.push(buffer);
    }
    if (chunks.length === 0)
        return {};
    return JSON.parse(Buffer.concat(chunks).toString("utf8"));
}
export function readBearerToken(request) {
    const authorization = request.headers.authorization;
    if (!authorization?.startsWith("Bearer "))
        return undefined;
    return authorization.slice("Bearer ".length);
}
export function readHeaderString(request, name) {
    const value = request.headers[name];
    return typeof value === "string" ? value : undefined;
}
export function readOrigin(request) {
    return readHeaderString(request, "origin");
}
export function isLoopbackHost(host) {
    return host === "127.0.0.1" || host === "::1" || host === "localhost";
}
export function readString(value, fallback) {
    return typeof value === "string" ? value : fallback;
}
export function readOptionalString(value) {
    return typeof value === "string" ? value : undefined;
}
export function readLimit(value) {
    if (!value)
        return undefined;
    const parsed = Number.parseInt(value, 10);
    if (!Number.isFinite(parsed))
        return undefined;
    return Math.max(1, Math.min(200, parsed));
}
export function readStringArray(value) {
    if (!Array.isArray(value))
        return undefined;
    const strings = value.filter((item) => typeof item === "string");
    return strings.length > 0 ? strings : undefined;
}
export function readBooleanMap(value) {
    if (typeof value !== "object" || value === null || Array.isArray(value)) {
        return undefined;
    }
    const entries = Object.entries(value).filter((entry) => typeof entry[1] === "boolean");
    return entries.length > 0 ? Object.fromEntries(entries) : undefined;
}
