limitly 1.0.2 → 2.0.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 (79) hide show
  1. package/README.md +291 -12
  2. package/dist/algorithms/factory.d.ts +3 -2
  3. package/dist/algorithms/factory.d.ts.map +1 -1
  4. package/dist/algorithms/factory.js +3 -3
  5. package/dist/algorithms/factory.js.map +1 -1
  6. package/dist/algorithms/sliding-window.d.ts +4 -4
  7. package/dist/algorithms/sliding-window.d.ts.map +1 -1
  8. package/dist/algorithms/sliding-window.js +3 -23
  9. package/dist/algorithms/sliding-window.js.map +1 -1
  10. package/dist/algorithms/token-bucket.d.ts +4 -4
  11. package/dist/algorithms/token-bucket.d.ts.map +1 -1
  12. package/dist/algorithms/token-bucket.js +3 -20
  13. package/dist/algorithms/token-bucket.js.map +1 -1
  14. package/dist/index.d.ts +15 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +32 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/limiter.d.ts +19 -7
  19. package/dist/limiter.d.ts.map +1 -1
  20. package/dist/limiter.js +66 -15
  21. package/dist/limiter.js.map +1 -1
  22. package/dist/middleware/bun.d.ts +9 -0
  23. package/dist/middleware/bun.d.ts.map +1 -0
  24. package/dist/middleware/bun.js +96 -0
  25. package/dist/middleware/bun.js.map +1 -0
  26. package/dist/middleware/express.d.ts.map +1 -1
  27. package/dist/middleware/express.js +11 -5
  28. package/dist/middleware/express.js.map +1 -1
  29. package/dist/middleware/fastify.d.ts +3 -3
  30. package/dist/middleware/fastify.d.ts.map +1 -1
  31. package/dist/middleware/fastify.js +19 -13
  32. package/dist/middleware/fastify.js.map +1 -1
  33. package/dist/middleware/hono.d.ts +5 -0
  34. package/dist/middleware/hono.d.ts.map +1 -0
  35. package/dist/middleware/hono.js +57 -0
  36. package/dist/middleware/hono.js.map +1 -0
  37. package/dist/middleware/koa.d.ts +5 -0
  38. package/dist/middleware/koa.d.ts.map +1 -0
  39. package/dist/middleware/koa.js +54 -0
  40. package/dist/middleware/koa.js.map +1 -0
  41. package/dist/middleware/nest.d.ts +14 -0
  42. package/dist/middleware/nest.d.ts.map +1 -0
  43. package/dist/middleware/nest.js +102 -0
  44. package/dist/middleware/nest.js.map +1 -0
  45. package/dist/stores/factory.d.ts +5 -0
  46. package/dist/stores/factory.d.ts.map +1 -0
  47. package/dist/stores/factory.js +36 -0
  48. package/dist/stores/factory.js.map +1 -0
  49. package/dist/stores/memcached-store.d.ts +13 -0
  50. package/dist/stores/memcached-store.d.ts.map +1 -0
  51. package/dist/stores/memcached-store.js +117 -0
  52. package/dist/stores/memcached-store.js.map +1 -0
  53. package/dist/stores/redis-store.d.ts +12 -0
  54. package/dist/stores/redis-store.d.ts.map +1 -0
  55. package/dist/stores/redis-store.js +54 -0
  56. package/dist/stores/redis-store.js.map +1 -0
  57. package/dist/stores/types.d.ts +8 -0
  58. package/dist/stores/types.d.ts.map +1 -0
  59. package/dist/stores/types.js +3 -0
  60. package/dist/stores/types.js.map +1 -0
  61. package/dist/types/index.d.ts +62 -1
  62. package/dist/types/index.d.ts.map +1 -1
  63. package/dist/utils/defaults.d.ts +6 -0
  64. package/dist/utils/defaults.d.ts.map +1 -0
  65. package/dist/utils/defaults.js +59 -0
  66. package/dist/utils/defaults.js.map +1 -0
  67. package/dist/utils/memcached.d.ts +11 -0
  68. package/dist/utils/memcached.d.ts.map +1 -0
  69. package/dist/utils/memcached.js +91 -0
  70. package/dist/utils/memcached.js.map +1 -0
  71. package/dist/utils/metrics.d.ts +21 -0
  72. package/dist/utils/metrics.d.ts.map +1 -0
  73. package/dist/utils/metrics.js +60 -0
  74. package/dist/utils/metrics.js.map +1 -0
  75. package/dist/utils/redis.d.ts +1 -0
  76. package/dist/utils/redis.d.ts.map +1 -1
  77. package/dist/utils/redis.js +2 -0
  78. package/dist/utils/redis.js.map +1 -1
  79. package/package.json +60 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # limitly
2
2
 
3
- Distributed, Redis-powered rate limiting for Express and Fastify.
3
+ Distributed, Redis-powered rate limiting for Express, Fastify, Hono, Koa, Bun, and NestJS.
4
4
 
5
5
  > Express-rate-limit, but distributed, Redis-powered, and production ready.
6
6
 
@@ -8,6 +8,22 @@ Distributed, Redis-powered rate limiting for Express and Fastify.
8
8
 
