@upstash/ratelimit 2.0.6 → 2.0.8
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.d.mts +88 -5
- package/dist/index.d.ts +88 -5
- package/dist/index.js +390 -187
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +390 -187
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -12,7 +12,7 @@ type EphemeralCache = {
|
|
|
12
12
|
blockUntil: (identifier: string, reset: number) => void;
|
|
13
13
|
set: (key: string, value: number) => void;
|
|
14
14
|
get: (key: string) => number | null;
|
|
15
|
-
incr: (key: string) => number;
|
|
15
|
+
incr: (key: string, incrementAmount?: number) => number;
|
|
16
16
|
pop: (key: string) => void;
|
|
17
17
|
empty: () => void;
|
|
18
18
|
size: () => number;
|
|
@@ -20,6 +20,15 @@ type EphemeralCache = {
|
|
|
20
20
|
type RegionContext = {
|
|
21
21
|
redis: Redis$1;
|
|
22
22
|
cache?: EphemeralCache;
|
|
23
|
+
/**
|
|
24
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
25
|
+
* using MGET before applying the regular limit.
|
|
26
|
+
*/
|
|
27
|
+
dynamicLimits?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* The prefix used for Redis keys
|
|
30
|
+
*/
|
|
31
|
+
prefix: string;
|
|
23
32
|
};
|
|
24
33
|
type MultiRegionContext = {
|
|
25
34
|
regionContexts: Omit<RegionContext[], "cache">;
|
|
@@ -87,6 +96,7 @@ type Algorithm<TContext> = () => {
|
|
|
87
96
|
getRemaining: (ctx: TContext, identifier: string) => Promise<{
|
|
88
97
|
remaining: number;
|
|
89
98
|
reset: number;
|
|
99
|
+
limit: number;
|
|
90
100
|
}>;
|
|
91
101
|
resetTokens: (ctx: TContext, identifier: string) => Promise<void>;
|
|
92
102
|
};
|
|
@@ -183,6 +193,16 @@ type RatelimitConfig<TContext> = {
|
|
|
183
193
|
* @default `@upstash/ratelimit`
|
|
184
194
|
*/
|
|
185
195
|
prefix?: string;
|
|
196
|
+
/**
|
|
197
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
198
|
+
* before applying the regular limit. This allows you to change the rate
|
|
199
|
+
* limit at runtime using setDynamicLimit().
|
|
200
|
+
*
|
|
201
|
+
* When enabled, adds +1 Redis command (GET) to every limit check.
|
|
202
|
+
*
|
|
203
|
+
* @default false
|
|
204
|
+
*/
|
|
205
|
+
dynamicLimits?: boolean;
|
|
186
206
|
/**
|
|
187
207
|
* If enabled, the ratelimiter will keep a global cache of identifiers, that have
|
|
188
208
|
* exhausted their ratelimit. In serverless environments this is only possible if
|
|
@@ -249,6 +269,7 @@ declare abstract class Ratelimit<TContext extends Context> {
|
|
|
249
269
|
protected readonly analytics?: Analytics;
|
|
250
270
|
protected readonly enableProtection: boolean;
|
|
251
271
|
protected readonly denyListThreshold: number;
|
|
272
|
+
protected readonly dynamicLimits: boolean;
|
|
252
273
|
constructor(config: RatelimitConfig<TContext>);
|
|
253
274
|
/**
|
|
254
275
|
* Determine if a request should pass or be rejected based on the identifier and previously chosen ratelimit.
|
|
@@ -315,13 +336,14 @@ declare abstract class Ratelimit<TContext extends Context> {
|
|
|
315
336
|
* Returns the remaining token count together with a reset timestamps
|
|
316
337
|
*
|
|
317
338
|
* @param identifier identifir to check
|
|
318
|
-
* @returns object with `remaining` and
|
|
319
|
-
* the remaining tokens
|
|
320
|
-
* tokens reset.
|
|
339
|
+
* @returns object with `remaining`, `reset`, and `limit` fields. `remaining` denotes
|
|
340
|
+
* the remaining tokens, `limit` is the effective limit (considering dynamic
|
|
341
|
+
* limits if enabled), and `reset` denotes the timestamp when the tokens reset.
|
|
321
342
|
*/
|
|
322
343
|
getRemaining: (identifier: string) => Promise<{
|
|
323
344
|
remaining: number;
|
|
324
345
|
reset: number;
|
|
346
|
+
limit: number;
|
|
325
347
|
}>;
|
|
326
348
|
/**
|
|
327
349
|
* Checks if the identifier or the values in req are in the deny list cache.
|
|
@@ -363,6 +385,46 @@ declare abstract class Ratelimit<TContext extends Context> {
|
|
|
363
385
|
* @returns list of defined values
|
|
364
386
|
*/
|
|
365
387
|
private getDefinedMembers;
|
|
388
|
+
/**
|
|
389
|
+
* Set a dynamic rate limit globally.
|
|
390
|
+
*
|
|
391
|
+
* When dynamicLimits is enabled, this limit will override the default limit
|
|
392
|
+
* set in the constructor for all requests.
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* const ratelimit = new Ratelimit({
|
|
397
|
+
* redis: Redis.fromEnv(),
|
|
398
|
+
* limiter: Ratelimit.slidingWindow(10, "10 s"),
|
|
399
|
+
* dynamicLimits: true
|
|
400
|
+
* });
|
|
401
|
+
*
|
|
402
|
+
* // Set global dynamic limit to 120 requests
|
|
403
|
+
* await ratelimit.setDynamicLimit({ limit: 120 });
|
|
404
|
+
*
|
|
405
|
+
* // Disable dynamic limit (falls back to default)
|
|
406
|
+
* await ratelimit.setDynamicLimit({ limit: false });
|
|
407
|
+
* ```
|
|
408
|
+
*
|
|
409
|
+
* @param options.limit - The new rate limit to apply globally, or false to disable
|
|
410
|
+
*/
|
|
411
|
+
setDynamicLimit: (options: {
|
|
412
|
+
limit: number | false;
|
|
413
|
+
}) => Promise<void>;
|
|
414
|
+
/**
|
|
415
|
+
* Get the current global dynamic rate limit.
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* ```ts
|
|
419
|
+
* const { dynamicLimit } = await ratelimit.getDynamicLimit();
|
|
420
|
+
* console.log(dynamicLimit); // 120 or null if not set
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* @returns Object containing the current global dynamic limit, or null if not set
|
|
424
|
+
*/
|
|
425
|
+
getDynamicLimit: () => Promise<{
|
|
426
|
+
dynamicLimit: number | null;
|
|
427
|
+
}>;
|
|
366
428
|
}
|
|
367
429
|
|
|
368
430
|
type MultiRegionRatelimitConfig = {
|
|
@@ -422,6 +484,17 @@ type MultiRegionRatelimitConfig = {
|
|
|
422
484
|
* @default true
|
|
423
485
|
*/
|
|
424
486
|
cacheScripts?: boolean;
|
|
487
|
+
/**
|
|
488
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
489
|
+
* before applying the regular limit. This allows you to change the rate
|
|
490
|
+
* limit at runtime using setDynamicLimit().
|
|
491
|
+
*
|
|
492
|
+
* Note: Dynamic limits are not yet supported for multi-region rate limiters.
|
|
493
|
+
* This option will be ignored for MultiRegionRatelimit.
|
|
494
|
+
*
|
|
495
|
+
* @default false
|
|
496
|
+
*/
|
|
497
|
+
dynamicLimits?: boolean;
|
|
425
498
|
};
|
|
426
499
|
/**
|
|
427
500
|
* Ratelimiter using serverless redis from https://upstash.com/
|
|
@@ -497,7 +570,7 @@ declare class MultiRegionRatelimit extends Ratelimit<MultiRegionContext> {
|
|
|
497
570
|
window: Duration): Algorithm<MultiRegionContext>;
|
|
498
571
|
}
|
|
499
572
|
|
|
500
|
-
type Redis = Pick<Redis$1, "get" | "set">;
|
|
573
|
+
type Redis = Pick<Redis$1, "evalsha" | "get" | "set">;
|
|
501
574
|
type RegionRatelimitConfig = {
|
|
502
575
|
/**
|
|
503
576
|
* Instance of `@upstash/redis`
|
|
@@ -569,6 +642,16 @@ type RegionRatelimitConfig = {
|
|
|
569
642
|
* @default 6
|
|
570
643
|
*/
|
|
571
644
|
denyListThreshold?: number;
|
|
645
|
+
/**
|
|
646
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
647
|
+
* before applying the regular limit. This allows you to change the rate
|
|
648
|
+
* limit at runtime using setDynamicLimit().
|
|
649
|
+
*
|
|
650
|
+
* When enabled, adds +1 Redis command (GET) to every limit check.
|
|
651
|
+
*
|
|
652
|
+
* @default false
|
|
653
|
+
*/
|
|
654
|
+
dynamicLimits?: boolean;
|
|
572
655
|
};
|
|
573
656
|
/**
|
|
574
657
|
* Ratelimiter using serverless redis from https://upstash.com/
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ type EphemeralCache = {
|
|
|
12
12
|
blockUntil: (identifier: string, reset: number) => void;
|
|
13
13
|
set: (key: string, value: number) => void;
|
|
14
14
|
get: (key: string) => number | null;
|
|
15
|
-
incr: (key: string) => number;
|
|
15
|
+
incr: (key: string, incrementAmount?: number) => number;
|
|
16
16
|
pop: (key: string) => void;
|
|
17
17
|
empty: () => void;
|
|
18
18
|
size: () => number;
|
|
@@ -20,6 +20,15 @@ type EphemeralCache = {
|
|
|
20
20
|
type RegionContext = {
|
|
21
21
|
redis: Redis$1;
|
|
22
22
|
cache?: EphemeralCache;
|
|
23
|
+
/**
|
|
24
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
25
|
+
* using MGET before applying the regular limit.
|
|
26
|
+
*/
|
|
27
|
+
dynamicLimits?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* The prefix used for Redis keys
|
|
30
|
+
*/
|
|
31
|
+
prefix: string;
|
|
23
32
|
};
|
|
24
33
|
type MultiRegionContext = {
|
|
25
34
|
regionContexts: Omit<RegionContext[], "cache">;
|
|
@@ -87,6 +96,7 @@ type Algorithm<TContext> = () => {
|
|
|
87
96
|
getRemaining: (ctx: TContext, identifier: string) => Promise<{
|
|
88
97
|
remaining: number;
|
|
89
98
|
reset: number;
|
|
99
|
+
limit: number;
|
|
90
100
|
}>;
|
|
91
101
|
resetTokens: (ctx: TContext, identifier: string) => Promise<void>;
|
|
92
102
|
};
|
|
@@ -183,6 +193,16 @@ type RatelimitConfig<TContext> = {
|
|
|
183
193
|
* @default `@upstash/ratelimit`
|
|
184
194
|
*/
|
|
185
195
|
prefix?: string;
|
|
196
|
+
/**
|
|
197
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
198
|
+
* before applying the regular limit. This allows you to change the rate
|
|
199
|
+
* limit at runtime using setDynamicLimit().
|
|
200
|
+
*
|
|
201
|
+
* When enabled, adds +1 Redis command (GET) to every limit check.
|
|
202
|
+
*
|
|
203
|
+
* @default false
|
|
204
|
+
*/
|
|
205
|
+
dynamicLimits?: boolean;
|
|
186
206
|
/**
|
|
187
207
|
* If enabled, the ratelimiter will keep a global cache of identifiers, that have
|
|
188
208
|
* exhausted their ratelimit. In serverless environments this is only possible if
|
|
@@ -249,6 +269,7 @@ declare abstract class Ratelimit<TContext extends Context> {
|
|
|
249
269
|
protected readonly analytics?: Analytics;
|
|
250
270
|
protected readonly enableProtection: boolean;
|
|
251
271
|
protected readonly denyListThreshold: number;
|
|
272
|
+
protected readonly dynamicLimits: boolean;
|
|
252
273
|
constructor(config: RatelimitConfig<TContext>);
|
|
253
274
|
/**
|
|
254
275
|
* Determine if a request should pass or be rejected based on the identifier and previously chosen ratelimit.
|
|
@@ -315,13 +336,14 @@ declare abstract class Ratelimit<TContext extends Context> {
|
|
|
315
336
|
* Returns the remaining token count together with a reset timestamps
|
|
316
337
|
*
|
|
317
338
|
* @param identifier identifir to check
|
|
318
|
-
* @returns object with `remaining` and
|
|
319
|
-
* the remaining tokens
|
|
320
|
-
* tokens reset.
|
|
339
|
+
* @returns object with `remaining`, `reset`, and `limit` fields. `remaining` denotes
|
|
340
|
+
* the remaining tokens, `limit` is the effective limit (considering dynamic
|
|
341
|
+
* limits if enabled), and `reset` denotes the timestamp when the tokens reset.
|
|
321
342
|
*/
|
|
322
343
|
getRemaining: (identifier: string) => Promise<{
|
|
323
344
|
remaining: number;
|
|
324
345
|
reset: number;
|
|
346
|
+
limit: number;
|
|
325
347
|
}>;
|
|
326
348
|
/**
|
|
327
349
|
* Checks if the identifier or the values in req are in the deny list cache.
|
|
@@ -363,6 +385,46 @@ declare abstract class Ratelimit<TContext extends Context> {
|
|
|
363
385
|
* @returns list of defined values
|
|
364
386
|
*/
|
|
365
387
|
private getDefinedMembers;
|
|
388
|
+
/**
|
|
389
|
+
* Set a dynamic rate limit globally.
|
|
390
|
+
*
|
|
391
|
+
* When dynamicLimits is enabled, this limit will override the default limit
|
|
392
|
+
* set in the constructor for all requests.
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* const ratelimit = new Ratelimit({
|
|
397
|
+
* redis: Redis.fromEnv(),
|
|
398
|
+
* limiter: Ratelimit.slidingWindow(10, "10 s"),
|
|
399
|
+
* dynamicLimits: true
|
|
400
|
+
* });
|
|
401
|
+
*
|
|
402
|
+
* // Set global dynamic limit to 120 requests
|
|
403
|
+
* await ratelimit.setDynamicLimit({ limit: 120 });
|
|
404
|
+
*
|
|
405
|
+
* // Disable dynamic limit (falls back to default)
|
|
406
|
+
* await ratelimit.setDynamicLimit({ limit: false });
|
|
407
|
+
* ```
|
|
408
|
+
*
|
|
409
|
+
* @param options.limit - The new rate limit to apply globally, or false to disable
|
|
410
|
+
*/
|
|
411
|
+
setDynamicLimit: (options: {
|
|
412
|
+
limit: number | false;
|
|
413
|
+
}) => Promise<void>;
|
|
414
|
+
/**
|
|
415
|
+
* Get the current global dynamic rate limit.
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* ```ts
|
|
419
|
+
* const { dynamicLimit } = await ratelimit.getDynamicLimit();
|
|
420
|
+
* console.log(dynamicLimit); // 120 or null if not set
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* @returns Object containing the current global dynamic limit, or null if not set
|
|
424
|
+
*/
|
|
425
|
+
getDynamicLimit: () => Promise<{
|
|
426
|
+
dynamicLimit: number | null;
|
|
427
|
+
}>;
|
|
366
428
|
}
|
|
367
429
|
|
|
368
430
|
type MultiRegionRatelimitConfig = {
|
|
@@ -422,6 +484,17 @@ type MultiRegionRatelimitConfig = {
|
|
|
422
484
|
* @default true
|
|
423
485
|
*/
|
|
424
486
|
cacheScripts?: boolean;
|
|
487
|
+
/**
|
|
488
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
489
|
+
* before applying the regular limit. This allows you to change the rate
|
|
490
|
+
* limit at runtime using setDynamicLimit().
|
|
491
|
+
*
|
|
492
|
+
* Note: Dynamic limits are not yet supported for multi-region rate limiters.
|
|
493
|
+
* This option will be ignored for MultiRegionRatelimit.
|
|
494
|
+
*
|
|
495
|
+
* @default false
|
|
496
|
+
*/
|
|
497
|
+
dynamicLimits?: boolean;
|
|
425
498
|
};
|
|
426
499
|
/**
|
|
427
500
|
* Ratelimiter using serverless redis from https://upstash.com/
|
|
@@ -497,7 +570,7 @@ declare class MultiRegionRatelimit extends Ratelimit<MultiRegionContext> {
|
|
|
497
570
|
window: Duration): Algorithm<MultiRegionContext>;
|
|
498
571
|
}
|
|
499
572
|
|
|
500
|
-
type Redis = Pick<Redis$1, "get" | "set">;
|
|
573
|
+
type Redis = Pick<Redis$1, "evalsha" | "get" | "set">;
|
|
501
574
|
type RegionRatelimitConfig = {
|
|
502
575
|
/**
|
|
503
576
|
* Instance of `@upstash/redis`
|
|
@@ -569,6 +642,16 @@ type RegionRatelimitConfig = {
|
|
|
569
642
|
* @default 6
|
|
570
643
|
*/
|
|
571
644
|
denyListThreshold?: number;
|
|
645
|
+
/**
|
|
646
|
+
* If enabled, the ratelimiter will check for dynamic limits in Redis
|
|
647
|
+
* before applying the regular limit. This allows you to change the rate
|
|
648
|
+
* limit at runtime using setDynamicLimit().
|
|
649
|
+
*
|
|
650
|
+
* When enabled, adds +1 Redis command (GET) to every limit check.
|
|
651
|
+
*
|
|
652
|
+
* @default false
|
|
653
|
+
*/
|
|
654
|
+
dynamicLimits?: boolean;
|
|
572
655
|
};
|
|
573
656
|
/**
|
|
574
657
|
* Ratelimiter using serverless redis from https://upstash.com/
|