/**
* Simple rate limiting utility
* Tracks request counts per key with time windows
*/
interface RateLimitRecord {
count: number;
resetAt: number;
}
const rateLimiters = new Map<string, RateLimitRecord>();
/**
* Check if request is allowed within rate limit
* @param key - Unique key for rate limiting (e.g., 'late-api', 'openai')
* @param maxRequests - Maximum number of requests allowed
* @param windowMs - Time window in milliseconds
* @returns true if request is allowed, false if rate limit exceeded
*/
export const checkRateLimit = (
key: string,
maxRequests: number,
windowMs: number
): boolean => {
const now = Date.now();
const record = rateLimiters.get(key);
// No record or window expired - reset
if (!record || now > record.resetAt) {
rateLimiters.set(key, { count: 1, resetAt: now + windowMs });
return true;
}
// Rate limit exceeded
if (record.count >= maxRequests) {
return false;
}
// Increment counter
record.count++;
return true;
};
/**
* Get remaining requests and reset time
* @param key - Rate limit key
* @param maxRequests - Maximum requests allowed
* @returns Object with remaining count and reset time, or null if no record
*/
export const getRateLimitInfo = (
key: string,
maxRequests: number
): { remaining: number; resetIn: number } | null => {
const record = rateLimiters.get(key);
if (!record) {
return null;
}
const now = Date.now();
if (now > record.resetAt) {
return null;
}
return {
remaining: Math.max(0, maxRequests - record.count),
resetIn: Math.max(0, record.resetAt - now),
};
};