export interface RateLimitContext { key: string; ip?: string; userId?: string; userPlan?: string; endpoint?: string; method?: string; path?: string; headers?: Record; metadata?: Record; [key: string]: unknown; } export interface RateLimitCheckOptions { points?: number; context?: RateLimitContext; } export interface RateLimitResult { allowed: boolean; limit: number; remaining: number; reset: number; retryAfter?: number; appliedRuleId?: string; context?: RateLimitContext; } export interface RateLimitConfig { windowSize: number; maxRequests: number; keyPrefix?: string; skipSuccessfulRequests?: boolean; skipFailedRequests?: boolean; requestWasSuccessful?: (statusCode?: number) => boolean; onLimitReached?: (key: string, result: RateLimitResult, context?: RateLimitContext) => void | Promise; } export interface RateLimiter { check(key: string, options?: RateLimitCheckOptions): Promise; reset(key: string, context?: RateLimitContext): Promise; setLimit(key: string, limit: number, context?: RateLimitContext): Promise; getLimit(key: string, context?: RateLimitContext): Promise; getUsage(key: string, context?: RateLimitContext): Promise<{ used: number; remaining: number; reset: number; } | null>; } export interface RateLimitStorage { get(key: string): Promise; set(key: string, data: RateLimitData, ttl?: number): Promise; increment(key: string, amount?: number): Promise; delete(key: string): Promise; exists(key: string): Promise; expire(key: string, ttl: number): Promise; multi(): RateLimitTransaction; } export interface RateLimitTransaction { get(key: string): this; set(key: string, data: RateLimitData, ttl?: number): this; increment(key: string, amount?: number): this; delete(key: string): this; expire(key: string, ttl: number): this; exec(): Promise; } export interface RateLimitData { count: number; resetTime: number; window?: number; tokens?: number; lastRefill?: number; } export interface TokenBucketConfig extends RateLimitConfig { bucketSize: number; refillRate: number; tokensPerRequest?: number; } export interface SlidingWindowConfig extends RateLimitConfig { precision?: number; } export interface FixedWindowConfig extends RateLimitConfig { } export interface LeakyBucketConfig extends RateLimitConfig { bucketSize: number; leakRate: number; } export type RateLimitAlgorithm = 'token-bucket' | 'sliding-window' | 'fixed-window' | 'leaky-bucket'; export interface RateLimiterOptions { algorithm: RateLimitAlgorithm; config: RateLimitConfig; storage: RateLimitStorage; } export interface RateLimitRule { id?: string; description?: string; priority?: number; algorithm?: RateLimitAlgorithm; limit?: number; windowMs?: number; bucketSize?: number; refillRate?: number; tokensPerRequest?: number; precision?: number; leakRate?: number; keyPrefix?: string; onLimitReached?: (key: string, result: RateLimitResult, context?: RateLimitContext) => void | Promise; match: (context: RateLimitContext) => boolean | Promise; } export interface CreateRateLimiterOptions { algorithm?: RateLimitAlgorithm; limit: number; windowMs: number; bucketSize?: number; refillRate?: number; tokensPerRequest?: number; precision?: number; leakRate?: number; keyPrefix?: string; storage?: RateLimitStorage | RateLimitStorageOptions; skipOnError?: boolean; onLimitReached?: (key: string, result: RateLimitResult, context?: RateLimitContext) => void | Promise; customRules?: RateLimitRule[]; } export type RateLimitStorageOptions = 'memory' | { type: 'memory'; cleanupIntervalMs?: number; } | { type: 'redis'; client: unknown; keyPrefix?: string; } | { type: 'ioredis'; client: unknown; keyPrefix?: string; } | { type: 'database'; adapter: RateLimitDatabaseAdapter; keyPrefix?: string; }; export interface RateLimitDatabaseAdapter { get(key: string): Promise; set(key: string, data: RateLimitData, ttl?: number): Promise; increment(key: string, amount?: number): Promise; delete(key: string): Promise; expire(key: string, ttl: number): Promise; } export interface MiddlewareOptions { keyGenerator?: (req: any) => string | Promise; skip?: (req: any) => boolean | Promise; handler?: (req: any, res: any, result: RateLimitResult) => void | Promise; standardHeaders?: boolean; legacyHeaders?: boolean; requestPropertyName?: string; points?: number | ((req: any) => number | Promise); contextBuilder?: (req: any) => RateLimitContext | Promise; } export interface RateLimitHeaders { 'X-RateLimit-Limit'?: number; 'X-RateLimit-Remaining'?: number; 'X-RateLimit-Reset'?: number; 'X-Rate-Limit-Limit'?: number; 'X-Rate-Limit-Remaining'?: number; 'X-Rate-Limit-Reset'?: number; 'Retry-After'?: number; }