express-rate-limit 6.3.0 → 6.5.2

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/changelog.md CHANGED
@@ -6,6 +6,33 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to
7
7
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [6.5.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.5.0)
10
+
11
+ ## Changed
12
+
13
+ - The message option can now be a (sync/asynx) function that returns a value
14
+ (#311)
15
+ - Updated all dependencies
16
+
17
+ ## [6.4.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
18
+
19
+ ### Added
20
+
21
+ - Adds Express 5 (`5.0.0-beta.1`) as a supported peer dependency (#304)
22
+
23
+ ## Changed
24
+
25
+ - Tests are now run on Node 12, 14, 16 and 18 on CI (#305)
26
+ - Updated all development dependencies (#306)
27
+
28
+ ## [6.3.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
29
+
30
+ ### Changed
31
+
32
+ - Changes the build target to es2019 so that ESBuild outputs code that can run
33
+ with Node 12.
34
+ - Changes the minimum required Node version to 12.9.0.
35
+
9
36
  ## [6.2.1](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.2.1)
10
37
 
11
38
  ### Fixed
package/dist/index.cjs CHANGED
@@ -1,25 +1,21 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
6
6
  var __export = (target, all) => {
7
7
  for (var name in all)
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
- var __reExport = (target, module2, copyDefault, desc) => {
11
- if (module2 && typeof module2 === "object" || typeof module2 === "function") {
12
- for (let key of __getOwnPropNames(module2))
13
- if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
14
- __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
15
  }
16
- return target;
16
+ return to;
17
17
  };
18
- var __toCommonJS = /* @__PURE__ */ ((cache) => {
19
- return (module2, temp) => {
20
- return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
21
- };
22
- })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
19
 
24
20
  // source/index.ts
25
21
  var source_exports = {};
@@ -28,6 +24,7 @@ __export(source_exports, {
28
24
  default: () => lib_default,
29
25
  rateLimit: () => lib_default
30
26
  });
27
+ module.exports = __toCommonJS(source_exports);
31
28
 
32
29
  // source/memory-store.ts
33
30
  var calculateNextResetTime = (windowMs) => {
@@ -89,14 +86,14 @@ var promisifyStore = (passedStore) => {
89
86
  });
90
87
  }
91
88
  async decrement(key) {
92
- return Promise.resolve(legacyStore.decrement(key));
89
+ return legacyStore.decrement(key);
93
90
  }
94
91
  async resetKey(key) {
95
- return Promise.resolve(legacyStore.resetKey(key));
92
+ return legacyStore.resetKey(key);
96
93
  }
97
94
  async resetAll() {
98
95
  if (typeof legacyStore.resetAll === "function")
99
- return Promise.resolve(legacyStore.resetAll());
96
+ return legacyStore.resetAll();
100
97
  }
101
98
  }
102
99
  return new PromisifiedStore();
@@ -116,16 +113,20 @@ var parseOptions = (passedOptions) => {
116
113
  skipSuccessfulRequests: false,
117
114
  requestWasSuccessful: (_request, response) => response.statusCode < 400,
118
115
  skip: (_request, _response) => false,
119
- keyGenerator: (request, _response) => {
116
+ keyGenerator(request, _response) {
120
117
  if (!request.ip) {
121
118
  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.");
122
119
  }
123
120
  return request.ip;
124
121
  },
125
- handler: (_request, response, _next, _optionsUsed) => {
126
- response.status(config.statusCode).send(config.message);
122
+ async handler(request, response, _next, _optionsUsed) {
123
+ response.status(config.statusCode);
124
+ const message = typeof config.message === "function" ? await config.message(request, response) : config.message;
125
+ if (!response.writableEnded) {
126
+ response.send(message != null ? message : "Too many requests, please try again later.");
127
+ }
127
128
  },
128
- onLimitReached: (_request, _response, _optionsUsed) => {
129
+ onLimitReached(_request, _response, _optionsUsed) {
129
130
  },
130
131
  ...notUndefinedOptions,
131
132
  store: promisifyStore((_c = notUndefinedOptions.store) != null ? _c : new MemoryStore())
@@ -233,5 +234,4 @@ var omitUndefinedOptions = (passedOptions) => {
233
234
  return omittedOptions;
234
235
  };
235
236
  var lib_default = rateLimit;
236
- module.exports = __toCommonJS(source_exports);
237
237
  module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Generated by dts-bundle-generator v6.4.0
1
+ // Generated by dts-bundle-generator v6.12.0
2
2
 
3
3
  import { NextFunction, Request, RequestHandler, Response } from 'express';
4
4
 
@@ -152,7 +152,7 @@ export interface Options {
152
152
  *
153
153
  * Defaults to `'Too many requests, please try again later.'`
154
154
  */
155
- readonly message: any;
155
+ readonly message: any | ValueDeterminingMiddleware<any>;
156
156
  /**
157
157
  * The HTTP status code to send back when a client is rate limited.
158
158
  *
@@ -276,7 +276,7 @@ export interface RateLimitInfo {
276
276
  *
277
277
  * @public
278
278
  */
279
- export declare const rateLimit: (passedOptions?: Partial<Options> | undefined) => RateLimitRequestHandler;
279
+ export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
280
280
  /**
281
281
  * A `Store` that stores the hit count for each client in memory.
282
282
  *
package/dist/index.mjs CHANGED
@@ -58,14 +58,14 @@ var promisifyStore = (passedStore) => {
58
58
  });
59
59
  }
60
60
  async decrement(key) {
61
- return Promise.resolve(legacyStore.decrement(key));
61
+ return legacyStore.decrement(key);
62
62
  }
63
63
  async resetKey(key) {
64
- return Promise.resolve(legacyStore.resetKey(key));
64
+ return legacyStore.resetKey(key);
65
65
  }
66
66
  async resetAll() {
67
67
  if (typeof legacyStore.resetAll === "function")
68
- return Promise.resolve(legacyStore.resetAll());
68
+ return legacyStore.resetAll();
69
69
  }
70
70
  }
71
71
  return new PromisifiedStore();
@@ -85,16 +85,20 @@ var parseOptions = (passedOptions) => {
85
85
  skipSuccessfulRequests: false,
86
86
  requestWasSuccessful: (_request, response) => response.statusCode < 400,
87
87
  skip: (_request, _response) => false,
88
- keyGenerator: (request, _response) => {
88
+ keyGenerator(request, _response) {
89
89
  if (!request.ip) {
90
90
  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.");
91
91
  }
92
92
  return request.ip;
93
93
  },
94
- handler: (_request, response, _next, _optionsUsed) => {
95
- response.status(config.statusCode).send(config.message);
94
+ async handler(request, response, _next, _optionsUsed) {
95
+ response.status(config.statusCode);
96
+ const message = typeof config.message === "function" ? await config.message(request, response) : config.message;
97
+ if (!response.writableEnded) {
98
+ response.send(message != null ? message : "Too many requests, please try again later.");
99
+ }
96
100
  },
97
- onLimitReached: (_request, _response, _optionsUsed) => {
101
+ onLimitReached(_request, _response, _optionsUsed) {
98
102
  },
99
103
  ...notUndefinedOptions,
100
104
  store: promisifyStore((_c = notUndefinedOptions.store) != null ? _c : new MemoryStore())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-rate-limit",
3
- "version": "6.3.0",
3
+ "version": "6.5.2",
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",
@@ -30,6 +30,7 @@
30
30
  "type": "module",
31
31
  "exports": {
32
32
  ".": {
33
+ "types": "./dist/index.d.ts",
33
34
  "import": "./dist/index.mjs",
34
35
  "require": "./dist/index.cjs"
35
36
  }
@@ -67,28 +68,28 @@
67
68
  "prepare": "run-s compile && husky install config/husky"
68
69
  },
69
70
  "peerDependencies": {
70
- "express": "^4"
71
+ "express": "^4 || ^5"
71
72
  },
72
73
  "devDependencies": {
73
- "@jest/globals": "^27.4.6",
74
- "@types/express": "^4.17.13",
75
- "@types/jest": "^27.4.0",
76
- "@types/node": "^16.11.21",
77
- "@types/supertest": "^2.0.11",
78
- "cross-env": "^7.0.3",
79
- "del-cli": "^4.0.1",
80
- "dts-bundle-generator": "^6.4.0",
81
- "esbuild": "^0.14.12",
82
- "express": "^4.17.1",
83
- "husky": "^7.0.4",
84
- "jest": "^27.4.7",
85
- "lint-staged": "^12.2.2",
86
- "npm-run-all": "^4.1.5",
87
- "supertest": "^6.2.2",
88
- "ts-jest": "^27.1.3",
89
- "ts-node": "^10.4.0",
90
- "typescript": "^4.5.5",
91
- "xo": "^0.47.0"
74
+ "@jest/globals": "28.1.3",
75
+ "@types/express": "4.17.13",
76
+ "@types/jest": "28.1.6",
77
+ "@types/node": "18.0.6",
78
+ "@types/supertest": "2.0.12",
79
+ "cross-env": "7.0.3",
80
+ "del-cli": "4.0.1",
81
+ "dts-bundle-generator": "6.12.0",
82
+ "esbuild": "0.14.49",
83
+ "express": "4.18.1",
84
+ "husky": "8.0.1",
85
+ "jest": "28.1.3",
86
+ "lint-staged": "13.0.3",
87
+ "npm-run-all": "4.1.5",
88
+ "supertest": "6.2.4",
89
+ "ts-jest": "28.0.7",
90
+ "ts-node": "10.9.1",
91
+ "typescript": "4.7.4",
92
+ "xo": "0.49.0"
92
93
  },
93
94
  "xo": {
94
95
  "prettier": true,
package/readme.md CHANGED
@@ -239,11 +239,30 @@ const limiter = rateLimit({
239
239
  The response body to send back when a client is rate limited.
240
240
 
241
241
  May be a `string`, JSON object, or any other value that Express's
242
- [response.send](https://expressjs.com/en/4x/api.html#response.send) method
243
- supports.
242
+ [`response.send`](https://expressjs.com/en/4x/api.html#res.send) method
243
+ supports. It can also be a (sync/async) function that accepts the Express
244
+ request and response objects and then returns a `string`, JSON object or any
245
+ other value the Express `response.send` function accepts.
244
246
 
245
247
  Defaults to `'Too many requests, please try again later.'`
246
248
 
249
+ An example of using a function:
250
+
251
+ ```ts
252
+ const isPremium = async (user) => {
253
+ // ...
254
+ }
255
+
256
+ const limiter = rateLimit({
257
+ // ...
258
+ message: async (request, response) => {
259
+ if (await isPremium(request.user))
260
+ return 'You can only make 10 requests every hour.'
261
+ else return 'You can only make 5 requests every hour.'
262
+ },
263
+ })
264
+ ```
265
+
247
266
  ### `statusCode`
248
267
 
249
268
  > `number`
@@ -348,7 +367,8 @@ const limiter = rateLimit({
348
367
  Express request handler that sends back a response when a client is
349
368
  rate-limited.
350
369
 
351
- By default, sends back the `statusCode` and `message` set via the options:
370
+ By default, sends back the `statusCode` and `message` set via the `options`,
371
+ similar to this:
352
372
 
353
373
  ```ts
354
374
  const limiter = rateLimit({