.
This commit is contained in:
327
qwen/nodejs/node_modules/express-rate-limit/changelog.md
generated
vendored
Normal file
327
qwen/nodejs/node_modules/express-rate-limit/changelog.md
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to
|
||||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [6.11.2](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.11.2)
|
||||
|
||||
Fixed:
|
||||
|
||||
- Restored `IncrementResponse ` TypeScript type (See
|
||||
[#397](https://github.com/express-rate-limit/express-rate-limit/pull/397))
|
||||
|
||||
## [6.11.1](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.11.1)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Check for prefixed keys when validating that the stores have single counted
|
||||
keys (See
|
||||
[#395](https://github.com/express-rate-limit/express-rate-limit/issues/395)).
|
||||
|
||||
## [6.11.0](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.11.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Support for retrieving the current hit count and reset time for a given key
|
||||
from a store (See
|
||||
[#390](https://github.com/express-rate-limit/express-rate-limit/issues/389)).
|
||||
|
||||
## [6.10.0](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.10.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Support for combined `RateLimit` header from the
|
||||
[RateLimit header fields for HTTP standardization draft](https://github.com/ietf-wg-httpapi/ratelimit-headers)
|
||||
adopted by the IETF. Enable by setting `standardHeaders: 'draft-7'`
|
||||
- New `standardHeaders: 'draft-6'` option, treated equivalent to
|
||||
`standardHeaders: true` from previous releases. (`true` and `false` are still
|
||||
supported.)
|
||||
- New `RateLimit-Policy` header added when `standardHeaders` is set to
|
||||
`'draft-6'`, `'draft-7'`, or `true`
|
||||
- Warning when using deprecated `draft_polli_ratelimit_headers` option
|
||||
- Warning when using deprecated `onLimitReached` option
|
||||
- Warning when `totalHits` value returned from Store is invalid
|
||||
|
||||
## [6.9.0](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.9.0)
|
||||
|
||||
### Added
|
||||
|
||||
- New validaion check for double-counted requests
|
||||
- Added help link to each ValidationError, directing users to the appropriate
|
||||
wiki page for more info
|
||||
|
||||
### Changed
|
||||
|
||||
- Miscaleanous documenation improvements
|
||||
|
||||
## [6.8.1](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.8.0) & [6.7.2](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.8.0)
|
||||
|
||||
### Changed
|
||||
|
||||
- Revert 6.7.1 change that bumped typescript from 5.x to 4.x and
|
||||
dts-bundle-generator from 8.x to 7.x (See
|
||||
[#360](https://github.com/express-rate-limit/express-rate-limit/issues/360))
|
||||
|
||||
## [6.8.0](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.8.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Added a set of validation checks that will log an error if failed. See
|
||||
https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes for
|
||||
a list of potential errors. Can be disabled by setting `validate: false` in
|
||||
the configuration. Automatically disables after the first request. (See
|
||||
[#358](https://github.com/express-rate-limit/express-rate-limit/issues/358))
|
||||
|
||||
## [6.7.1](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.7.1)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed compatibility with TypeScript's TypeScript new `node16` module
|
||||
resolution strategy (See
|
||||
[#355](https://github.com/express-rate-limit/express-rate-limit/issues/355))
|
||||
|
||||
### Changed
|
||||
|
||||
- Bumped development dependencies
|
||||
- This initially include bumping typescript from 4.x to 5.x and
|
||||
dts-bundle-generator from 7.x to 8.x
|
||||
- Added `node` 20 to list of versions the CI jobs run on.
|
||||
|
||||
No functional changes.
|
||||
|
||||
## [6.7.0](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v6.7.0)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated links to point to the new `express-rate-limit` organization on GitHub.
|
||||
- Added advertisement to `readme.md` for project sponsor
|
||||
[Zuplo](https://zuplo.link/express-rate-limit).
|
||||
- Updated to `typescript` version 5 and bumped other dependencies.
|
||||
- Dropped `node` 12, and added `node` 19 to the list of versions the CI jobs run
|
||||
on.
|
||||
|
||||
No functional changes.
|
||||
|
||||
## [6.6.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.6.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Added `shutdown` method to the Store interface and the MemoryStore.
|
||||
|
||||
## [6.5.2](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.5.2)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue with missing types in ESM monorepos.
|
||||
|
||||
## [6.5.1](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.5.1)
|
||||
|
||||
### Added
|
||||
|
||||
- The message option can now be a (sync/asynx) function that returns a value
|
||||
(#311)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated all dependencies
|
||||
|
||||
Note: 6.5.0 was not released due to CI automation issues.
|
||||
|
||||
## [6.4.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Adds Express 5 (`5.0.0-beta.1`) as a supported peer dependency (#304)
|
||||
|
||||
### Changed
|
||||
|
||||
- Tests are now run on Node 12, 14, 16 and 18 on CI (#305)
|
||||
- Updated all development dependencies (#306)
|
||||
|
||||
## [6.3.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
|
||||
|
||||
### Changed
|
||||
|
||||
- Changes the build target to es2019 so that ESBuild outputs code that can run
|
||||
with Node 12.
|
||||
- Changes the minimum required Node version to 12.9.0.
|
||||
|
||||
## [6.2.1](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.2.1)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use the default value for an option when `undefined` is passed to the rate
|
||||
limiter.
|
||||
|
||||
## [6.2.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.2.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Export the `MemoryStore`, so it can now be imported as a named import
|
||||
(`import { MemoryStore } from 'express-rate-limit'`).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Deprecate the `onLimitReached` option (this was supposed to be deprecated in
|
||||
v6.0.0 itself); developers should use a custom handler function that checks if
|
||||
the rate limit has been exceeded instead.
|
||||
|
||||
## [6.1.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.1.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Added a named export `rateLimit` in case the default import does not work.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Added a named export `default`, so Typescript CommonJS developers can
|
||||
default-import the library (`import rateLimit from 'express-rate-limit'`).
|
||||
|
||||
## [6.0.5](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.0.5)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use named imports for ExpressJS types so users do not need to enable the
|
||||
`esModuleInterop` flag in their Typescript compiler configuration.
|
||||
|
||||
## [6.0.4](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.0.4)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Upload the built package as a `.tgz` to GitHub releases.
|
||||
|
||||
### Changed
|
||||
|
||||
- Add ` main` and `module` fields to `package.json`. This helps tools such as
|
||||
ESLint that do not yet support the `exports` field.
|
||||
- Bumped the minimum node.js version in `package-lock.json` to match
|
||||
`package.json`
|
||||
|
||||
## [6.0.3](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.0.3)
|
||||
|
||||
### Changed
|
||||
|
||||
- Bumped minimum Node version from 12.9 to 14.5 in `package.json` because the
|
||||
transpiled output uses the nullish coalescing operator (`??`), which
|
||||
[isn't supported in node.js prior to 14.x](https://node.green/#ES2020-features--nullish-coalescing-operator-----).
|
||||
|
||||
## [6.0.2](https://github.com/nfriedly/express-rate-limit/releases/v6.0.2)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ensure CommonJS projects can import the module.
|
||||
|
||||
### Added
|
||||
|
||||
- Add additional tests that test:
|
||||
- importing the library in `js-cjs`, `js-esm`, `ts-cjs`, `ts-esm`
|
||||
environments.
|
||||
- usage of the library with external stores (`redis`, `mongo`, `memcached`,
|
||||
`precise`).
|
||||
|
||||
### Changed
|
||||
|
||||
- Use [`esbuild`](https://esbuild.github.io/) to generate ESM and CJS output.
|
||||
This reduces the size of the built package from 138 kb to 13kb and build time
|
||||
to 4 ms! :rocket:
|
||||
- Use [`dts-bundle-generator`](https://github.com/timocov/dts-bundle-generator)
|
||||
to generate a single Typescript declaration file.
|
||||
|
||||
## [6.0.1](https://github.com/nfriedly/express-rate-limit/releases/v6.0.1)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ensure CommonJS projects can import the module.
|
||||
|
||||
## [6.0.0](https://github.com/nfriedly/express-rate-limit/releases/v6.0.0)
|
||||
|
||||
### Added
|
||||
|
||||
- `express` 4.x as a peer dependency.
|
||||
- Better Typescript support (the library was rewritten in Typescript).
|
||||
- Export the package as both ESM and CJS.
|
||||
- Publish the built package (`.tgz` file) on GitHub releases as well as the npm
|
||||
registry.
|
||||
- Issue and PR templates.
|
||||
- A contributing guide.
|
||||
|
||||
### Changed
|
||||
|
||||
- Rename the `draft_polli_ratelimit_headers` option to `standardHeaders`.
|
||||
- Rename the `headers` option to `legacyHeaders`.
|
||||
- `Retry-After` header is now sent if either `legacyHeaders` or
|
||||
`standardHeaders` is set.
|
||||
- Allow `keyGenerator` to be an async function/return a promise.
|
||||
- Change the way custom stores are defined.
|
||||
- Add the `init` method for stores to set themselves up using options passed
|
||||
to the middleware.
|
||||
- Rename the `incr` method to `increment`.
|
||||
- Allow the `increment`, `decrement`, `resetKey` and `resetAll` methods to
|
||||
return a promise.
|
||||
- Old stores will automatically be promisified and used.
|
||||
- The package can now only be used with NodeJS version 12.9.0 or greater.
|
||||
- The `onLimitReached` configuration option is now deprecated. Replace it with a
|
||||
custom `handler` that checks the number of hits.
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove the deprecated `limiter.resetIp` method (use the `limiter.resetKey`
|
||||
method instead).
|
||||
- Remove the deprecated options `delayMs`, `delayAfter` (the delay functionality
|
||||
was moved to the
|
||||
[`express-slow-down`](https://github.com/nfriedly/express-slow-down) package)
|
||||
and `global` (use a key generator that returns a constant value).
|
||||
|
||||
## [5.x](https://github.com/nfriedly/express-rate-limit/releases/tag/v5.5.1)
|
||||
|
||||
### Added
|
||||
|
||||
- The middleware ~throws~ logs an error if `request.ip` is undefined.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removes typescript typings. (See
|
||||
[#138](https://github.com/nfriedly/express-rate-limit/issues/138))
|
||||
|
||||
## [4.x](https://github.com/nfriedly/express-rate-limit/releases/tag/v4.0.4)
|
||||
|
||||
### Changed
|
||||
|
||||
- The library no longer modifies the passed-in options object, it instead makes
|
||||
a clone of it.
|
||||
|
||||
## [3.x](https://github.com/nfriedly/express-rate-limit/releases/tag/v3.5.2)
|
||||
|
||||
### Added
|
||||
|
||||
- Simplifies the default `handler` function so that it no longer changes the
|
||||
response format. The default handler also uses
|
||||
[response.send](https://expressjs.com/en/4x/api.html#response.send).
|
||||
|
||||
### Changes
|
||||
|
||||
- `onLimitReached` now only triggers once for a client and window. However, the
|
||||
`handle` method is called for every blocked request.
|
||||
|
||||
### Removed
|
||||
|
||||
- The `delayAfter` and `delayMs` options; they were moved to the
|
||||
[express-slow-down](https://npmjs.org/package/express-slow-down) package.
|
||||
|
||||
## [2.x](https://github.com/nfriedly/express-rate-limit/releases/tag/v2.14.2)
|
||||
|
||||
### Added
|
||||
|
||||
- A `limiter.resetKey()` method to reset the hit counter for a particular client
|
||||
|
||||
### Changes
|
||||
|
||||
- The rate limiter now uses a less precise but less resource intensive method of
|
||||
tracking hits from a client.
|
||||
|
||||
### Removed
|
||||
|
||||
- The `global` option.
|
||||
674
qwen/nodejs/node_modules/express-rate-limit/dist/index.cjs
generated
vendored
Normal file
674
qwen/nodejs/node_modules/express-rate-limit/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,674 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
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 });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var __publicField = (obj, key, value) => {
|
||||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||
return value;
|
||||
};
|
||||
|
||||
// source/index.ts
|
||||
var source_exports = {};
|
||||
__export(source_exports, {
|
||||
MemoryStore: () => MemoryStore,
|
||||
default: () => lib_default,
|
||||
rateLimit: () => lib_default
|
||||
});
|
||||
module.exports = __toCommonJS(source_exports);
|
||||
|
||||
// source/headers.ts
|
||||
var getResetSeconds = (resetTime, windowMs) => {
|
||||
let resetSeconds = void 0;
|
||||
if (resetTime) {
|
||||
const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);
|
||||
resetSeconds = Math.max(0, deltaSeconds);
|
||||
} else if (windowMs) {
|
||||
resetSeconds = Math.ceil(windowMs / 1e3);
|
||||
}
|
||||
return resetSeconds;
|
||||
};
|
||||
var setLegacyHeaders = (response, info) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
response.setHeader("X-RateLimit-Limit", info.limit);
|
||||
response.setHeader("X-RateLimit-Remaining", info.remaining);
|
||||
if (info.resetTime instanceof Date) {
|
||||
response.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString());
|
||||
response.setHeader(
|
||||
"X-RateLimit-Reset",
|
||||
Math.ceil(info.resetTime.getTime() / 1e3)
|
||||
);
|
||||
}
|
||||
};
|
||||
var setDraft6Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(info.resetTime);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader("RateLimit-Limit", info.limit);
|
||||
response.setHeader("RateLimit-Remaining", info.remaining);
|
||||
if (resetSeconds)
|
||||
response.setHeader("RateLimit-Reset", resetSeconds);
|
||||
};
|
||||
var setDraft7Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader(
|
||||
"RateLimit",
|
||||
`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`
|
||||
);
|
||||
};
|
||||
var setRetryAfterHeader = (response, info, windowMs) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
||||
response.setHeader("Retry-After", resetSeconds);
|
||||
};
|
||||
|
||||
// source/validations.ts
|
||||
var import_node_net = require("net");
|
||||
var ValidationError = class extends Error {
|
||||
/**
|
||||
* The code must be a string, in snake case and all capital, that starts with
|
||||
* the substring `ERR_ERL_`.
|
||||
*
|
||||
* The message must be a string, starting with an uppercase character,
|
||||
* describing the issue in detail.
|
||||
*/
|
||||
constructor(code, message) {
|
||||
const url = `https://express-rate-limit.github.io/${code}/`;
|
||||
super(`${message} See ${url} for more information.`);
|
||||
__publicField(this, "name");
|
||||
__publicField(this, "code");
|
||||
__publicField(this, "help");
|
||||
this.name = this.constructor.name;
|
||||
this.code = code;
|
||||
this.help = url;
|
||||
}
|
||||
};
|
||||
var ChangeWarning = class extends ValidationError {
|
||||
};
|
||||
var _Validations = class _Validations {
|
||||
constructor(enabled) {
|
||||
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
||||
__publicField(this, "enabled");
|
||||
this.enabled = enabled;
|
||||
}
|
||||
enable() {
|
||||
this.enabled = true;
|
||||
}
|
||||
disable() {
|
||||
this.enabled = false;
|
||||
}
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip) {
|
||||
this.wrap(() => {
|
||||
if (ip === void 0) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNDEFINED_IP_ADDRESS",
|
||||
`An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.`
|
||||
);
|
||||
}
|
||||
if (!(0, import_node_net.isIP)(ip)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_IP_ADDRESS",
|
||||
`An invalid 'request.ip' (${ip}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request) {
|
||||
this.wrap(() => {
|
||||
if (request.app.get("trust proxy") === true) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_PERMISSIVE_TRUST_PROXY",
|
||||
`The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request) {
|
||||
this.wrap(() => {
|
||||
if (request.headers["x-forwarded-for"] && request.app.get("trust proxy") === false) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNEXPECTED_X_FORWARDED_FOR",
|
||||
`The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits) {
|
||||
this.wrap(() => {
|
||||
if (typeof hits !== "number" || hits < 1 || hits !== Math.round(hits)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_HITS",
|
||||
`The totalHits value returned from the store must be a positive integer, got ${hits}`
|
||||
// eslint-disable-line @typescript-eslint/restrict-template-expressions
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request, store, key) {
|
||||
this.wrap(() => {
|
||||
var _a;
|
||||
let storeKeys = _Validations.singleCountKeys.get(request);
|
||||
if (!storeKeys) {
|
||||
storeKeys = /* @__PURE__ */ new Map();
|
||||
_Validations.singleCountKeys.set(request, storeKeys);
|
||||
}
|
||||
const storeKey = store.localKeys ? store : store.constructor.name;
|
||||
let keys = storeKeys.get(storeKey);
|
||||
if (!keys) {
|
||||
keys = [];
|
||||
storeKeys.set(storeKey, keys);
|
||||
}
|
||||
const prefixedKey = `${(_a = store.prefix) != null ? _a : ""}${key}`;
|
||||
if (keys.includes(prefixedKey)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_DOUBLE_COUNT",
|
||||
`The hit count for ${key} was incremented more than once for a single request.`
|
||||
);
|
||||
}
|
||||
keys.push(prefixedKey);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` is changing in the next
|
||||
* major release.
|
||||
*
|
||||
* @param max {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
max(max) {
|
||||
this.wrap(() => {
|
||||
if (max === 0) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_MAX_ZERO",
|
||||
`Setting max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {boolean|undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers) {
|
||||
this.wrap(() => {
|
||||
if (draft_polli_ratelimit_headers) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS",
|
||||
`The draft_polli_ratelimit_headers configuration option is deprecated and will be removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and will be removed in the next
|
||||
* major release.
|
||||
*
|
||||
* @param onLimitReached {function|undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached) {
|
||||
this.wrap(() => {
|
||||
if (onLimitReached) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_ON_LIMIT_REACHED",
|
||||
`The onLimitReached configuration option is deprecated and will be removed in express-rate-limit v7.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime) {
|
||||
this.wrap(() => {
|
||||
if (!resetTime) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_HEADERS_NO_RESET",
|
||||
`standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
wrap(validation) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
validation.call(this);
|
||||
} catch (error) {
|
||||
if (error instanceof ChangeWarning)
|
||||
console.warn(error);
|
||||
else
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Maps the key used in a store for a certain request, and ensures that the
|
||||
* same key isn't used more than once per request.
|
||||
*
|
||||
* The store can be any one of the following:
|
||||
* - An instance, for stores like the MemoryStore where two instances do not
|
||||
* share state.
|
||||
* - A string (class name), for stores where multiple instances
|
||||
* typically share state, such as the Redis store.
|
||||
*/
|
||||
__publicField(_Validations, "singleCountKeys", /* @__PURE__ */ new WeakMap());
|
||||
var Validations = _Validations;
|
||||
|
||||
// source/memory-store.ts
|
||||
var calculateNextResetTime = (windowMs) => {
|
||||
const resetTime = /* @__PURE__ */ new Date();
|
||||
resetTime.setMilliseconds(resetTime.getMilliseconds() + windowMs);
|
||||
return resetTime;
|
||||
};
|
||||
var MemoryStore = class {
|
||||
constructor() {
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
__publicField(this, "windowMs");
|
||||
/**
|
||||
* The map that stores the number of hits for each client in memory.
|
||||
*/
|
||||
__publicField(this, "hits");
|
||||
/**
|
||||
* The time at which all hit counts will be reset.
|
||||
*/
|
||||
__publicField(this, "resetTime");
|
||||
/**
|
||||
* Reference to the active timer.
|
||||
*/
|
||||
__publicField(this, "interval");
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
__publicField(this, "localKeys", true);
|
||||
}
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options) {
|
||||
this.windowMs = options.windowMs;
|
||||
this.resetTime = calculateNextResetTime(this.windowMs);
|
||||
this.hits = {};
|
||||
this.interval = setInterval(async () => {
|
||||
await this.resetAll();
|
||||
}, this.windowMs);
|
||||
if (this.interval.unref)
|
||||
this.interval.unref();
|
||||
}
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async get(key) {
|
||||
if (this.hits[key] !== void 0)
|
||||
return {
|
||||
totalHits: this.hits[key],
|
||||
resetTime: this.resetTime
|
||||
};
|
||||
return void 0;
|
||||
}
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async increment(key) {
|
||||
var _a;
|
||||
const totalHits = ((_a = this.hits[key]) != null ? _a : 0) + 1;
|
||||
this.hits[key] = totalHits;
|
||||
return {
|
||||
totalHits,
|
||||
resetTime: this.resetTime
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async decrement(key) {
|
||||
const current = this.hits[key];
|
||||
if (current)
|
||||
this.hits[key] = current - 1;
|
||||
}
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetKey(key) {
|
||||
delete this.hits[key];
|
||||
}
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetAll() {
|
||||
this.hits = {};
|
||||
this.resetTime = calculateNextResetTime(this.windowMs);
|
||||
}
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown() {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
};
|
||||
|
||||
// source/lib.ts
|
||||
var isLegacyStore = (store) => (
|
||||
// Check that `incr` exists but `increment` does not - store authors might want
|
||||
// to keep both around for backwards compatibility.
|
||||
typeof store.incr === "function" && typeof store.increment !== "function"
|
||||
);
|
||||
var promisifyStore = (passedStore) => {
|
||||
if (!isLegacyStore(passedStore)) {
|
||||
return passedStore;
|
||||
}
|
||||
const legacyStore = passedStore;
|
||||
class PromisifiedStore {
|
||||
/* istanbul ignore next */
|
||||
async get(key) {
|
||||
return void 0;
|
||||
}
|
||||
async increment(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
legacyStore.incr(
|
||||
key,
|
||||
(error, totalHits, resetTime) => {
|
||||
if (error)
|
||||
reject(error);
|
||||
resolve({ totalHits, resetTime });
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
async decrement(key) {
|
||||
return legacyStore.decrement(key);
|
||||
}
|
||||
async resetKey(key) {
|
||||
return legacyStore.resetKey(key);
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
async resetAll() {
|
||||
if (typeof legacyStore.resetAll === "function")
|
||||
return legacyStore.resetAll();
|
||||
}
|
||||
}
|
||||
return new PromisifiedStore();
|
||||
};
|
||||
var getOptionsFromConfig = (config) => {
|
||||
const { validations, ...directlyPassableEntries } = config;
|
||||
return {
|
||||
...directlyPassableEntries,
|
||||
validate: validations.enabled
|
||||
};
|
||||
};
|
||||
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;
|
||||
};
|
||||
var parseOptions = (passedOptions) => {
|
||||
var _a, _b, _c, _d;
|
||||
const notUndefinedOptions = omitUndefinedOptions(passedOptions);
|
||||
const validations = new Validations((_a = notUndefinedOptions == null ? void 0 : notUndefinedOptions.validate) != null ? _a : true);
|
||||
validations.draftPolliHeaders(
|
||||
notUndefinedOptions.draft_polli_ratelimit_headers
|
||||
);
|
||||
validations.onLimitReached(notUndefinedOptions.onLimitReached);
|
||||
let standardHeaders = (_b = notUndefinedOptions.standardHeaders) != null ? _b : false;
|
||||
if (standardHeaders === true || standardHeaders === void 0 && notUndefinedOptions.draft_polli_ratelimit_headers) {
|
||||
standardHeaders = "draft-6";
|
||||
}
|
||||
const config = {
|
||||
windowMs: 60 * 1e3,
|
||||
max: 5,
|
||||
message: "Too many requests, please try again later.",
|
||||
statusCode: 429,
|
||||
legacyHeaders: (_c = passedOptions.headers) != null ? _c : true,
|
||||
requestPropertyName: "rateLimit",
|
||||
skipFailedRequests: false,
|
||||
skipSuccessfulRequests: false,
|
||||
requestWasSuccessful: (_request, response) => response.statusCode < 400,
|
||||
skip: (_request, _response) => false,
|
||||
keyGenerator(request, _response) {
|
||||
validations.ip(request.ip);
|
||||
validations.trustProxy(request);
|
||||
validations.xForwardedForHeader(request);
|
||||
return request.ip;
|
||||
},
|
||||
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);
|
||||
}
|
||||
},
|
||||
onLimitReached(_request, _response, _optionsUsed) {
|
||||
},
|
||||
// Allow the default options to be overriden by the options passed to the middleware.
|
||||
...notUndefinedOptions,
|
||||
// `standardHeaders` is resolved into a draft version above, use that.
|
||||
standardHeaders,
|
||||
// Note that this field is declared after the user's options are spread in,
|
||||
// so that this field doesn't get overriden with an un-promisified store!
|
||||
store: promisifyStore((_d = notUndefinedOptions.store) != null ? _d : new MemoryStore()),
|
||||
// Print an error to the console if a few known misconfigurations are detected.
|
||||
validations
|
||||
};
|
||||
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || config.store.resetAll !== void 0 && typeof config.store.resetAll !== "function" || config.store.init !== void 0 && 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."
|
||||
);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
var handleAsyncErrors = (fn) => async (request, response, next) => {
|
||||
try {
|
||||
await Promise.resolve(fn(request, response, next)).catch(next);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
var rateLimit = (passedOptions) => {
|
||||
var _a;
|
||||
const config = parseOptions(passedOptions != null ? passedOptions : {});
|
||||
const options = getOptionsFromConfig(config);
|
||||
if (typeof config.store.init === "function")
|
||||
config.store.init(options);
|
||||
const middleware = handleAsyncErrors(
|
||||
async (request, response, next) => {
|
||||
const skip = await config.skip(request, response);
|
||||
if (skip) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const augmentedRequest = request;
|
||||
const key = await config.keyGenerator(request, response);
|
||||
const { totalHits, resetTime } = await config.store.increment(key);
|
||||
config.validations.positiveHits(totalHits);
|
||||
config.validations.singleCount(request, config.store, key);
|
||||
const retrieveQuota = typeof config.max === "function" ? config.max(request, response) : config.max;
|
||||
const maxHits = await retrieveQuota;
|
||||
config.validations.max(maxHits);
|
||||
const info = {
|
||||
limit: maxHits,
|
||||
current: totalHits,
|
||||
remaining: Math.max(maxHits - totalHits, 0),
|
||||
resetTime
|
||||
};
|
||||
augmentedRequest[config.requestPropertyName] = info;
|
||||
if (config.legacyHeaders && !response.headersSent) {
|
||||
setLegacyHeaders(response, info);
|
||||
}
|
||||
if (config.standardHeaders && !response.headersSent) {
|
||||
if (config.standardHeaders === "draft-6") {
|
||||
setDraft6Headers(response, info, config.windowMs);
|
||||
} else if (config.standardHeaders === "draft-7") {
|
||||
config.validations.headersResetTime(info.resetTime);
|
||||
setDraft7Headers(response, info, config.windowMs);
|
||||
}
|
||||
}
|
||||
if (config.skipFailedRequests || config.skipSuccessfulRequests) {
|
||||
let decremented = false;
|
||||
const decrementKey = async () => {
|
||||
if (!decremented) {
|
||||
await config.store.decrement(key);
|
||||
decremented = true;
|
||||
}
|
||||
};
|
||||
if (config.skipFailedRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (!config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
response.on("close", async () => {
|
||||
if (!response.writableEnded)
|
||||
await decrementKey();
|
||||
});
|
||||
response.on("error", async () => {
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
if (config.skipSuccessfulRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
}
|
||||
if (maxHits && totalHits === maxHits + 1) {
|
||||
config.onLimitReached(request, response, options);
|
||||
}
|
||||
config.validations.disable();
|
||||
if (maxHits && totalHits > maxHits) {
|
||||
if (config.legacyHeaders || config.standardHeaders) {
|
||||
setRetryAfterHeader(response, info, config.windowMs);
|
||||
}
|
||||
config.handler(request, response, next, options);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
);
|
||||
middleware.resetKey = config.store.resetKey.bind(config.store);
|
||||
middleware.getKey = (_a = config.store.get) == null ? void 0 : _a.bind(
|
||||
config.store
|
||||
);
|
||||
return middleware;
|
||||
};
|
||||
var lib_default = rateLimit;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
MemoryStore,
|
||||
rateLimit
|
||||
});
|
||||
module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;
|
||||
410
qwen/nodejs/node_modules/express-rate-limit/dist/index.d.cts
generated
vendored
Normal file
410
qwen/nodejs/node_modules/express-rate-limit/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
// Generated by dts-bundle-generator v7.0.0
|
||||
|
||||
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
/**
|
||||
* Callback that fires when a client's hit counter is incremented.
|
||||
*
|
||||
* @param error {Error | undefined} - The error that occurred, if any.
|
||||
* @param totalHits {number} - The number of hits for that client so far.
|
||||
* @param resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type IncrementCallback = (error: Error | undefined, totalHits: number, resetTime: Date | undefined) => void;
|
||||
/**
|
||||
* Method (in the form of middleware) to generate/retrieve a value based on the
|
||||
* incoming request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
*
|
||||
* @returns {T} - The value needed.
|
||||
*/
|
||||
export type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param next {NextFunction} - The Express `next` function, can be called to skip responding.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Event callback that is triggered on a client's first request that exceeds the limit
|
||||
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
||||
* send a response.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Data returned from the `Store` when a client's hit counter is incremented.
|
||||
*
|
||||
* @property totalHits {number} - The number of hits for that client so far.
|
||||
* @property resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type ClientRateLimitInfo = {
|
||||
totalHits: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
export type IncrementResponse = ClientRateLimitInfo;
|
||||
/**
|
||||
* A modified Express request handler with the rate limit functions.
|
||||
*/
|
||||
export type RateLimitRequestHandler = RequestHandler & {
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
getKey?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*
|
||||
* @deprecated 6.x - Implement the `Store` interface instead.
|
||||
*/
|
||||
export type LegacyStore = {
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
* @param callback {IncrementCallback} - The callback to call once the counter is incremented.
|
||||
*/
|
||||
incr: (key: string, callback: IncrementCallback) => void;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => void;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*/
|
||||
export type Store = {
|
||||
/**
|
||||
* Method that initializes the store, and has access to the options passed to
|
||||
* the middleware too.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init?: (options: Options) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
||||
*/
|
||||
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => Promise<void> | void;
|
||||
/**
|
||||
* Method to shutdown the store, stop timers, and release all resources.
|
||||
*/
|
||||
shutdown?: () => Promise<void> | void;
|
||||
/**
|
||||
* Flag to indicate that keys incremented in one instance of this store can
|
||||
* not affect other instances. Typically false if a database is used, true for
|
||||
* MemoryStore.
|
||||
*
|
||||
* Used to help detect double-counting misconfigurations.
|
||||
*/
|
||||
localKeys?: boolean;
|
||||
/**
|
||||
* Optional value that the store prepends to keys
|
||||
*
|
||||
* Used by the double-count check to avoid false-positives when a key is counted twice, but with different prefixes
|
||||
*/
|
||||
prefix?: string;
|
||||
};
|
||||
export type DraftHeadersVersion = "draft-6" | "draft-7";
|
||||
/**
|
||||
* The configuration options for the rate limiter.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* How long we should remember the requests.
|
||||
*
|
||||
* Defaults to `60000` ms (= 1 minute).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* Defaults to `5`.
|
||||
*/
|
||||
max: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* The response body to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `'Too many requests, please try again later.'`
|
||||
*/
|
||||
message: any | ValueDeterminingMiddleware<any>;
|
||||
/**
|
||||
* The HTTP status code to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
|
||||
*/
|
||||
statusCode: number;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* Defaults to `true` (for backward compatibility).
|
||||
*/
|
||||
legacyHeaders: boolean;
|
||||
/**
|
||||
* Whether to enable support for the standardized rate limit headers (`RateLimit-*`).
|
||||
*
|
||||
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
||||
*/
|
||||
standardHeaders: boolean | DraftHeadersVersion;
|
||||
/**
|
||||
* The name of the property on the request object to store the rate limit info.
|
||||
*
|
||||
* Defaults to `rateLimit`.
|
||||
*/
|
||||
requestPropertyName: string;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a 4XX
|
||||
* or 5XX status.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipFailedRequests: boolean;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a
|
||||
* status code less than 400.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipSuccessfulRequests: boolean;
|
||||
/**
|
||||
* Method to generate custom identifiers for clients.
|
||||
*
|
||||
* By default, the client's IP address is used.
|
||||
*/
|
||||
keyGenerator: ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* By default, sends back the `statusCode` and `message` set via the options.
|
||||
*/
|
||||
handler: RateLimitExceededEventHandler;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client has
|
||||
* reached their rate limit, and will be rate limited on their next request.
|
||||
*
|
||||
* @deprecated 6.x - Please use a custom `handler` that checks the number of
|
||||
* hits instead.
|
||||
*/
|
||||
onLimitReached: RateLimitReachedEventHandler;
|
||||
/**
|
||||
* Method (in the form of middleware) to determine whether or not this request
|
||||
* counts towards a client's quota.
|
||||
*
|
||||
* By default, skips no requests.
|
||||
*/
|
||||
skip: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* Method to determine whether or not the request counts as 'succesful'. Used
|
||||
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
|
||||
*
|
||||
* By default, requests with a response status code less than 400 are considered
|
||||
* successful.
|
||||
*/
|
||||
requestWasSuccessful: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* The `Store` to use to store the hit count for each client.
|
||||
*
|
||||
* By default, the built-in `MemoryStore` will be used.
|
||||
*/
|
||||
store: Store | LegacyStore;
|
||||
/**
|
||||
* Whether or not the validation checks should run.
|
||||
*/
|
||||
validate: boolean;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `legacyHeaders`.
|
||||
*/
|
||||
headers?: boolean;
|
||||
/**
|
||||
* Whether to send `RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `standardHeaders`.
|
||||
*/
|
||||
draft_polli_ratelimit_headers?: boolean;
|
||||
};
|
||||
/**
|
||||
* The extended request object that includes information about the client's
|
||||
* rate limit.
|
||||
*/
|
||||
export type AugmentedRequest = Request & {
|
||||
[key: string]: RateLimitInfo;
|
||||
};
|
||||
/**
|
||||
* The rate limit related information for each client included in the
|
||||
* Express request object.
|
||||
*/
|
||||
export type RateLimitInfo = {
|
||||
limit: number;
|
||||
current: number;
|
||||
remaining: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
/**
|
||||
*
|
||||
* Create an instance of IP rate-limiting middleware for Express.
|
||||
*
|
||||
* @param passedOptions {Options} - Options to configure the rate limiter.
|
||||
*
|
||||
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
||||
/**
|
||||
* A `Store` that stores the hit count for each client in memory.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class MemoryStore implements Store {
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The map that stores the number of hits for each client in memory.
|
||||
*/
|
||||
hits: {
|
||||
[key: string]: number | undefined;
|
||||
};
|
||||
/**
|
||||
* The time at which all hit counts will be reset.
|
||||
*/
|
||||
resetTime: Date;
|
||||
/**
|
||||
* Reference to the active timer.
|
||||
*/
|
||||
interval?: NodeJS.Timer;
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
localKeys: boolean;
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options: Options): void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get(key: string): Promise<ClientRateLimitInfo | undefined>;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
increment(key: string): Promise<ClientRateLimitInfo>;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
decrement(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetKey(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetAll(): Promise<void>;
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown(): void;
|
||||
}
|
||||
|
||||
export {
|
||||
rateLimit as default,
|
||||
};
|
||||
|
||||
export {};
|
||||
410
qwen/nodejs/node_modules/express-rate-limit/dist/index.d.mts
generated
vendored
Normal file
410
qwen/nodejs/node_modules/express-rate-limit/dist/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
// Generated by dts-bundle-generator v7.0.0
|
||||
|
||||
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
/**
|
||||
* Callback that fires when a client's hit counter is incremented.
|
||||
*
|
||||
* @param error {Error | undefined} - The error that occurred, if any.
|
||||
* @param totalHits {number} - The number of hits for that client so far.
|
||||
* @param resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type IncrementCallback = (error: Error | undefined, totalHits: number, resetTime: Date | undefined) => void;
|
||||
/**
|
||||
* Method (in the form of middleware) to generate/retrieve a value based on the
|
||||
* incoming request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
*
|
||||
* @returns {T} - The value needed.
|
||||
*/
|
||||
export type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param next {NextFunction} - The Express `next` function, can be called to skip responding.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Event callback that is triggered on a client's first request that exceeds the limit
|
||||
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
||||
* send a response.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Data returned from the `Store` when a client's hit counter is incremented.
|
||||
*
|
||||
* @property totalHits {number} - The number of hits for that client so far.
|
||||
* @property resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type ClientRateLimitInfo = {
|
||||
totalHits: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
export type IncrementResponse = ClientRateLimitInfo;
|
||||
/**
|
||||
* A modified Express request handler with the rate limit functions.
|
||||
*/
|
||||
export type RateLimitRequestHandler = RequestHandler & {
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
getKey?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*
|
||||
* @deprecated 6.x - Implement the `Store` interface instead.
|
||||
*/
|
||||
export type LegacyStore = {
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
* @param callback {IncrementCallback} - The callback to call once the counter is incremented.
|
||||
*/
|
||||
incr: (key: string, callback: IncrementCallback) => void;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => void;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*/
|
||||
export type Store = {
|
||||
/**
|
||||
* Method that initializes the store, and has access to the options passed to
|
||||
* the middleware too.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init?: (options: Options) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
||||
*/
|
||||
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => Promise<void> | void;
|
||||
/**
|
||||
* Method to shutdown the store, stop timers, and release all resources.
|
||||
*/
|
||||
shutdown?: () => Promise<void> | void;
|
||||
/**
|
||||
* Flag to indicate that keys incremented in one instance of this store can
|
||||
* not affect other instances. Typically false if a database is used, true for
|
||||
* MemoryStore.
|
||||
*
|
||||
* Used to help detect double-counting misconfigurations.
|
||||
*/
|
||||
localKeys?: boolean;
|
||||
/**
|
||||
* Optional value that the store prepends to keys
|
||||
*
|
||||
* Used by the double-count check to avoid false-positives when a key is counted twice, but with different prefixes
|
||||
*/
|
||||
prefix?: string;
|
||||
};
|
||||
export type DraftHeadersVersion = "draft-6" | "draft-7";
|
||||
/**
|
||||
* The configuration options for the rate limiter.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* How long we should remember the requests.
|
||||
*
|
||||
* Defaults to `60000` ms (= 1 minute).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* Defaults to `5`.
|
||||
*/
|
||||
max: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* The response body to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `'Too many requests, please try again later.'`
|
||||
*/
|
||||
message: any | ValueDeterminingMiddleware<any>;
|
||||
/**
|
||||
* The HTTP status code to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
|
||||
*/
|
||||
statusCode: number;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* Defaults to `true` (for backward compatibility).
|
||||
*/
|
||||
legacyHeaders: boolean;
|
||||
/**
|
||||
* Whether to enable support for the standardized rate limit headers (`RateLimit-*`).
|
||||
*
|
||||
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
||||
*/
|
||||
standardHeaders: boolean | DraftHeadersVersion;
|
||||
/**
|
||||
* The name of the property on the request object to store the rate limit info.
|
||||
*
|
||||
* Defaults to `rateLimit`.
|
||||
*/
|
||||
requestPropertyName: string;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a 4XX
|
||||
* or 5XX status.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipFailedRequests: boolean;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a
|
||||
* status code less than 400.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipSuccessfulRequests: boolean;
|
||||
/**
|
||||
* Method to generate custom identifiers for clients.
|
||||
*
|
||||
* By default, the client's IP address is used.
|
||||
*/
|
||||
keyGenerator: ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* By default, sends back the `statusCode` and `message` set via the options.
|
||||
*/
|
||||
handler: RateLimitExceededEventHandler;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client has
|
||||
* reached their rate limit, and will be rate limited on their next request.
|
||||
*
|
||||
* @deprecated 6.x - Please use a custom `handler` that checks the number of
|
||||
* hits instead.
|
||||
*/
|
||||
onLimitReached: RateLimitReachedEventHandler;
|
||||
/**
|
||||
* Method (in the form of middleware) to determine whether or not this request
|
||||
* counts towards a client's quota.
|
||||
*
|
||||
* By default, skips no requests.
|
||||
*/
|
||||
skip: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* Method to determine whether or not the request counts as 'succesful'. Used
|
||||
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
|
||||
*
|
||||
* By default, requests with a response status code less than 400 are considered
|
||||
* successful.
|
||||
*/
|
||||
requestWasSuccessful: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* The `Store` to use to store the hit count for each client.
|
||||
*
|
||||
* By default, the built-in `MemoryStore` will be used.
|
||||
*/
|
||||
store: Store | LegacyStore;
|
||||
/**
|
||||
* Whether or not the validation checks should run.
|
||||
*/
|
||||
validate: boolean;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `legacyHeaders`.
|
||||
*/
|
||||
headers?: boolean;
|
||||
/**
|
||||
* Whether to send `RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `standardHeaders`.
|
||||
*/
|
||||
draft_polli_ratelimit_headers?: boolean;
|
||||
};
|
||||
/**
|
||||
* The extended request object that includes information about the client's
|
||||
* rate limit.
|
||||
*/
|
||||
export type AugmentedRequest = Request & {
|
||||
[key: string]: RateLimitInfo;
|
||||
};
|
||||
/**
|
||||
* The rate limit related information for each client included in the
|
||||
* Express request object.
|
||||
*/
|
||||
export type RateLimitInfo = {
|
||||
limit: number;
|
||||
current: number;
|
||||
remaining: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
/**
|
||||
*
|
||||
* Create an instance of IP rate-limiting middleware for Express.
|
||||
*
|
||||
* @param passedOptions {Options} - Options to configure the rate limiter.
|
||||
*
|
||||
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
||||
/**
|
||||
* A `Store` that stores the hit count for each client in memory.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class MemoryStore implements Store {
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The map that stores the number of hits for each client in memory.
|
||||
*/
|
||||
hits: {
|
||||
[key: string]: number | undefined;
|
||||
};
|
||||
/**
|
||||
* The time at which all hit counts will be reset.
|
||||
*/
|
||||
resetTime: Date;
|
||||
/**
|
||||
* Reference to the active timer.
|
||||
*/
|
||||
interval?: NodeJS.Timer;
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
localKeys: boolean;
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options: Options): void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get(key: string): Promise<ClientRateLimitInfo | undefined>;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
increment(key: string): Promise<ClientRateLimitInfo>;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
decrement(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetKey(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetAll(): Promise<void>;
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown(): void;
|
||||
}
|
||||
|
||||
export {
|
||||
rateLimit as default,
|
||||
};
|
||||
|
||||
export {};
|
||||
410
qwen/nodejs/node_modules/express-rate-limit/dist/index.d.ts
generated
vendored
Normal file
410
qwen/nodejs/node_modules/express-rate-limit/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
// Generated by dts-bundle-generator v7.0.0
|
||||
|
||||
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
/**
|
||||
* Callback that fires when a client's hit counter is incremented.
|
||||
*
|
||||
* @param error {Error | undefined} - The error that occurred, if any.
|
||||
* @param totalHits {number} - The number of hits for that client so far.
|
||||
* @param resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type IncrementCallback = (error: Error | undefined, totalHits: number, resetTime: Date | undefined) => void;
|
||||
/**
|
||||
* Method (in the form of middleware) to generate/retrieve a value based on the
|
||||
* incoming request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
*
|
||||
* @returns {T} - The value needed.
|
||||
*/
|
||||
export type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param next {NextFunction} - The Express `next` function, can be called to skip responding.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Event callback that is triggered on a client's first request that exceeds the limit
|
||||
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
||||
* send a response.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Data returned from the `Store` when a client's hit counter is incremented.
|
||||
*
|
||||
* @property totalHits {number} - The number of hits for that client so far.
|
||||
* @property resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type ClientRateLimitInfo = {
|
||||
totalHits: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
export type IncrementResponse = ClientRateLimitInfo;
|
||||
/**
|
||||
* A modified Express request handler with the rate limit functions.
|
||||
*/
|
||||
export type RateLimitRequestHandler = RequestHandler & {
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
getKey?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*
|
||||
* @deprecated 6.x - Implement the `Store` interface instead.
|
||||
*/
|
||||
export type LegacyStore = {
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
* @param callback {IncrementCallback} - The callback to call once the counter is incremented.
|
||||
*/
|
||||
incr: (key: string, callback: IncrementCallback) => void;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => void;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*/
|
||||
export type Store = {
|
||||
/**
|
||||
* Method that initializes the store, and has access to the options passed to
|
||||
* the middleware too.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init?: (options: Options) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
||||
*/
|
||||
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => Promise<void> | void;
|
||||
/**
|
||||
* Method to shutdown the store, stop timers, and release all resources.
|
||||
*/
|
||||
shutdown?: () => Promise<void> | void;
|
||||
/**
|
||||
* Flag to indicate that keys incremented in one instance of this store can
|
||||
* not affect other instances. Typically false if a database is used, true for
|
||||
* MemoryStore.
|
||||
*
|
||||
* Used to help detect double-counting misconfigurations.
|
||||
*/
|
||||
localKeys?: boolean;
|
||||
/**
|
||||
* Optional value that the store prepends to keys
|
||||
*
|
||||
* Used by the double-count check to avoid false-positives when a key is counted twice, but with different prefixes
|
||||
*/
|
||||
prefix?: string;
|
||||
};
|
||||
export type DraftHeadersVersion = "draft-6" | "draft-7";
|
||||
/**
|
||||
* The configuration options for the rate limiter.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* How long we should remember the requests.
|
||||
*
|
||||
* Defaults to `60000` ms (= 1 minute).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* Defaults to `5`.
|
||||
*/
|
||||
max: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* The response body to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `'Too many requests, please try again later.'`
|
||||
*/
|
||||
message: any | ValueDeterminingMiddleware<any>;
|
||||
/**
|
||||
* The HTTP status code to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
|
||||
*/
|
||||
statusCode: number;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* Defaults to `true` (for backward compatibility).
|
||||
*/
|
||||
legacyHeaders: boolean;
|
||||
/**
|
||||
* Whether to enable support for the standardized rate limit headers (`RateLimit-*`).
|
||||
*
|
||||
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
||||
*/
|
||||
standardHeaders: boolean | DraftHeadersVersion;
|
||||
/**
|
||||
* The name of the property on the request object to store the rate limit info.
|
||||
*
|
||||
* Defaults to `rateLimit`.
|
||||
*/
|
||||
requestPropertyName: string;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a 4XX
|
||||
* or 5XX status.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipFailedRequests: boolean;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a
|
||||
* status code less than 400.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipSuccessfulRequests: boolean;
|
||||
/**
|
||||
* Method to generate custom identifiers for clients.
|
||||
*
|
||||
* By default, the client's IP address is used.
|
||||
*/
|
||||
keyGenerator: ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* By default, sends back the `statusCode` and `message` set via the options.
|
||||
*/
|
||||
handler: RateLimitExceededEventHandler;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client has
|
||||
* reached their rate limit, and will be rate limited on their next request.
|
||||
*
|
||||
* @deprecated 6.x - Please use a custom `handler` that checks the number of
|
||||
* hits instead.
|
||||
*/
|
||||
onLimitReached: RateLimitReachedEventHandler;
|
||||
/**
|
||||
* Method (in the form of middleware) to determine whether or not this request
|
||||
* counts towards a client's quota.
|
||||
*
|
||||
* By default, skips no requests.
|
||||
*/
|
||||
skip: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* Method to determine whether or not the request counts as 'succesful'. Used
|
||||
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
|
||||
*
|
||||
* By default, requests with a response status code less than 400 are considered
|
||||
* successful.
|
||||
*/
|
||||
requestWasSuccessful: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* The `Store` to use to store the hit count for each client.
|
||||
*
|
||||
* By default, the built-in `MemoryStore` will be used.
|
||||
*/
|
||||
store: Store | LegacyStore;
|
||||
/**
|
||||
* Whether or not the validation checks should run.
|
||||
*/
|
||||
validate: boolean;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `legacyHeaders`.
|
||||
*/
|
||||
headers?: boolean;
|
||||
/**
|
||||
* Whether to send `RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `standardHeaders`.
|
||||
*/
|
||||
draft_polli_ratelimit_headers?: boolean;
|
||||
};
|
||||
/**
|
||||
* The extended request object that includes information about the client's
|
||||
* rate limit.
|
||||
*/
|
||||
export type AugmentedRequest = Request & {
|
||||
[key: string]: RateLimitInfo;
|
||||
};
|
||||
/**
|
||||
* The rate limit related information for each client included in the
|
||||
* Express request object.
|
||||
*/
|
||||
export type RateLimitInfo = {
|
||||
limit: number;
|
||||
current: number;
|
||||
remaining: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
/**
|
||||
*
|
||||
* Create an instance of IP rate-limiting middleware for Express.
|
||||
*
|
||||
* @param passedOptions {Options} - Options to configure the rate limiter.
|
||||
*
|
||||
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
||||
/**
|
||||
* A `Store` that stores the hit count for each client in memory.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class MemoryStore implements Store {
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The map that stores the number of hits for each client in memory.
|
||||
*/
|
||||
hits: {
|
||||
[key: string]: number | undefined;
|
||||
};
|
||||
/**
|
||||
* The time at which all hit counts will be reset.
|
||||
*/
|
||||
resetTime: Date;
|
||||
/**
|
||||
* Reference to the active timer.
|
||||
*/
|
||||
interval?: NodeJS.Timer;
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
localKeys: boolean;
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options: Options): void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get(key: string): Promise<ClientRateLimitInfo | undefined>;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
increment(key: string): Promise<ClientRateLimitInfo>;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
decrement(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetKey(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetAll(): Promise<void>;
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown(): void;
|
||||
}
|
||||
|
||||
export {
|
||||
rateLimit as default,
|
||||
};
|
||||
|
||||
export {};
|
||||
647
qwen/nodejs/node_modules/express-rate-limit/dist/index.mjs
generated
vendored
Normal file
647
qwen/nodejs/node_modules/express-rate-limit/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,647 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||
var __publicField = (obj, key, value) => {
|
||||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||
return value;
|
||||
};
|
||||
|
||||
// source/headers.ts
|
||||
var getResetSeconds = (resetTime, windowMs) => {
|
||||
let resetSeconds = void 0;
|
||||
if (resetTime) {
|
||||
const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);
|
||||
resetSeconds = Math.max(0, deltaSeconds);
|
||||
} else if (windowMs) {
|
||||
resetSeconds = Math.ceil(windowMs / 1e3);
|
||||
}
|
||||
return resetSeconds;
|
||||
};
|
||||
var setLegacyHeaders = (response, info) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
response.setHeader("X-RateLimit-Limit", info.limit);
|
||||
response.setHeader("X-RateLimit-Remaining", info.remaining);
|
||||
if (info.resetTime instanceof Date) {
|
||||
response.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString());
|
||||
response.setHeader(
|
||||
"X-RateLimit-Reset",
|
||||
Math.ceil(info.resetTime.getTime() / 1e3)
|
||||
);
|
||||
}
|
||||
};
|
||||
var setDraft6Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(info.resetTime);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader("RateLimit-Limit", info.limit);
|
||||
response.setHeader("RateLimit-Remaining", info.remaining);
|
||||
if (resetSeconds)
|
||||
response.setHeader("RateLimit-Reset", resetSeconds);
|
||||
};
|
||||
var setDraft7Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader(
|
||||
"RateLimit",
|
||||
`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`
|
||||
);
|
||||
};
|
||||
var setRetryAfterHeader = (response, info, windowMs) => {
|
||||
if (response.headersSent)
|
||||
return;
|
||||
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
||||
response.setHeader("Retry-After", resetSeconds);
|
||||
};
|
||||
|
||||
// source/validations.ts
|
||||
import { isIP } from "net";
|
||||
var ValidationError = class extends Error {
|
||||
/**
|
||||
* The code must be a string, in snake case and all capital, that starts with
|
||||
* the substring `ERR_ERL_`.
|
||||
*
|
||||
* The message must be a string, starting with an uppercase character,
|
||||
* describing the issue in detail.
|
||||
*/
|
||||
constructor(code, message) {
|
||||
const url = `https://express-rate-limit.github.io/${code}/`;
|
||||
super(`${message} See ${url} for more information.`);
|
||||
__publicField(this, "name");
|
||||
__publicField(this, "code");
|
||||
__publicField(this, "help");
|
||||
this.name = this.constructor.name;
|
||||
this.code = code;
|
||||
this.help = url;
|
||||
}
|
||||
};
|
||||
var ChangeWarning = class extends ValidationError {
|
||||
};
|
||||
var _Validations = class _Validations {
|
||||
constructor(enabled) {
|
||||
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
||||
__publicField(this, "enabled");
|
||||
this.enabled = enabled;
|
||||
}
|
||||
enable() {
|
||||
this.enabled = true;
|
||||
}
|
||||
disable() {
|
||||
this.enabled = false;
|
||||
}
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip) {
|
||||
this.wrap(() => {
|
||||
if (ip === void 0) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNDEFINED_IP_ADDRESS",
|
||||
`An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.`
|
||||
);
|
||||
}
|
||||
if (!isIP(ip)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_IP_ADDRESS",
|
||||
`An invalid 'request.ip' (${ip}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request) {
|
||||
this.wrap(() => {
|
||||
if (request.app.get("trust proxy") === true) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_PERMISSIVE_TRUST_PROXY",
|
||||
`The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request) {
|
||||
this.wrap(() => {
|
||||
if (request.headers["x-forwarded-for"] && request.app.get("trust proxy") === false) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNEXPECTED_X_FORWARDED_FOR",
|
||||
`The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits) {
|
||||
this.wrap(() => {
|
||||
if (typeof hits !== "number" || hits < 1 || hits !== Math.round(hits)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_HITS",
|
||||
`The totalHits value returned from the store must be a positive integer, got ${hits}`
|
||||
// eslint-disable-line @typescript-eslint/restrict-template-expressions
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request, store, key) {
|
||||
this.wrap(() => {
|
||||
var _a;
|
||||
let storeKeys = _Validations.singleCountKeys.get(request);
|
||||
if (!storeKeys) {
|
||||
storeKeys = /* @__PURE__ */ new Map();
|
||||
_Validations.singleCountKeys.set(request, storeKeys);
|
||||
}
|
||||
const storeKey = store.localKeys ? store : store.constructor.name;
|
||||
let keys = storeKeys.get(storeKey);
|
||||
if (!keys) {
|
||||
keys = [];
|
||||
storeKeys.set(storeKey, keys);
|
||||
}
|
||||
const prefixedKey = `${(_a = store.prefix) != null ? _a : ""}${key}`;
|
||||
if (keys.includes(prefixedKey)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_DOUBLE_COUNT",
|
||||
`The hit count for ${key} was incremented more than once for a single request.`
|
||||
);
|
||||
}
|
||||
keys.push(prefixedKey);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` is changing in the next
|
||||
* major release.
|
||||
*
|
||||
* @param max {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
max(max) {
|
||||
this.wrap(() => {
|
||||
if (max === 0) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_MAX_ZERO",
|
||||
`Setting max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {boolean|undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers) {
|
||||
this.wrap(() => {
|
||||
if (draft_polli_ratelimit_headers) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS",
|
||||
`The draft_polli_ratelimit_headers configuration option is deprecated and will be removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and will be removed in the next
|
||||
* major release.
|
||||
*
|
||||
* @param onLimitReached {function|undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached) {
|
||||
this.wrap(() => {
|
||||
if (onLimitReached) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_ON_LIMIT_REACHED",
|
||||
`The onLimitReached configuration option is deprecated and will be removed in express-rate-limit v7.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime) {
|
||||
this.wrap(() => {
|
||||
if (!resetTime) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_HEADERS_NO_RESET",
|
||||
`standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
wrap(validation) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
validation.call(this);
|
||||
} catch (error) {
|
||||
if (error instanceof ChangeWarning)
|
||||
console.warn(error);
|
||||
else
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Maps the key used in a store for a certain request, and ensures that the
|
||||
* same key isn't used more than once per request.
|
||||
*
|
||||
* The store can be any one of the following:
|
||||
* - An instance, for stores like the MemoryStore where two instances do not
|
||||
* share state.
|
||||
* - A string (class name), for stores where multiple instances
|
||||
* typically share state, such as the Redis store.
|
||||
*/
|
||||
__publicField(_Validations, "singleCountKeys", /* @__PURE__ */ new WeakMap());
|
||||
var Validations = _Validations;
|
||||
|
||||
// source/memory-store.ts
|
||||
var calculateNextResetTime = (windowMs) => {
|
||||
const resetTime = /* @__PURE__ */ new Date();
|
||||
resetTime.setMilliseconds(resetTime.getMilliseconds() + windowMs);
|
||||
return resetTime;
|
||||
};
|
||||
var MemoryStore = class {
|
||||
constructor() {
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
__publicField(this, "windowMs");
|
||||
/**
|
||||
* The map that stores the number of hits for each client in memory.
|
||||
*/
|
||||
__publicField(this, "hits");
|
||||
/**
|
||||
* The time at which all hit counts will be reset.
|
||||
*/
|
||||
__publicField(this, "resetTime");
|
||||
/**
|
||||
* Reference to the active timer.
|
||||
*/
|
||||
__publicField(this, "interval");
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
__publicField(this, "localKeys", true);
|
||||
}
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options) {
|
||||
this.windowMs = options.windowMs;
|
||||
this.resetTime = calculateNextResetTime(this.windowMs);
|
||||
this.hits = {};
|
||||
this.interval = setInterval(async () => {
|
||||
await this.resetAll();
|
||||
}, this.windowMs);
|
||||
if (this.interval.unref)
|
||||
this.interval.unref();
|
||||
}
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async get(key) {
|
||||
if (this.hits[key] !== void 0)
|
||||
return {
|
||||
totalHits: this.hits[key],
|
||||
resetTime: this.resetTime
|
||||
};
|
||||
return void 0;
|
||||
}
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async increment(key) {
|
||||
var _a;
|
||||
const totalHits = ((_a = this.hits[key]) != null ? _a : 0) + 1;
|
||||
this.hits[key] = totalHits;
|
||||
return {
|
||||
totalHits,
|
||||
resetTime: this.resetTime
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async decrement(key) {
|
||||
const current = this.hits[key];
|
||||
if (current)
|
||||
this.hits[key] = current - 1;
|
||||
}
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetKey(key) {
|
||||
delete this.hits[key];
|
||||
}
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetAll() {
|
||||
this.hits = {};
|
||||
this.resetTime = calculateNextResetTime(this.windowMs);
|
||||
}
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown() {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
};
|
||||
|
||||
// source/lib.ts
|
||||
var isLegacyStore = (store) => (
|
||||
// Check that `incr` exists but `increment` does not - store authors might want
|
||||
// to keep both around for backwards compatibility.
|
||||
typeof store.incr === "function" && typeof store.increment !== "function"
|
||||
);
|
||||
var promisifyStore = (passedStore) => {
|
||||
if (!isLegacyStore(passedStore)) {
|
||||
return passedStore;
|
||||
}
|
||||
const legacyStore = passedStore;
|
||||
class PromisifiedStore {
|
||||
/* istanbul ignore next */
|
||||
async get(key) {
|
||||
return void 0;
|
||||
}
|
||||
async increment(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
legacyStore.incr(
|
||||
key,
|
||||
(error, totalHits, resetTime) => {
|
||||
if (error)
|
||||
reject(error);
|
||||
resolve({ totalHits, resetTime });
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
async decrement(key) {
|
||||
return legacyStore.decrement(key);
|
||||
}
|
||||
async resetKey(key) {
|
||||
return legacyStore.resetKey(key);
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
async resetAll() {
|
||||
if (typeof legacyStore.resetAll === "function")
|
||||
return legacyStore.resetAll();
|
||||
}
|
||||
}
|
||||
return new PromisifiedStore();
|
||||
};
|
||||
var getOptionsFromConfig = (config) => {
|
||||
const { validations, ...directlyPassableEntries } = config;
|
||||
return {
|
||||
...directlyPassableEntries,
|
||||
validate: validations.enabled
|
||||
};
|
||||
};
|
||||
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;
|
||||
};
|
||||
var parseOptions = (passedOptions) => {
|
||||
var _a, _b, _c, _d;
|
||||
const notUndefinedOptions = omitUndefinedOptions(passedOptions);
|
||||
const validations = new Validations((_a = notUndefinedOptions == null ? void 0 : notUndefinedOptions.validate) != null ? _a : true);
|
||||
validations.draftPolliHeaders(
|
||||
notUndefinedOptions.draft_polli_ratelimit_headers
|
||||
);
|
||||
validations.onLimitReached(notUndefinedOptions.onLimitReached);
|
||||
let standardHeaders = (_b = notUndefinedOptions.standardHeaders) != null ? _b : false;
|
||||
if (standardHeaders === true || standardHeaders === void 0 && notUndefinedOptions.draft_polli_ratelimit_headers) {
|
||||
standardHeaders = "draft-6";
|
||||
}
|
||||
const config = {
|
||||
windowMs: 60 * 1e3,
|
||||
max: 5,
|
||||
message: "Too many requests, please try again later.",
|
||||
statusCode: 429,
|
||||
legacyHeaders: (_c = passedOptions.headers) != null ? _c : true,
|
||||
requestPropertyName: "rateLimit",
|
||||
skipFailedRequests: false,
|
||||
skipSuccessfulRequests: false,
|
||||
requestWasSuccessful: (_request, response) => response.statusCode < 400,
|
||||
skip: (_request, _response) => false,
|
||||
keyGenerator(request, _response) {
|
||||
validations.ip(request.ip);
|
||||
validations.trustProxy(request);
|
||||
validations.xForwardedForHeader(request);
|
||||
return request.ip;
|
||||
},
|
||||
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);
|
||||
}
|
||||
},
|
||||
onLimitReached(_request, _response, _optionsUsed) {
|
||||
},
|
||||
// Allow the default options to be overriden by the options passed to the middleware.
|
||||
...notUndefinedOptions,
|
||||
// `standardHeaders` is resolved into a draft version above, use that.
|
||||
standardHeaders,
|
||||
// Note that this field is declared after the user's options are spread in,
|
||||
// so that this field doesn't get overriden with an un-promisified store!
|
||||
store: promisifyStore((_d = notUndefinedOptions.store) != null ? _d : new MemoryStore()),
|
||||
// Print an error to the console if a few known misconfigurations are detected.
|
||||
validations
|
||||
};
|
||||
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || config.store.resetAll !== void 0 && typeof config.store.resetAll !== "function" || config.store.init !== void 0 && 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."
|
||||
);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
var handleAsyncErrors = (fn) => async (request, response, next) => {
|
||||
try {
|
||||
await Promise.resolve(fn(request, response, next)).catch(next);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
var rateLimit = (passedOptions) => {
|
||||
var _a;
|
||||
const config = parseOptions(passedOptions != null ? passedOptions : {});
|
||||
const options = getOptionsFromConfig(config);
|
||||
if (typeof config.store.init === "function")
|
||||
config.store.init(options);
|
||||
const middleware = handleAsyncErrors(
|
||||
async (request, response, next) => {
|
||||
const skip = await config.skip(request, response);
|
||||
if (skip) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const augmentedRequest = request;
|
||||
const key = await config.keyGenerator(request, response);
|
||||
const { totalHits, resetTime } = await config.store.increment(key);
|
||||
config.validations.positiveHits(totalHits);
|
||||
config.validations.singleCount(request, config.store, key);
|
||||
const retrieveQuota = typeof config.max === "function" ? config.max(request, response) : config.max;
|
||||
const maxHits = await retrieveQuota;
|
||||
config.validations.max(maxHits);
|
||||
const info = {
|
||||
limit: maxHits,
|
||||
current: totalHits,
|
||||
remaining: Math.max(maxHits - totalHits, 0),
|
||||
resetTime
|
||||
};
|
||||
augmentedRequest[config.requestPropertyName] = info;
|
||||
if (config.legacyHeaders && !response.headersSent) {
|
||||
setLegacyHeaders(response, info);
|
||||
}
|
||||
if (config.standardHeaders && !response.headersSent) {
|
||||
if (config.standardHeaders === "draft-6") {
|
||||
setDraft6Headers(response, info, config.windowMs);
|
||||
} else if (config.standardHeaders === "draft-7") {
|
||||
config.validations.headersResetTime(info.resetTime);
|
||||
setDraft7Headers(response, info, config.windowMs);
|
||||
}
|
||||
}
|
||||
if (config.skipFailedRequests || config.skipSuccessfulRequests) {
|
||||
let decremented = false;
|
||||
const decrementKey = async () => {
|
||||
if (!decremented) {
|
||||
await config.store.decrement(key);
|
||||
decremented = true;
|
||||
}
|
||||
};
|
||||
if (config.skipFailedRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (!config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
response.on("close", async () => {
|
||||
if (!response.writableEnded)
|
||||
await decrementKey();
|
||||
});
|
||||
response.on("error", async () => {
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
if (config.skipSuccessfulRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
}
|
||||
if (maxHits && totalHits === maxHits + 1) {
|
||||
config.onLimitReached(request, response, options);
|
||||
}
|
||||
config.validations.disable();
|
||||
if (maxHits && totalHits > maxHits) {
|
||||
if (config.legacyHeaders || config.standardHeaders) {
|
||||
setRetryAfterHeader(response, info, config.windowMs);
|
||||
}
|
||||
config.handler(request, response, next, options);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
);
|
||||
middleware.resetKey = config.store.resetKey.bind(config.store);
|
||||
middleware.getKey = (_a = config.store.get) == null ? void 0 : _a.bind(
|
||||
config.store
|
||||
);
|
||||
return middleware;
|
||||
};
|
||||
var lib_default = rateLimit;
|
||||
export {
|
||||
MemoryStore,
|
||||
lib_default as default,
|
||||
lib_default as rateLimit
|
||||
};
|
||||
20
qwen/nodejs/node_modules/express-rate-limit/license.md
generated
vendored
Normal file
20
qwen/nodejs/node_modules/express-rate-limit/license.md
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# MIT License
|
||||
|
||||
Copyright 2021 Nathan Friedly
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
132
qwen/nodejs/node_modules/express-rate-limit/package.json
generated
vendored
Normal file
132
qwen/nodejs/node_modules/express-rate-limit/package.json
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
{
|
||||
"name": "express-rate-limit",
|
||||
"version": "6.11.2",
|
||||
"description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",
|
||||
"author": {
|
||||
"name": "Nathan Friedly",
|
||||
"url": "http://nfriedly.com/"
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/express-rate-limit/express-rate-limit",
|
||||
"repository": "https://github.com/express-rate-limit/express-rate-limit",
|
||||
"keywords": [
|
||||
"express-rate-limit",
|
||||
"express",
|
||||
"rate",
|
||||
"limit",
|
||||
"ratelimit",
|
||||
"rate-limit",
|
||||
"middleware",
|
||||
"ip",
|
||||
"auth",
|
||||
"authorization",
|
||||
"security",
|
||||
"brute",
|
||||
"force",
|
||||
"bruteforce",
|
||||
"brute-force",
|
||||
"attack"
|
||||
],
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/",
|
||||
"tsconfig.json",
|
||||
"package.json",
|
||||
"readme.md",
|
||||
"license.md",
|
||||
"changelog.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "del-cli dist/ coverage/ *.log *.tmp *.bak *.tgz",
|
||||
"build:cjs": "esbuild --platform=node --bundle --target=es2019 --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;\" source/index.ts",
|
||||
"build:esm": "esbuild --platform=node --bundle --target=es2019 --format=esm --outfile=dist/index.mjs source/index.ts",
|
||||
"build:types": "dts-bundle-generator --out-file=dist/index.d.ts source/index.ts && cp dist/index.d.ts dist/index.d.cts && cp dist/index.d.ts dist/index.d.mts",
|
||||
"compile": "run-s clean build:*",
|
||||
"lint:code": "xo",
|
||||
"lint:rest": "prettier --check .",
|
||||
"lint": "run-s lint:*",
|
||||
"format:code": "xo --fix",
|
||||
"format:rest": "prettier --write .",
|
||||
"format": "run-s format:*",
|
||||
"test:lib": "cross-env NODE_NO_WARNINGS=1 NODE_OPTIONS=--experimental-vm-modules jest --config config/jest.json",
|
||||
"test:ext": "cd test/external/ && bash run-all-tests",
|
||||
"test": "run-s lint test:lib",
|
||||
"pre-commit": "lint-staged",
|
||||
"prepare": "run-s compile && husky install config/husky"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"express": "^4 || ^5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@express-rate-limit/prettier": "1.0.0",
|
||||
"@express-rate-limit/tsconfig": "1.0.0",
|
||||
"@jest/globals": "29.6.2",
|
||||
"@types/express": "4.17.17",
|
||||
"@types/jest": "29.5.3",
|
||||
"@types/node": "20.4.0",
|
||||
"@types/supertest": "2.0.12",
|
||||
"cross-env": "7.0.3",
|
||||
"del-cli": "5.0.0",
|
||||
"dts-bundle-generator": "7.0.0",
|
||||
"esbuild": "0.18.11",
|
||||
"express": "4.18.2",
|
||||
"husky": "8.0.3",
|
||||
"jest": "29.6.2",
|
||||
"lint-staged": "13.2.3",
|
||||
"npm-run-all": "4.1.5",
|
||||
"ratelimit-header-parser": "0.1.0",
|
||||
"supertest": "6.3.3",
|
||||
"ts-jest": "29.1.1",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.9.5",
|
||||
"xo": "0.54.2"
|
||||
},
|
||||
"xo": {
|
||||
"prettier": true,
|
||||
"rules": {
|
||||
"@typescript-eslint/no-empty-function": 0,
|
||||
"@typescript-eslint/no-dynamic-delete": 0,
|
||||
"@typescript-eslint/no-confusing-void-expression": 0,
|
||||
"@typescript-eslint/consistent-indexed-object-style": [
|
||||
"error",
|
||||
"index-signature"
|
||||
],
|
||||
"n/no-unsupported-features/es-syntax": 0
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "test/library/*.ts",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unsafe-argument": 0,
|
||||
"@typescript-eslint/no-unsafe-assignment": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"ignore": [
|
||||
"test/external"
|
||||
]
|
||||
},
|
||||
"prettier": "@express-rate-limit/prettier",
|
||||
"lint-staged": {
|
||||
"{source,test}/**/*.ts": "xo --fix",
|
||||
"**/*.{json,yaml,md}": "prettier --write "
|
||||
}
|
||||
}
|
||||
579
qwen/nodejs/node_modules/express-rate-limit/readme.md
generated
vendored
Normal file
579
qwen/nodejs/node_modules/express-rate-limit/readme.md
generated
vendored
Normal file
@@ -0,0 +1,579 @@
|
||||
# <div align="center"> Express Rate Limit </div>
|
||||
|
||||
---
|
||||
|
||||
Sponsored by [Zuplo](https://zuplo.link/express-rate-limit) a fully-managed API
|
||||
Gateway for developers. Add
|
||||
[dynamic rate-limiting](https://zuplo.link/dynamic-rate-limiting),
|
||||
authentication and more to any API in minutes. Learn more at
|
||||
[zuplo.com](https://zuplo.link/express-rate-limit)
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://github.com/express-rate-limit/express-rate-limit/actions/workflows/ci.yaml)
|
||||
[](https://npmjs.org/package/express-rate-limit 'View this project on NPM')
|
||||
[](https://www.npmjs.com/package/express-rate-limit)
|
||||
|
||||
Basic rate-limiting middleware for [Express](http://expressjs.com/). Use to
|
||||
limit repeated requests to public APIs and/or endpoints such as password reset.
|
||||
Plays nice with
|
||||
[express-slow-down](https://www.npmjs.com/package/express-slow-down).
|
||||
|
||||
</div>
|
||||
|
||||
## Use Cases
|
||||
|
||||
Depending on your use case, you may need to switch to a different
|
||||
[store](#store).
|
||||
|
||||
#### Abuse Prevention
|
||||
|
||||
The default `MemoryStore` is probably fine.
|
||||
|
||||
#### API Rate Limit Enforcement
|
||||
|
||||
You likely want to switch to a different [store](#store). As a performance
|
||||
optimization, the default `MemoryStore` uses a global time window, so if your
|
||||
limit is 10 requests per minute, a single user might be able to get an initial
|
||||
burst of up to 20 requests in a row if they happen to get the first 10 in at the
|
||||
end of one minute and the next 10 in at the start of the next minute. (After the
|
||||
initial burst, they will be limited to the expected 10 requests per minute.) All
|
||||
other stores use per-user time windows, so a user will get exactly 10 requests
|
||||
regardless.
|
||||
|
||||
Additionally, if you have multiple servers or processes (for example, with the
|
||||
[node:cluster](https://nodejs.org/api/cluster.html) module), you'll likely want
|
||||
to use an external data store to syhcnronize hits
|
||||
([redis](https://npmjs.com/package/rate-limit-redis),
|
||||
[memcached](https://npmjs.org/package/rate-limit-memcached), [etc.](#store))
|
||||
This will guarentee the expected result even if some requests get handled by
|
||||
different servers/processes.
|
||||
|
||||
### Alternate Rate Limiters
|
||||
|
||||
This module was designed to only handle the basics and didn't even support
|
||||
external stores initially. These other options all are excellent pieces of
|
||||
software and may be more appropriate for some situations:
|
||||
|
||||
- [`rate-limiter-flexible`](https://www.npmjs.com/package/rate-limiter-flexible)
|
||||
- [`express-brute`](https://www.npmjs.com/package/express-brute)
|
||||
- [`rate-limiter`](https://www.npmjs.com/package/express-limiter)
|
||||
|
||||
## Installation
|
||||
|
||||
From the npm registry:
|
||||
|
||||
```sh
|
||||
# Using npm
|
||||
> npm install express-rate-limit
|
||||
# Using yarn or pnpm
|
||||
> yarn/pnpm add express-rate-limit
|
||||
```
|
||||
|
||||
From Github Releases:
|
||||
|
||||
```sh
|
||||
# Using npm
|
||||
> npm install https://github.com/express-rate-limit/express-rate-limit/releases/download/v{version}/express-rate-limit.tgz
|
||||
# Using yarn or pnpm
|
||||
> yarn/pnpm add https://github.com/express-rate-limit/express-rate-limit/releases/download/v{version}/express-rate-limit.tgz
|
||||
```
|
||||
|
||||
Replace `{version}` with the version of the package that you want to your, e.g.:
|
||||
`6.0.0`.
|
||||
|
||||
## Usage
|
||||
|
||||
### Importing
|
||||
|
||||
This library is provided in ESM as well as CJS forms, and works with both
|
||||
Javascript and Typescript projects.
|
||||
|
||||
**This package requires you to use Node 14 or above.**
|
||||
|
||||
Import it in a CommonJS project (`type: commonjs` or no `type` field in
|
||||
`package.json`) as follows:
|
||||
|
||||
```ts
|
||||
const { rateLimit } = require('express-rate-limit')
|
||||
```
|
||||
|
||||
Import it in a ESM project (`type: module` in `package.json`) as follows:
|
||||
|
||||
```ts
|
||||
import { rateLimit } from 'express-rate-limit'
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
To use it in an API-only server where the rate-limiter should be applied to all
|
||||
requests:
|
||||
|
||||
```ts
|
||||
import { rateLimit } from 'express-rate-limit'
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
||||
standardHeaders: 'draft-7', // draft-6: RateLimit-* headers; draft-7: combined RateLimit header
|
||||
legacyHeaders: false, // X-RateLimit-* headers
|
||||
// store: ... , // Use an external store for more precise rate limiting
|
||||
})
|
||||
|
||||
// Apply the rate limiting middleware to all requests
|
||||
app.use(limiter)
|
||||
```
|
||||
|
||||
To use it in a 'regular' web server (e.g. anything that uses
|
||||
`express.static()`), where the rate-limiter should only apply to certain
|
||||
requests:
|
||||
|
||||
```ts
|
||||
import { rateLimit } from 'express-rate-limit'
|
||||
|
||||
const apiLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
||||
standardHeaders: 'draft-7', // Set `RateLimit` and `RateLimit-Policy`` headers
|
||||
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
|
||||
// store: ... , // Use an external store for more precise rate limiting
|
||||
})
|
||||
|
||||
// Apply the rate limiting middleware to API calls only
|
||||
app.use('/api', apiLimiter)
|
||||
```
|
||||
|
||||
To create multiple instances to apply different rules to different endpoints:
|
||||
|
||||
```ts
|
||||
import { rateLimit } from 'express-rate-limit'
|
||||
|
||||
const apiLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
||||
standardHeaders: 'draft-7', // draft-6: RateLimit-* headers; draft-7: combined RateLimit header
|
||||
legacyHeaders: false, // X-RateLimit-* headers
|
||||
// store: ... , // Use an external store for more precise rate limiting
|
||||
})
|
||||
|
||||
app.use('/api/', apiLimiter)
|
||||
|
||||
const createAccountLimiter = rateLimit({
|
||||
windowMs: 60 * 60 * 1000, // 1 hour
|
||||
max: 5, // Limit each IP to 5 create account requests per `window` (here, per hour)
|
||||
message:
|
||||
'Too many accounts created from this IP, please try again after an hour',
|
||||
standardHeaders: 'draft-7', // draft-6: RateLimit-* headers; draft-7: combined RateLimit header
|
||||
legacyHeaders: false, // X-RateLimit-* headers
|
||||
})
|
||||
|
||||
app.post('/create-account', createAccountLimiter, (request, response) => {
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
To use a custom store:
|
||||
|
||||
```ts
|
||||
import { rateLimit } from 'express-rate-limit'
|
||||
import RedisStore from 'rate-limit-redis'
|
||||
import RedisClient from 'ioredis'
|
||||
|
||||
const redisClient = new RedisClient()
|
||||
const rateLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
||||
standardHeaders: 'draft-7', // draft-6: RateLimit-* headers; draft-7: combined RateLimit header
|
||||
legacyHeaders: false, // X-RateLimit-* headers
|
||||
store: new RedisStore({
|
||||
/* ... */
|
||||
}), // Use the external store
|
||||
})
|
||||
|
||||
// Apply the rate limiting middleware to all requests
|
||||
app.use(rateLimiter)
|
||||
```
|
||||
|
||||
> **Note:** most stores will require additional configuration, such as custom
|
||||
> prefixes, when using multiple instances. The default built-in memory store is
|
||||
> an exception to this rule.
|
||||
|
||||
### Troubleshooting Proxy Issues
|
||||
|
||||
If you are behind a proxy/load balancer (usually the case with most hosting
|
||||
services, e.g. Heroku, Bluemix, AWS ELB, Nginx, Cloudflare, Akamai, Fastly,
|
||||
Firebase Hosting, Rackspace LB, Riverbed Stingray, etc.), the IP address of the
|
||||
request might be the IP of the load balancer/reverse proxy (making the rate
|
||||
limiter effectively a global one and blocking all requests once the limit is
|
||||
reached) or `undefined`. To solve this issue, add the following line to your
|
||||
code (right after you create the express application):
|
||||
|
||||
```ts
|
||||
app.set('trust proxy', numberOfProxies)
|
||||
```
|
||||
|
||||
Where `numberOfProxies` is the number of proxies between the user and the
|
||||
server. To find the correct number, create a test endpoint that returns the
|
||||
client IP:
|
||||
|
||||
```ts
|
||||
app.set('trust proxy', 1)
|
||||
app.get('/ip', (request, response) => response.send(request.ip))
|
||||
```
|
||||
|
||||
Go to `/ip` and see the IP address returned in the response. If it matches your
|
||||
public IP address, then the number of proxies is correct and the rate limiter
|
||||
should now work correctly. If not, then keep increasing the number until it
|
||||
does.
|
||||
|
||||
For more information about the `trust proxy` setting, take a look at the
|
||||
[official Express documentation](https://expressjs.com/en/guide/behind-proxies.html).
|
||||
|
||||
## Configuration
|
||||
|
||||
### `windowMs`
|
||||
|
||||
> `number`
|
||||
|
||||
Time frame for which requests are checked/remembered. Also used in the
|
||||
`Retry-After` header when the limit is reached.
|
||||
|
||||
Note: with stores that do not implement the `init` function (see the table in
|
||||
the [`stores` section below](#stores)), you may need to configure this value
|
||||
twice, once here and once on the store. In some cases the units also differ
|
||||
(e.g. seconds vs miliseconds).
|
||||
|
||||
Defaults to `60000` ms (= 1 minute).
|
||||
|
||||
### `max`
|
||||
|
||||
> `number | function`
|
||||
|
||||
The maximum number of connections to allow during the `window` before rate
|
||||
limiting the client.
|
||||
|
||||
Can be the limit itself as a number or a (sync/async) function that accepts the
|
||||
Express `request` and `response` objects and then returns a number.
|
||||
|
||||
Defaults to `5`. Set it to `0` to disable the rate limiter.
|
||||
|
||||
An example of using a function:
|
||||
|
||||
```ts
|
||||
const isPremium = async (user) => {
|
||||
// ...
|
||||
}
|
||||
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
max: async (request, response) => {
|
||||
if (await isPremium(request.user)) return 10
|
||||
else return 5
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### `message`
|
||||
|
||||
> `any`
|
||||
|
||||
The response body to send back when a client is rate limited.
|
||||
|
||||
May be a `string`, JSON object, or any other value that Express's
|
||||
[`response.send`](https://expressjs.com/en/4x/api.html#res.send) method
|
||||
supports. It can also be a (sync/async) function that accepts the Express
|
||||
request and response objects and then returns a `string`, JSON object or any
|
||||
other value the Express `response.send` function accepts.
|
||||
|
||||
Defaults to `'Too many requests, please try again later.'`
|
||||
|
||||
An example of using a function:
|
||||
|
||||
```ts
|
||||
const isPremium = async (user) => {
|
||||
// ...
|
||||
}
|
||||
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
message: async (request, response) => {
|
||||
if (await isPremium(request.user))
|
||||
return 'You can only make 10 requests every hour.'
|
||||
else return 'You can only make 5 requests every hour.'
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### `statusCode`
|
||||
|
||||
> `number`
|
||||
|
||||
The HTTP status code to send back when a client is rate limited.
|
||||
|
||||
Defaults to `429` (HTTP 429 Too Many Requests - RFC 6585).
|
||||
|
||||
### `legacyHeaders`
|
||||
|
||||
> `boolean`
|
||||
|
||||
Whether to send the legacy rate limit headers for the limit
|
||||
(`X-RateLimit-Limit`), current usage (`X-RateLimit-Remaining`) and reset time
|
||||
(if the store provides it) (`X-RateLimit-Reset`) on all responses. If set to
|
||||
`true`, the middleware also sends the `Retry-After` header on all blocked
|
||||
requests.
|
||||
|
||||
Defaults to `true` (for backward compatibility).
|
||||
|
||||
> Renamed in `6.x` from `headers` to `legacyHeaders`.
|
||||
|
||||
### `standardHeaders`
|
||||
|
||||
> `boolean` | `'draft-6'` | `'draft-7'`
|
||||
|
||||
Whether to enable support for headers conforming to the
|
||||
[RateLimit header fields for HTTP standardization draft](https://github.com/ietf-wg-httpapi/ratelimit-headers)
|
||||
adopted by the IETF.
|
||||
|
||||
If set to `draft-6`, separate `RateLimit-Policy` `RateLimit-Limit`,
|
||||
`RateLimit-Remaining`, and, if the store supports it, `RateLimit-Reset` headers
|
||||
are set on the response, in accordance with
|
||||
[draft-ietf-httpapi-ratelimit-headers-06](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers-06).
|
||||
|
||||
If set to `draft-7`, a combined `RateLimit` header is set containing limit,
|
||||
remaining, and reset values, and a `RateLimit-Policy` header is set, in
|
||||
accordiance with
|
||||
[draft-ietf-httpapi-ratelimit-headers-07](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers-07).
|
||||
`windowMs` is used for the reset value if the store does not provide a reset
|
||||
time.
|
||||
|
||||
If set to `true`, it is treated as `draft-6`, however this behavior may change
|
||||
in a future semver major release.
|
||||
|
||||
If set to any truthy value, the middleware also sends the `Retry-After` header
|
||||
on all blocked requests.
|
||||
|
||||
The `standardHeaders` option may be used in conjunction with, or instead of the
|
||||
`legacyHeaders` option.
|
||||
|
||||
ℹ️ Tip: use
|
||||
[ratelimit-header-parser](https://www.npmjs.com/package/ratelimit-header-parser)
|
||||
in clients to read/parse any form of express-rate-limit's headers.
|
||||
|
||||
Defaults to `false`.
|
||||
|
||||
> Renamed in `6.x` from `draft_polli_ratelimit_headers` to `standardHeaders`.
|
||||
|
||||
### `requestPropertyName`
|
||||
|
||||
> `string`
|
||||
|
||||
The name of the property on the Express `request` object to store the rate limit
|
||||
info.
|
||||
|
||||
Defaults to `'rateLimit'`.
|
||||
|
||||
### `skipFailedRequests`
|
||||
|
||||
> `boolean`
|
||||
|
||||
When set to `true`, failed requests won't be counted. Request considered failed
|
||||
when the `requestWasSuccessful` option returns `false`. By default, this means
|
||||
requests fail when:
|
||||
|
||||
- the response status >= 400
|
||||
- the request was cancelled before last chunk of data was sent (response `close`
|
||||
event triggered)
|
||||
- the response `error` event was triggered by response
|
||||
|
||||
(Technically they are counted and then un-counted, so a large number of slow
|
||||
requests all at once could still trigger a rate-limit. This may be fixed in a
|
||||
future release. PRs welcome!)
|
||||
|
||||
Defaults to `false`.
|
||||
|
||||
### `skipSuccessfulRequests`
|
||||
|
||||
> `boolean`
|
||||
|
||||
If `true`, the library will (by default) skip all requests that are considered
|
||||
'failed' by the `requestWasSuccessful` function. By default, this means requests
|
||||
succeed when the response status code < 400.
|
||||
|
||||
(Technically they are counted and then un-counted, so a large number of slow
|
||||
requests all at once could still trigger a rate-limit. This may be fixed in a
|
||||
future release. PRs welcome!)
|
||||
|
||||
Defaults to `false`.
|
||||
|
||||
### `keyGenerator`
|
||||
|
||||
> `function`
|
||||
|
||||
Method to retrieve custom identifiers for clients, such as their IP address,
|
||||
username, or API Key.
|
||||
|
||||
Should be a (sync/async) function that accepts the Express `request` and
|
||||
`response` objects and then returns a string.
|
||||
|
||||
By default, the client's IP address is used:
|
||||
|
||||
```ts
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
keyGenerator: (request, response) => request.ip,
|
||||
})
|
||||
```
|
||||
|
||||
> **Note** If a `keyGenerator` returns the same value for every user, it becomes
|
||||
> a global rate limiter. This could be combined with a second instance of
|
||||
> `express-rate-limit` to have both global and per-user limits.
|
||||
|
||||
### `handler`
|
||||
|
||||
> `function`
|
||||
|
||||
Express request handler that sends back a response when a client is
|
||||
rate-limited.
|
||||
|
||||
By default, sends back the `statusCode` and `message` set via the `options`,
|
||||
similar to this:
|
||||
|
||||
```ts
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
handler: (request, response, next, options) =>
|
||||
response.status(options.statusCode).send(options.message),
|
||||
})
|
||||
```
|
||||
|
||||
### `onLimitReached`
|
||||
|
||||
> `function`
|
||||
|
||||
A (sync/async) function that accepts the Express `request` and `response`
|
||||
objects that is called the on the request where a client has just exceeded their
|
||||
rate limit.
|
||||
|
||||
This method was
|
||||
[deprecated in v6](https://github.com/express-rate-limit/express-rate-limit/releases/v6.0.0) -
|
||||
Please use a custom `handler` that checks the number of hits instead.
|
||||
|
||||
### `skip`
|
||||
|
||||
> `function`
|
||||
|
||||
Function to determine whether or not this request counts towards a client's
|
||||
quota. Should be a (sync/async) function that accepts the Express `request` and
|
||||
`response` objects and then returns `true` or `false`.
|
||||
|
||||
Could also act as an allowlist for certain keys:
|
||||
|
||||
```ts
|
||||
const allowlist = ['192.168.0.56', '192.168.0.21']
|
||||
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
skip: (request, response) => allowlist.includes(request.ip),
|
||||
})
|
||||
```
|
||||
|
||||
By default, it skips no requests:
|
||||
|
||||
```ts
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
skip: (request, response) => false,
|
||||
})
|
||||
```
|
||||
|
||||
### `requestWasSuccessful`
|
||||
|
||||
> `function`
|
||||
|
||||
Method to determine whether or not the request counts as 'succesful'. Used when
|
||||
either `skipSuccessfulRequests` or `skipFailedRequests` is set to true. Should
|
||||
be a (sync/async) function that accepts the Express `request` and `response`
|
||||
objects and then returns `true` or `false`.
|
||||
|
||||
By default, requests with a response status code less than 400 are considered
|
||||
successful:
|
||||
|
||||
```ts
|
||||
const limiter = rateLimit({
|
||||
// ...
|
||||
requestWasSuccessful: (request, response) => response.statusCode < 400,
|
||||
})
|
||||
```
|
||||
|
||||
### `validate`
|
||||
|
||||
> `boolean`
|
||||
|
||||
When enabled, a set of validation checks are run on the first request to detect
|
||||
common misconfigurations with proxies, etc. Prints an error to the console if
|
||||
any issue is detected.
|
||||
|
||||
Automatically disables after the first request is processed.
|
||||
|
||||
See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes
|
||||
for more info.
|
||||
|
||||
Defaults to true.
|
||||
|
||||
### `store`
|
||||
|
||||
> `Store`
|
||||
|
||||
The `Store` to use to store the hit count for each client.
|
||||
|
||||
By default, the [`memory-store`](source/memory-store.ts) is used.
|
||||
|
||||
Here is a list of external stores:
|
||||
|
||||
| Name | Description | Legacy/Modern |
|
||||
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------- |
|
||||
| [`memory-store`](source/memory-store.ts) | _(default)_ Simple in-memory option. Does not share state when app has multiple processes or servers. | Modern as of v6.0.0 |
|
||||
| [`rate-limit-redis`](https://npmjs.com/package/rate-limit-redis) | A [Redis](http://redis.io/)-backed store, more suitable for large or demanding deployments. | Modern as of v3.0.0 |
|
||||
| [`rate-limit-memcached`](https://npmjs.org/package/rate-limit-memcached) | A [Memcached](https://memcached.org/)-backed store. | Legacy |
|
||||
| [`rate-limit-mongo`](https://www.npmjs.com/package/rate-limit-mongo) | A [MongoDB](https://www.mongodb.com/)-backed store. | Legacy |
|
||||
| [`precise-memory-rate-limit`](https://www.npmjs.com/package/precise-memory-rate-limit) | A memory store similar to the built-in one, except that it stores a distinct timestamp for each key. | Modern as of v2.0.0 |
|
||||
|
||||
Take a look at
|
||||
[this guide](https://github.com/express-rate-limit/express-rate-limit/wiki/Creating-Your-Own-Store)
|
||||
if you wish to create your own store.
|
||||
|
||||
## Request API
|
||||
|
||||
A `request.rateLimit` property is added to all requests with the `limit`,
|
||||
`current`, and `remaining` number of requests and, if the store provides it, a
|
||||
`resetTime` Date object. These may be used in your application code to take
|
||||
additional actions or inform the user of their status.
|
||||
|
||||
The property name can be configured with the configuration option
|
||||
`requestPropertyName`.
|
||||
|
||||
## Instance API
|
||||
|
||||
### `resetKey(key)`
|
||||
|
||||
Resets the rate limiting for a given key. An example use case is to allow users
|
||||
to complete a captcha or whatever to reset their rate limit, then call this
|
||||
method.
|
||||
|
||||
## Issues and Contributing
|
||||
|
||||
If you encounter a bug or want to see something added/changed, please go ahead
|
||||
and
|
||||
[open an issue](https://github.com/nfriexpress-rate-limitedly/express-rate-limit/issues/new)!
|
||||
If you need help with something, feel free to
|
||||
[start a discussion](https://github.com/express-rate-limit/express-rate-limit/discussions/new)!
|
||||
|
||||
If you wish to contribute to the library, thanks! First, please read
|
||||
[the contributing guide](contributing.md). Then you can pick up any issue and
|
||||
fix/implement it!
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Nathan Friedly](http://nfriedly.com/)
|
||||
5
qwen/nodejs/node_modules/express-rate-limit/tsconfig.json
generated
vendored
Normal file
5
qwen/nodejs/node_modules/express-rate-limit/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"include": ["source/"],
|
||||
"exclude": ["node_modules/"],
|
||||
"extends": "@express-rate-limit/tsconfig"
|
||||
}
|
||||
Reference in New Issue
Block a user