express-rate-limit 8.0.0 → 8.1.0

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.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // source/index.ts
@@ -39,20 +29,18 @@ module.exports = __toCommonJS(index_exports);
39
29
 
40
30
  // source/ip-key-generator.ts
41
31
  var import_node_net = require("node:net");
42
- var import_ip = __toESM(require("ip"), 1);
32
+ var import_ip_address = require("ip-address");
43
33
  function ipKeyGenerator(ip, ipv6Subnet = 56) {
44
34
  if (ipv6Subnet && (0, import_node_net.isIPv6)(ip)) {
45
- return `${import_ip.default.mask(
46
- ip,
47
- import_ip.default.fromPrefixLen(ipv6Subnet)
48
- )}/${ipv6Subnet}`;
35
+ return `${new import_ip_address.Address6(`${ip}/${ipv6Subnet}`).startAddress().correctForm()}/${ipv6Subnet}`;
49
36
  }
50
37
  return ip;
51
38
  }
52
39
 
53
40
  // source/memory-store.ts
54
41
  var MemoryStore = class {
55
- constructor() {
42
+ constructor(validations2) {
43
+ this.validations = validations2;
56
44
  /**
57
45
  * These two maps store usage (requests) and reset time by key (for example, IP
58
46
  * addresses or API keys).
@@ -78,6 +66,7 @@ var MemoryStore = class {
78
66
  */
79
67
  init(options) {
80
68
  this.windowMs = options.windowMs;
69
+ this.validations?.windowMs(this.windowMs);
81
70
  if (this.interval) clearInterval(this.interval);
82
71
  this.interval = setInterval(() => {
83
72
  this.clearExpired();
@@ -250,7 +239,7 @@ var setDraft6Headers = (response, info, windowMs) => {
250
239
  response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
251
240
  response.setHeader("RateLimit-Limit", info.limit.toString());
252
241
  response.setHeader("RateLimit-Remaining", info.remaining.toString());
253
- if (resetSeconds)
242
+ if (typeof resetSeconds === "number")
254
243
  response.setHeader("RateLimit-Reset", resetSeconds.toString());
255
244
  };
256
245
  var setDraft7Headers = (response, info, windowMs) => {
@@ -380,6 +369,21 @@ var validations = {
380
369
  );
381
370
  }
382
371
  },
372
+ /**
373
+ * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
374
+ *
375
+ * @param request {Request} - The Express request object.
376
+ *
377
+ * @returns {void}
378
+ */
379
+ forwardedHeader(request) {
380
+ if (request.headers.forwarded && request.ip === request.socket?.remoteAddress) {
381
+ throw new ValidationError(
382
+ "ERR_ERL_FORWARDED_HEADER",
383
+ `The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.`
384
+ );
385
+ }
386
+ },
383
387
  /**
384
388
  * Ensures totalHits value from store is a positive integer.
385
389
  *
@@ -448,7 +452,7 @@ var validations = {
448
452
  if (limit === 0) {
449
453
  throw new ChangeWarning(
450
454
  "WRN_ERL_MAX_ZERO",
451
- `Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7`
455
+ "Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7"
452
456
  );
453
457
  }
454
458
  },
@@ -480,7 +484,7 @@ var validations = {
480
484
  if (onLimitReached) {
481
485
  throw new ChangeWarning(
482
486
  "WRN_ERL_DEPRECATED_ON_LIMIT_REACHED",
483
- `The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.`
487
+ "The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7."
484
488
  );
485
489
  }
486
490
  },
@@ -559,7 +563,7 @@ var validations = {
559
563
  }
560
564
  throw new ValidationError(
561
565
  "ERR_ERL_CREATED_IN_REQUEST_HANDLER",
562
- `express-rate-limit instance should be created at app initialization, not when responding to a request.`
566
+ "express-rate-limit instance should be created at app initialization, not when responding to a request."
563
567
  );
564
568
  }
565
569
  },
@@ -590,7 +594,22 @@ var validations = {
590
594
  if ((src.includes("req.ip") || src.includes("request.ip")) && !src.includes("ipKeyGenerator")) {
591
595
  throw new ValidationError(
592
596
  "ERR_ERL_KEY_GEN_IPV6",
593
- `Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits.`
597
+ "Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits."
598
+ );
599
+ }
600
+ },
601
+ /**
602
+ * Checks to see if the window duration is greater than 2^32 - 1. This is only
603
+ * called by the default MemoryStore, since it uses Node's setInterval method.
604
+ *
605
+ * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
606
+ */
607
+ windowMs(windowMs) {
608
+ const SET_TIMEOUT_MAX = 2 ** 31 - 1;
609
+ if (typeof windowMs !== "number" || Number.isNaN(windowMs) || windowMs < 1 || windowMs > SET_TIMEOUT_MAX) {
610
+ throw new ValidationError(
611
+ "ERR_ERL_WINDOW_MS",
612
+ `Invalid windowMs value: ${windowMs}${typeof windowMs !== "number" ? ` (${typeof windowMs})` : ""}, must be a number between 1 and ${SET_TIMEOUT_MAX} when using the default MemoryStore`
594
613
  );
595
614
  }
596
615
  }
@@ -719,6 +738,7 @@ var parseOptions = (passedOptions) => {
719
738
  validations2.ip(request.ip);
720
739
  validations2.trustProxy(request);
721
740
  validations2.xForwardedForHeader(request);
741
+ validations2.forwardedHeader(request);
722
742
  const ip = request.ip;
723
743
  let subnet = 56;
724
744
  if ((0, import_node_net3.isIPv6)(ip)) {
@@ -744,7 +764,9 @@ var parseOptions = (passedOptions) => {
744
764
  standardHeaders,
745
765
  // Note that this field is declared after the user's options are spread in,
746
766
  // so that this field doesn't get overridden with an un-promisified store!
747
- store: promisifyStore(notUndefinedOptions.store ?? new MemoryStore()),
767
+ store: promisifyStore(
768
+ notUndefinedOptions.store ?? new MemoryStore(validations2)
769
+ ),
748
770
  // Print an error to the console if a few known misconfigurations are detected.
749
771
  validations: validations2
750
772
  };
@@ -891,4 +913,4 @@ var rate_limit_default = rateLimit;
891
913
  ipKeyGenerator,
892
914
  rateLimit
893
915
  });
894
- module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;
916
+ module.exports = Object.assign(rateLimit, module.exports);
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- // Generated by dts-bundle-generator v9.5.1
1
+ // Generated by dts-bundle-generator v8.1.2
2
2
 
3
- import { NextFunction, Request as Request$1, RequestHandler, Response as Response$1 } from 'express';
3
+ import { NextFunction, Request, RequestHandler, Response } from 'express';
4
4
 
5
5
  /**
6
6
  * Returns the IP address itself for IPv4, or a CIDR-notation subnet for IPv6.
@@ -8,7 +8,7 @@ import { NextFunction, Request as Request$1, RequestHandler, Response as Respons
8
8
  * If you write a custom keyGenerator that allows a fallback to IP address for
9
9
  * unauthenticated users, return ipKeyGenerator(req.ip) rather than just req.ip.
10
10
  *
11
- * For more infomration, {@see Options.ipv6Subnet}.
11
+ * For more information, {@see Options.ipv6Subnet}.
12
12
  *
13
13
  * @param ip {string} - The IP address to process, usually request.ip.
14
14
  * @param ipv6Subnet {number | false} - The subnet mask for IPv6 addresses.
@@ -60,6 +60,14 @@ declare const validations: {
60
60
  * @returns {void}
61
61
  */
62
62
  xForwardedForHeader(request: Request): void;
63
+ /**
64
+ * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
65
+ *
66
+ * @param request {Request} - The Express request object.
67
+ *
68
+ * @returns {void}
69
+ */
70
+ forwardedHeader(request: Request): void;
63
71
  /**
64
72
  * Ensures totalHits value from store is a positive integer.
65
73
  *
@@ -141,6 +149,13 @@ declare const validations: {
141
149
  ipv6Subnet(ipv6Subnet?: any): void;
142
150
  ipv6SubnetOrKeyGenerator(options: Partial<Options>): void;
143
151
  keyGeneratorIpFallback(keyGenerator?: ValueDeterminingMiddleware<string>): void;
152
+ /**
153
+ * Checks to see if the window duration is greater than 2^32 - 1. This is only
154
+ * called by the default MemoryStore, since it uses Node's setInterval method.
155
+ *
156
+ * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
157
+ */
158
+ windowMs(windowMs: number): void;
144
159
  };
145
160
  export type Validations = typeof validations;
146
161
  /**
@@ -496,6 +511,7 @@ export type Client = {
496
511
  * @public
497
512
  */
498
513
  export declare class MemoryStore implements Store {
514
+ private validations?;
499
515
  /**
500
516
  * The duration of time before which all hit counts are reset (in milliseconds).
501
517
  */
@@ -521,6 +537,7 @@ export declare class MemoryStore implements Store {
521
537
  * cannot affect other instances.
522
538
  */
523
539
  localKeys: boolean;
540
+ constructor(validations?: Validations | undefined);
524
541
  /**
525
542
  * Method that initializes the store.
526
543
  *
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- // Generated by dts-bundle-generator v9.5.1
1
+ // Generated by dts-bundle-generator v8.1.2
2
2
 
3
- import { NextFunction, Request as Request$1, RequestHandler, Response as Response$1 } from 'express';
3
+ import { NextFunction, Request, RequestHandler, Response } from 'express';
4
4
 
5
5
  /**
6
6
  * Returns the IP address itself for IPv4, or a CIDR-notation subnet for IPv6.
@@ -8,7 +8,7 @@ import { NextFunction, Request as Request$1, RequestHandler, Response as Respons
8
8
  * If you write a custom keyGenerator that allows a fallback to IP address for
9
9
  * unauthenticated users, return ipKeyGenerator(req.ip) rather than just req.ip.
10
10
  *
11
- * For more infomration, {@see Options.ipv6Subnet}.
11
+ * For more information, {@see Options.ipv6Subnet}.
12
12
  *
13
13
  * @param ip {string} - The IP address to process, usually request.ip.
14
14
  * @param ipv6Subnet {number | false} - The subnet mask for IPv6 addresses.
@@ -60,6 +60,14 @@ declare const validations: {
60
60
  * @returns {void}
61
61
  */
62
62
  xForwardedForHeader(request: Request): void;
63
+ /**
64
+ * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
65
+ *
66
+ * @param request {Request} - The Express request object.
67
+ *
68
+ * @returns {void}
69
+ */
70
+ forwardedHeader(request: Request): void;
63
71
  /**
64
72
  * Ensures totalHits value from store is a positive integer.
65
73
  *
@@ -141,6 +149,13 @@ declare const validations: {
141
149
  ipv6Subnet(ipv6Subnet?: any): void;
142
150
  ipv6SubnetOrKeyGenerator(options: Partial<Options>): void;
143
151
  keyGeneratorIpFallback(keyGenerator?: ValueDeterminingMiddleware<string>): void;
152
+ /**
153
+ * Checks to see if the window duration is greater than 2^32 - 1. This is only
154
+ * called by the default MemoryStore, since it uses Node's setInterval method.
155
+ *
156
+ * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
157
+ */
158
+ windowMs(windowMs: number): void;
144
159
  };
145
160
  export type Validations = typeof validations;
146
161
  /**
@@ -496,6 +511,7 @@ export type Client = {
496
511
  * @public
497
512
  */
498
513
  export declare class MemoryStore implements Store {
514
+ private validations?;
499
515
  /**
500
516
  * The duration of time before which all hit counts are reset (in milliseconds).
501
517
  */
@@ -521,6 +537,7 @@ export declare class MemoryStore implements Store {
521
537
  * cannot affect other instances.
522
538
  */
523
539
  localKeys: boolean;
540
+ constructor(validations?: Validations | undefined);
524
541
  /**
525
542
  * Method that initializes the store.
526
543
  *
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- // Generated by dts-bundle-generator v9.5.1
1
+ // Generated by dts-bundle-generator v8.1.2
2
2
 
3
- import { NextFunction, Request as Request$1, RequestHandler, Response as Response$1 } from 'express';
3
+ import { NextFunction, Request, RequestHandler, Response } from 'express';
4
4
 
5
5
  /**
6
6
  * Returns the IP address itself for IPv4, or a CIDR-notation subnet for IPv6.
@@ -8,7 +8,7 @@ import { NextFunction, Request as Request$1, RequestHandler, Response as Respons
8
8
  * If you write a custom keyGenerator that allows a fallback to IP address for
9
9
  * unauthenticated users, return ipKeyGenerator(req.ip) rather than just req.ip.
10
10
  *
11
- * For more infomration, {@see Options.ipv6Subnet}.
11
+ * For more information, {@see Options.ipv6Subnet}.
12
12
  *
13
13
  * @param ip {string} - The IP address to process, usually request.ip.
14
14
  * @param ipv6Subnet {number | false} - The subnet mask for IPv6 addresses.
@@ -60,6 +60,14 @@ declare const validations: {
60
60
  * @returns {void}
61
61
  */
62
62
  xForwardedForHeader(request: Request): void;
63
+ /**
64
+ * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
65
+ *
66
+ * @param request {Request} - The Express request object.
67
+ *
68
+ * @returns {void}
69
+ */
70
+ forwardedHeader(request: Request): void;
63
71
  /**
64
72
  * Ensures totalHits value from store is a positive integer.
65
73
  *
@@ -141,6 +149,13 @@ declare const validations: {
141
149
  ipv6Subnet(ipv6Subnet?: any): void;
142
150
  ipv6SubnetOrKeyGenerator(options: Partial<Options>): void;
143
151
  keyGeneratorIpFallback(keyGenerator?: ValueDeterminingMiddleware<string>): void;
152
+ /**
153
+ * Checks to see if the window duration is greater than 2^32 - 1. This is only
154
+ * called by the default MemoryStore, since it uses Node's setInterval method.
155
+ *
156
+ * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
157
+ */
158
+ windowMs(windowMs: number): void;
144
159
  };
145
160
  export type Validations = typeof validations;
146
161
  /**
@@ -496,6 +511,7 @@ export type Client = {
496
511
  * @public
497
512
  */
498
513
  export declare class MemoryStore implements Store {
514
+ private validations?;
499
515
  /**
500
516
  * The duration of time before which all hit counts are reset (in milliseconds).
501
517
  */
@@ -521,6 +537,7 @@ export declare class MemoryStore implements Store {
521
537
  * cannot affect other instances.
522
538
  */
523
539
  localKeys: boolean;
540
+ constructor(validations?: Validations | undefined);
524
541
  /**
525
542
  * Method that initializes the store.
526
543
  *
package/dist/index.mjs CHANGED
@@ -1,19 +1,17 @@
1
1
  // source/ip-key-generator.ts
2
2
  import { isIPv6 } from "node:net";
3
- import iptools from "ip";
3
+ import { Address6 } from "ip-address";
4
4
  function ipKeyGenerator(ip, ipv6Subnet = 56) {
5
5
  if (ipv6Subnet && isIPv6(ip)) {
6
- return `${iptools.mask(
7
- ip,
8
- iptools.fromPrefixLen(ipv6Subnet)
9
- )}/${ipv6Subnet}`;
6
+ return `${new Address6(`${ip}/${ipv6Subnet}`).startAddress().correctForm()}/${ipv6Subnet}`;
10
7
  }
11
8
  return ip;
12
9
  }
13
10
 
14
11
  // source/memory-store.ts
15
12
  var MemoryStore = class {
16
- constructor() {
13
+ constructor(validations2) {
14
+ this.validations = validations2;
17
15
  /**
18
16
  * These two maps store usage (requests) and reset time by key (for example, IP
19
17
  * addresses or API keys).
@@ -39,6 +37,7 @@ var MemoryStore = class {
39
37
  */
40
38
  init(options) {
41
39
  this.windowMs = options.windowMs;
40
+ this.validations?.windowMs(this.windowMs);
42
41
  if (this.interval) clearInterval(this.interval);
43
42
  this.interval = setInterval(() => {
44
43
  this.clearExpired();
@@ -211,7 +210,7 @@ var setDraft6Headers = (response, info, windowMs) => {
211
210
  response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
212
211
  response.setHeader("RateLimit-Limit", info.limit.toString());
213
212
  response.setHeader("RateLimit-Remaining", info.remaining.toString());
214
- if (resetSeconds)
213
+ if (typeof resetSeconds === "number")
215
214
  response.setHeader("RateLimit-Reset", resetSeconds.toString());
216
215
  };
217
216
  var setDraft7Headers = (response, info, windowMs) => {
@@ -341,6 +340,21 @@ var validations = {
341
340
  );
342
341
  }
343
342
  },
343
+ /**
344
+ * Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
345
+ *
346
+ * @param request {Request} - The Express request object.
347
+ *
348
+ * @returns {void}
349
+ */
350
+ forwardedHeader(request) {
351
+ if (request.headers.forwarded && request.ip === request.socket?.remoteAddress) {
352
+ throw new ValidationError(
353
+ "ERR_ERL_FORWARDED_HEADER",
354
+ `The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.`
355
+ );
356
+ }
357
+ },
344
358
  /**
345
359
  * Ensures totalHits value from store is a positive integer.
346
360
  *
@@ -409,7 +423,7 @@ var validations = {
409
423
  if (limit === 0) {
410
424
  throw new ChangeWarning(
411
425
  "WRN_ERL_MAX_ZERO",
412
- `Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7`
426
+ "Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7"
413
427
  );
414
428
  }
415
429
  },
@@ -441,7 +455,7 @@ var validations = {
441
455
  if (onLimitReached) {
442
456
  throw new ChangeWarning(
443
457
  "WRN_ERL_DEPRECATED_ON_LIMIT_REACHED",
444
- `The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.`
458
+ "The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7."
445
459
  );
446
460
  }
447
461
  },
@@ -520,7 +534,7 @@ var validations = {
520
534
  }
521
535
  throw new ValidationError(
522
536
  "ERR_ERL_CREATED_IN_REQUEST_HANDLER",
523
- `express-rate-limit instance should be created at app initialization, not when responding to a request.`
537
+ "express-rate-limit instance should be created at app initialization, not when responding to a request."
524
538
  );
525
539
  }
526
540
  },
@@ -551,7 +565,22 @@ var validations = {
551
565
  if ((src.includes("req.ip") || src.includes("request.ip")) && !src.includes("ipKeyGenerator")) {
552
566
  throw new ValidationError(
553
567
  "ERR_ERL_KEY_GEN_IPV6",
554
- `Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits.`
568
+ "Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits."
569
+ );
570
+ }
571
+ },
572
+ /**
573
+ * Checks to see if the window duration is greater than 2^32 - 1. This is only
574
+ * called by the default MemoryStore, since it uses Node's setInterval method.
575
+ *
576
+ * See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
577
+ */
578
+ windowMs(windowMs) {
579
+ const SET_TIMEOUT_MAX = 2 ** 31 - 1;
580
+ if (typeof windowMs !== "number" || Number.isNaN(windowMs) || windowMs < 1 || windowMs > SET_TIMEOUT_MAX) {
581
+ throw new ValidationError(
582
+ "ERR_ERL_WINDOW_MS",
583
+ `Invalid windowMs value: ${windowMs}${typeof windowMs !== "number" ? ` (${typeof windowMs})` : ""}, must be a number between 1 and ${SET_TIMEOUT_MAX} when using the default MemoryStore`
555
584
  );
556
585
  }
557
586
  }
@@ -680,6 +709,7 @@ var parseOptions = (passedOptions) => {
680
709
  validations2.ip(request.ip);
681
710
  validations2.trustProxy(request);
682
711
  validations2.xForwardedForHeader(request);
712
+ validations2.forwardedHeader(request);
683
713
  const ip = request.ip;
684
714
  let subnet = 56;
685
715
  if (isIPv62(ip)) {
@@ -705,7 +735,9 @@ var parseOptions = (passedOptions) => {
705
735
  standardHeaders,
706
736
  // Note that this field is declared after the user's options are spread in,
707
737
  // so that this field doesn't get overridden with an un-promisified store!
708
- store: promisifyStore(notUndefinedOptions.store ?? new MemoryStore()),
738
+ store: promisifyStore(
739
+ notUndefinedOptions.store ?? new MemoryStore(validations2)
740
+ ),
709
741
  // Print an error to the console if a few known misconfigurations are detected.
710
742
  validations: validations2
711
743
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-rate-limit",
3
- "version": "8.0.0",
3
+ "version": "8.1.0",
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",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "scripts": {
58
58
  "clean": "del-cli dist/ coverage/ *.log *.tmp *.bak *.tgz",
59
- "build:cjs": "esbuild --packages=external --platform=node --bundle --target=es2022 --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",
59
+ "build:cjs": "esbuild --packages=external --platform=node --bundle --target=es2022 --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = Object.assign(rateLimit, module.exports);\" source/index.ts",
60
60
  "build:esm": "esbuild --packages=external --platform=node --bundle --target=es2022 --format=esm --outfile=dist/index.mjs source/index.ts",
61
61
  "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",
62
62
  "compile": "run-s clean build:*",
@@ -73,41 +73,40 @@
73
73
  "pre-commit": "lint-staged",
74
74
  "prepare": "run-s compile && husky"
75
75
  },
76
- "dependencies": {
77
- "ip": "2.0.1"
78
- },
79
76
  "peerDependencies": {
80
77
  "express": ">= 4.11"
81
78
  },
82
79
  "devDependencies": {
83
- "@biomejs/biome": "2.1.1",
80
+ "@biomejs/biome": "2.2.2",
84
81
  "@express-rate-limit/prettier": "1.1.1",
85
82
  "@express-rate-limit/tsconfig": "1.0.2",
86
- "@jest/globals": "30.0.4",
83
+ "@jest/globals": "30.1.2",
87
84
  "@types/express": "5.0.3",
88
- "@types/ip": "1.1.3",
89
85
  "@types/jest": "30.0.0",
90
- "@types/node": "24.0.14",
86
+ "@types/node": "24.3.0",
91
87
  "@types/supertest": "6.0.3",
92
88
  "del-cli": "6.0.0",
93
- "dts-bundle-generator": "9.5.1",
94
- "esbuild": "0.25.6",
89
+ "dts-bundle-generator": "8.1.2",
90
+ "esbuild": "0.25.9",
95
91
  "express": "5.1.0",
96
92
  "husky": "9.1.7",
97
- "jest": "30.0.4",
98
- "lint-staged": "16.1.2",
99
- "mintlify": "4.2.15",
93
+ "jest": "30.1.2",
94
+ "lint-staged": "16.1.6",
95
+ "mintlify": "4.2.94",
100
96
  "npm-run-all": "4.1.5",
101
97
  "prettier": "3.6.2",
102
98
  "ratelimit-header-parser": "0.1.0",
103
- "supertest": "7.1.3",
104
- "ts-jest": "29.4.0",
99
+ "supertest": "7.1.4",
100
+ "ts-jest": "29.4.1",
105
101
  "ts-node": "10.9.2",
106
- "typescript": "5.8.3"
102
+ "typescript": "5.9.2"
107
103
  },
108
104
  "prettier": "@express-rate-limit/prettier",
109
105
  "lint-staged": {
110
106
  "*.{js,ts,json}": "biome check --write",
111
107
  "*.{md,yaml}": "prettier --write"
108
+ },
109
+ "dependencies": {
110
+ "ip-address": "10.0.1"
112
111
  }
113
112
  }