express-rate-limit 6.0.0 → 6.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,198 @@
1
+ // source/memory-store.ts
2
+ var calculateNextResetTime = (windowMs) => {
3
+ const resetTime = new Date();
4
+ resetTime.setMilliseconds(resetTime.getMilliseconds() + windowMs);
5
+ return resetTime;
6
+ };
7
+ var MemoryStore = class {
8
+ init(options) {
9
+ this.windowMs = options.windowMs;
10
+ this.resetTime = calculateNextResetTime(this.windowMs);
11
+ this.hits = {};
12
+ const interval = setInterval(async () => {
13
+ await this.resetAll();
14
+ }, this.windowMs);
15
+ if (interval.unref) {
16
+ interval.unref();
17
+ }
18
+ }
19
+ async increment(key) {
20
+ const totalHits = (this.hits[key] ?? 0) + 1;
21
+ this.hits[key] = totalHits;
22
+ return {
23
+ totalHits,
24
+ resetTime: this.resetTime
25
+ };
26
+ }
27
+ async decrement(key) {
28
+ const current = this.hits[key];
29
+ if (current) {
30
+ this.hits[key] = current - 1;
31
+ }
32
+ }
33
+ async resetKey(key) {
34
+ delete this.hits[key];
35
+ }
36
+ async resetAll() {
37
+ this.hits = {};
38
+ this.resetTime = calculateNextResetTime(this.windowMs);
39
+ }
40
+ };
41
+
42
+ // source/lib.ts
43
+ var isLegacyStore = (store) => typeof store.incr === "function" && typeof store.increment !== "function";
44
+ var promisifyStore = (passedStore) => {
45
+ if (!isLegacyStore(passedStore)) {
46
+ return passedStore;
47
+ }
48
+ const legacyStore = passedStore;
49
+ class PromisifiedStore {
50
+ async increment(key) {
51
+ return new Promise((resolve, reject) => {
52
+ legacyStore.incr(key, (error, totalHits, resetTime) => {
53
+ if (error)
54
+ reject(error);
55
+ resolve({ totalHits, resetTime });
56
+ });
57
+ });
58
+ }
59
+ async decrement(key) {
60
+ return Promise.resolve(legacyStore.decrement(key));
61
+ }
62
+ async resetKey(key) {
63
+ return Promise.resolve(legacyStore.resetKey(key));
64
+ }
65
+ async resetAll() {
66
+ if (typeof legacyStore.resetAll === "function")
67
+ return Promise.resolve(legacyStore.resetAll());
68
+ }
69
+ }
70
+ return new PromisifiedStore();
71
+ };
72
+ var parseOptions = (passedOptions) => {
73
+ const options = {
74
+ windowMs: 60 * 1e3,
75
+ store: new MemoryStore(),
76
+ max: 5,
77
+ message: "Too many requests, please try again later.",
78
+ statusCode: 429,
79
+ legacyHeaders: passedOptions.headers ?? true,
80
+ standardHeaders: passedOptions.draft_polli_ratelimit_headers ?? false,
81
+ requestPropertyName: "rateLimit",
82
+ skipFailedRequests: false,
83
+ skipSuccessfulRequests: false,
84
+ requestWasSuccessful: (_request, response) => response.statusCode < 400,
85
+ skip: (_request, _response) => false,
86
+ keyGenerator: (request, _response) => {
87
+ if (!request.ip) {
88
+ console.error("WARN | `express-rate-limit` | `request.ip` is undefined. You can avoid this by providing a custom `keyGenerator` function, but it may be indicative of a larger issue.");
89
+ }
90
+ return request.ip;
91
+ },
92
+ handler: (_request, response, _next, _optionsUsed) => {
93
+ response.status(options.statusCode).send(options.message);
94
+ },
95
+ onLimitReached: (_request, _response, _optionsUsed) => {
96
+ },
97
+ ...passedOptions
98
+ };
99
+ if (typeof options.store.incr !== "function" && typeof options.store.increment !== "function" || typeof options.store.decrement !== "function" || typeof options.store.resetKey !== "function" || typeof options.store.resetAll !== "undefined" && typeof options.store.resetAll !== "function" || typeof options.store.init !== "undefined" && typeof options.store.init !== "function") {
100
+ throw new TypeError("An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.");
101
+ }
102
+ options.store = promisifyStore(options.store);
103
+ return options;
104
+ };
105
+ var handleAsyncErrors = (fn) => async (request, response, next) => {
106
+ try {
107
+ await Promise.resolve(fn(request, response, next)).catch(next);
108
+ } catch (error) {
109
+ next(error);
110
+ }
111
+ };
112
+ var rateLimit = (passedOptions) => {
113
+ const options = parseOptions(passedOptions ?? {});
114
+ if (typeof options.store.init === "function")
115
+ options.store.init(options);
116
+ const middleware = handleAsyncErrors(async (request, response, next) => {
117
+ const skip = await options.skip(request, response);
118
+ if (skip) {
119
+ next();
120
+ return;
121
+ }
122
+ const augmentedRequest = request;
123
+ const key = await options.keyGenerator(request, response);
124
+ const { totalHits, resetTime } = await options.store.increment(key);
125
+ const retrieveQuota = typeof options.max === "function" ? options.max(request, response) : options.max;
126
+ const maxHits = await retrieveQuota;
127
+ augmentedRequest[options.requestPropertyName] = {
128
+ limit: maxHits,
129
+ current: totalHits,
130
+ remaining: Math.max(maxHits - totalHits, 0),
131
+ resetTime
132
+ };
133
+ if (options.legacyHeaders && !response.headersSent) {
134
+ response.setHeader("X-RateLimit-Limit", maxHits);
135
+ response.setHeader("X-RateLimit-Remaining", augmentedRequest[options.requestPropertyName].remaining);
136
+ if (resetTime instanceof Date) {
137
+ response.setHeader("Date", new Date().toUTCString());
138
+ response.setHeader("X-RateLimit-Reset", Math.ceil(resetTime.getTime() / 1e3));
139
+ }
140
+ }
141
+ if (options.standardHeaders && !response.headersSent) {
142
+ response.setHeader("RateLimit-Limit", maxHits);
143
+ response.setHeader("RateLimit-Remaining", augmentedRequest[options.requestPropertyName].remaining);
144
+ if (resetTime) {
145
+ const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);
146
+ response.setHeader("RateLimit-Reset", Math.max(0, deltaSeconds));
147
+ }
148
+ }
149
+ if (options.skipFailedRequests || options.skipSuccessfulRequests) {
150
+ let decremented = false;
151
+ const decrementKey = async () => {
152
+ if (!decremented) {
153
+ await options.store.decrement(key);
154
+ decremented = true;
155
+ }
156
+ };
157
+ if (options.skipFailedRequests) {
158
+ response.on("finish", async () => {
159
+ if (!options.requestWasSuccessful(request, response))
160
+ await decrementKey();
161
+ });
162
+ response.on("close", async () => {
163
+ if (!response.writableEnded)
164
+ await decrementKey();
165
+ });
166
+ response.on("error", async () => {
167
+ await decrementKey();
168
+ });
169
+ }
170
+ if (options.skipSuccessfulRequests) {
171
+ response.on("finish", async () => {
172
+ if (options.requestWasSuccessful(request, response))
173
+ await decrementKey();
174
+ });
175
+ }
176
+ }
177
+ if (maxHits && totalHits === maxHits + 1) {
178
+ options.onLimitReached(request, response, options);
179
+ }
180
+ if (maxHits && totalHits > maxHits) {
181
+ if ((options.legacyHeaders || options.standardHeaders) && !response.headersSent) {
182
+ response.setHeader("Retry-After", Math.ceil(options.windowMs / 1e3));
183
+ }
184
+ options.handler(request, response, next, options);
185
+ return;
186
+ }
187
+ next();
188
+ });
189
+ middleware.resetKey = options.store.resetKey.bind(options.store);
190
+ return middleware;
191
+ };
192
+ var lib_default = rateLimit;
193
+
194
+ // source/index.ts
195
+ var source_default = lib_default;
196
+ export {
197
+ source_default as default
198
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-rate-limit",
3
- "version": "6.0.0",
3
+ "version": "6.0.4",
4
4
  "description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",
5
5
  "author": {
6
6
  "name": "Nathan Friedly",
@@ -28,53 +28,43 @@
28
28
  "attack"
29
29
  ],
30
30
  "type": "module",
31
- "module": "dist/esm/index.js",
32
- "main": "dist/cjs/index.js",
33
31
  "exports": {
34
32
  ".": {
35
- "import": "./dist/esm/index.js",
36
- "require": "./dist/cjs/index.js"
37
- },
38
- "./memory-store": {
39
- "import": "./dist/esm/memory-store.js",
40
- "require": "./dist/cjs/memory-store.js"
41
- }
42
- },
43
- "typesVersions": {
44
- "*": {
45
- ".": [
46
- "./dist/esm/index.d.ts"
47
- ],
48
- "./memory-store": [
49
- "./dist/esm/memory-store.d.ts"
50
- ]
33
+ "import": "./dist/index.mjs",
34
+ "require": "./dist/index.cjs"
51
35
  }
52
36
  },
37
+ "main": "./dist/index.cjs",
38
+ "module": "./dist/index.mjs",
39
+ "types": "./dist/index.d.ts",
53
40
  "files": [
54
41
  "dist/",
55
42
  "tsconfig.json",
56
43
  "package.json",
57
- "package-lock.json",
58
44
  "readme.md",
59
45
  "license.md",
60
46
  "changelog.md"
61
47
  ],
62
48
  "engines": {
63
- "node": ">= 12.9.0"
49
+ "node": ">= 14.5.0"
64
50
  },
65
51
  "scripts": {
66
52
  "clean": "del-cli dist/ coverage/ *.log *.tmp *.bak *.tgz",
67
- "build:cjs": "tsc --project config/typescript/cjs.json",
68
- "build:esm": "tsc --project config/typescript/esm.json",
69
- "build": "run-p build:*",
70
- "compile": "run-s clean build",
71
- "lint": "xo",
72
- "autofix": "xo --fix",
73
- "test-lib": "cross-env TS_NODE_PROJECT=config/typescript/test.json NODE_OPTIONS=--experimental-vm-modules jest",
74
- "test": "run-s compile lint test-lib",
75
- "view-coverage": "npx serve coverage/lcov-report",
53
+ "build:cjs": "esbuild --bundle --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = rateLimit;\" source/index.ts",
54
+ "build:esm": "esbuild --bundle --format=esm --outfile=dist/index.mjs source/index.ts",
55
+ "build:types": "dts-bundle-generator --out-file=dist/index.d.ts source/index.ts",
56
+ "compile": "run-s clean build:*",
57
+ "lint:code": "xo --ignore test/external/",
58
+ "lint:rest": "prettier --ignore-path .gitignore --ignore-unknown --check .",
59
+ "lint": "run-s lint:*",
60
+ "autofix:code": "xo --ignore test/external/ --fix",
61
+ "autofix:rest": "prettier --ignore-path .gitignore --ignore-unknown --write .",
62
+ "autofix": "run-s autofix:*",
63
+ "test:lib": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
64
+ "test:ext": "npm pack && cd test/external/ && bash run-all-tests",
65
+ "test": "run-s lint test:*",
76
66
  "pre-commit": "lint-staged",
77
- "prepare": "npm run compile && husky install config/husky"
67
+ "prepare": "run-s compile && husky install config/husky"
78
68
  },
79
69
  "peerDependencies": {
80
70
  "express": "^4"
@@ -87,6 +77,8 @@
87
77
  "@types/supertest": "^2.0.11",
88
78
  "cross-env": "^7.0.3",
89
79
  "del-cli": "^4.0.1",
80
+ "dts-bundle-generator": "^6.2.0",
81
+ "esbuild": "^0.14.8",
90
82
  "express": "^4.17.1",
91
83
  "husky": "^7.0.4",
92
84
  "jest": "^27.4.3",
@@ -107,9 +99,7 @@
107
99
  "@typescript-eslint/consistent-indexed-object-style": [
108
100
  "error",
109
101
  "index-signature"
110
- ],
111
- "import/no-named-as-default-member": 0,
112
- "import/no-cycle": 0
102
+ ]
113
103
  }
