express-rate-limiter-ts
Version:
A powerful, flexible and modern rate limiter middleware for Express.js written in TypeScript.
86 lines (85 loc) • 2.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryStore = void 0;
// In-memory store for rate limiting. Not recommended for production use in distributed systems.
class MemoryStore {
// Initialize the memory store with a window duration
constructor(windowMs) {
// Stores statistics for each route
this.stats = {};
this.windowMs = windowMs;
this.hits = new Map();
this.banned = new Map();
}
// Increment the request count for a key and return rate limit info
async incr(key) {
const now = Date.now();
let entry = this.hits.get(key);
if (!entry || entry.resetTime < now) {
entry = { count: 1, resetTime: now + this.windowMs };
}
else {
entry.count++;
}
this.hits.set(key, entry);
return {
current: entry.count,
remaining: Math.max(0, (this.windowMs - (entry.count - 1))),
resetTime: new Date(entry.resetTime),
exceeded: false,
};
}
// Get the current request count and reset time for a key
async get(key) {
return this.hits.get(key);
}
// Reset the request count for a key
async reset(key) {
this.hits.delete(key);
}
// Record statistics for a route (increment count and update last triggered time)
async recordStat(route) {
if (!this.stats[route]) {
this.stats[route] = { count: 1, lastTriggered: new Date() };
}
else {
this.stats[route].count++;
this.stats[route].lastTriggered = new Date();
}
}
// Get all route statistics
async getStats() {
return this.stats;
}
// Ban a key for a given number of seconds with a reason
async ban(key, seconds, reason) {
this.banned.set(key, { banExpiresAt: Date.now() + seconds * 1000, reason });
}
// Check if a key is currently banned
async isBanned(key) {
const ban = this.banned.get(key);
if (ban && ban.banExpiresAt > Date.now()) {
return { banned: true, banExpiresAt: new Date(ban.banExpiresAt), reason: ban.reason };
}
else if (ban) {
this.banned.delete(key);
}
return { banned: false };
}
// Get all currently banned keys with their expiration and reason
async getBanned() {
const result = {};
for (const [key, value] of this.banned.entries()) {
if (value.banExpiresAt > Date.now()) {
result[key] = { banExpiresAt: new Date(value.banExpiresAt), reason: value.reason };
}
}
return result;
}
// Remove ban and reset request count for a key
async unban(key) {
this.banned.delete(key);
this.hits.delete(key);
}
}
exports.MemoryStore = MemoryStore;