@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 +68 -5
- package/dist/throttler.service.d.ts +1 -1
- package/dist/throttler.service.js +10 -10
- package/dist/throttler.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +38 -36
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
|
|
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
|
-
|
|
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 `@
|
|
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
|
-
|
|
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
|
|
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(
|
|
30
|
+
this.timeoutIds.set(key, this.timeoutIds.get(key).filter((id) => id !== timeoutId));
|
|
31
31
|
}, ttlMilliseconds);
|
|
32
|
-
this.timeoutIds.get(
|
|
32
|
+
this.timeoutIds.get(key).push(timeoutId);
|
|
33
33
|
}
|
|
34
|
-
clearExpirationTimes(
|
|
35
|
-
this.timeoutIds.get(
|
|
36
|
-
this.timeoutIds.set(
|
|
34
|
+
clearExpirationTimes(key) {
|
|
35
|
+
this.timeoutIds.get(key).forEach(clearTimeout);
|
|
36
|
+
this.timeoutIds.set(key, []);
|
|
37
37
|
}
|
|
38
|
-
|
|
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(
|
|
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(
|
|
52
|
-
this.timeoutIds.set(
|
|
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.
|
|
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":";;;;;;;;;AAAA,2CAAmE;AAS5D,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAA7B;QACG,aAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;QAC3D,eAAU,GAAkC,IAAI,GAAG,EAAE,CAAC;IA6HhE,CAAC;IA3HC,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAKO,iBAAiB,CAAC,GAAW;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1E,CAAC;IAKO,sBAAsB,CAAC,GAAW;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/E,CAAC;IAKO,iBAAiB,CAAC,GAAW,EAAE,eAAuB,EAAE,aAAqB;QACnF,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5C,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,GAAG,CACjB,
|
|
1
|
+
{"version":3,"file":"throttler.service.js","sourceRoot":"","sources":["../src/throttler.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAmE;AAS5D,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAA7B;QACG,aAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;QAC3D,eAAU,GAAkC,IAAI,GAAG,EAAE,CAAC;IA6HhE,CAAC;IA3HC,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAKO,iBAAiB,CAAC,GAAW;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1E,CAAC;IAKO,sBAAsB,CAAC,GAAW;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/E,CAAC;IAKO,iBAAiB,CAAC,GAAW,EAAE,eAAuB,EAAE,aAAqB;QACnF,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5C,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,GAAG,CACjB,GAAG,EACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,CAC1D,CAAC;QACJ,CAAC,EAAE,eAAe,CAAC,CAAC;QACpB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;IAKO,oBAAoB,CAAC,GAAW;QACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;IAKO,mBAAmB,CAAC,GAAW,EAAE,aAAqB;QAC5D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAKO,YAAY,CAAC,GAAW,EAAE,aAAqB,EAAE,GAAW;QAClE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5C,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,SAAS,CACb,GAAW,EACX,GAAW,EACX,KAAa,EACb,aAAqB,EACrB,aAAqB;QAErB,MAAM,eAAe,GAAG,GAAG,CAAC;QAC5B,MAAM,yBAAyB,GAAG,aAAa,CAAC;QAEhD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;gBACpB,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;gBACxC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe;gBACvC,cAAc,EAAE,CAAC;gBACjB,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAG/C,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC;YAC/D,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;QACzD,CAAC;QAGD,IACE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,KAAK;YAC1D,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,EAChC,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,yBAAyB,CAAC;QAChF,CAAC;QAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAG3D,IAAI,iBAAiB,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;YAC9D,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;YAC7C,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;QACzD,CAAC;QAED,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;YAC7D,YAAY;YACZ,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS;YAC1C,iBAAiB,EAAE,iBAAiB;SACrC,CAAC;IACJ,CAAC;IAED,qBAAqB;QACnB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IACxE,CAAC;CACF,CAAA;AA/HY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAU,GAAE;GACA,uBAAuB,CA+HnC"}
|