@depup/rate-limiter-flexible 9.1.1-depup.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.
Files changed (42) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +25 -0
  3. package/changes.json +5 -0
  4. package/index.js +55 -0
  5. package/lib/BurstyRateLimiter.js +78 -0
  6. package/lib/ExpressBruteFlexible.js +359 -0
  7. package/lib/RLWrapperBlackAndWhite.js +195 -0
  8. package/lib/RLWrapperTimeouts.js +82 -0
  9. package/lib/RateLimiterAbstract.js +125 -0
  10. package/lib/RateLimiterCluster.js +367 -0
  11. package/lib/RateLimiterDrizzle.js +174 -0
  12. package/lib/RateLimiterDrizzleNonAtomic.js +175 -0
  13. package/lib/RateLimiterDynamo.js +401 -0
  14. package/lib/RateLimiterEtcd.js +63 -0
  15. package/lib/RateLimiterEtcdNonAtomic.js +80 -0
  16. package/lib/RateLimiterInsuredAbstract.js +112 -0
  17. package/lib/RateLimiterMemcache.js +150 -0
  18. package/lib/RateLimiterMemory.js +106 -0
  19. package/lib/RateLimiterMongo.js +261 -0
  20. package/lib/RateLimiterMySQL.js +400 -0
  21. package/lib/RateLimiterPostgres.js +351 -0
  22. package/lib/RateLimiterPrisma.js +127 -0
  23. package/lib/RateLimiterQueue.js +131 -0
  24. package/lib/RateLimiterRedis.js +209 -0
  25. package/lib/RateLimiterRedisNonAtomic.js +195 -0
  26. package/lib/RateLimiterRes.js +64 -0
  27. package/lib/RateLimiterSQLite.js +338 -0
  28. package/lib/RateLimiterStoreAbstract.js +349 -0
  29. package/lib/RateLimiterUnion.js +51 -0
  30. package/lib/RateLimiterValkey.js +117 -0
  31. package/lib/RateLimiterValkeyGlide.js +273 -0
  32. package/lib/component/BlockedKeys/BlockedKeys.js +75 -0
  33. package/lib/component/BlockedKeys/index.js +3 -0
  34. package/lib/component/MemoryStorage/MemoryStorage.js +83 -0
  35. package/lib/component/MemoryStorage/Record.js +40 -0
  36. package/lib/component/MemoryStorage/index.js +3 -0
  37. package/lib/component/RateLimiterEtcdTransactionFailedError.js +10 -0
  38. package/lib/component/RateLimiterQueueError.js +13 -0
  39. package/lib/component/RateLimiterSetupError.js +10 -0
  40. package/lib/constants.js +21 -0
  41. package/package.json +100 -0
  42. package/types.d.ts +581 -0