9
9
  ```bash
10
10
  npm install limitly ioredis
11
+
12
+ # Memcached backend
13
+ npm install limitly memcached
14
+
15
+ # NestJS
16
+ npm install limitly ioredis @nestjs/common @nestjs/core
17
+ ```
18
+
19
+ Framework-specific subpath imports are available for tree-shaking:
20
+
21
+ ```typescript
22
+ import { createExpressMiddleware } from "limitly/express";
23
+ import { createFastifyPlugin } from "limitly/fastify";
24
+ import { createHonoMiddleware } from "limitly/hono";
25
+ import { createKoaMiddleware } from "limitly/koa";
26
+ import { createBunMiddleware } from "limitly/bun";
11
27
  ```
12
28
 
13
29
  ## Quick Start
@@ -51,11 +67,185 @@ await fastify.register(limiter.fastifyPlugin, {
51
67
  });
52
68
  ```
53
69
 
70
+ ### Hono
71
+
72
+ ```typescript
73
+ import { Hono } from "hono";
74
+ import Redis from "ioredis";
75
+ import { createLimiter } from "limitly";
76
+
77
+ const app = new Hono();
78
+ const limiter = createLimiter({ redis: new Redis() });
79
+
80
+ app.use(
81
+ "*",
82
+ limiter.honoMiddleware({
83
+ algorithm: "sliding-window",
84
+ limit: 100,
85
+ window: 60,
86
+ key: (c) => c.req.header("x-api-key"),
87
+ })
88
+ );
89
+ ```
90
+
91
+ ### Koa
92
+
93
+ ```typescript
94
+ import Koa from "koa";
95
+ import Redis from "ioredis";
96
+ import { createLimiter } from "limitly";
97
+
98
+ const app = new Koa();
99
+ const limiter = createLimiter({ redis: new Redis() });
100
+
101
+ app.use(
102
+ limiter.koaMiddleware({
103
+ algorithm: "sliding-window",
104
+ limit: 100,
105
+ window: 60,
106
+ key: (ctx) => ctx.ip,
107
+ })
108
+ );
109
+ ```
110
+
111
+ ### Bun
112
+
113
+ ```typescript
114
+ import Redis from "ioredis";
115
+ import { composeBunHandler, createLimiter } from "limitly";
116
+
117
+ const limiter = createLimiter({ redis: new Redis() });
118
+
119
+ const rateLimit = limiter.bunMiddleware({
120
+ algorithm: "sliding-window",
121
+ limit: 100,
122
+ window: 60,
123
+ key: (req) => req.headers.get("x-api-key"),
124
+ });
125
+
126
+ const fetch = composeBunHandler(
127
+ [rateLimit],
128
+ () => Response.json({ message: "Hello Bun!" })
129
+ );
130
+
131
+ Bun.serve({ port: 3000, fetch });
132
+ ```
133
+
134
+ ### NestJS
135
+
136
+ ```typescript
137
+ import { Module } from "@nestjs/common";
138
+ import { APP_GUARD } from "@nestjs/core";
139
+ import Redis from "ioredis";
140
+ import { createLimiter } from "limitly";
141
+ import { RateLimit } from "limitly/nest";
142
+
143
+ const limiter = createLimiter({ redis: new Redis() });
144
+ const NestGuard = limiter.nestGuard({
145
+ algorithm: "sliding-window",
146
+ limit: 100,
147
+ window: 60,
148
+ key: (req) => req.ip,
149
+ });
150
+
151
+ @Module({
152
+ providers: [{ provide: APP_GUARD, useClass: NestGuard }],
153
+ })
154
+ export class AppModule {}
155
+ ```
156
+
157
+ Per-route limits with `@RateLimit()`:
158
+
159
+ ```typescript
160
+ import { Controller, Get } from "@nestjs/common";
161
+ import { RateLimit } from "limitly/nest";
162
+
163
+ @Controller("api")
164
+ export class ApiController {
165
+ @Get()
166
+ @RateLimit({ algorithm: "sliding-window", limit: 10, window: 60 })
167
+ findAll() {
168
+ return { ok: true };
169
+ }
170
+ }
171
+ ```
172
+
173
+ Module helper (like `redisLimitPlugin` for Fastify):
174
+
175
+ ```typescript
176
+ import { limitlyNestModule } from "limitly/nest";
177
+
178
+ @Module({
179
+ imports: [
180
+ limitlyNestModule({
181
+ limiter,
182
+ algorithm: "token-bucket",
183
+ capacity: 50,
184
+ refillRate: 10,
185
+ global: true,
186
+ }),
187
+ ],
188
+ })
189
+ export class AppModule {}
190
+ ```
191
+
192
+ ## Default Algorithm
193
+
194
+ If you omit algorithm options, limitly uses **sliding-window** with `limit: 100` and `window: 60`:
195
+
196
+ ```typescript
197
+ const limiter = createLimiter({ redis: new Redis() });
198
+
199
+ app.use(limiter.middleware({ key: (req) => req.ip }));
200
+
201
+ // equivalent to:
202
+ app.use(
203
+ limiter.middleware({
204
+ algorithm: "sliding-window",
205
+ limit: 100,
206
+ window: 60,
207
+ key: (req) => req.ip,
208
+ })
209
+ );
210
+ ```
211
+
212
+ Set limiter-wide defaults:
213
+
214
+ ```typescript
215
+ const limiter = createLimiter({
216
+ redis: new Redis(),
217
+ default: { limit: 50, window: 30 },
218
+ });
219
+
220
+ app.use(limiter.middleware({ key: (req) => req.ip }));
221
+ ```
222
+
223
+ ## Programmatic Checks
224
+
225
+ Use `limiter.check()` outside middleware — useful for login guards, background jobs, or custom response handling:
226
+
227
+ ```typescript
228
+ const result = await limiter.check(req.ip ?? "unknown", {
229
+ algorithm: "sliding-window",
230
+ limit: 5,
231
+ window: 10,
232
+ });
233
+
234
+ if (!result.allowed) {
235
+ return res.status(429).json({
236
+ error: "Too many attempts",
237
+ retryAfter: result.retryAfter,
238
+ });
239
+ }
240
+ ```
241
+
242
+ `check()` respects limiter-wide defaults, `failOpen`, and global `onMetrics` hooks.
243
+
54
244
  ## Algorithms
55
245
 
56
246
  ### Sliding Window
57
247
 
58
- Uses Redis Sorted Sets for precise rate limiting over a rolling time window.
248
+ Uses Redis Sorted Sets (or Memcached counters) for rate limiting over a rolling time window.
59
249
 
60
250
  ```typescript
