UNPKG

rate-limiter-flexible

Version:

Node.js atomic and non-atomic counters, rate limiting tools, protection from DoS and brute-force attacks at scale

83 lines (67 loc) 2.15 kB
const RateLimiterAbstract = require('./RateLimiterAbstract'); const RateLimiterInsuredAbstract = require('./RateLimiterInsuredAbstract'); module.exports = class RLWrapperTimeouts extends RateLimiterInsuredAbstract { constructor(opts= {}) { super(opts); this.limiter = opts.limiter; this.timeoutMs = opts.timeoutMs || 0; } get limiter() { return this._limiter; } set limiter(limiter) { if (!(limiter instanceof RateLimiterAbstract)) { throw new TypeError('limiter must be an instance of RateLimiterAbstract'); } this._limiter = limiter; if (!this.insuranceLimiter && limiter instanceof RateLimiterInsuredAbstract) { this.insuranceLimiter = limiter.insuranceLimiter; } } get timeoutMs() { return this._timeoutMs; } set timeoutMs(value) { if (typeof value !== 'number' || value < 0) { throw new TypeError('timeoutMs must be a non-negative number'); } this._timeoutMs = value; } _run(funcName, params) { return new Promise(async (resolve, reject) => { const timeout = setTimeout(() => { return reject(new Error('Operation timed out')); }, this.timeoutMs); await this.limiter[funcName](...params) .then((result) => { clearTimeout(timeout); resolve(result); }) .catch((err) => { clearTimeout(timeout); reject(err); }); }); } _consume(key, pointsToConsume = 1, options = {}) { return this._run('consume', [key, pointsToConsume, options]); } _penalty(key, points = 1, options = {}) { return this._run('penalty', [key, points, options]); } _reward(key, points = 1, options = {}) { return this._run('reward', [key, points, options]); } _get(key, options = {}) { return this._run('get', [key, options]); } _set(key, points, secDuration, options = {}) { return this._run('set', [key, points, secDuration, options]); } _block(key, secDuration, options = {}) { return this._run('block', [key, secDuration, options]); } _delete(key, options = {}) { return this._run('delete', [key, options]); } }