UNPKG

@developers-joyride/rate-limiter

Version:

A flexible rate limiting library with TypeScript support, Express middleware, and NestJS guard/interceptor capabilities

106 lines (105 loc) 3.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RateLimiterService = void 0; const mongodb_cache_provider_1 = require("../providers/mongodb-cache.provider"); const redis_cache_provider_1 = require("../providers/redis-cache.provider"); class RateLimiterService { constructor(config) { this.isInitialized = false; this.config = { cacheProvider: { type: config.cacheProvider.type, collectionName: config.cacheProvider.collectionName || "rateLimitingLogs", redisKeyPrefix: config.cacheProvider.redisKeyPrefix || "rate_limit:", mongoUrl: config.cacheProvider.mongoUrl, redisUrl: config.cacheProvider.redisUrl, }, keyGenerator: config.keyGenerator || ((req) => req.ip || req.connection.remoteAddress || "unknown"), errorMessage: config.errorMessage || "Too many requests, please try again later.", includeHeaders: config.includeHeaders !== undefined ? config.includeHeaders : true, statusCode: config.statusCode || 429, maxRequests: config.maxRequests, windowMs: config.windowMs, }; // Initialize the appropriate cache provider if (this.config.cacheProvider.type === "mongodb") { if (!this.config.cacheProvider.mongoUrl) { throw new Error("MongoDB URL is required when using MongoDB cache provider"); } this.cacheProvider = new mongodb_cache_provider_1.MongoDBCacheProvider(this.config.cacheProvider); } else if (this.config.cacheProvider.type === "redis") { if (!this.config.cacheProvider.redisUrl) { throw new Error("Redis URL is required when using Redis cache provider"); } this.cacheProvider = new redis_cache_provider_1.RedisCacheProvider(this.config.cacheProvider); } else { throw new Error(`Unsupported cache provider type: ${this.config.cacheProvider.type}`); } } /** * Initialize the cache provider */ async initialize() { if (this.isInitialized) { return; } try { await this.cacheProvider.initialize(); this.isInitialized = true; console.log("Rate limiter service initialized successfully"); } catch (error) { console.error("Failed to initialize rate limiter service:", error); throw error; } } /** * Check if a request is allowed based on rate limiting rules */ async checkLimit(req) { await this.ensureInitialized(); const key = this.config.keyGenerator(req); return await this.cacheProvider.checkLimit(key, this.config.maxRequests, this.config.windowMs); } /** * Reset rate limit for a specific key */ async resetLimit(key) { await this.ensureInitialized(); await this.cacheProvider.resetLimit(key); } /** * Get current rate limit info for a key */ async getLimitInfo(key) { await this.ensureInitialized(); return await this.cacheProvider.getLimitInfo(key); } /** * Ensure cache provider is initialized */ async ensureInitialized() { if (!this.isInitialized) { await this.initialize(); } } /** * Close the cache provider connection */ async close() { if (this.isInitialized) { await this.cacheProvider.close(); this.isInitialized = false; } } /** * Get the current configuration */ getConfig() { return { ...this.config }; } } exports.RateLimiterService = RateLimiterService;