61
251
  limiter.middleware({
@@ -77,30 +267,56 @@ limiter.middleware({
77
267
  });
78
268
  ```
79
269
 
80
- ## Redis Connection
270
+ ## Storage Backends
271
+
272
+ limitly supports Redis, Valkey, DragonflyDB (Redis-compatible), and Memcached.
273
+
274
+ ### Redis / Valkey / DragonflyDB
81
275
 
82
- Supports multiple connection modes:
276
+ Redis-compatible backends use atomic Lua scripts (sorted sets + hashes). Connect with `ioredis`:
83
277
 
84
278
  ```typescript
85
- // Existing Redis instance
279
+ import Redis from "ioredis";
280
+
281
+ // Redis
86
282
  createLimiter({ redis: new Redis() });
87
283
 
88
- // Connection URL
89
- createLimiter({ redis: "redis://localhost:6379" });
284
+ // Valkey
285
+ createLimiter({ store: "valkey", redis: "redis://localhost:6379" });
90
286
 
91
- // Options object
92
- createLimiter({ redis: { host: "localhost", port: 6379 } });
287
+ // DragonflyDB
288
+ createLimiter({ store: "dragonfly", redis: { host: "localhost", port: 6379 } });
93
289
 
94
290
  // Cluster
95
291
  createLimiter({
96
- redis: {
97
- nodes: [{ host: "127.0.0.1", port: 7000 }],
98
- },
292
+ store: "redis",
293
+ redis: { nodes: [{ host: "127.0.0.1", port: 7000 }] },
294
+ });
295
+ ```
296
+
297
+ ### Memcached
298
+
299
+ Memcached uses counter-based sliding window and CAS token bucket (no Lua required):
300
+
301
+ ```typescript
302
+ import Memcached from "memcached";
303
+
304
+ createLimiter({
305
+ store: "memcached",
306
+ memcached: "localhost:11211",
99
307
  });
308
+
309
+ // Or pass an existing client
310
+ createLimiter({ memcached: new Memcached(["localhost:11211"]) });
100
311
  ```
101
312
 
313
+ > Memcached sliding window uses a weighted two-window counter (high accuracy, no sorted sets).
314
+ > Token bucket uses `gets`/`cas` for atomic updates.
315
+
102
316
  ## Key Extraction
103
317
 
318
+ The `key` option identifies **who** is being rate limited (per request):
319
+
104
320
  ```typescript
105
321
  // IP-based
106
322
  key: (req) => req.ip;
@@ -112,6 +328,29 @@ key: (req) => req.headers["x-api-key"];
112
328
  key: (req) => req.user.id;
113
329
  ```
114
330
 
331
+ ## Storage Key Prefix
332
+
333
+ The `keyPrefix` option controls **where** counters are stored in Redis/Memcached.
334
+ Default is `limitly`:
335
+
336
+ ```typescript
337
+ createLimiter({ redis: new Redis() });
338
+ // stores keys like: limitly:sw:203.0.113.1
339
+
340
+ createLimiter({
341
+ redis: new Redis(),
342
+ keyPrefix: "myapp:prod",
343
+ });
344
+ // stores keys like: myapp:prod:sw:203.0.113.1
345
+ ```
346
+
347
+ Key format:
348
+
349
+ ```
350
+ {keyPrefix}:sw:{id} — sliding window
351
+ {keyPrefix}:tb:{id} — token bucket
352
+ ```
353
+
115
354
  ## Response Headers
116
355
 
117
356
  Standard rate limit headers are set by default:
@@ -138,6 +377,46 @@ limiter.middleware({
138
377
  });
139
378
  ```
140
379
 
380
+ ## Metrics
381
+
382
+ Emit observability events via the `onMetrics` hook. Set it globally on the limiter or per middleware/route:
383
+
384
+ ```typescript
385
+ const limiter = createLimiter({
386
+ redis: new Redis(),
387
+ onMetrics: (event) => {
388
+ console.log(event.type, event.key, `${event.durationMs.toFixed(2)}ms`);
389
+ },
390
+ });
391
+
392
+ // Per-route override
393
+ limiter.middleware({
394
+ algorithm: "sliding-window",
395
+ limit: 100,
396
+ window: 60,
397
+ onMetrics: (event) => metrics.increment(`ratelimit.${event.type}`),
398
+ });
399
+ ```
400
+
401
+ Event types:
402
+
403
+ | Type | When |
404
+ |------|------|
405
+ | `allowed` | Request passed the rate limit check |
406
+ | `blocked` | Request exceeded the limit |
407
+ | `error` | Store operation failed |
408
+ | `fail_open` | Store failed but `failOpen: true` allowed traffic through |
409
+
410
+ Each event includes `key`, `algorithm`, `durationMs`, and optionally `store`, `context` (the request object), and `result` or `error` depending on type.
411
+
412
+ Multiple hooks are supported:
413
+
414
+ ```typescript
415
+ onMetrics: [logToConsole, sendToDatadog]
416
+ ```
417
+
418
+ `limiter.check()` and all framework middleware use the same metrics pipeline.
419
+
141
420
  ## Fail Open / Closed
142
421
 
143
422
  When Redis is unavailable:
@@ -1,3 +1,4 @@
1
- import type { AlgorithmConfig, RateLimitStrategy, RedisClient } from "../types";
2
- export declare function createStrategy(redis: RedisClient, config: AlgorithmConfig, keyPrefix?: string): RateLimitStrategy;
1
+ import type { AlgorithmConfig, RateLimitStrategy } from "../types";
2
+ import type { RateLimitStore } from "../stores/types";
3
+ export declare function createStrategy(store: RateLimitStore, config: AlgorithmConfig): RateLimitStrategy;
3
4
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/algorithms/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,UAAU,CAAC;AAIlB,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,MAAM,GACjB,iBAAiB,CAanB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/algorithms/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAItD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,eAAe,GACtB,iBAAiB,CAanB"}
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createStrategy = createStrategy;
4
4
  const sliding_window_1 = require("./sliding-window");
5
5
  const token_bucket_1 = require("./token-bucket");
6
- function createStrategy(redis, config, keyPrefix) {
6
+ function createStrategy(store, config) {
7
7
  switch (config.algorithm) {
8
8
  case "sliding-window":
9
- return new sliding_window_1.SlidingWindowStrategy(redis, config, keyPrefix);
9
+ return new sliding_window_1.SlidingWindowStrategy(store, config);
10
10
  case "token-bucket":
11
- return new token_bucket_1.TokenBucketStrategy(redis, config, keyPrefix);
11
+ return new token_bucket_1.TokenBucketStrategy(store, config);
12
12
  default: {
13
13
  const exhaustive = config;
14
14
  throw new Error(`Unknown algorithm: ${exhaustive.algorithm}`);
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/algorithms/factory.ts"],"names":[],"mappings":";;AAQA,wCAiBC;AApBD,qDAAyD;AACzD,iDAAqD;AAErD,SAAgB,cAAc,CAC5B,KAAkB,EAClB,MAAuB,EACvB,SAAkB;IAElB,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,KAAK,gBAAgB;YACnB,OAAO,IAAI,sCAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7D,KAAK,cAAc;YACjB,OAAO,IAAI,kCAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,MAAM,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,sBAAuB,UAA8B,CAAC,SAAS,EAAE,CAClE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/algorithms/factory.ts"],"names":[],"mappings":";;AAKA,wCAgBC;AAnBD,qDAAyD;AACzD,iDAAqD;AAErD,SAAgB,cAAc,CAC5B,KAAqB,EACrB,MAAuB;IAEvB,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,KAAK,gBAAgB;YACnB,OAAO,IAAI,sCAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,KAAK,cAAc;YACjB,OAAO,IAAI,kCAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,MAAM,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,sBAAuB,UAA8B,CAAC,SAAS,EAAE,CAClE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,10 +1,10 @@
1
- import type { RateLimitResult, RateLimitStrategy, RedisClient, SlidingWindowConfig } from "../types";
1
+ import type { RateLimitResult, RateLimitStrategy, SlidingWindowConfig } from "../types";
2
+ import type { RateLimitStore } from "../stores/types";
2
3
  export declare class SlidingWindowStrategy implements RateLimitStrategy {
3
- private readonly redis;
4
+ private readonly store;
4
5
  private readonly limit;
5
6
  private readonly window;
6
- private readonly keyPrefix;
7
- constructor(redis: RedisClient, config: SlidingWindowConfig, keyPrefix?: string);
7
+ constructor(store: RateLimitStore, config: SlidingWindowConfig);
8
8
  consume(key: string): Promise<RateLimitResult>;
9
9
  }
10
10
  //# sourceMappingURL=sliding-window.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sliding-window.d.ts","sourceRoot":"","sources":["../../src/algorithms/sliding-window.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAIlB,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGjC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,mBAAmB,EAC3B,SAAS,SAAe;IAQpB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAsBrD"}
1
+ {"version":3,"file":"sliding-window.d.ts","sourceRoot":"","sources":["../../src/algorithms/sliding-window.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,mBAAmB;IAMxD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAGrD"}
@@ -1,34 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SlidingWindowStrategy = void 0;
4
- const crypto_1 = require("crypto");
5
- const redis_1 = require("../utils/redis");
6
- const scripts_1 = require("../utils/scripts");
7
4
  class SlidingWindowStrategy {
8
- constructor(redis, config, keyPrefix = "redislimit") {
9
- this.redis = redis;
5
+ constructor(store, config) {
6
+ this.store = store;
10
7
  this.limit = config.limit;
11
8
  this.window = config.window;
12
- this.keyPrefix = keyPrefix;
13
9
  }
14
10
  async consume(key) {
15
- const redisKey = (0, redis_1.buildKey)(this.keyPrefix, `sw:${key}`);
16
- const now = Date.now();
17
- const requestId = (0, crypto_1.randomUUID)();
18
- const result = await (0, scripts_1.evalScript)(this.redis, "sliding", [redisKey], [
19
- this.limit,
20
- this.window,
21
- now,
22
- requestId,
23
- ]);
24
- const parsed = (0, scripts_1.parseScriptResult)(result);
25
- return {
26
- allowed: parsed.allowed,
27
- limit: parsed.limit,
28
- remaining: parsed.remaining,
29
- reset: parsed.reset,
30
- retryAfter: parsed.retryAfter || undefined,
31
- };
11
+ return this.store.slidingWindow(key, this.limit, this.window);
32
12
  }
33
13
  }
34
14
  exports.SlidingWindowStrategy = SlidingWindowStrategy;
@@ -1 +1 @@
1
- {"version":3,"file":"sliding-window.js","sourceRoot":"","sources":["../../src/algorithms/sliding-window.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AAOpC,0CAA0C;AAC1C,8CAAiE;AAEjE,MAAa,qBAAqB;IAMhC,YACE,KAAkB,EAClB,MAA2B,EAC3B,SAAS,GAAG,YAAY;QAExB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAA,mBAAU,GAAE,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAU,EAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE;YACjE,IAAI,CAAC,KAAK;YACV,IAAI,CAAC,MAAM;YACX,GAAG;YACH,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAA,2BAAiB,EAAC,MAAM,CAAC,CAAC;QAEzC,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,SAAS;SAC3C,CAAC;IACJ,CAAC;CACF;AAvCD,sDAuCC"}
1
+ {"version":3,"file":"sliding-window.js","sourceRoot":"","sources":["../../src/algorithms/sliding-window.ts"],"names":[],"mappings":";;;AAOA,MAAa,qBAAqB;IAKhC,YAAY,KAAqB,EAAE,MAA2B;QAC5D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;CACF;AAdD,sDAcC"}
@@ -1,10 +1,10 @@
1
- import type { RateLimitResult, RateLimitStrategy, RedisClient, TokenBucketConfig } from "../types";
1
+ import type { RateLimitResult, RateLimitStrategy, TokenBucketConfig } from "../types";
2
+ import type { RateLimitStore } from "../stores/types";
2
3
  export declare class TokenBucketStrategy implements RateLimitStrategy {
3
- private readonly redis;
4
+ private readonly store;
4
5
  private readonly capacity;
5
6
  private readonly refillRate;
6
- private readonly keyPrefix;
7
- constructor(redis: RedisClient, config: TokenBucketConfig, keyPrefix?: string);
7
+ constructor(store: RateLimitStore, config: TokenBucketConfig);
8
8
  consume(key: string): Promise<RateLimitResult>;
9
9
  }
10
10
  //# sourceMappingURL=token-bucket.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-bucket.d.ts","sourceRoot":"","sources":["../../src/algorithms/token-bucket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAIlB,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGjC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,iBAAiB,EACzB,SAAS,SAAe;IAQpB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAoBrD"}
1
+ {"version":3,"file":"token-bucket.d.ts","sourceRoot":"","sources":["../../src/algorithms/token-bucket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB;IAMtD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAGrD"}
@@ -1,31 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TokenBucketStrategy = void 0;
4
- const redis_1 = require("../utils/redis");
5
- const scripts_1 = require("../utils/scripts");
6
4
  class TokenBucketStrategy {
7
- constructor(redis, config, keyPrefix = "redislimit") {
8
- this.redis = redis;
5
+ constructor(store, config) {
6
+ this.store = store;
9
7
  this.capacity = config.capacity;
10
8
  this.refillRate = config.refillRate;
11
- this.keyPrefix = keyPrefix;
12
9
  }
13
10
  async consume(key) {
14
- const redisKey = (0, redis_1.buildKey)(this.keyPrefix, `tb:${key}`);
15
- const now = Date.now();
16
- const result = await (0, scripts_1.evalScript)(this.redis, "token", [redisKey], [
17
- this.capacity,
18
- this.refillRate,
19
- now,
20
- ]);
21
- const parsed = (0, scripts_1.parseScriptResult)(result);
22
- return {
23
- allowed: parsed.allowed,
24
- limit: parsed.limit,
25
- remaining: parsed.remaining,
26
- reset: parsed.reset,
27
- retryAfter: parsed.retryAfter || undefined,
28
- };
11
+ return this.store.tokenBucket(key, this.capacity, this.refillRate);
29
12
  }
30
13
  }
31
14
  exports.TokenBucketStrategy = TokenBucketStrategy;
@@ -1 +1 @@
1
- {"version":3,"file":"token-bucket.js","sourceRoot":"","sources":["../../src/algorithms/token-bucket.ts"],"names":[],"mappings":";;;AAMA,0CAA0C;AAC1C,8CAAiE;AAEjE,MAAa,mBAAmB;IAM9B,YACE,KAAkB,EAClB,MAAyB,EACzB,SAAS,GAAG,YAAY;QAExB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAU,EAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE;YAC/D,IAAI,CAAC,QAAQ;YACb,IAAI,CAAC,UAAU;YACf,GAAG;SACJ,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAA,2BAAiB,EAAC,MAAM,CAAC,CAAC;QAEzC,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,SAAS;SAC3C,CAAC;IACJ,CAAC;CACF;AArCD,kDAqCC"}
1
+ {"version":3,"file":"token-bucket.js","sourceRoot":"","sources":["../../src/algorithms/token-bucket.ts"],"names":[],"mappings":";;;AAOA,MAAa,mBAAmB;IAK9B,YAAY,KAAqB,EAAE,MAAyB;QAC1D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC;CACF;AAdD,kDAcC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,22 @@
1
1
  export { RedisLimit, createLimiter } from "./limiter";
2
2
  export { createExpressMiddleware } from "./middleware/express";
3
3
  export { createFastifyPlugin, redisLimitPlugin } from "./middleware/fastify";
4
+ export { createHonoMiddleware } from "./middleware/hono";
5
+ export { createKoaMiddleware } from "./middleware/koa";
6
+ export { applyRateLimitHeaders, composeBunHandler, createBunMiddleware, jsonResponse, } from "./middleware/bun";
7
+ export type { BunMiddleware, BunNext } from "./middleware/bun";
8
+ export { createNestGuard, limitlyNestModule, LimitlyModule, RateLimit, RATE_LIMIT_KEY, } from "./middleware/nest";
9
+ export type { NestRateLimitOptions } from "./middleware/nest";
4
10
  export { SlidingWindowStrategy } from "./algorithms/sliding-window";
5
11
  export { TokenBucketStrategy } from "./algorithms/token-bucket";
6
12
  export type { RateLimitStrategy } from "./algorithms/strategy";
7
- export type { AlgorithmConfig, BaseMiddlewareOptions, MiddlewareOptions, RateLimitHeaders, RateLimitResult, RedisClient, RedisConfig, RedisLimitOptions, SlidingWindowConfig, TokenBucketConfig, } from "./types";
13
+ export { DEFAULT_KEY_PREFIX } from "./utils/redis";
14
+ export { DEFAULT_SLIDING_WINDOW, DEFAULT_TOKEN_BUCKET, resolveAlgorithmConfig, resolveMiddlewareOptions, } from "./utils/defaults";
15
+ export { consumeRateLimit } from "./utils/metrics";
16
+ export type { RateLimitCheckOutcome } from "./utils/metrics";
17
+ export { createStore, resolveStoreType } from "./stores/factory";
18
+ export { RedisStore } from "./stores/redis-store";
19
+ export { MemcachedStore } from "./stores/memcached-store";
20
+ export type { RateLimitStore, StoreType } from "./stores/types";
21
+ export type { AlgorithmConfig, BaseMiddlewareOptions, MemcachedClient, MemcachedConfig, MemcachedOptions, MiddlewareOptions, MiddlewareOptionsInput, RateLimitHeaders, RateLimitMetricsEvent, RateLimitMetricsHook, RateLimitResult, RedisClient, RedisConfig, RedisLimitOptions, SlidingWindowConfig, TokenBucketConfig, } from "./types";
8
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TokenBucketStrategy = exports.SlidingWindowStrategy = exports.redisLimitPlugin = exports.createFastifyPlugin = exports.createExpressMiddleware = exports.createLimiter = exports.RedisLimit = void 0;
3
+ exports.MemcachedStore = exports.RedisStore = exports.resolveStoreType = exports.createStore = exports.consumeRateLimit = exports.resolveMiddlewareOptions = exports.resolveAlgorithmConfig = exports.DEFAULT_TOKEN_BUCKET = exports.DEFAULT_SLIDING_WINDOW = exports.DEFAULT_KEY_PREFIX = exports.TokenBucketStrategy = exports.SlidingWindowStrategy = exports.RATE_LIMIT_KEY = exports.RateLimit = exports.LimitlyModule = exports.limitlyNestModule = exports.createNestGuard = exports.jsonResponse = exports.createBunMiddleware = exports.composeBunHandler = exports.applyRateLimitHeaders = exports.createKoaMiddleware = exports.createHonoMiddleware = exports.redisLimitPlugin = exports.createFastifyPlugin = exports.createExpressMiddleware = exports.createLimiter = exports.RedisLimit = void 0;
4
4
  var limiter_1 = require("./limiter");
5
5
  Object.defineProperty(exports, "RedisLimit", { enumerable: true, get: function () { return limiter_1.RedisLimit; } });
6
6
  Object.defineProperty(exports, "createLimiter", { enumerable: true, get: function () { return limiter_1.createLimiter; } });
@@ -9,8 +9,39 @@ Object.defineProperty(exports, "createExpressMiddleware", { enumerable: true, ge
9
9
  var fastify_1 = require("./middleware/fastify");
10
10
  Object.defineProperty(exports, "createFastifyPlugin", { enumerable: true, get: function () { return fastify_1.createFastifyPlugin; } });
11
11
  Object.defineProperty(exports, "redisLimitPlugin", { enumerable: true, get: function () { return fastify_1.redisLimitPlugin; } });
12
+ var hono_1 = require("./middleware/hono");
13
+ Object.defineProperty(exports, "createHonoMiddleware", { enumerable: true, get: function () { return hono_1.createHonoMiddleware; } });
14
+ var koa_1 = require("./middleware/koa");
15
+ Object.defineProperty(exports, "createKoaMiddleware", { enumerable: true, get: function () { return koa_1.createKoaMiddleware; } });
16
+ var bun_1 = require("./middleware/bun");
17
+ Object.defineProperty(exports, "applyRateLimitHeaders", { enumerable: true, get: function () { return bun_1.applyRateLimitHeaders; } });
18
+ Object.defineProperty(exports, "composeBunHandler", { enumerable: true, get: function () { return bun_1.composeBunHandler; } });
19
+ Object.defineProperty(exports, "createBunMiddleware", { enumerable: true, get: function () { return bun_1.createBunMiddleware; } });
20
+ Object.defineProperty(exports, "jsonResponse", { enumerable: true, get: function () { return bun_1.jsonResponse; } });
21
+ var nest_1 = require("./middleware/nest");
22
+ Object.defineProperty(exports, "createNestGuard", { enumerable: true, get: function () { return nest_1.createNestGuard; } });
23
+ Object.defineProperty(exports, "limitlyNestModule", { enumerable: true, get: function () { return nest_1.limitlyNestModule; } });
24
+ Object.defineProperty(exports, "LimitlyModule", { enumerable: true, get: function () { return nest_1.LimitlyModule; } });
25
+ Object.defineProperty(exports, "RateLimit", { enumerable: true, get: function () { return nest_1.RateLimit; } });
26
+ Object.defineProperty(exports, "RATE_LIMIT_KEY", { enumerable: true, get: function () { return nest_1.RATE_LIMIT_KEY; } });
12
27
  var sliding_window_1 = require("./algorithms/sliding-window");
13
28
  Object.defineProperty(exports, "SlidingWindowStrategy", { enumerable: true, get: function () { return sliding_window_1.SlidingWindowStrategy; } });
14
29
  var token_bucket_1 = require("./algorithms/token-bucket");
15
30
  Object.defineProperty(exports, "TokenBucketStrategy", { enumerable: true, get: function () { return token_bucket_1.TokenBucketStrategy; } });
31
+ var redis_1 = require("./utils/redis");
32
+ Object.defineProperty(exports, "DEFAULT_KEY_PREFIX", { enumerable: true, get: function () { return redis_1.DEFAULT_KEY_PREFIX; } });
33
+ var defaults_1 = require("./utils/defaults");
34
+ Object.defineProperty(exports, "DEFAULT_SLIDING_WINDOW", { enumerable: true, get: function () { return defaults_1.DEFAULT_SLIDING_WINDOW; } });
35
+ Object.defineProperty(exports, "DEFAULT_TOKEN_BUCKET", { enumerable: true, get: function () { return defaults_1.DEFAULT_TOKEN_BUCKET; } });
36
+ Object.defineProperty(exports, "resolveAlgorithmConfig", { enumerable: true, get: function () { return defaults_1.resolveAlgorithmConfig; } });
37
+ Object.defineProperty(exports, "resolveMiddlewareOptions", { enumerable: true, get: function () { return defaults_1.resolveMiddlewareOptions; } });
38
+ var metrics_1 = require("./utils/metrics");
39
+ Object.defineProperty(exports, "consumeRateLimit", { enumerable: true, get: function () { return metrics_1.consumeRateLimit; } });
40
+ var factory_1 = require("./stores/factory");
41
+ Object.defineProperty(exports, "createStore", { enumerable: true, get: function () { return factory_1.createStore; } });
42
+ Object.defineProperty(exports, "resolveStoreType", { enumerable: true, get: function () { return factory_1.resolveStoreType; } });
43
+ var redis_store_1 = require("./stores/redis-store");
44
+ Object.defineProperty(exports, "RedisStore", { enumerable: true, get: function () { return redis_store_1.RedisStore; } });
45
+ var memcached_store_1 = require("./stores/memcached-store");
46
+ Object.defineProperty(exports, "MemcachedStore", { enumerable: true, get: function () { return memcached_store_1.MemcachedStore; } });
16
47
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAAsD;AAA7C,qGAAA,UAAU,OAAA;AAAE,wGAAA,aAAa,OAAA;AAClC,gDAA+D;AAAtD,kHAAA,uBAAuB,OAAA;AAChC,gDAA6E;AAApE,8GAAA,mBAAmB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAC9C,8DAAoE;AAA3D,uHAAA,qBAAqB,OAAA;AAC9B,0DAAgE;AAAvD,mHAAA,mBAAmB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAAsD;AAA7C,qGAAA,UAAU,OAAA;AAAE,wGAAA,aAAa,OAAA;AAClC,gDAA+D;AAAtD,kHAAA,uBAAuB,OAAA;AAChC,gDAA6E;AAApE,8GAAA,mBAAmB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAC9C,0CAAyD;AAAhD,4GAAA,oBAAoB,OAAA;AAC7B,wCAAuD;AAA9C,0GAAA,mBAAmB,OAAA;AAC5B,wCAK0B;AAJxB,4GAAA,qBAAqB,OAAA;AACrB,wGAAA,iBAAiB,OAAA;AACjB,0GAAA,mBAAmB,OAAA;AACnB,mGAAA,YAAY,OAAA;AAGd,0CAM2B;AALzB,uGAAA,eAAe,OAAA;AACf,yGAAA,iBAAiB,OAAA;AACjB,qGAAA,aAAa,OAAA;AACb,iGAAA,SAAS,OAAA;AACT,sGAAA,cAAc,OAAA;AAGhB,8DAAoE;AAA3D,uHAAA,qBAAqB,OAAA;AAC9B,0DAAgE;AAAvD,mHAAA,mBAAmB,OAAA;AAE5B,uCAAmD;AAA1C,2GAAA,kBAAkB,OAAA;AAC3B,6CAK0B;AAJxB,kHAAA,sBAAsB,OAAA;AACtB,gHAAA,oBAAoB,OAAA;AACpB,kHAAA,sBAAsB,OAAA;AACtB,oHAAA,wBAAwB,OAAA;AAE1B,2CAAmD;AAA1C,2GAAA,gBAAgB,OAAA;AAEzB,4CAAiE;AAAxD,sGAAA,WAAW,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AACtC,oDAAkD;AAAzC,yGAAA,UAAU,OAAA;AACnB,4DAA0D;AAAjD,iHAAA,cAAc,OAAA"}
package/dist/limiter.d.ts CHANGED
@@ -1,19 +1,31 @@
1
+ import type { RateLimitStore } from "./stores/types";
1
2
  import type { FastifyPluginAsync } from "fastify";
2
- import type { AlgorithmConfig, MiddlewareOptions, RateLimitResult, RateLimitStrategy, RedisClient, RedisLimitOptions } from "./types";
3
+ import type { CanActivate, Type } from "@nestjs/common";
4
+ import type { AlgorithmConfig, MemcachedClient, MiddlewareOptions, MiddlewareOptionsInput, RateLimitResult, RateLimitStrategy, RedisClient, RedisLimitOptions } from "./types";
3
5
  export declare class RedisLimit {
4
- private readonly redis;
6
+ private readonly store;
5
7
  private readonly failOpen;
6
- private readonly keyPrefix;
8
+ private readonly defaultOptions;
7
9
  constructor(options: RedisLimitOptions);
10
+ getStore(): RateLimitStore;
11
+ getStoreType(): RateLimitStore["type"];
12
+ getDefaultOptions(): MiddlewareOptionsInput;
13
+ resolveOptions(options?: MiddlewareOptionsInput): MiddlewareOptions;
8
14
  getRedis(): RedisClient;
15
+ getMemcached(): MemcachedClient;
9
16
  createStrategy(config: AlgorithmConfig): RateLimitStrategy;
10
- check(key: string, config: AlgorithmConfig, options?: {
17
+ createStrategyFromOptions(options?: MiddlewareOptionsInput): RateLimitStrategy;
18
+ check(key: string, config?: MiddlewareOptionsInput, options?: {
11
19
  failOpen?: boolean;
12
20
  }): Promise<RateLimitResult>;
13
- middleware(options: MiddlewareOptions): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => Promise<void>;
14
- get fastifyPlugin(): FastifyPluginAsync<MiddlewareOptions>;
21
+ middleware(options?: MiddlewareOptionsInput): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => Promise<void>;
22
+ honoMiddleware(options?: MiddlewareOptionsInput): (c: import("hono").Context, next: import("hono").Next) => Promise<Response | void>;
23
+ koaMiddleware(options?: MiddlewareOptionsInput): (ctx: import("koa").Context, next: import("koa").Next) => Promise<void>;
24
+ bunMiddleware(options?: MiddlewareOptionsInput): import("./middleware/bun").BunMiddleware;
25
+ get fastifyPlugin(): FastifyPluginAsync<MiddlewareOptionsInput>;
26
+ nestGuard(defaultOptions?: MiddlewareOptionsInput): Type<CanActivate>;
15
27
  private createFailOpenResult;
16
28
  }
17
29
  export declare function createLimiter(options: RedisLimitOptions): RedisLimit;
18
- export type { MiddlewareOptions };
30
+ export type { MiddlewareOptions, MiddlewareOptionsInput };
19
31
  //# sourceMappingURL=limiter.d.ts.map