109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
|
|
/**
|
||
|
|
* Configuration options for rate limiter
|
||
|
|
*/
|
||
|
|
export interface IRateLimitConfig {
|
||
|
|
/** Maximum tokens per period */
|
||
|
|
maxPerPeriod: number;
|
||
|
|
/** Time period in milliseconds */
|
||
|
|
periodMs: number;
|
||
|
|
/** Whether to apply per domain/key (vs globally) */
|
||
|
|
perKey: boolean;
|
||
|
|
/** Initial token count (defaults to max) */
|
||
|
|
initialTokens?: number;
|
||
|
|
/** Grace tokens to allow occasional bursts */
|
||
|
|
burstTokens?: number;
|
||
|
|
/** Apply global limit in addition to per-key limits */
|
||
|
|
useGlobalLimit?: boolean;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Rate limiter using token bucket algorithm
|
||
|
|
* Provides more sophisticated rate limiting with burst handling
|
||
|
|
*/
|
||
|
|
export declare class RateLimiter {
|
||
|
|
/** Rate limit configuration */
|
||
|
|
private config;
|
||
|
|
/** Token buckets per key */
|
||
|
|
private buckets;
|
||
|
|
/** Global bucket for non-keyed rate limiting */
|
||
|
|
private globalBucket;
|
||
|
|
/**
|
||
|
|
* Create a new rate limiter
|
||
|
|
* @param config Rate limiter configuration
|
||
|
|
*/
|
||
|
|
constructor(config: IRateLimitConfig);
|
||
|
|
/**
|
||
|
|
* Check if a request is allowed under rate limits
|
||
|
|
* @param key Key to check rate limit for (e.g. domain, user, IP)
|
||
|
|
* @param cost Token cost (defaults to 1)
|
||
|
|
* @returns Whether the request is allowed
|
||
|
|
*/
|
||
|
|
isAllowed(key?: string, cost?: number): boolean;
|
||
|
|
/**
|
||
|
|
* Check if a bucket has enough tokens and consume them
|
||
|
|
* @param bucket The token bucket to check
|
||
|
|
* @param cost Token cost
|
||
|
|
* @returns Whether tokens were consumed
|
||
|
|
*/
|
||
|
|
private checkBucket;
|
||
|
|
/**
|
||
|
|
* Consume tokens for a request (if available)
|
||
|
|
* @param key Key to consume tokens for
|
||
|
|
* @param cost Token cost (defaults to 1)
|
||
|
|
* @returns Whether tokens were consumed
|
||
|
|
*/
|
||
|
|
consume(key?: string, cost?: number): boolean;
|
||
|
|
/**
|
||
|
|
* Get the remaining tokens for a key
|
||
|
|
* @param key Key to check
|
||
|
|
* @returns Number of remaining tokens
|
||
|
|
*/
|
||
|
|
getRemainingTokens(key?: string): number;
|
||
|
|
/**
|
||
|
|
* Get stats for a specific key
|
||
|
|
* @param key Key to get stats for
|
||
|
|
* @returns Rate limit statistics
|
||
|
|
*/
|
||
|
|
getStats(key?: string): {
|
||
|
|
remaining: number;
|
||
|
|
limit: number;
|
||
|
|
resetIn: number;
|
||
|
|
allowed: number;
|
||
|
|
denied: number;
|
||
|
|
};
|
||
|
|
/**
|
||
|
|
* Get or create a token bucket for a key
|
||
|
|
* @param key The rate limit key
|
||
|
|
* @returns Token bucket
|
||
|
|
*/
|
||
|
|
private getBucket;
|
||
|
|
/**
|
||
|
|
* Refill tokens in a bucket based on elapsed time
|
||
|
|
* @param bucket Token bucket to refill
|
||
|
|
*/
|
||
|
|
private refillBucket;
|
||
|
|
/**
|
||
|
|
* Reset rate limits for a specific key
|
||
|
|
* @param key Key to reset
|
||
|
|
*/
|
||
|
|
reset(key?: string): void;
|
||
|
|
/**
|
||
|
|
* Reset all rate limiters
|
||
|
|
*/
|
||
|
|
resetAll(): void;
|
||
|
|
/**
|
||
|
|
* Cleanup old buckets to prevent memory leaks
|
||
|
|
* @param maxAge Maximum age in milliseconds
|
||
|
|
*/
|
||
|
|
cleanup(maxAge?: number): void;
|
||
|
|
/**
|
||
|
|
* Record an error for a key (e.g., IP address) and determine if blocking is needed
|
||
|
|
* RFC 5321 Section 4.5.4.1 suggests limiting errors to prevent abuse
|
||
|
|
*
|
||
|
|
* @param key Key to record error for (typically an IP address)
|
||
|
|
* @param errorWindow Time window for error tracking in ms (default: 5 minutes)
|
||
|
|
* @param errorThreshold Maximum errors before blocking (default: 10)
|
||
|
|
* @returns true if the key should be blocked due to excessive errors
|
||
|
|
*/
|
||
|
|
recordError(key: string, errorWindow?: number, errorThreshold?: number): boolean;
|
||
|
|
}
|