114
104
  },
115
105
  "prettier": {
@@ -134,7 +124,7 @@
134
124
  ],
135
125
  "testTimeout": 30000,
136
126
  "testMatch": [
137
- "**/test/**/*-test.[jt]s?(x)"
127
+ "**/test/library/**/*-test.[jt]s?(x)"
138
128
  ],
139
129
  "moduleFileExtensions": [
140
130
  "js",
@@ -148,7 +138,7 @@
148
138
  }
149
139
  },
150
140
  "lint-staged": {
151
- "{source,test}/**/*.ts": "xo --fix",
152
- "**/*.{json,yaml,md}": "prettier --write"
141
+ "{source,test}/**/*.ts": "xo --ignore test/external/ --fix",
142
+ "**/*.{json,yaml,md}": "prettier --ignore-path .gitignore --ignore-unknown --write "
153
143
  }
154
144
  }
package/readme.md CHANGED
@@ -12,11 +12,11 @@ public APIs and/or endpoints such as password reset. Plays nice with
12
12
 
13
13
  </div>
14
14
 
15
- ### Alternate Rate-limiters
15
+ ### Alternate Rate Limiters
16
16
 
17
- > This module does not share state with other processes/servers by
18
- > default. If you need a more robust solution, I recommend using an external
19
- > store. See the [`stores` section](#store) below for a list of external stores.
17
+ > This module does not share state with other processes/servers by default. If
18
+ > you need a more robust solution, I recommend using an external store. See the
19
+ > [`stores` section](#store) below for a list of external stores.
20
20
 
21
21
  This module was designed to only handle the basics and didn't even support
22
22
  external stores initially. These other options all are excellent pieces of
@@ -26,7 +26,7 @@ software and may be more appropriate for some situations:
26
26
  - [express-brute](https://www.npmjs.com/package/express-brute)
27
27
  - [rate-limiter](https://www.npmjs.com/package/express-limiter)
28
28
 
29
- ## Install
29
+ ## Installation
30
30
 
31
31
  From the npm registry:
32
32
 
@@ -51,19 +51,64 @@ Replace `{version}` with the version of the package that you want to your, e.g.:
51
51
 
52
52
  ## Usage
53
53
 
54
- This library is provided in ESM as well as CJS forms. To import it in a CJS
55
- project:
54
+ ### Importing
55
+
56
+ This library is provided in ESM as well as CJS forms, and works with both
57
+ Javascript and Typescript projects.
58
+
59
+ **This package requires you to use Node 14 or above.**
60
+
61
+ #### Javascript
62
+
63
+ Import it in a CommonJS project as follows:
56
64
 
57
65
  ```ts
58
66
  const rateLimit = require('express-rate-limit')
59
67
  ```
60
68
 
61
- To import it in a Typescript/ESM project:
69
+ Import it in a ESM project as follows:
62
70
 
63
71
  ```ts
64
72
  import rateLimit from 'express-rate-limit'
65
73
  ```
66
74
 
75
+ #### Typescript
76
+
77
+ If you are using this library in a Typescript project that outputs CommonJS (no
78
+ `type: module` in `package.json` and `module: commonjs` in `tsconfig.json`), set
79
+ `esModuleInterop` to `true` in the `compilerOptions` of your `tsconfig.json` and
80
+ then import it as follows:
81
+
82
+ ```ts
83
+ import rateLimit from 'express-rate-limit'
84
+ ```
85
+
86
+ If you cannot set `esModuleInterop` to true, import it as follows instead:
87
+
88
+ ```ts
89
+ const rateLimit = require('express-rate-limit')
90
+ ```
91
+
92
+ And use the following to import any types if you need to:
93
+
94
+ ```ts
95
+ import { Store, IncrementResponse, ... } from 'express-rate-limit'
96
+ ```
97
+
98
+ If you are using this library in a Typescript project that outputs ESM
99
+ (`type: module` in `package.json` and `module: esnext` in `tsconfig.json`),
100
+ import it as follows:
101
+
102
+ ```ts
103
+ import rateLimit from 'express-rate-limit'
104
+ ```
105
+
106
+ And use the following to import any types if you need to:
107
+
108
+ ```ts
109
+ import rateLimit, { Store, IncrementResponse, ... } from 'express-rate-limit'
110
+ ```
111
+
67
112
  ### Examples
68
113
 
69
114
  To use it in an API-only server where the rate-limiter should be applied to all
@@ -72,10 +117,6 @@ requests:
72
117
  ```ts
73
118
  import rateLimit from 'express-rate-limit'
74
119
 
75
- // Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
76
- // see https://expressjs.com/en/guide/behind-proxies.html
77
- // app.set('trust proxy', 1);
78
-
79
120
  const limiter = rateLimit({
80
121
  windowMs: 15 * 60 * 1000, // 15 minutes
81
122
  max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
@@ -94,10 +135,6 @@ requests:
94
135
  ```ts
95
136
  import rateLimit from 'express-rate-limit'
96
137
 
97
- // Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
98
- // see https://expressjs.com/en/guide/behind-proxies.html
99
- // app.set('trust proxy', 1);
100
-
101
138
  const apiLimiter = rateLimit({
102
139
  windowMs: 15 * 60 * 1000, // 15 minutes
103
140
  max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
@@ -114,10 +151,6 @@ To create multiple instances to apply different rules to different endpoints:
114
151
  ```ts
115
152
  import rateLimit from 'express-rate-limit'
116
153
 
117
- // Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
118
- // see https://expressjs.com/en/guide/behind-proxies.html
119
- // app.set('trust proxy', 1);
120
-
121
154
  const apiLimiter = rateLimit({
122
155
  windowMs: 15 * 60 * 1000, // 15 minutes
123
156
  max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
@@ -147,10 +180,6 @@ To use a custom store:
147
180
  import rateLimit from 'express-rate-limit'
148
181
  import MemoryStore from 'express-rate-limit/memory-store.js'
149
182
 
150
- // Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
151
- // see https://expressjs.com/en/guide/behind-proxies.html
152
- // app.set('trust proxy', 1);
153
-
154
183
  const apiLimiter = rateLimit({
155
184
  windowMs: 15 * 60 * 1000, // 15 minutes
156
185
  max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
@@ -166,6 +195,38 @@ app.use('/api', apiLimiter)
166
195
  > prefixes, when using multiple instances. The default built-in memory store is
167
196
  > an exception to this rule.
168
197
 
198
+ ### Troubleshooting Proxy Issues
199
+
200
+ If you are behind a proxy/load balancer (usually the case with most hosting
201
+ services, e.g. Heroku, Bluemix, AWS ELB, Nginx, Cloudflare, Akamai, Fastly,
202
+ Firebase Hosting, Rackspace LB, Riverbed Stingray, etc.), the IP address of the
203
+ request might be the IP of the load balancer/reverse proxy (making the rate
204
+ limiter effectively a global one and blocking all requests once the limit is
205
+ reached) or `undefined`. To solve this issue, add the following line to your
206
+ code (right after you create the express application):
207
+
208
+ ```ts
209
+ app.set('trust proxy', numberOfProxies)
210
+ ```
211
+
212
+ Where `numberOfProxies` is the number of proxies between the user and the
213
+ server. To find the correct number, create a test endpoint that returns the
214
+ client IP:
215
+
216
+ ```ts
217
+ app.set('trust proxy', 1)
218
+ app.get('/ip', (request, response) => response.send(request.ip))
219
+ ```
220
+
221
+ Go to `/ip` and see the IP address returned in the response. If it matches your
222
+ IP address (which you can get by going to http://ip.nfriedly.com/ or
223
+ https://api.ipify.org/), then the number of proxies is correct and the rate
224
+ limiter should now work correctly. If not, then keep increasing the number until
225
+ it does.
226
+
227
+ For more information about the `trust proxy` setting, take a look at the
228
+ [official Express documentation](https://expressjs.com/en/guide/behind-proxies.html).
229
+
169
230
  ## Request API
170
231
 
171
232
  A `request.rateLimit` property is added to all requests with the `limit`,
@@ -275,9 +336,9 @@ const keyGenerator = (request /*, response*/) => request.ip
275
336
 
276
337
  The function to handle requests once the max limit is exceeded. It receives the
277
338
  `request` and the `response` objects. The `next` param is available if you need
278
- to pass to the next middleware/route. Finally, the `optionsUsed` param has all
279
- of the options that originally passed in when creating the current limiter and
280
- the default values for other options.
339
+ to pass to the next middleware/route. Finally, the `options` param has all of
340
+ the options that originally passed in when creating the current limiter and the
341
+ default values for other options.
281
342
 
282
343
  The `request.rateLimit` object has `limit`, `current`, and `remaining` number of
283
344
  requests and, if the store provides it, a `resetTime` Date object.
@@ -285,7 +346,7 @@ requests and, if the store provides it, a `resetTime` Date object.
285
346
  Defaults to:
286
347
 
287
348
  ```ts
288
- const handler = (request, response, next, optionsUsed) => {
349
+ const handler = (request, response, next, options) => {
289
350
  response.status(options.statusCode).send(options.message)
290
351
  }
291
352
  ```
package/tsconfig.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "declaration": true,
4
- "sourceMap": true,
5
4
 
6
5
  "strict": true,
7
6
  "noUnusedLocals": true,
@@ -9,9 +8,7 @@
9
8
  "noFallthroughCasesInSwitch": true,
10
9
 
11
10
  "moduleResolution": "node",
12
- "esModuleInterop": true,
13
-
14
- "inlineSources": true
11
+ "esModuleInterop": true
15
12
  },
16
13
  "include": ["./source/**/*.ts"],
17
14
  "exclude": ["./node_modules"]
@@ -1,2 +0,0 @@
1
- export * from './types.js';
2
- export { default } from './lib.js';
package/dist/cjs/index.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- // /source/index.ts
3
- // Export away!
4
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
- if (k2 === undefined) k2 = k;
6
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
7
- }) : (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- o[k2] = m[k];
10
- }));
11
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
12
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
13
- };
14
- exports.__esModule = true;
15
- exports["default"] = void 0;
16
- __exportStar(require("./types.js"), exports);
17
- var lib_js_1 = require("./lib.js");
18
- __createBinding(exports, lib_js_1, "default");
19
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/index.ts"],"names":[],"mappings":";AAAA,mBAAmB;AACnB,eAAe;;;;;;;;;;;;;AAEf,6CAA0B;AAC1B,mCAAkC;AAAzB,8CAAO","sourcesContent":["// /source/index.ts\n// Export away!\n\nexport * from './types.js'\nexport { default } from './lib.js'\n"]}
package/dist/cjs/lib.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import { Options, RateLimitRequestHandler, LegacyStore, Store } from './types.js';
2
- /**
3
- *
4
- * Create an instance of IP rate-limiting middleware for Express.
5
- *
6
- * @param passedOptions {Options} - Options to configure the rate limiter
7
- *
8
- * @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration
9
- *
10
- * @public
11
- */
12
- declare const rateLimit: (passedOptions?: (Omit<Partial<Options>, "store"> & {
13
- store?: LegacyStore | Store | undefined;
14
- }) | undefined) => RateLimitRequestHandler;
15
- export default rateLimit;