@nestjs/throttler 6.5.0 → 6.6.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/README.md CHANGED
@@ -94,9 +94,46 @@ There may come upon times where you want to set up multiple throttling definitio
94
94
  export class AppModule {}
95
95
  ```
96
96
 
97
+ #### Important note on using decorators with Named Throttlers:
98
+
99
+ When you have configured named throttlers (e.g., 'short', 'medium', 'long' as shown above), both the `@SkipThrottle()` and `@Throttle()` decorators must be provided with an object where keys are the names of your throttlers.
100
+
101
+ If you use `@SkipThrottle()` without specifying the names, it will not skip any of your named throttlers. Similarly, `@Throttle()` without specifying names cannot override settings for specific named throttlers.
102
+
103
+ **Correct usage with named throttlers:**
104
+
105
+ To skip specific named throttlers:
106
+ ```typescript
107
+ @SkipThrottle({ short: true, medium: true })
108
+ @Controller('users')
109
+ export class UsersController {}
110
+ ```
111
+
112
+ To override limits for specific named throttlers:
113
+ ```typescript
114
+ @Throttle({ short: { limit: 5, ttl: 1000 }, medium: { limit: 30, ttl: 10000 } })
115
+ @Get()
116
+ findAll() {
117
+ return "Custom limits for specific throttlers";
118
+ }
119
+ ```
120
+
121
+ **Incorrect usage** (will not work as intended for named throttlers):
122
+ ```typescript
123
+ @SkipThrottle() // This will NOT skip any named throttlers
124
+ @Controller('users')
125
+ export class UsersController {}
126
+ ```
127
+
128
+ For more details on this behavior, especially if migrating from older versions, please refer to the [Migration to v5](#migrating-to-v5-from-earlier-versions) guide.
129
+
97
130
  ### Customization
98
131
 
99
- There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator, to negate the throttler for an entire class or a single route. The `@SkipThrottle()` decorator can also take in an object of string keys with boolean values, if you have more than one throttler set. If you do not pass an object, the default is to use `{ default: true }`
132
+ There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator to negate the throttler for an entire class or a single route.
133
+
134
+ The `@SkipThrottle()` decorator behaves differently based on your ThrottlerModule configuration:
135
+
136
+ 1. **For a single, default (unnamed) throttler:** You can use `@SkipThrottle()`, `@SkipThrottle(true)`, or `@SkipThrottle({ default: true })`.
100
137
 
101
138
  ```typescript
102
139
  @SkipThrottle()
@@ -104,10 +141,20 @@ There may be a time where you want to bind the guard to a controller or globally
104
141
  export class UsersController {}
105
142
  ```
106
143
 
107
- This `@SkipThrottle()` decorator can be used to skip a route or a class or to negate the skipping of a route in a class that is skipped.
144
+ 2. **For multiple named throttlers** (e.g., 'short', 'medium'): You must provide an object where keys are the names of the throttlers you wish to skip, and values are `true`.
108
145
 
109
146
  ```typescript
110
- @SkipThrottle()
147
+ @SkipThrottle({ short: true, medium: true })
148
+ @Controller('users')
149
+ export class UsersController {}
150
+ ```
151
+
152
+ > **Important:** Simply using `@SkipThrottle()` without an object will not skip any named throttlers. See the [Multiple Throttler Definitions](#multiple-throttler-definitions) section for a detailed example and explanation.
153
+
154
+ The `@SkipThrottle()` decorator can also be used to negate the skipping of a route in a class that is already skipped:
155
+
156
+ ```typescript
157
+ @SkipThrottle({ default: true })
111
158
  @Controller('users')
