import config from "../config.ts"; interface Bucket { count: number; resetAt: number; } const buckets = new Map(); let sweepCounter = 0; function maybeSweep() { if (++sweepCounter < 1000) return; sweepCounter = 0; const now = Date.now(); for (const [key, bucket] of buckets) { if (now > bucket.resetAt) buckets.delete(key); } } export function checkRateLimit( ip: string | null, maxRequests: number, windowMs: number, ): boolean { if (config.RATE_LIMIT_DISABLED || !ip) return true; const now = Date.now(); const bucket = buckets.get(ip); if (!bucket || now > bucket.resetAt) { buckets.set(ip, { count: 1, resetAt: now + windowMs }); maybeSweep(); return true; } if (bucket.count >= maxRequests) return false; bucket.count++; return true; } export function getClientIp( request: Request, server: Bun.Server | null, ): string | null { if (config.TRUSTED_PROXY) { return ( request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? null ); } return server?.requestIP(request)?.address ?? null; }