@commandkit/ratelimit 0.0.0-dev.20260317060555

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 (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +801 -0
  3. package/dist/api.d.ts +79 -0
  4. package/dist/api.js +266 -0
  5. package/dist/augmentation.d.ts +11 -0
  6. package/dist/augmentation.js +8 -0
  7. package/dist/configure.d.ts +28 -0
  8. package/dist/configure.js +85 -0
  9. package/dist/constants.d.ts +17 -0
  10. package/dist/constants.js +21 -0
  11. package/dist/directive/use-ratelimit-directive.d.ts +22 -0
  12. package/dist/directive/use-ratelimit-directive.js +38 -0
  13. package/dist/directive/use-ratelimit.d.ts +14 -0
  14. package/dist/directive/use-ratelimit.js +169 -0
  15. package/dist/engine/RateLimitEngine.d.ts +48 -0
  16. package/dist/engine/RateLimitEngine.js +137 -0
  17. package/dist/engine/algorithms/fixed-window.d.ts +44 -0
  18. package/dist/engine/algorithms/fixed-window.js +198 -0
  19. package/dist/engine/algorithms/leaky-bucket.d.ts +48 -0
  20. package/dist/engine/algorithms/leaky-bucket.js +119 -0
  21. package/dist/engine/algorithms/sliding-window.d.ts +45 -0
  22. package/dist/engine/algorithms/sliding-window.js +127 -0
  23. package/dist/engine/algorithms/token-bucket.d.ts +47 -0
  24. package/dist/engine/algorithms/token-bucket.js +118 -0
  25. package/dist/engine/violations.d.ts +55 -0
  26. package/dist/engine/violations.js +106 -0
  27. package/dist/errors.d.ts +21 -0
  28. package/dist/errors.js +28 -0
  29. package/dist/index.d.ts +31 -0
  30. package/dist/index.js +53 -0
  31. package/dist/plugin.d.ts +140 -0
  32. package/dist/plugin.js +796 -0
  33. package/dist/providers/fallback.d.ts +7 -0
  34. package/dist/providers/fallback.js +11 -0
  35. package/dist/providers/memory.d.ts +6 -0
  36. package/dist/providers/memory.js +11 -0
  37. package/dist/providers/redis.d.ts +7 -0
  38. package/dist/providers/redis.js +11 -0
  39. package/dist/runtime.d.ts +45 -0
  40. package/dist/runtime.js +67 -0
  41. package/dist/storage/fallback.d.ts +180 -0
  42. package/dist/storage/fallback.js +261 -0
  43. package/dist/storage/memory.d.ts +146 -0
  44. package/dist/storage/memory.js +304 -0
  45. package/dist/storage/redis.d.ts +130 -0
  46. package/dist/storage/redis.js +243 -0
  47. package/dist/types.d.ts +296 -0
  48. package/dist/types.js +40 -0
  49. package/dist/utils/config.d.ts +34 -0
  50. package/dist/utils/config.js +105 -0
  51. package/dist/utils/keys.d.ts +102 -0
  52. package/dist/utils/keys.js +304 -0
  53. package/dist/utils/locking.d.ts +17 -0
  54. package/dist/utils/locking.js +60 -0
  55. package/dist/utils/time.d.ts +23 -0
  56. package/dist/utils/time.js +72 -0
  57. package/package.json +65 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * In-memory storage.
3
+ *
4
+ * Used for tests and local development; implements TTL and sorted-set helpers.
5
+ * Not suitable for multi-process deployments.
6
+ */
7
+ import type { FixedWindowConsumeResult, RateLimitStorage, SlidingWindowConsumeResult } from '../types';
8
+ /**
9
+ * In-memory storage used for tests and local usage.
10
+ *
11
+ * @implements RateLimitStorage
12
+ */
13
+ export declare class MemoryRateLimitStorage implements RateLimitStorage {
14
+ private readonly kv;
15
+ private readonly zsets;
16
+ private now;
17
+ private isExpired;
18
+ /**
19
+ * Clear expired entries so reads reflect current state.
20
+ *
21
+ * @param key - Storage key to clean.
22
+ */
23
+ private cleanupKey;
24
+ /**
25
+ * Read a value from the in-memory key/value store.
26
+ *
27
+ * @param key - Storage key to read.
28
+ * @returns Stored value or null when absent/expired.
29
+ */
30
+ get<T = unknown>(key: string): Promise<T | null>;
31
+ /**
32
+ * Store a value in memory with optional TTL.
33
+ *
34
+ * @param key - Storage key to write.
35
+ * @param value - Value to store.
36
+ * @param ttlMs - Optional TTL in milliseconds.
37
+ * @returns Resolves when the value is stored.
38
+ */
39
+ set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void>;
40
+ /**
41
+ * Delete a key from the in-memory store.
42
+ *
43
+ * @param key - Storage key to delete.
44
+ * @returns Resolves when the key is removed.
45
+ */
46
+ delete(key: string): Promise<void>;
47
+ /**
48
+ * Increment a fixed-window counter with TTL handling.
49
+ *
50
+ * @param key - Storage key to increment.
51
+ * @param ttlMs - TTL window in milliseconds.
52
+ * @returns Updated counter value and remaining TTL.
53
+ */
54
+ incr(key: string, ttlMs: number): Promise<FixedWindowConsumeResult>;
55
+ /**
56
+ * Read the TTL for a key when present.
57
+ *
58
+ * @param key - Storage key to inspect.
59
+ * @returns Remaining TTL in ms or null when no TTL is set.
60
+ */
61
+ ttl(key: string): Promise<number | null>;
62
+ /**
63
+ * Update the TTL for an existing key.
64
+ *
65
+ * @param key - Storage key to update.
66
+ * @param ttlMs - TTL in milliseconds.
67
+ * @returns Resolves after the TTL is updated.
68
+ */
69
+ expire(key: string, ttlMs: number): Promise<void>;
70
+ /**
71
+ * Add a member to a sorted set with the given score.
72
+ *
73
+ * @param key - Sorted-set key.
74
+ * @param score - Score to associate with the member.
75
+ * @param member - Member identifier.
76
+ * @returns Resolves when the member is added.
77
+ */
78
+ zAdd(key: string, score: number, member: string): Promise<void>;
79
+ /**
80
+ * Remove sorted-set members with scores in the given range.
81
+ *
82
+ * @param key - Sorted-set key.
83
+ * @param min - Minimum score (inclusive).
84
+ * @param max - Maximum score (inclusive).
85
+ * @returns Resolves when the range is removed.
86
+ */
87
+ zRemRangeByScore(key: string, min: number, max: number): Promise<void>;
88
+ /**
89
+ * Count members in a sorted set.
90
+ *
91
+ * @param key - Sorted-set key.
92
+ * @returns Number of members in the set.
93
+ */
94
+ zCard(key: string): Promise<number>;
95
+ /**
96
+ * Read sorted-set members in a score range.
97
+ *
98
+ * @param key - Sorted-set key.
99
+ * @param min - Minimum score (inclusive).
100
+ * @param max - Maximum score (inclusive).
101
+ * @returns Ordered members in the score range.
102
+ */
103
+ zRangeByScore(key: string, min: number, max: number): Promise<string[]>;
104
+ /**
105
+ * Atomically consume a fixed-window counter for the key.
106
+ *
107
+ * @param key - Storage key to consume.
108
+ * @param limit - Request limit for the window.
109
+ * @param windowMs - Window size in milliseconds.
110
+ * @param nowMs - Current timestamp in milliseconds.
111
+ * @returns Fixed-window consume result.
112
+ */
113
+ consumeFixedWindow(key: string, _limit: number, windowMs: number, _nowMs: number): Promise<FixedWindowConsumeResult>;
114
+ /**
115
+ * Atomically consume a sliding-window log for the key.
116
+ *
117
+ * @param key - Storage key to consume.
118
+ * @param limit - Request limit for the window.
119
+ * @param windowMs - Window size in milliseconds.
120
+ * @param nowMs - Current timestamp in milliseconds.
121
+ * @param member - Member identifier for this request.
122
+ * @returns Sliding-window consume result.
123
+ */
124
+ consumeSlidingWindowLog(key: string, limit: number, windowMs: number, nowMs: number, member: string): Promise<SlidingWindowConsumeResult>;
125
+ /**
126
+ * Delete keys with the given prefix.
127
+ *
128
+ * @param prefix - Prefix to match.
129
+ * @returns Resolves after matching keys are deleted.
130
+ */
131
+ deleteByPrefix(prefix: string): Promise<void>;
132
+ /**
133
+ * Delete keys matching a glob pattern.
134
+ *
135
+ * @param pattern - Glob pattern to match.
136
+ * @returns Resolves after matching keys are deleted.
137
+ */
138
+ deleteByPattern(pattern: string): Promise<void>;
139
+ /**
140
+ * List keys that match a prefix.
141
+ *
142
+ * @param prefix - Prefix to match.
143
+ * @returns Matching keys.
144
+ */
145
+ keysByPrefix(prefix: string): Promise<string[]>;
146
+ }
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ /**
3
+ * In-memory storage.
4
+ *
5
+ * Used for tests and local development; implements TTL and sorted-set helpers.
6
+ * Not suitable for multi-process deployments.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.MemoryRateLimitStorage = void 0;
10
+ /**
11
+ * In-memory storage used for tests and local usage.
12
+ *
13
+ * @implements RateLimitStorage
14
+ */
15
+ class MemoryRateLimitStorage {
16
+ constructor() {
17
+ this.kv = new Map();
18
+ this.zsets = new Map();
19
+ }
20
+ now() {
21
+ return Date.now();
22
+ }
23
+ isExpired(expiresAt) {
24
+ return expiresAt != null && expiresAt <= this.now();
25
+ }
26
+ /**
27
+ * Clear expired entries so reads reflect current state.
28
+ *
29
+ * @param key - Storage key to clean.
30
+ */
31
+ cleanupKey(key) {
32
+ const kvEntry = this.kv.get(key);
33
+ if (kvEntry && this.isExpired(kvEntry.expiresAt)) {
34
+ this.kv.delete(key);
35
+ }
36
+ const zEntry = this.zsets.get(key);
37
+ if (zEntry && this.isExpired(zEntry.expiresAt)) {
38
+ this.zsets.delete(key);
39
+ }
40
+ }
41
+ /**
42
+ * Read a value from the in-memory key/value store.
43
+ *
44
+ * @param key - Storage key to read.
45
+ * @returns Stored value or null when absent/expired.
46
+ */
47
+ async get(key) {
48
+ this.cleanupKey(key);
49
+ const entry = this.kv.get(key);
50
+ if (!entry)
51
+ return null;
52
+ return entry.value;
53
+ }
54
+ /**
55
+ * Store a value in memory with optional TTL.
56
+ *
57
+ * @param key - Storage key to write.
58
+ * @param value - Value to store.
59
+ * @param ttlMs - Optional TTL in milliseconds.
60
+ * @returns Resolves when the value is stored.
61
+ */
62
+ async set(key, value, ttlMs) {
63
+ const expiresAt = typeof ttlMs === 'number' ? this.now() + ttlMs : null;
64
+ this.kv.set(key, { value, expiresAt });
65
+ }
66
+ /**
67
+ * Delete a key from the in-memory store.
68
+ *
69
+ * @param key - Storage key to delete.
70
+ * @returns Resolves when the key is removed.
71
+ */
72
+ async delete(key) {
73
+ this.kv.delete(key);
74
+ this.zsets.delete(key);
75
+ }
76
+ /**
77
+ * Increment a fixed-window counter with TTL handling.
78
+ *
79
+ * @param key - Storage key to increment.
80
+ * @param ttlMs - TTL window in milliseconds.
81
+ * @returns Updated counter value and remaining TTL.
82
+ */
83
+ async incr(key, ttlMs) {
84
+ this.cleanupKey(key);
85
+ const entry = this.kv.get(key);
86
+ if (!entry || typeof entry.value !== 'number') {
87
+ const expiresAt = this.now() + ttlMs;
88
+ this.kv.set(key, { value: 1, expiresAt });
89
+ return { count: 1, ttlMs };
90
+ }
91
+ const count = entry.value + 1;
92
+ entry.value = count;
93
+ if (!entry.expiresAt) {
94
+ entry.expiresAt = this.now() + ttlMs;
95
+ }
96
+ const remainingTtl = Math.max(0, (entry.expiresAt ?? this.now()) - this.now());
97
+ return { count, ttlMs: remainingTtl };
98
+ }
99
+ /**
100
+ * Read the TTL for a key when present.
101
+ *
102
+ * @param key - Storage key to inspect.
103
+ * @returns Remaining TTL in ms or null when no TTL is set.
104
+ */
105
+ async ttl(key) {
106
+ this.cleanupKey(key);
107
+ const entry = this.kv.get(key) ?? this.zsets.get(key);
108
+ if (!entry)
109
+ return null;
110
+ if (entry.expiresAt == null)
111
+ return null;
112
+ return Math.max(0, entry.expiresAt - this.now());
113
+ }
114
+ /**
115
+ * Update the TTL for an existing key.
116
+ *
117
+ * @param key - Storage key to update.
118
+ * @param ttlMs - TTL in milliseconds.
119
+ * @returns Resolves after the TTL is updated.
120
+ */
121
+ async expire(key, ttlMs) {
122
+ const expiresAt = this.now() + ttlMs;
123
+ const kvEntry = this.kv.get(key);
124
+ if (kvEntry)
125
+ kvEntry.expiresAt = expiresAt;
126
+ const zEntry = this.zsets.get(key);
127
+ if (zEntry)
128
+ zEntry.expiresAt = expiresAt;
129
+ }
130
+ /**
131
+ * Add a member to a sorted set with the given score.
132
+ *
133
+ * @param key - Sorted-set key.
134
+ * @param score - Score to associate with the member.
135
+ * @param member - Member identifier.
136
+ * @returns Resolves when the member is added.
137
+ */
138
+ async zAdd(key, score, member) {
139
+ this.cleanupKey(key);
140
+ const entry = this.zsets.get(key) ?? { items: [], expiresAt: null };
141
+ const existingIndex = entry.items.findIndex((item) => item.member === member);
142
+ if (existingIndex >= 0) {
143
+ entry.items[existingIndex] = { score, member };
144
+ }
145
+ else {
146
+ entry.items.push({ score, member });
147
+ }
148
+ entry.items.sort((a, b) => a.score - b.score);
149
+ this.zsets.set(key, entry);
150
+ }
151
+ /**
152
+ * Remove sorted-set members with scores in the given range.
153
+ *
154
+ * @param key - Sorted-set key.
155
+ * @param min - Minimum score (inclusive).
156
+ * @param max - Maximum score (inclusive).
157
+ * @returns Resolves when the range is removed.
158
+ */
159
+ async zRemRangeByScore(key, min, max) {
160
+ this.cleanupKey(key);
161
+ const entry = this.zsets.get(key);
162
+ if (!entry)
163
+ return;
164
+ entry.items = entry.items.filter((item) => item.score < min || item.score > max);
165
+ }
166
+ /**
167
+ * Count members in a sorted set.
168
+ *
169
+ * @param key - Sorted-set key.
170
+ * @returns Number of members in the set.
171
+ */
172
+ async zCard(key) {
173
+ this.cleanupKey(key);
174
+ const entry = this.zsets.get(key);
175
+ return entry ? entry.items.length : 0;
176
+ }
177
+ /**
178
+ * Read sorted-set members in a score range.
179
+ *
180
+ * @param key - Sorted-set key.
181
+ * @param min - Minimum score (inclusive).
182
+ * @param max - Maximum score (inclusive).
183
+ * @returns Ordered members in the score range.
184
+ */
185
+ async zRangeByScore(key, min, max) {
186
+ this.cleanupKey(key);
187
+ const entry = this.zsets.get(key);
188
+ if (!entry)
189
+ return [];
190
+ return entry.items
191
+ .filter((item) => item.score >= min && item.score <= max)
192
+ .map((item) => item.member);
193
+ }
194
+ /**
195
+ * Atomically consume a fixed-window counter for the key.
196
+ *
197
+ * @param key - Storage key to consume.
198
+ * @param limit - Request limit for the window.
199
+ * @param windowMs - Window size in milliseconds.
200
+ * @param nowMs - Current timestamp in milliseconds.
201
+ * @returns Fixed-window consume result.
202
+ */
203
+ async consumeFixedWindow(key, _limit, windowMs, _nowMs) {
204
+ return this.incr(key, windowMs);
205
+ }
206
+ /**
207
+ * Atomically consume a sliding-window log for the key.
208
+ *
209
+ * @param key - Storage key to consume.
210
+ * @param limit - Request limit for the window.
211
+ * @param windowMs - Window size in milliseconds.
212
+ * @param nowMs - Current timestamp in milliseconds.
213
+ * @param member - Member identifier for this request.
214
+ * @returns Sliding-window consume result.
215
+ */
216
+ async consumeSlidingWindowLog(key, limit, windowMs, nowMs, member) {
217
+ await this.zRemRangeByScore(key, 0, nowMs - windowMs);
218
+ const count = await this.zCard(key);
219
+ if (count >= limit) {
220
+ const oldest = await this.zRangeByScore(key, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY);
221
+ const oldestMember = oldest[0];
222
+ const oldestTs = parseMemberTimestamp(oldestMember, nowMs);
223
+ return { allowed: false, count, resetAt: oldestTs + windowMs };
224
+ }
225
+ await this.zAdd(key, nowMs, member);
226
+ await this.expire(key, windowMs);
227
+ const newCount = count + 1;
228
+ const oldest = await this.zRangeByScore(key, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY);
229
+ const oldestMember = oldest[0];
230
+ const oldestTs = parseMemberTimestamp(oldestMember, nowMs);
231
+ return { allowed: true, count: newCount, resetAt: oldestTs + windowMs };
232
+ }
233
+ /**
234
+ * Delete keys with the given prefix.
235
+ *
236
+ * @param prefix - Prefix to match.
237
+ * @returns Resolves after matching keys are deleted.
238
+ */
239
+ async deleteByPrefix(prefix) {
240
+ for (const key of Array.from(this.kv.keys())) {
241
+ if (key.startsWith(prefix))
242
+ this.kv.delete(key);
243
+ }
244
+ for (const key of Array.from(this.zsets.keys())) {
245
+ if (key.startsWith(prefix))
246
+ this.zsets.delete(key);
247
+ }
248
+ }
249
+ /**
250
+ * Delete keys matching a glob pattern.
251
+ *
252
+ * @param pattern - Glob pattern to match.
253
+ * @returns Resolves after matching keys are deleted.
254
+ */
255
+ async deleteByPattern(pattern) {
256
+ const regex = globToRegex(pattern);
257
+ for (const key of Array.from(this.kv.keys())) {
258
+ if (regex.test(key))
259
+ this.kv.delete(key);
260
+ }
261
+ for (const key of Array.from(this.zsets.keys())) {
262
+ if (regex.test(key))
263
+ this.zsets.delete(key);
264
+ }
265
+ }
266
+ /**
267
+ * List keys that match a prefix.
268
+ *
269
+ * @param prefix - Prefix to match.
270
+ * @returns Matching keys.
271
+ */
272
+ async keysByPrefix(prefix) {
273
+ const keys = new Set();
274
+ const kvKeys = Array.from(this.kv.keys());
275
+ for (const key of kvKeys) {
276
+ this.cleanupKey(key);
277
+ if (this.kv.has(key) && key.startsWith(prefix)) {
278
+ keys.add(key);
279
+ }
280
+ }
281
+ const zsetKeys = Array.from(this.zsets.keys());
282
+ for (const key of zsetKeys) {
283
+ this.cleanupKey(key);
284
+ if (this.zsets.has(key) && key.startsWith(prefix)) {
285
+ keys.add(key);
286
+ }
287
+ }
288
+ return Array.from(keys);
289
+ }
290
+ }
291
+ exports.MemoryRateLimitStorage = MemoryRateLimitStorage;
292
+ function globToRegex(glob) {
293
+ const escaped = glob.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
294
+ const regex = `^${escaped.replace(/\*/g, '.*')}$`;
295
+ return new RegExp(regex);
296
+ }
297
+ function parseMemberTimestamp(member, fallback) {
298
+ if (!member)
299
+ return fallback;
300
+ const prefix = member.split('-')[0];
301
+ const parsed = Number(prefix);
302
+ return Number.isFinite(parsed) ? parsed : fallback;
303
+ }
304
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0b3JhZ2UvbWVtb3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7O0FBdUJIOzs7O0dBSUc7QUFDSCxNQUFhLHNCQUFzQjtJQUFuQztRQUNtQixPQUFFLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7UUFDaEMsVUFBSyxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO0lBeVR4RCxDQUFDO0lBdlRTLEdBQUc7UUFDVCxPQUFPLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sU0FBUyxDQUFDLFNBQXdCO1FBQ3hDLE9BQU8sU0FBUyxJQUFJLElBQUksSUFBSSxTQUFTLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3RELENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssVUFBVSxDQUFDLEdBQVc7UUFDNUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakMsSUFBSSxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QixDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLEdBQUcsQ0FBYyxHQUFXO1FBQ2hDLElB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QyxHQUFHLENBQUMsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQy9DLEtBQUssTUFBTSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQixDQUFDO0NBQ0Y7QUEzVEQsd0RBMlRDO0FBRUQsU0FBUyxXQUFXLENBQUMsSUFBWTtJQUMvQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzNELE1BQU0sS0FBSyxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNsRCxPQUFPLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUMzQixNQUEwQixFQUMxQixRQUFnQjtJQUVoQixJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQzdCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlCLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7QUFDckQsQ0FBQyJ9
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Redis storage.
3
+ *
4
+ * Uses Lua scripts for atomic fixed/sliding window operations.
5
+ */
6
+ import Redis, { type RedisOptions } from 'ioredis';
7
+ import type { FixedWindowConsumeResult, RateLimitStorage, SlidingWindowConsumeResult } from '../types';
8
+ /**
9
+ * Redis-backed storage with Lua scripts for atomic window operations.
10
+ *
11
+ * @implements RateLimitStorage
12
+ */
13
+ export declare class RedisRateLimitStorage implements RateLimitStorage {
14
+ readonly redis: Redis;
15
+ constructor(redis?: Redis | RedisOptions);
16
+ /**
17
+ * Read a value from Redis and JSON-decode it.
18
+ *
19
+ * @param key - Storage key to read.
20
+ * @returns Parsed value or null when absent.
21
+ */
22
+ get<T = unknown>(key: string): Promise<T | null>;
23
+ /**
24
+ * Store a value in Redis with optional TTL.
25
+ *
26
+ * @param key - Storage key to write.
27
+ * @param value - Value to serialize and store.
28
+ * @param ttlMs - Optional TTL in milliseconds.
29
+ * @returns Resolves when the value is stored.
30
+ */
31
+ set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void>;
32
+ /**
33
+ * Delete a key from Redis.
34
+ *
35
+ * @param key - Storage key to delete.
36
+ * @returns Resolves when the key is removed.
37
+ */
38
+ delete(key: string): Promise<void>;
39
+ /**
40
+ * Read the TTL for a key when present.
41
+ *
42
+ * @param key - Storage key to inspect.
43
+ * @returns Remaining TTL in ms or null when no TTL is set.
44
+ */
45
+ ttl(key: string): Promise<number | null>;
46
+ /**
47
+ * Update the TTL for an existing key.
48
+ *
49
+ * @param key - Storage key to update.
50
+ * @param ttlMs - TTL in milliseconds.
51
+ * @returns Resolves after the TTL is updated.
52
+ */
53
+ expire(key: string, ttlMs: number): Promise<void>;
54
+ /**
55
+ * Add a member to a sorted set with the given score.
56
+ *
57
+ * @param key - Sorted-set key.
58
+ * @param score - Score to associate with the member.
59
+ * @param member - Member identifier.
60
+ * @returns Resolves when the member is added.
61
+ */
62
+ zAdd(key: string, score: number, member: string): Promise<void>;
63
+ /**
64
+ * Remove sorted-set members with scores in the given range.
65
+ *
66
+ * @param key - Sorted-set key.
67
+ * @param min - Minimum score (inclusive).
68
+ * @param max - Maximum score (inclusive).
69
+ * @returns Resolves when the range is removed.
70
+ */
71
+ zRemRangeByScore(key: string, min: number, max: number): Promise<void>;
72
+ /**
73
+ * Count members in a sorted set.
74
+ *
75
+ * @param key - Sorted-set key.
76
+ * @returns Number of members in the set.
77
+ */
78
+ zCard(key: string): Promise<number>;
79
+ /**
80
+ * Read sorted-set members in a score range.
81
+ *
82
+ * @param key - Sorted-set key.
83
+ * @param min - Minimum score (inclusive).
84
+ * @param max - Maximum score (inclusive).
85
+ * @returns Ordered members in the score range.
86
+ */
87
+ zRangeByScore(key: string, min: number, max: number): Promise<string[]>;
88
+ /**
89
+ * Atomically consume a fixed-window counter via Lua.
90
+ *
91
+ * @param key - Storage key to consume.
92
+ * @param _limit - Limit (unused by the script).
93
+ * @param windowMs - Window size in milliseconds.
94
+ * @param _nowMs - Current time (unused by the script).
95
+ * @returns Fixed-window consume result.
96
+ */
97
+ consumeFixedWindow(key: string, _limit: number, windowMs: number, _nowMs: number): Promise<FixedWindowConsumeResult>;
98
+ /**
99
+ * Atomically consume a sliding-window log via Lua.
100
+ *
101
+ * @param key - Storage key to consume.
102
+ * @param limit - Request limit for the window.
103
+ * @param windowMs - Window size in milliseconds.
104
+ * @param nowMs - Current timestamp in milliseconds.
105
+ * @param member - Member identifier for this request.
106
+ * @returns Sliding-window consume result.
107
+ */
108
+ consumeSlidingWindowLog(key: string, limit: number, windowMs: number, nowMs: number, member: string): Promise<SlidingWindowConsumeResult>;
109
+ /**
110
+ * Delete keys with the given prefix.
111
+ *
112
+ * @param prefix - Prefix to match.
113
+ * @returns Resolves after matching keys are deleted.
114
+ */
115
+ deleteByPrefix(prefix: string): Promise<void>;
116
+ /**
117
+ * Delete keys matching a glob pattern using SCAN to avoid blocking Redis.
118
+ *
119
+ * @param pattern - Glob pattern to match keys against.
120
+ * @returns Resolves after matching keys are deleted.
121
+ */
122
+ deleteByPattern(pattern: string): Promise<void>;
123
+ /**
124
+ * List keys that match a prefix using SCAN.
125
+ *
126
+ * @param prefix - Prefix to match.
127
+ * @returns Matching keys.
128
+ */
129
+ keysByPrefix(prefix: string): Promise<string[]>;
130
+ }