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.
- package/README.md +291 -12
- package/dist/algorithms/factory.d.ts +3 -2
- package/dist/algorithms/factory.d.ts.map +1 -1
- package/dist/algorithms/factory.js +3 -3
- package/dist/algorithms/factory.js.map +1 -1
- package/dist/algorithms/sliding-window.d.ts +4 -4
- package/dist/algorithms/sliding-window.d.ts.map +1 -1
- package/dist/algorithms/sliding-window.js +3 -23
- package/dist/algorithms/sliding-window.js.map +1 -1
- package/dist/algorithms/token-bucket.d.ts +4 -4
- package/dist/algorithms/token-bucket.d.ts.map +1 -1
- package/dist/algorithms/token-bucket.js +3 -20
- package/dist/algorithms/token-bucket.js.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/limiter.d.ts +19 -7
- package/dist/limiter.d.ts.map +1 -1
- package/dist/limiter.js +66 -15
- package/dist/limiter.js.map +1 -1
- package/dist/middleware/bun.d.ts +9 -0
- package/dist/middleware/bun.d.ts.map +1 -0
- package/dist/middleware/bun.js +96 -0
- package/dist/middleware/bun.js.map +1 -0
- package/dist/middleware/express.d.ts.map +1 -1
- package/dist/middleware/express.js +11 -5
- package/dist/middleware/express.js.map +1 -1
- package/dist/middleware/fastify.d.ts +3 -3
- package/dist/middleware/fastify.d.ts.map +1 -1
- package/dist/middleware/fastify.js +19 -13
- package/dist/middleware/fastify.js.map +1 -1
- package/dist/middleware/hono.d.ts +5 -0
- package/dist/middleware/hono.d.ts.map +1 -0
- package/dist/middleware/hono.js +57 -0
- package/dist/middleware/hono.js.map +1 -0
- package/dist/middleware/koa.d.ts +5 -0
- package/dist/middleware/koa.d.ts.map +1 -0
- package/dist/middleware/koa.js +54 -0
- package/dist/middleware/koa.js.map +1 -0
- package/dist/middleware/nest.d.ts +14 -0
- package/dist/middleware/nest.d.ts.map +1 -0
- package/dist/middleware/nest.js +102 -0
- package/dist/middleware/nest.js.map +1 -0
- package/dist/stores/factory.d.ts +5 -0
- package/dist/stores/factory.d.ts.map +1 -0
- package/dist/stores/factory.js +36 -0
- package/dist/stores/factory.js.map +1 -0
- package/dist/stores/memcached-store.d.ts +13 -0
- package/dist/stores/memcached-store.d.ts.map +1 -0
- package/dist/stores/memcached-store.js +117 -0
- package/dist/stores/memcached-store.js.map +1 -0
- package/dist/stores/redis-store.d.ts +12 -0
- package/dist/stores/redis-store.d.ts.map +1 -0
- package/dist/stores/redis-store.js +54 -0
- package/dist/stores/redis-store.js.map +1 -0
- package/dist/stores/types.d.ts +8 -0
- package/dist/stores/types.d.ts.map +1 -0
- package/dist/stores/types.js +3 -0
- package/dist/stores/types.js.map +1 -0
- package/dist/types/index.d.ts +62 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/defaults.d.ts +6 -0
- package/dist/utils/defaults.d.ts.map +1 -0
- package/dist/utils/defaults.js +59 -0
- package/dist/utils/defaults.js.map +1 -0
- package/dist/utils/memcached.d.ts +11 -0
- package/dist/utils/memcached.d.ts.map +1 -0
- package/dist/utils/memcached.js +91 -0
- package/dist/utils/memcached.js.map +1 -0
- package/dist/utils/metrics.d.ts +21 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +60 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/redis.d.ts +1 -0
- package/dist/utils/redis.d.ts.map +1 -1
- package/dist/utils/redis.js +2 -0
- package/dist/utils/redis.js.map +1 -1
- 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
|
|
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
|
|
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
|
-
##
|
|
270
|
+
## Storage Backends
|
|
271
|
+
|
|
272
|
+
limitly supports Redis, Valkey, DragonflyDB (Redis-compatible), and Memcached.
|
|
273
|
+
|
|
274
|
+
### Redis / Valkey / DragonflyDB
|
|
81
275
|
|
|
82
|
-
|
|
276
|
+
Redis-compatible backends use atomic Lua scripts (sorted sets + hashes). Connect with `ioredis`:
|
|
83
277
|
|
|
84
278
|
```typescript
|
|
85
|
-
|
|
279
|
+
import Redis from "ioredis";
|
|
280
|
+
|
|
281
|
+
// Redis
|
|
86
282
|
createLimiter({ redis: new Redis() });
|
|
87
283
|
|
|
88
|
-
//
|
|
89
|
-
createLimiter({ redis: "redis://localhost:6379" });
|
|
284
|
+
// Valkey
|
|
285
|
+
createLimiter({ store: "valkey", redis: "redis://localhost:6379" });
|
|
90
286
|
|
|
91
|
-
//
|
|
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
|
-
|
|
97
|
-
|
|
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
|
|
2
|
-
|
|
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,
|
|
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(
|
|
6
|
+
function createStrategy(store, config) {
|
|
7
7
|
switch (config.algorithm) {
|
|
8
8
|
case "sliding-window":
|
|
9
|
-
return new sliding_window_1.SlidingWindowStrategy(
|
|
9
|
+
return new sliding_window_1.SlidingWindowStrategy(store, config);
|
|
10
10
|
case "token-bucket":
|
|
11
|
-
return new token_bucket_1.TokenBucketStrategy(
|
|
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":";;
|
|
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,
|
|
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
|
|
4
|
+
private readonly store;
|
|
4
5
|
private readonly limit;
|
|
5
6
|
private readonly window;
|
|
6
|
-
|
|
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":"
|
|
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(
|
|
9
|
-
this.
|
|
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
|
-
|
|
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":";;;
|
|
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,
|
|
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
|
|
4
|
+
private readonly store;
|
|
4
5
|
private readonly capacity;
|
|
5
6
|
private readonly refillRate;
|
|
6
|
-
|
|
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,
|
|
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(
|
|
8
|
-
this.
|
|
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
|
-
|
|
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":";;;
|
|
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
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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 {
|
|
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
|
|
6
|
+
private readonly store;
|
|
5
7
|
private readonly failOpen;
|
|
6
|
-
private readonly
|
|
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
|
-
|
|
17
|
+
createStrategyFromOptions(options?: MiddlewareOptionsInput): RateLimitStrategy;
|
|
18
|
+
check(key: string, config?: MiddlewareOptionsInput, options?: {
|
|
11
19
|
failOpen?: boolean;
|
|
12
20
|
}): Promise<RateLimitResult>;
|
|
13
|
-
middleware(options
|
|
14
|
-
|
|
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
|