express-rate-limiter-ts
Version:
A powerful, flexible and modern rate limiter middleware for Express.js written in TypeScript.
101 lines (100 loc) • 3.64 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryStore = void 0;
class MemoryStore {
constructor(windowMs) {
this.stats = {};
this.windowMs = windowMs;
this.hits = new Map();
this.banned = new Map();
}
incr(key) {
return __awaiter(this, void 0, void 0, function* () {
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(key) {
return __awaiter(this, void 0, void 0, function* () {
return this.hits.get(key);
});
}
reset(key) {
return __awaiter(this, void 0, void 0, function* () {
this.hits.delete(key);
});
}
recordStat(route) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.stats[route]) {
this.stats[route] = { count: 1, lastTriggered: new Date() };
}
else {
this.stats[route].count++;
this.stats[route].lastTriggered = new Date();
}
});
}
getStats() {
return __awaiter(this, void 0, void 0, function* () {
return this.stats;
});
}
ban(key, seconds, reason) {
return __awaiter(this, void 0, void 0, function* () {
this.banned.set(key, { banExpiresAt: Date.now() + seconds * 1000, reason });
});
}
isBanned(key) {
return __awaiter(this, void 0, void 0, function* () {
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 };
});
}
getBanned() {
return __awaiter(this, void 0, void 0, function* () {
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;
});
}
unban(key) {
return __awaiter(this, void 0, void 0, function* () {
this.banned.delete(key);
this.hits.delete(key);
});
}
}
exports.MemoryStore = MemoryStore;