112
159
  export class UsersController {
113
160
  // Rate limiting is applied to this route.
@@ -373,13 +420,29 @@ If you migrate to v5 from earlier versions, you need to wrap your options in an
373
420
 
374
421
  If you are using a custom storage, you should wrap you `ttl` and `limit` in an array and assign it to the `throttlers` property of the options object.
375
422
 
376
- Any `@ThrottleSkip()` should now take in an object with `string: boolean` props. The strings are the names of the throttlers. If you do not have a name, pass the string `'default'`, as this is what will be used under the hood otherwise.
423
+ Any `@SkipThrottle()` should now take in an object with `string: boolean` props. The strings are the names of the throttlers. If you do not have a name, pass the string `'default'`, as this is what will be used under the hood otherwise.
424
+
425
+ **Migration examples for decorators:**
426
+
427
+ ```typescript
428
+ // Before v5
429
+ @SkipThrottle()
430
+ @Throttle(10, 60)
431
+
432
+ // After v5 (with default throttler)
433
+ @SkipThrottle({ default: true })
434
+ @Throttle({ default: { limit: 10, ttl: 60000 } })
435
+
436
+ // After v5 (with named throttlers)
437
+ @SkipThrottle({ short: true, medium: true })
438
+ @Throttle({ short: { limit: 5, ttl: 1000 }, long: { limit: 100, ttl: 60000 } })
439
+ ```
377
440
 
378
441
  Any `@Throttle()` decorators should also now take in an object with string keys, relating to the names of the throttler contexts (again, `'default'` if no name) and values of objects that have `limit` and `ttl` keys.
379
442
 
380
443
  > **Important:** The `ttl` is now in **milliseconds**. If you want to keep your ttl in seconds for readability, use the `seconds` helper from this package. It just multiplies the ttl by 1000 to make it in milliseconds.
381
444
 
382
- For more info, see the [Changelog](https://github.com/nestjs/throttler/blob/master/CHANGELOG.md#500)
445
+ > **Note:** When using named throttlers, simply using `@SkipThrottle()` without parameters will not work as expected. See the [Important note on using decorators with Named Throttlers](#important-note-on-using-decorators-with-named-throttlers) section for details.
383
446
 
384
447
  ## Community Storage Providers
385
448
 
@@ -10,7 +10,7 @@ export declare class ThrottlerStorageService implements ThrottlerStorage, OnAppl
10
10
  private getBlockExpirationTime;
11
11
  private setExpirationTime;
12
12
  private clearExpirationTimes;
13
- private resetBlockdRequest;
13
+ private resetBlockedRequest;
14
14
  private fireHitCount;
15
15
  increment(key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string): Promise<ThrottlerStorageRecord>;
16
16
  onApplicationShutdown(): void;
@@ -27,18 +27,18 @@ let ThrottlerStorageService = class ThrottlerStorageService {
27
27
  const { totalHits } = this.storage.get(key);
28
28
  totalHits.set(throttlerName, totalHits.get(throttlerName) - 1);
29
29
  clearTimeout(timeoutId);
30
- this.timeoutIds.set(throttlerName, this.timeoutIds.get(throttlerName).filter((id) => id !== timeoutId));
30
+ this.timeoutIds.set(key, this.timeoutIds.get(key).filter((id) => id !== timeoutId));
31
31
  }, ttlMilliseconds);
32
- this.timeoutIds.get(throttlerName).push(timeoutId);
32
+ this.timeoutIds.get(key).push(timeoutId);
33
33
  }
34
- clearExpirationTimes(throttlerName) {
35
- this.timeoutIds.get(throttlerName).forEach(clearTimeout);
36
- this.timeoutIds.set(throttlerName, []);
34
+ clearExpirationTimes(key) {
35
+ this.timeoutIds.get(key).forEach(clearTimeout);
36
+ this.timeoutIds.set(key, []);
37
37
  }
38
- resetBlockdRequest(key, throttlerName) {
38
+ resetBlockedRequest(key, throttlerName) {
39
39
  this.storage.get(key).isBlocked = false;
40
40
  this.storage.get(key).totalHits.set(throttlerName, 0);
41
- this.clearExpirationTimes(throttlerName);
41
+ this.clearExpirationTimes(key);
42
42
  }
43
43
  fireHitCount(key, throttlerName, ttl) {
44
44
  const { totalHits } = this.storage.get(key);
@@ -48,8 +48,8 @@ let ThrottlerStorageService = class ThrottlerStorageService {
48
48
  async increment(key, ttl, limit, blockDuration, throttlerName) {
49
49
  const ttlMilliseconds = ttl;
50
50
  const blockDurationMilliseconds = blockDuration;
51
- if (!this.timeoutIds.has(throttlerName)) {
52
- this.timeoutIds.set(throttlerName, []);
51
+ if (!this.timeoutIds.has(key)) {
52
+ this.timeoutIds.set(key, []);
53
53
  }
54
54
  if (!this.storage.has(key)) {
55
55
  this.storage.set(key, {
@@ -74,7 +74,7 @@ let ThrottlerStorageService = class ThrottlerStorageService {
74
74
  }
75
75
  const timeToBlockExpire = this.getBlockExpirationTime(key);
76
76
  if (timeToBlockExpire <= 0 && this.storage.get(key).isBlocked) {
77
- this.resetBlockdRequest(key, throttlerName);
77
+ this.resetBlockedRequest(key, throttlerName);
78
78
  this.fireHitCount(key, throttlerName, ttlMilliseconds);
79
79
  }
80
80
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"throttler.service.js","sourceRoot":"","sources":["../src/throttler.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"throttler.service.js","sourceRoot":"","sources":["../src/throttler.service.ts"],"names":[],"mappings":"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"}