Files
infohliadka/lib/rate-limiter.ts

61 lines
1.3 KiB
TypeScript

interface RateLimitData {
count: number
resetTime: number
}
const cache = new Map<string, RateLimitData>()
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<typeof rateLimit>) {
return {
'X-RateLimit-Limit': '100',
'X-RateLimit-Remaining': result.remaining.toString(),
'X-RateLimit-Reset': new Date(result.resetTime).toISOString()
}
}