interface RateLimitData { count: number resetTime: number } const cache = new Map() export interface RateLimitConfig { windowMs: number maxRequests: number } const defaultConfig: RateLimitConfig = { windowMs: 60 * 1000, // 1 minute maxRequests: 100 } export function rateLimit( identifier: string, config: RateLimitConfig = defaultConfig ): { allowed: boolean; remaining: number; resetTime: number } { const now = Date.now() const windowStart = now - config.windowMs // Clean expired entries for (const [key, data] of cache.entries()) { if (data.resetTime < now) { cache.delete(key) } } let data = cache.get(identifier) if (!data || data.resetTime < now) { data = { count: 0, resetTime: now + config.windowMs } } data.count++ cache.set(identifier, data) const allowed = data.count <= config.maxRequests const remaining = Math.max(0, config.maxRequests - data.count) return { allowed, remaining, resetTime: data.resetTime } } export function getRateLimitHeaders(result: ReturnType) { return { 'X-RateLimit-Limit': '100', 'X-RateLimit-Remaining': result.remaining.toString(), 'X-RateLimit-Reset': new Date(result.resetTime).toISOString() } }