@@ -0,0 +1,21 @@
1
+ const LIMITER_TYPES = {
2
+ MEMORY: 'memory',
3
+ CLUSTER: 'cluster',
4
+ MEMCACHE: 'memcache',
5
+ MONGO: 'mongo',
6
+ REDIS: 'redis',
7
+ MYSQL: 'mysql',
8
+ POSTGRES: 'postgres',
9
+ DYNAMO: 'dynamo',
10
+ PRISMA: 'prisma',
11
+ SQLITE: 'sqlite',
12
+ VALKEY: 'valkey',
13
+ VALKEY_GLIDE: 'valkey-glide',
14
+ };
15
+
16
+ const ERR_UNKNOWN_LIMITER_TYPE_MESSAGE = 'Unknown limiter type. Use one of LIMITER_TYPES constants.';
17
+
18
+ module.exports = {
19
+ LIMITER_TYPES,
20
+ ERR_UNKNOWN_LIMITER_TYPE_MESSAGE,
21
+ };
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "@depup/rate-limiter-flexible",
3
+ "version": "9.1.1-depup.0",
4
+ "description": "[DepUp] Node.js atomic and non-atomic counters, rate limiting tools, protection from DoS and brute-force attacks at scale",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "dc:up": "docker-compose -f docker-compose.yml up -d",
8
+ "dc:down": "docker-compose -f docker-compose.yml down",
9
+ "valkey-cluster:up": "docker-compose -f docker-compose.valkey-cluster.yml up -d",
10
+ "valkey-cluster:down": "docker-compose -f docker-compose.valkey-cluster.yml down -v",
11
+ "test:valkey-cluster": "VALKEY_CLUSTER_PORT=7001 mocha test/RateLimiterValkeyGlide.test.js -- -g 'RateLimiterValkeyGlide with cluster client'",
12
+ "prisma:postgres": "prisma generate --schema=./test/RateLimiterPrisma/Postgres/schema.prisma && prisma db push --schema=./test/RateLimiterPrisma/Postgres/schema.prisma",
13
+ "drizzle:postgres": "cd ./test/RateLimiterDrizzle/Postgres && drizzle-kit push",
14
+ "test": "npm run prisma:postgres && npm run drizzle:postgres && nyc --reporter=html --reporter=text mocha \"test/**/*.test.js\"",
15
+ "debug-test": "mocha --inspect-brk lib/**/**.test.js",
16
+ "coveralls": "cat ./coverage/lcov.info | coveralls",
17
+ "eslint": "eslint --quiet lib/**/**.js test/**/**.js",
18
+ "eslint-fix": "eslint --fix lib/**/**.js test/**/**.js"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/animir/node-rate-limiter-flexible.git"
23
+ },
24
+ "keywords": [
25
+ "depup",
26
+ "dependency-bumped",
27
+ "updated-deps",
28
+ "rate-limiter-flexible",
29
+ "ratelimter",
30
+ "authorization",
31
+ "security",
32
+ "rate",
33
+ "limit",
34
+ "bruteforce",
35
+ "throttle",
36
+ "redis",
37
+ "mongodb",
38
+ "dynamodb",
39
+ "mysql",
40
+ "postgres",
41
+ "prisma",
42
+ "drizzle",
43
+ "koa",
44
+ "express",
45
+ "hapi",
46
+ "valkey",
47
+ "valkey-glide",
48
+ "GLIDE",
49
+ "cluster",
50
+ "memcached"
51
+ ],
52
+ "author": "animir <animirr@gmail.com>",
53
+ "license": "ISC",
54
+ "bugs": {
55
+ "url": "https://github.com/animir/node-rate-limiter-flexible/issues"
56
+ },
57
+ "homepage": "https://github.com/animir/node-rate-limiter-flexible#readme",
58
+ "types": "./types.d.ts",
59
+ "devDependencies": {
60
+ "@aws-sdk/client-dynamodb": "^3.431.0",
61
+ "@prisma/client": "^5.8.0",
62
+ "@valkey/valkey-glide": "^1.3.1",
63
+ "better-sqlite3": "^11.9.0",
64
+ "chai": "^4.1.2",
65
+ "coveralls": "^3.0.1",
66
+ "drizzle-kit": "^0.31.4",
67
+ "drizzle-orm": "^0.44.3",
68
+ "eslint": "^4.19.1",
69
+ "eslint-config-airbnb-base": "^12.1.0",
70
+ "eslint-plugin-import": "^2.7.0",
71
+ "eslint-plugin-node": "^6.0.1",
72
+ "eslint-plugin-security": "^1.4.0",
73
+ "etcd3": "^1.1.2",
74
+ "ioredis": "^5.3.2",
75
+ "iovalkey": "^0.3.1",
76
+ "istanbul": "^1.1.0-alpha.1",
77
+ "knex": "^3.1.0",
78
+ "memcached-mock": "^0.1.0",
79
+ "mocha": "^10.2.0",
80
+ "nyc": "^15.1.0",
81
+ "pg": "^8.16.3",
82
+ "prisma": "^5.8.0",
83
+ "redis": "^4.6.8",
84
+ "redis-mock": "^0.48.0",
85
+ "sinon": "^17.0.1",
86
+ "sqlite3": "^5.1.7"
87
+ },
88
+ "browser": {
89
+ "cluster": false,
90
+ "crypto": false
91
+ },
92
+ "depup": {
93
+ "changes": {},
94
+ "depsUpdated": 0,
95
+ "originalPackage": "rate-limiter-flexible",
96
+ "originalVersion": "9.1.1",
97
+ "processedAt": "2026-03-09T05:24:58.594Z",
98
+ "smokeTest": "passed"
99
+ }
100
+ }
package/types.d.ts ADDED
@@ -0,0 +1,581 @@
1
+ export interface IRateLimiterRes {
2
+ msBeforeNext?: number;
3
+ remainingPoints?: number;
4
+ consumedPoints?: number;
5
+ isFirstInDuration?: boolean;
6
+ }
7
+
8
+ export class RateLimiterRes {
9
+ constructor(
10
+ remainingPoints?: number,
11
+ msBeforeNext?: number,
12
+ consumedPoints?: number,
13
+ isFirstInDuration?: boolean
14
+ );
15
+
16
+ readonly msBeforeNext: number;
17
+ readonly remainingPoints: number;
18
+ readonly consumedPoints: number;
19
+ readonly isFirstInDuration: boolean;
20
+
21
+ toString(): string;
22
+ toJSON(): {
23
+ remainingPoints: number;
24
+ msBeforeNext: number;
25
+ consumedPoints: number;
26
+ isFirstInDuration: boolean;
27
+ };
28
+ }
29
+
30
+ export class RateLimiterAbstract {
31
+ constructor(opts: IRateLimiterOptions);
32
+
33
+ /**
34
+ * Maximum number of points can be consumed over duration. Limiter compares this number with
35
+ * number of consumed points by key to decide if an operation should be rejected or resolved.
36
+ */
37
+ points: number;
38
+
39
+ /**
40
+ * Number of seconds before consumed points are reset.
41
+ * Keys never expire, if duration is 0.
42
+ */
43
+ duration: number;
44
+
45
+ /**
46
+ * duration in milliseconds
47
+ */
48
+ get msDuration(): number;
49
+
50
+ /**
51
+ * If positive number and consumed more than points in current duration, block for blockDuration
52
+ * seconds.
53
+ */
54
+ blockDuration: number;
55
+
56
+ /**
57
+ * blockDuration in milliseconds
58
+ */
59
+ get msBlockDuration(): number;
60
+
61
+ /**
62
+ * Delay action to be executed evenly over duration First action in duration is executed without
63
+ * delay. All next allowed actions in current duration are delayed by formula
64
+ * msBeforeDurationEnd / (remainingPoints + 2) with minimum delay of duration * 1000 / points.
65
+ * It allows to cut off load peaks similar way to Leaky Bucket.
66
+ *
67
+ * Note: it isn't recommended to use it for long duration and few points, as it may delay action
68
+ * for too long with default execEvenlyMinDelayMs.
69
+ */
70
+ execEvenly: boolean;
71
+
72
+ /**
73
+ * Sets minimum delay in milliseconds, when action is delayed with execEvenly
74
+ */
75
+ execEvenlyMinDelayMs: number;
76
+
77
+ /**
78
+ * If you need to create several limiters for different purpose.
79
+ * Set to empty string '', if keys should be stored without prefix.
80
+ */
81
+ keyPrefix: string;
82
+
83
+ /**
84
+ * Returns internal key prefixed with keyPrefix option as it is saved in store.
85
+ */
86
+ getKey(key: string | number): string;
87
+
88
+ /**
89
+ * Returns internal key without the keyPrefix.
90
+ */
91
+ parseKey(rlKey: string): string;
92
+
93
+ /**
94
+ * @param key is usually IP address or some unique client id
95
+ * @param pointsToConsume number of points consumed. default: 1
96
+ * @param options is object with additional settings:
97
+ * - customDuration expire in seconds for this operation only overwrites limiter's duration. It doesn't work, if key already created.
98
+ * @returns Returns Promise, which:
99
+ * - `resolved` with `RateLimiterRes` when point(s) is consumed, so action can be done
100
+ * - `rejected` only for store and database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
101
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
102
+ * - `rejected` when there is no points to be consumed, where reject reason `rejRes` is `RateLimiterRes` object
103
+ * - `rejected` when key is blocked (if block strategy is set up), where reject reason `rejRes` is `RateLimiterRes` object
104
+ */
105
+ consume(
106
+ key: string | number,
107
+ pointsToConsume?: number,
108
+ options?: { [key: string]: any }
109
+ ): Promise<RateLimiterRes>;
110
+
111
+ /**
112
+ * Fine key by points number of points for one duration.
113
+ *
114
+ * Note: Depending on time penalty may go to next durations
115
+ *
116
+ * @returns Returns Promise, which:
117
+ * - `resolved` with RateLimiterRes
118
+ * - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
119
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
120
+ */
121
+ penalty(
122
+ key: string | number,
123
+ points?: number,
124
+ options?: { [key: string]: any }
125
+ ): Promise<RateLimiterRes>;
126
+
127
+ /**
128
+ * Reward key by points number of points for one duration.
129
+ * Note: Depending on time reward may go to next durations
130
+ * @returns Promise, which:
131
+ * - `resolved` with RateLimiterRes
132
+ * - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
133
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
134
+ */
135
+ reward(
136
+ key: string | number,
137
+ points?: number,
138
+ options?: { [key: string]: any }
139
+ ): Promise<RateLimiterRes>;
140
+
141
+ /**
142
+ * Get RateLimiterRes in current duration. It always returns RateLimiterRes.isFirstInDuration=false.
143
+ * @param key is usually IP address or some unique client id
144
+ * @param options
145
+ * @returns Promise, which:
146
+ * - `resolved` with RateLimiterRes if key is set
147
+ * - `resolved` with null if key is NOT set or expired
148
+ * - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
149
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
150
+ */
151
+ get(
152
+ key: string | number,
153
+ options?: { [key: string]: any }
154
+ ): Promise<RateLimiterRes | null>;
155
+
156
+ /**
157
+ * Set points to key for secDuration seconds.
158
+ * Store it forever, if secDuration is 0.
159
+ * @param key
160
+ * @param points
161
+ * @param secDuration
162
+ * @param options
163
+ * @returns Promise, which:
164
+ * - `resolved` with RateLimiterRes
165
+ * - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
166
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
167
+ */
168
+ set(
169
+ key: string | number,
170
+ points: number,
171
+ secDuration: number,
172
+ options?: { [key: string]: any }
173
+ ): Promise<RateLimiterRes>;
174
+
175
+ /**
176
+ * Block key by setting consumed points to points + 1 for secDuration seconds.
177
+ *
178
+ * It force updates expire, if there is already key.
179
+ *
180
+ * Blocked key never expires, if secDuration is 0.
181
+ * @returns Promise, which:
182
+ * - `resolved` with RateLimiterRes
183
+ * - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
184
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
185
+ */
186
+ block(
187
+ key: string | number,
188
+ secDuration: number,
189
+ options?: { [key: string]: any }
190
+ ): Promise<RateLimiterRes>;
191
+
192
+ /**
193
+ * Delete all data related to key.
194
+ *
195
+ * For example, previously blocked key is not blocked after delete as there is no data anymore.
196
+ * @returns Promise, which:
197
+ * - `resolved` with boolean, true if data is removed by key, false if there is no such key.
198
+ * - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
199
+ * - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
200
+ */
201
+ delete(
202
+ key: string | number,
203
+ options?: { [key: string]: any }
204
+ ): Promise<boolean>;
205
+ }
206
+
207
+ export class RateLimiterInsuredAbstract extends RateLimiterAbstract {
208
+ constructor(opts: IRateLimiterOptions);
209
+ }
210
+
211
+ export class RateLimiterStoreAbstract extends RateLimiterInsuredAbstract {
212
+ constructor(opts: IRateLimiterStoreOptions);
213
+
214
+ /**
215
+ * Cleanup keys blocked in current process memory
216
+ */
217
+ deleteInMemoryBlockedAll(): void;
218
+ }
219
+
220
+ interface IRateLimiterOptions {
221
+ keyPrefix?: string;
222
+ points?: number;
223
+ duration?: number;
224
+ execEvenly?: boolean;
225
+ execEvenlyMinDelayMs?: number;
226
+ blockDuration?: number;
227
+ insuranceLimiter?: RateLimiterAbstract;
228
+ }
229
+
230
+ interface IRateLimiterClusterOptions extends IRateLimiterOptions {
231
+ timeoutMs?: number;
232
+ }
233
+
234
+ interface IRateLimiterStoreOptions extends IRateLimiterOptions {
235
+ storeClient: any;
236
+ storeType?: string;
237
+ inMemoryBlockOnConsumed?: number;
238
+ inMemoryBlockDuration?: number;
239
+ insuranceLimiter?: RateLimiterAbstract;
240
+ dbName?: string;
241
+ tableName?: string;
242
+ tableCreated?: boolean;
243
+ }
244
+
245
+ interface IRateLimiterStoreNoAutoExpiryOptions extends IRateLimiterStoreOptions {
246
+ clearExpiredByTimeout?: boolean;
247
+ }
248
+
249
+ interface IRateLimiterStoreNoAutoExpiryOptionsAndSchema extends IRateLimiterStoreNoAutoExpiryOptions {
250
+ schema: any;
251
+ }
252
+
253
+ interface IRateLimiterMongoOptions extends IRateLimiterStoreOptions {
254
+ indexKeyPrefix?: {
255
+ [key: string]: any;
256
+ };
257
+ disableIndexesCreation?: boolean;
258
+ }
259
+
260
+ interface IRateLimiterPostgresOptions extends IRateLimiterStoreNoAutoExpiryOptions {
261
+ schemaName?: string;
262
+ }
263
+
264
+ interface IRateLimiterRedisOptions extends IRateLimiterStoreOptions {
265
+ rejectIfRedisNotReady?: boolean;
266
+ useRedisPackage?: boolean;
267
+ useRedis3AndLowerPackage?: boolean;
268
+ customIncrTtlLuaScript?: string;
269
+ }
270
+
271
+ interface IRateLimiterValkeyOptions extends IRateLimiterStoreOptions {
272
+ customIncrTtlLuaScript?: string;
273
+ }
274
+
275
+ interface ICallbackReady {
276
+ (error?: Error): void;
277
+ }
278
+
279
+ interface IRLWrapperBlackAndWhiteOptions {
280
+ limiter: RateLimiterAbstract;
281
+ blackList?: string[] | number[];
282
+ whiteList?: string[] | number[];
283
+ isBlackListed?(key: any): boolean;
284
+ isWhiteListed?(key: any): boolean;
285
+ runActionAnyway?: boolean;
286
+ }
287
+
288
+ export class RateLimiterMemory extends RateLimiterAbstract {
289
+ constructor(opts: IRateLimiterOptions);
290
+ }
291
+
292
+ export class RateLimiterCluster extends RateLimiterAbstract {
293
+ constructor(opts: IRateLimiterClusterOptions);
294
+ }
295
+
296
+ export class RateLimiterClusterMaster {
297
+ constructor();
298
+ }
299
+
300
+ export class RateLimiterClusterMasterPM2 {
301
+ constructor(pm2: any);
302
+ }
303
+
304
+ export class RateLimiterRedis extends RateLimiterStoreAbstract {
305
+ constructor(opts: IRateLimiterRedisOptions);
306
+ }
307
+
308
+ export class RateLimiterRedisNonAtomic extends RateLimiterStoreAbstract {
309
+ constructor(opts: IRateLimiterRedisOptions);
310
+ }
311
+
312
+ export class RateLimiterValkey extends RateLimiterStoreAbstract {
313
+ constructor(opts: IRateLimiterValkeyOptions);
314
+ }
315
+
316
+ export interface IRateLimiterMongoFunctionOptions {
317
+ attrs: { [key: string]: any };
318
+ }
319
+
320
+ export class RateLimiterMongo extends RateLimiterStoreAbstract {
321
+ constructor(opts: IRateLimiterMongoOptions);
322
+ indexKeyPrefix(): Object;
323
+ indexKeyPrefix(obj?: Object): void;
324
+
325
+ createIndexes(): Promise<void>;
326
+
327
+ consume(
328
+ key: string | number,
329
+ pointsToConsume?: number,
330
+ options?: IRateLimiterMongoFunctionOptions
331
+ ): Promise<RateLimiterRes>;
332
+
333
+ penalty(
334
+ key: string | number,
335
+ points?: number,
336
+ options?: IRateLimiterMongoFunctionOptions
337
+ ): Promise<RateLimiterRes>;
338
+
339
+ reward(
340
+ key: string | number,
341
+ points?: number,
342
+ options?: IRateLimiterMongoFunctionOptions
343
+ ): Promise<RateLimiterRes>;
344
+
345
+ block(
346
+ key: string | number,
347
+ secDuration: number,
348
+ options?: IRateLimiterMongoFunctionOptions
349
+ ): Promise<RateLimiterRes>;
350
+
351
+ get(
352
+ key: string | number,
353
+ options?: IRateLimiterMongoFunctionOptions
354
+ ): Promise<RateLimiterRes | null>;
355
+
356
+ set(
357
+ key: string | number,
358
+ points: number,
359
+ secDuration: number,
360
+ options?: IRateLimiterMongoFunctionOptions
361
+ ): Promise<RateLimiterRes>;
362
+
363
+ delete(
364
+ key: string | number,
365
+ options?: IRateLimiterMongoFunctionOptions
366
+ ): Promise<boolean>;
367
+ }
368
+
369
+ export class RateLimiterMySQL extends RateLimiterStoreAbstract {
370
+ constructor(opts: IRateLimiterStoreNoAutoExpiryOptions, cb?: ICallbackReady);
371
+ }
372
+
373
+ export class RateLimiterPostgres extends RateLimiterStoreAbstract {
374
+ constructor(opts: IRateLimiterPostgresOptions, cb?: ICallbackReady);
375
+ }
376
+
377
+ export class RateLimiterSQLite extends RateLimiterStoreAbstract {
378
+ constructor(opts: IRateLimiterStoreNoAutoExpiryOptions, cb?: ICallbackReady);
379
+ }
380
+
381
+ export class RateLimiterPrisma extends RateLimiterStoreAbstract {
382
+ constructor(opts: IRateLimiterStoreNoAutoExpiryOptions, cb?: ICallbackReady);
383
+ }
384
+
385
+ export class RateLimiterDrizzle extends RateLimiterStoreAbstract {
386
+ constructor(opts: IRateLimiterStoreNoAutoExpiryOptionsAndSchema, cb?: ICallbackReady);
387
+ }
388
+
389
+ export class RateLimiterDrizzleNonAtomic extends RateLimiterStoreAbstract {
390
+ constructor(opts: IRateLimiterStoreNoAutoExpiryOptionsAndSchema, cb?: ICallbackReady);
391
+ }
392
+
393
+ export class RateLimiterMemcache extends RateLimiterStoreAbstract { }
394
+
395
+ export class RateLimiterUnion {
396
+ constructor(...limiters: RateLimiterAbstract[]);
397
+
398
+ consume(key: string | number, points?: number): Promise<Record<string, RateLimiterRes>>;
399
+ }
400
+
401
+ export class RLWrapperBlackAndWhite extends RateLimiterAbstract {
402
+ constructor(opts: IRLWrapperBlackAndWhiteOptions);
403
+ }
404
+
405
+ interface IRLWrapperTimeoutsOptions extends IRateLimiterOptions {
406
+ limiter: RateLimiterAbstract;
407
+ timeoutMs?: number;
408
+ }
409
+
410
+ export class RLWrapperTimeouts extends RateLimiterInsuredAbstract {
411
+ constructor(opts: IRLWrapperTimeoutsOptions);
412
+ }
413
+
414
+ interface IRateLimiterQueueOpts {
415
+ maxQueueSize?: number;
416
+ }
417
+
418
+ export class RateLimiterQueue {
419
+ constructor(
420
+ limiterFlexible: RateLimiterAbstract | BurstyRateLimiter,
421
+ opts?: IRateLimiterQueueOpts
422
+ );
423
+
424
+ getTokensRemaining(key?: string | number): Promise<number>;
425
+
426
+ removeTokens(tokens: number, key?: string | number): Promise<number>;
427
+ }
428
+
429
+ export class BurstyRateLimiter {
430
+ constructor(
431
+ rateLimiter: RateLimiterAbstract,
432
+ burstLimiter: RateLimiterAbstract
433
+ );
434
+
435
+ consume(
436
+ key: string | number,
437
+ pointsToConsume?: number,
438
+ options?: IRateLimiterMongoFunctionOptions
439
+ ): Promise<RateLimiterRes>;
440
+ }
441
+
442
+ interface IRateLimiterDynamoOptions extends IRateLimiterStoreOptions {
443
+ dynamoTableOpts?: {
444
+ readCapacityUnits: number;
445
+ writeCapacityUnits: number;
446
+ };
447
+ ttlSet?: boolean;
448
+ }
449
+
450
+ export class RateLimiterDynamo extends RateLimiterStoreAbstract {
451
+ constructor(opts: IRateLimiterDynamoOptions, cb?: ICallbackReady);
452
+ }
453
+
454
+ /**
455
+ * Options for RateLimiterValkeyGlide
456
+ */
457
+ interface IRateLimiterValkeyGlideOptions extends IRateLimiterStoreOptions {
458
+ /**
459
+ * Valkey Glide client instance (GlideClient or GlideClusterClient)
460
+ */
461
+ storeClient: any; // GlideClient | GlideClusterClient;
462
+
463
+ /**
464
+ * Whether to reject requests if Valkey is not ready
465
+ * @default false
466
+ */
467
+ rejectIfValkeyNotReady?: boolean;
468
+
469
+ /**
470
+ * Custom Lua script for rate limiting logic.
471
+ * Must accept parameters:
472
+ * - KEYS[1]: The key being rate limited
473
+ * - ARGV[1]: Points to consume (as string, use tonumber() to convert)
474
+ * - ARGV[2]: Duration in seconds (as string, use tonumber() to convert)
475
+ *
476
+ * Must return an array with exactly two elements:
477
+ * - [0]: Consumed points (number)
478
+ * - [1]: TTL in milliseconds (number)
479
+ */
480
+ customFunction?: string;
481
+
482
+ /**
483
+ * Custom name for the function library, defaults to 'ratelimiter'.
484
+ * The name is used to identify the library of the Lua function.
485
+ * A custom name should be used only if you want to use different
486
+ * libraries for different rate limiters.
487
+ * @default 'ratelimiter'
488
+ */
489
+ customFunctionLibName?: string;
490
+ }
491
+
492
+ /**
493
+ * Rate limiter that uses Valkey Glide client for storage
494
+ */
495
+ export class RateLimiterValkeyGlide extends RateLimiterStoreAbstract {
496
+ /**
497
+ * Creates a new instance of RateLimiterValkeyGlide
498
+ *
499
+ * @param opts Configuration options
500
+ *
501
+ * @example
502
+ * ```typescript
503
+ * // Basic usage
504
+ * const rateLimiter = new RateLimiterValkeyGlide({
505
+ * storeClient: glideClient,
506
+ * points: 5,
507
+ * duration: 1
508
+ * });
509
+ *
510
+ * // With custom Lua function
511
+ * const customScript = `local key = KEYS[1]
512
+ * local pointsToConsume = tonumber(ARGV[1]) or 0
513
+ * local secDuration = tonumber(ARGV[2]) or 0
514
+ *
515
+ * -- Custom implementation
516
+ * -- ...
517
+ *
518
+ * -- Must return exactly two values: [consumed_points, ttl_in_ms]
519
+ * return {consumed, ttl}`;
520
+ *
521
+ * const rateLimiter = new RateLimiterValkeyGlide({
522
+ * storeClient: glideClient,
523
+ * points: 5,
524
+ * customFunction: customScript
525
+ * });
526
+ *
527
+ * // With insurance limiter
528
+ * const rateLimiter = new RateLimiterValkeyGlide({
529
+ * storeClient: primaryGlideClient,
530
+ * points: 5,
531
+ * duration: 2,
532
+ * insuranceLimiter: new RateLimiterMemory({
533
+ * points: 5,
534
+ * duration: 2
535
+ * })
536
+ * });
537
+ * ```
538
+ */
539
+ constructor(opts: IRateLimiterValkeyGlideOptions);
540
+
541
+ /**
542
+ * Close the rate limiter and release resources
543
+ * Note: The method won't close the Valkey client, as it may be shared with other instances.
544
+ *
545
+ * @returns Promise that resolves when the rate limiter is closed
546
+ */
547
+ close(): Promise<void>;
548
+ }
549
+
550
+ /**
551
+ * Etcd Rate Limiter class.
552
+ *
553
+ * The option "storeClient" needs to be set to an instance of class "EtcdClient".
554
+ */
555
+ export class RateLimiterEtcd extends RateLimiterEtcdNonAtomic {
556
+ constructor(opts: IRateLimiterStoreOptions);
557
+ }
558
+
559
+ /**
560
+ * Non-Atomic Etcd Rate Limiter class.
561
+ *
562
+ * The option "storeClient" needs to be set to an instance of class "EtcdClient".
563
+ */
564
+ export class RateLimiterEtcdNonAtomic extends RateLimiterStoreAbstract {
565
+ constructor(opts: IRateLimiterStoreOptions);
566
+ }
567
+
568
+ export class RateLimiterQueueError extends Error {
569
+ constructor(message?: string, extra?: string);
570
+
571
+ readonly name: string;
572
+ readonly message: string;
573
+ readonly extra: string;
574
+ }
575
+
576
+ export class RateLimiterEtcdTransactionFailedError extends Error {
577
+ constructor(message?: string);
578
+
579
+ readonly name: string;
580
+ readonly message: string;
581
+ }