urltomarkdown/node_modules/express-rate-limit/dist/index.cjs

262 lines
8.8 KiB
JavaScript
Raw Normal View History

2022-12-21 23:26:55 +00:00
"use strict";
2022-01-09 15:20:59 +00:00
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
2022-12-21 23:26:55 +00:00
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
return to;
2022-01-09 15:20:59 +00:00
};
2022-12-21 23:26:55 +00:00
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2022-01-09 15:20:59 +00:00
// source/index.ts
var source_exports = {};
__export(source_exports, {
2022-12-21 23:26:55 +00:00
MemoryStore: () => MemoryStore,
default: () => lib_default,
rateLimit: () => lib_default
2022-01-09 15:20:59 +00:00
});
2022-12-21 23:26:55 +00:00
module.exports = __toCommonJS(source_exports);
2022-01-09 15:20:59 +00:00
// source/memory-store.ts
var calculateNextResetTime = (windowMs) => {
const resetTime = new Date();
resetTime.setMilliseconds(resetTime.getMilliseconds() + windowMs);
return resetTime;
};
var MemoryStore = class {
init(options) {
this.windowMs = options.windowMs;
this.resetTime = calculateNextResetTime(this.windowMs);
this.hits = {};
2022-12-21 23:26:55 +00:00
this.interval = setInterval(async () => {
2022-01-09 15:20:59 +00:00
await this.resetAll();
}, this.windowMs);
2022-12-21 23:26:55 +00:00
if (this.interval.unref)
this.interval.unref();
2022-01-09 15:20:59 +00:00
}
async increment(key) {
2022-12-21 23:26:55 +00:00
var _a;
const totalHits = ((_a = this.hits[key]) != null ? _a : 0) + 1;
2022-01-09 15:20:59 +00:00
this.hits[key] = totalHits;
return {
totalHits,
resetTime: this.resetTime
};
}
async decrement(key) {
const current = this.hits[key];
2022-12-21 23:26:55 +00:00
if (current)
2022-01-09 15:20:59 +00:00
this.hits[key] = current - 1;
}
async resetKey(key) {
delete this.hits[key];
}
async resetAll() {
this.hits = {};
this.resetTime = calculateNextResetTime(this.windowMs);
}
2022-12-21 23:26:55 +00:00
shutdown() {
clearInterval(this.interval);
}
2022-01-09 15:20:59 +00:00
};
// source/lib.ts
var isLegacyStore = (store) => typeof store.incr === "function" && typeof store.increment !== "function";
var promisifyStore = (passedStore) => {
if (!isLegacyStore(passedStore)) {
return passedStore;
}
const legacyStore = passedStore;
class PromisifiedStore {
async increment(key) {
return new Promise((resolve, reject) => {
2022-12-21 23:26:55 +00:00
legacyStore.incr(
key,
(error, totalHits, resetTime) => {
if (error)
reject(error);
resolve({ totalHits, resetTime });
}
);
2022-01-09 15:20:59 +00:00
});
}
async decrement(key) {
2022-12-21 23:26:55 +00:00
return legacyStore.decrement(key);
2022-01-09 15:20:59 +00:00
}
async resetKey(key) {
2022-12-21 23:26:55 +00:00
return legacyStore.resetKey(key);
2022-01-09 15:20:59 +00:00
}
async resetAll() {
if (typeof legacyStore.resetAll === "function")
2022-12-21 23:26:55 +00:00
return legacyStore.resetAll();
2022-01-09 15:20:59 +00:00
}
}
return new PromisifiedStore();
};
var parseOptions = (passedOptions) => {
2022-12-21 23:26:55 +00:00
var _a, _b, _c;
const notUndefinedOptions = omitUndefinedOptions(passedOptions);
const config = {
2022-01-09 15:20:59 +00:00
windowMs: 60 * 1e3,
max: 5,
message: "Too many requests, please try again later.",
statusCode: 429,
2022-12-21 23:26:55 +00:00
legacyHeaders: (_a = passedOptions.headers) != null ? _a : true,
standardHeaders: (_b = passedOptions.draft_polli_ratelimit_headers) != null ? _b : false,
2022-01-09 15:20:59 +00:00
requestPropertyName: "rateLimit",
skipFailedRequests: false,
skipSuccessfulRequests: false,
requestWasSuccessful: (_request, response) => response.statusCode < 400,
skip: (_request, _response) => false,
2022-12-21 23:26:55 +00:00
keyGenerator(request, _response) {
2022-01-09 15:20:59 +00:00
if (!request.ip) {
2022-12-21 23:26:55 +00:00
console.error(
"WARN | `express-rate-limit` | `request.ip` is undefined. You can avoid this by providing a custom `keyGenerator` function, but it may be indicative of a larger issue."
);
2022-01-09 15:20:59 +00:00
}
return request.ip;
},
2022-12-21 23:26:55 +00:00
async handler(request, response, _next, _optionsUsed) {
response.status(config.statusCode);
const message = typeof config.message === "function" ? await config.message(
request,
response
) : config.message;
if (!response.writableEnded) {
response.send(message != null ? message : "Too many requests, please try again later.");
}
2022-01-09 15:20:59 +00:00
},
2022-12-21 23:26:55 +00:00
onLimitReached(_request, _response, _optionsUsed) {
2022-01-09 15:20:59 +00:00
},
2022-12-21 23:26:55 +00:00
...notUndefinedOptions,
store: promisifyStore((_c = notUndefinedOptions.store) != null ? _c : new MemoryStore())
2022-01-09 15:20:59 +00:00
};
2022-12-21 23:26:55 +00:00
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || typeof config.store.resetAll !== "undefined" && typeof config.store.resetAll !== "function" || typeof config.store.init !== "undefined" && typeof config.store.init !== "function") {
throw new TypeError(
"An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface."
);
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
return config;
2022-01-09 15:20:59 +00:00
};
var handleAsyncErrors = (fn) => async (request, response, next) => {
try {
await Promise.resolve(fn(request, response, next)).catch(next);
} catch (error) {
next(error);
}
};
var rateLimit = (passedOptions) => {
2022-12-21 23:26:55 +00:00
const options = parseOptions(passedOptions != null ? passedOptions : {});
2022-01-09 15:20:59 +00:00
if (typeof options.store.init === "function")
options.store.init(options);
2022-12-21 23:26:55 +00:00
const middleware = handleAsyncErrors(
async (request, response, next) => {
const skip = await options.skip(request, response);
if (skip) {
next();
return;
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
const augmentedRequest = request;
const key = await options.keyGenerator(request, response);
const { totalHits, resetTime } = await options.store.increment(key);
const retrieveQuota = typeof options.max === "function" ? options.max(request, response) : options.max;
const maxHits = await retrieveQuota;
augmentedRequest[options.requestPropertyName] = {
limit: maxHits,
current: totalHits,
remaining: Math.max(maxHits - totalHits, 0),
resetTime
};
if (options.legacyHeaders && !response.headersSent) {
response.setHeader("X-RateLimit-Limit", maxHits);
response.setHeader(
"X-RateLimit-Remaining",
augmentedRequest[options.requestPropertyName].remaining
);
if (resetTime instanceof Date) {
response.setHeader("Date", new Date().toUTCString());
response.setHeader(
"X-RateLimit-Reset",
Math.ceil(resetTime.getTime() / 1e3)
);
}
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
if (options.standardHeaders && !response.headersSent) {
response.setHeader("RateLimit-Limit", maxHits);
response.setHeader(
"RateLimit-Remaining",
augmentedRequest[options.requestPropertyName].remaining
);
if (resetTime) {
const deltaSeconds = Math.ceil(
(resetTime.getTime() - Date.now()) / 1e3
);
response.setHeader("RateLimit-Reset", Math.max(0, deltaSeconds));
2022-01-09 15:20:59 +00:00
}
}
2022-12-21 23:26:55 +00:00
if (options.skipFailedRequests || options.skipSuccessfulRequests) {
let decremented = false;
const decrementKey = async () => {
if (!decremented) {
await options.store.decrement(key);
decremented = true;
}
};
if (options.skipFailedRequests) {
response.on("finish", async () => {
if (!options.requestWasSuccessful(request, response))
await decrementKey();
});
response.on("close", async () => {
if (!response.writableEnded)
await decrementKey();
});
response.on("error", async () => {
2022-01-09 15:20:59 +00:00
await decrementKey();
2022-12-21 23:26:55 +00:00
});
}
if (options.skipSuccessfulRequests) {
response.on("finish", async () => {
if (options.requestWasSuccessful(request, response))
await decrementKey();
});
}
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
if (maxHits && totalHits === maxHits + 1) {
options.onLimitReached(request, response, options);
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
if (maxHits && totalHits > maxHits) {
if ((options.legacyHeaders || options.standardHeaders) && !response.headersSent) {
response.setHeader("Retry-After", Math.ceil(options.windowMs / 1e3));
}
options.handler(request, response, next, options);
return;
}
next();
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
);
2022-01-09 15:20:59 +00:00
middleware.resetKey = options.store.resetKey.bind(options.store);
return middleware;
};
2022-12-21 23:26:55 +00:00
var omitUndefinedOptions = (passedOptions) => {
const omittedOptions = {};
for (const k of Object.keys(passedOptions)) {
const key = k;
if (passedOptions[key] !== void 0) {
omittedOptions[key] = passedOptions[key];
}
}
return omittedOptions;
};
2022-01-09 15:20:59 +00:00
var lib_default = rateLimit;
2022-12-21 23:26:55 +00:00
module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;