UNPKG

okta-mcp-server

Version:

Model Context Protocol (MCP) server for Okta API operations with support for bulk operations and caching

82 lines 3.03 kB
export class RateLimitSimulator { counters = new Map(); config; constructor(config = { limit: 600, window: 60, warningThreshold: 0.8, simulateExhaustion: true, exhaustionProbability: 0.01, }) { this.config = config; } check(key = 'default') { const now = Date.now(); const counter = this.counters.get(key) || { count: 0, resetTime: now + this.config.window * 1000, }; // Reset counter if window has passed if (now > counter.resetTime) { counter.count = 0; counter.resetTime = now + this.config.window * 1000; } // Simulate random exhaustion for testing if (this.config.simulateExhaustion && Math.random() < this.config.exhaustionProbability) { counter.count = this.config.limit; } counter.count++; this.counters.set(key, counter); const remaining = Math.max(0, this.config.limit - counter.count); const allowed = counter.count <= this.config.limit; const resetTimestamp = Math.floor(counter.resetTime / 1000); const headers = { 'X-Rate-Limit-Limit': String(this.config.limit), 'X-Rate-Limit-Remaining': String(remaining), 'X-Rate-Limit-Reset': String(resetTimestamp), }; // Add warning headers when approaching limit if (this.config.warningThreshold && counter.count / this.config.limit >= this.config.warningThreshold) { headers['X-Rate-Limit-Warning'] = `Approaching rate limit: ${remaining} requests remaining`; } // Add retry-after header when rate limited if (!allowed) { const retryAfter = Math.ceil((counter.resetTime - now) / 1000); headers['Retry-After'] = String(retryAfter); } return { allowed, remaining, limit: this.config.limit, reset: resetTimestamp, headers, }; } reset(key = 'default') { this.counters.delete(key); } resetAll() { this.counters.clear(); } // Simulate different rate limit scenarios simulateScenario(scenario, key = 'default') { const now = Date.now(); const resetTime = now + this.config.window * 1000; switch (scenario) { case 'normal': this.counters.set(key, { count: Math.floor(this.config.limit * 0.3), resetTime }); break; case 'warning': this.counters.set(key, { count: Math.floor(this.config.limit * 0.85), resetTime }); break; case 'exhausted': this.counters.set(key, { count: this.config.limit + 1, resetTime }); break; case 'recovering': this.counters.set(key, { count: this.config.limit - 10, resetTime }); break; } } } //# sourceMappingURL=rate-limiter.js.map