@guren/server 1.0.0-rc.9 → 1.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 (68) hide show
  1. package/dist/{Application-DtWDHXr1.d.ts → Application-BnsyCKXY.d.ts} +79 -8
  2. package/dist/AuthManager-SfhCNkAU.d.ts +79 -0
  3. package/dist/{BroadcastManager-AkIWUGJo.d.ts → BroadcastManager-CGWl9rUO.d.ts} +5 -0
  4. package/dist/{ConsoleKernel-CqCVrdZs.d.ts → ConsoleKernel-BDtBETjm.d.ts} +1 -1
  5. package/dist/{Gate-CNkBYf8m.d.ts → Gate-CynjZCtS.d.ts} +5 -0
  6. package/dist/{I18nManager-Dtgzsf5n.d.ts → I18nManager-BiSoczfV.d.ts} +6 -1
  7. package/dist/McpServiceProvider-JW6PDVMD.js +7 -0
  8. package/dist/api-token-BSSCLlFW.d.ts +541 -0
  9. package/dist/auth/index.d.ts +9 -327
  10. package/dist/auth/index.js +59 -6684
  11. package/dist/authorization/index.d.ts +2 -2
  12. package/dist/authorization/index.js +19 -604
  13. package/dist/broadcasting/index.d.ts +2 -2
  14. package/dist/broadcasting/index.js +12 -895
  15. package/dist/cache/index.js +8 -809
  16. package/dist/chunk-2T6JN4VR.js +1563 -0
  17. package/dist/chunk-44F7JQ7I.js +950 -0
  18. package/dist/chunk-74HTZG3V.js +331 -0
  19. package/dist/chunk-A3ISJVEV.js +598 -0
  20. package/dist/chunk-CSDKWLFD.js +652 -0
  21. package/dist/chunk-CSRQTEQA.js +839 -0
  22. package/dist/chunk-DAQKYKLH.js +182 -0
  23. package/dist/chunk-EDRGAM6G.js +647 -0
  24. package/dist/chunk-EGU5KB7V.js +818 -0
  25. package/dist/chunk-H32L2NE3.js +372 -0
  26. package/dist/chunk-HKQSAFSN.js +837 -0
  27. package/dist/chunk-IOTWFHZU.js +558 -0
  28. package/dist/chunk-ONSDE37A.js +125 -0
  29. package/dist/chunk-QQKTH5KX.js +114 -0
  30. package/dist/chunk-R2TCP7D7.js +409 -0
  31. package/dist/chunk-SIP34GBE.js +380 -0
  32. package/dist/chunk-THSX7OOR.js +454 -0
  33. package/dist/chunk-UY3AZSYL.js +14 -0
  34. package/dist/chunk-VT5KRDPH.js +134 -0
  35. package/dist/chunk-VXXZIXAP.js +255 -0
  36. package/dist/chunk-WJJ5CTNI.js +907 -0
  37. package/dist/chunk-WVY45EIW.js +359 -0
  38. package/dist/chunk-ZRBLZY3M.js +462 -0
  39. package/dist/client-CKXJLsTe.d.ts +232 -0
  40. package/dist/email-verification-CAeArjui.d.ts +327 -0
  41. package/dist/encryption/index.js +48 -556
  42. package/dist/errors-JOOPDDQ6.js +34 -0
  43. package/dist/events/index.js +14 -316
  44. package/dist/health/index.js +12 -367
  45. package/dist/i18n/index.d.ts +2 -2
  46. package/dist/i18n/index.js +14 -583
  47. package/dist/index.d.ts +37 -239
  48. package/dist/index.js +2873 -19166
  49. package/dist/lambda/index.d.ts +9 -7
  50. package/dist/lambda/index.js +4 -9
  51. package/dist/logging/index.js +12 -545
  52. package/dist/mail/index.d.ts +29 -1
  53. package/dist/mail/index.js +15 -684
  54. package/dist/mcp/index.d.ts +7 -5
  55. package/dist/mcp/index.js +5 -378
  56. package/dist/notifications/index.d.ts +8 -6
  57. package/dist/notifications/index.js +13 -730
  58. package/dist/queue/index.d.ts +37 -7
  59. package/dist/queue/index.js +22 -940
  60. package/dist/redis/index.d.ts +366 -0
  61. package/dist/redis/index.js +597 -0
  62. package/dist/runtime/index.d.ts +8 -6
  63. package/dist/runtime/index.js +26 -244
  64. package/dist/scheduling/index.js +14 -822
  65. package/dist/storage/index.d.ts +1 -0
  66. package/dist/storage/index.js +6 -824
  67. package/package.json +15 -7
  68. package/dist/api-token-JOif2CtG.d.ts +0 -1792
@@ -0,0 +1,462 @@
1
+ import {
2
+ AuthorizationException
3
+ } from "./chunk-THSX7OOR.js";
4
+
5
+ // src/authorization/Gate.ts
6
+ var Response = {
7
+ allow(message) {
8
+ return { allowed: true, message };
9
+ },
10
+ deny(message, code) {
11
+ return { allowed: false, message: message ?? "This action is unauthorized.", code };
12
+ },
13
+ denyWithStatus(status, message) {
14
+ return { allowed: false, message: message ?? "This action is unauthorized.", status };
15
+ },
16
+ denyAsNotFound(message) {
17
+ return { allowed: false, message: message ?? "Not found.", status: 404 };
18
+ }
19
+ };
20
+ var Gate = class {
21
+ /**
22
+ * Defined gates.
23
+ */
24
+ gates = /* @__PURE__ */ new Map();
25
+ /**
26
+ * Registered policies.
27
+ */
28
+ policies = /* @__PURE__ */ new Map();
29
+ /**
30
+ * Policy instances cache.
31
+ */
32
+ policyInstances = /* @__PURE__ */ new Map();
33
+ /**
34
+ * Before callbacks.
35
+ */
36
+ beforeCallbacks = [];
37
+ /**
38
+ * After callbacks.
39
+ */
40
+ afterCallbacks = [];
41
+ /**
42
+ * User resolver function.
43
+ */
44
+ userResolver;
45
+ /**
46
+ * Current user for checks.
47
+ */
48
+ currentUser = null;
49
+ constructor(options = {}) {
50
+ this.userResolver = options.userResolver;
51
+ }
52
+ /**
53
+ * Define a new gate.
54
+ */
55
+ define(ability, callback) {
56
+ this.gates.set(ability, { callback });
57
+ return this;
58
+ }
59
+ /**
60
+ * Register a policy for a model class.
61
+ */
62
+ policy(modelClass, policyClass) {
63
+ this.policies.set(modelClass, policyClass);
64
+ return this;
65
+ }
66
+ /**
67
+ * Register a before callback.
68
+ * Return true to allow, false to deny, undefined to continue.
69
+ */
70
+ before(callback) {
71
+ this.beforeCallbacks.push(callback);
72
+ return this;
73
+ }
74
+ /**
75
+ * Register an after callback.
76
+ */
77
+ after(callback) {
78
+ this.afterCallbacks.push(callback);
79
+ return this;
80
+ }
81
+ /**
82
+ * Set the current user for authorization checks.
83
+ */
84
+ forUser(user) {
85
+ const clone = Object.assign(
86
+ Object.create(Object.getPrototypeOf(this)),
87
+ this
88
+ );
89
+ clone.currentUser = user;
90
+ return clone;
91
+ }
92
+ /**
93
+ * Resolve the user from context.
94
+ */
95
+ async resolveUser(ctx) {
96
+ if (this.currentUser !== null) {
97
+ return this.currentUser;
98
+ }
99
+ if (this.userResolver) {
100
+ return this.userResolver(ctx);
101
+ }
102
+ const user = ctx.get("user");
103
+ return user ?? null;
104
+ }
105
+ /**
106
+ * Check if the user has the given ability.
107
+ */
108
+ async allows(ability, ...args) {
109
+ return this.check(ability, this.currentUser, ...args);
110
+ }
111
+ /**
112
+ * Check if the user doesn't have the given ability.
113
+ */
114
+ async denies(ability, ...args) {
115
+ return !await this.allows(ability, ...args);
116
+ }
117
+ /**
118
+ * Check if the user has any of the given abilities.
119
+ */
120
+ async any(abilities, ...args) {
121
+ for (const ability of abilities) {
122
+ if (await this.allows(ability, ...args)) {
123
+ return true;
124
+ }
125
+ }
126
+ return false;
127
+ }
128
+ /**
129
+ * Check if the user has all of the given abilities.
130
+ */
131
+ async all(abilities, ...args) {
132
+ for (const ability of abilities) {
133
+ if (!await this.allows(ability, ...args)) {
134
+ return false;
135
+ }
136
+ }
137
+ return true;
138
+ }
139
+ /**
140
+ * Check if the user has none of the given abilities.
141
+ */
142
+ async none(abilities, ...args) {
143
+ return !await this.any(abilities, ...args);
144
+ }
145
+ /**
146
+ * Authorize the ability or throw an exception.
147
+ */
148
+ async authorize(ability, ...args) {
149
+ const allowed = await this.allows(ability, ...args);
150
+ if (!allowed) {
151
+ throw new AuthorizationException(`This action is unauthorized.`);
152
+ }
153
+ }
154
+ /**
155
+ * Get the authorization response.
156
+ */
157
+ async inspect(ability, ...args) {
158
+ const allowed = await this.check(ability, this.currentUser, ...args);
159
+ return allowed ? Response.allow() : Response.deny();
160
+ }
161
+ /**
162
+ * Check the ability with a specific user.
163
+ */
164
+ async check(ability, user, ...args) {
165
+ for (const beforeCallback of this.beforeCallbacks) {
166
+ const result = await beforeCallback(user, ability, ...args);
167
+ if (typeof result === "boolean") {
168
+ await this.runAfterCallbacks(user, ability, result, args);
169
+ return result;
170
+ }
171
+ }
172
+ const model = args[0];
173
+ if (model !== void 0 && model !== null) {
174
+ const policyResult = await this.checkPolicy(ability, user, model, args.slice(1));
175
+ if (policyResult !== void 0) {
176
+ await this.runAfterCallbacks(user, ability, policyResult, args);
177
+ return policyResult;
178
+ }
179
+ }
180
+ const gate = this.gates.get(ability);
181
+ if (gate) {
182
+ const result = await gate.callback(user, ...args);
183
+ await this.runAfterCallbacks(user, ability, result, args);
184
+ return result;
185
+ }
186
+ await this.runAfterCallbacks(user, ability, false, args);
187
+ return false;
188
+ }
189
+ /**
190
+ * Check a policy for the given ability.
191
+ *
192
+ * The subject may be a class instance (policy resolved via its constructor)
193
+ * or a `[ModelClass, record]` / `['key', record]` tuple. The tuple form is
194
+ * required for plain records returned by the ORM, which carry no constructor
195
+ * information.
196
+ */
197
+ async checkPolicy(ability, user, model, additionalArgs) {
198
+ let policyKey;
199
+ let subject = model;
200
+ let hasSubject = true;
201
+ if (Array.isArray(model) && model.length === 2 && (typeof model[0] === "function" || typeof model[0] === "string")) {
202
+ policyKey = model[0];
203
+ subject = model[1];
204
+ } else if (typeof model === "function") {
205
+ policyKey = model;
206
+ hasSubject = false;
207
+ } else {
208
+ policyKey = model?.constructor;
209
+ }
210
+ if (!policyKey) {
211
+ return void 0;
212
+ }
213
+ const policyClass = this.policies.get(policyKey);
214
+ if (!policyClass) {
215
+ return void 0;
216
+ }
217
+ const policy = this.getPolicyInstance(policyClass);
218
+ if (policy.before) {
219
+ const beforeResult = await policy.before(user, ability);
220
+ if (typeof beforeResult === "boolean") {
221
+ return beforeResult;
222
+ }
223
+ }
224
+ const method = policy[ability];
225
+ if (typeof method === "function") {
226
+ return hasSubject ? method.call(policy, user, subject, ...additionalArgs) : method.call(policy, user, ...additionalArgs);
227
+ }
228
+ return void 0;
229
+ }
230
+ /**
231
+ * Get or create a policy instance.
232
+ */
233
+ getPolicyInstance(policyClass) {
234
+ let instance = this.policyInstances.get(policyClass);
235
+ if (!instance) {
236
+ instance = new policyClass();
237
+ this.policyInstances.set(policyClass, instance);
238
+ }
239
+ return instance;
240
+ }
241
+ /**
242
+ * Run after callbacks.
243
+ */
244
+ async runAfterCallbacks(user, ability, result, args) {
245
+ for (const afterCallback of this.afterCallbacks) {
246
+ await afterCallback(user, ability, result, args);
247
+ }
248
+ }
249
+ /**
250
+ * Get all defined abilities.
251
+ */
252
+ abilities() {
253
+ return Array.from(this.gates.keys());
254
+ }
255
+ /**
256
+ * Check if an ability is defined.
257
+ */
258
+ has(ability) {
259
+ return this.gates.has(ability);
260
+ }
261
+ /**
262
+ * Get the policy for a model.
263
+ */
264
+ getPolicyFor(model) {
265
+ const modelConstructor = model?.constructor;
266
+ if (!modelConstructor) {
267
+ return void 0;
268
+ }
269
+ const policyClass = this.policies.get(modelConstructor);
270
+ if (!policyClass) {
271
+ return void 0;
272
+ }
273
+ return this.getPolicyInstance(policyClass);
274
+ }
275
+ };
276
+ var globalGate = null;
277
+ function createGate(options) {
278
+ return new Gate(options);
279
+ }
280
+ function setGate(gate) {
281
+ globalGate = gate;
282
+ }
283
+ function getGate() {
284
+ if (!globalGate) {
285
+ throw new Error("Gate not initialized. Call setGate() first.");
286
+ }
287
+ return globalGate;
288
+ }
289
+ function defineGate(ability, callback) {
290
+ getGate().define(ability, callback);
291
+ }
292
+ async function can(ability, ...args) {
293
+ return getGate().allows(ability, ...args);
294
+ }
295
+ async function cannot(ability, ...args) {
296
+ return getGate().denies(ability, ...args);
297
+ }
298
+ async function authorize(ability, ...args) {
299
+ return getGate().authorize(ability, ...args);
300
+ }
301
+
302
+ // src/authorization/Policy.ts
303
+ var Policy = class {
304
+ /**
305
+ * Allow the action.
306
+ */
307
+ allow(message) {
308
+ return Response.allow(message);
309
+ }
310
+ /**
311
+ * Deny the action.
312
+ */
313
+ deny(message, code) {
314
+ return Response.deny(message, code);
315
+ }
316
+ /**
317
+ * Deny with a specific HTTP status.
318
+ */
319
+ denyWithStatus(status, message) {
320
+ return Response.denyWithStatus(status, message);
321
+ }
322
+ /**
323
+ * Deny as not found (404).
324
+ */
325
+ denyAsNotFound(message) {
326
+ return Response.denyAsNotFound(message);
327
+ }
328
+ };
329
+ function definePolicy(definition) {
330
+ return class extends Policy {
331
+ before = definition.before;
332
+ viewAny(user) {
333
+ return definition.viewAny?.(user) ?? false;
334
+ }
335
+ view(user, model) {
336
+ return definition.view?.(user, model) ?? false;
337
+ }
338
+ create(user) {
339
+ return definition.create?.(user) ?? false;
340
+ }
341
+ update(user, model) {
342
+ return definition.update?.(user, model) ?? false;
343
+ }
344
+ delete(user, model) {
345
+ return definition.delete?.(user, model) ?? false;
346
+ }
347
+ restore(user, model) {
348
+ return definition.restore?.(user, model) ?? false;
349
+ }
350
+ forceDelete(user, model) {
351
+ return definition.forceDelete?.(user, model) ?? false;
352
+ }
353
+ };
354
+ }
355
+
356
+ // src/authorization/middleware.ts
357
+ function authorizeMiddleware(ability, modelResolver, options = {}) {
358
+ return async (ctx, next) => {
359
+ const gate = getGate();
360
+ const user = await gate.resolveUser(ctx);
361
+ const gateForUser = gate.forUser(user);
362
+ const abilities = Array.isArray(ability) ? ability : [ability];
363
+ const model = modelResolver ? await modelResolver(ctx) : void 0;
364
+ let authorized = false;
365
+ if (Array.isArray(ability)) {
366
+ authorized = await gateForUser.any(abilities, model);
367
+ } else {
368
+ authorized = await gateForUser.allows(ability, model);
369
+ }
370
+ if (!authorized) {
371
+ throw new AuthorizationException(
372
+ options.message ?? "This action is unauthorized."
373
+ );
374
+ }
375
+ await next();
376
+ };
377
+ }
378
+ function authorizeAllMiddleware(abilities, modelResolver, options = {}) {
379
+ return async (ctx, next) => {
380
+ const gate = getGate();
381
+ const user = await gate.resolveUser(ctx);
382
+ const gateForUser = gate.forUser(user);
383
+ const model = modelResolver ? await modelResolver(ctx) : void 0;
384
+ const authorized = await gateForUser.all(abilities, model);
385
+ if (!authorized) {
386
+ throw new AuthorizationException(
387
+ options.message ?? "This action is unauthorized."
388
+ );
389
+ }
390
+ await next();
391
+ };
392
+ }
393
+ function authorizeResourceMiddleware(modelResolver, options = {}) {
394
+ return async (ctx, next) => {
395
+ const method = ctx.req.method.toUpperCase();
396
+ let ability;
397
+ switch (method) {
398
+ case "GET":
399
+ case "HEAD":
400
+ ability = "view";
401
+ break;
402
+ case "POST":
403
+ ability = "create";
404
+ break;
405
+ case "PUT":
406
+ case "PATCH":
407
+ ability = "update";
408
+ break;
409
+ case "DELETE":
410
+ ability = "delete";
411
+ break;
412
+ default:
413
+ ability = "view";
414
+ }
415
+ const gate = getGate();
416
+ const user = await gate.resolveUser(ctx);
417
+ const gateForUser = gate.forUser(user);
418
+ const model = await modelResolver(ctx);
419
+ const authorized = await gateForUser.allows(ability, model);
420
+ if (!authorized) {
421
+ throw new AuthorizationException(
422
+ options.message ?? "This action is unauthorized."
423
+ );
424
+ }
425
+ await next();
426
+ };
427
+ }
428
+ function withAuthorization(gate) {
429
+ return async (ctx, next) => {
430
+ const user = await gate.resolveUser(ctx);
431
+ const gateForUser = gate.forUser(user);
432
+ ctx.set("gate", gateForUser);
433
+ ctx.set("can", async (ability, ...args) => {
434
+ return gateForUser.allows(ability, ...args);
435
+ });
436
+ ctx.set("cannot", async (ability, ...args) => {
437
+ return gateForUser.denies(ability, ...args);
438
+ });
439
+ ctx.set("authorize", async (ability, ...args) => {
440
+ return gateForUser.authorize(ability, ...args);
441
+ });
442
+ await next();
443
+ };
444
+ }
445
+
446
+ export {
447
+ Response,
448
+ Gate,
449
+ createGate,
450
+ setGate,
451
+ getGate,
452
+ defineGate,
453
+ can,
454
+ cannot,
455
+ authorize,
456
+ Policy,
457
+ definePolicy,
458
+ authorizeMiddleware,
459
+ authorizeAllMiddleware,
460
+ authorizeResourceMiddleware,
461
+ withAuthorization
462
+ };
@@ -0,0 +1,232 @@
1
+ import { Context, MiddlewareHandler } from 'hono';
2
+ import Redis, { RedisOptions } from 'ioredis';
3
+
4
+ /**
5
+ * Rate limit entry stored in the backing store.
6
+ */
7
+ interface RateLimitEntry {
8
+ count: number;
9
+ resetAt: number;
10
+ }
11
+ /**
12
+ * Store interface for rate limit data.
13
+ * Implement this for Redis or database-backed storage.
14
+ */
15
+ interface RateLimitStore {
16
+ /**
17
+ * Get the current rate limit entry for a key.
18
+ */
19
+ get(key: string): Promise<RateLimitEntry | null>;
20
+ /**
21
+ * Increment the count for a key and return the new entry.
22
+ * If the key doesn't exist, create it with count=1.
23
+ */
24
+ increment(key: string, windowMs: number): Promise<RateLimitEntry>;
25
+ /**
26
+ * Reset the count for a key.
27
+ */
28
+ reset(key: string): Promise<void>;
29
+ }
30
+ /**
31
+ * Base class for in-memory rate limit stores with automatic cleanup.
32
+ */
33
+ declare abstract class BaseMemoryStore implements RateLimitStore {
34
+ protected cleanupInterval?: ReturnType<typeof setInterval>;
35
+ constructor(cleanupIntervalMs?: number);
36
+ abstract get(key: string): Promise<RateLimitEntry | null>;
37
+ abstract increment(key: string, windowMs: number): Promise<RateLimitEntry>;
38
+ abstract reset(key: string): Promise<void>;
39
+ abstract cleanup(): void;
40
+ abstract clear(): void;
41
+ abstract get size(): number;
42
+ destroy(): void;
43
+ }
44
+ /**
45
+ * In-memory rate limit store.
46
+ * Suitable for single-process development, not for production clusters.
47
+ */
48
+ declare class MemoryRateLimitStore extends BaseMemoryStore {
49
+ private entries;
50
+ get(key: string): Promise<RateLimitEntry | null>;
51
+ increment(key: string, windowMs: number): Promise<RateLimitEntry>;
52
+ reset(key: string): Promise<void>;
53
+ cleanup(): void;
54
+ clear(): void;
55
+ get size(): number;
56
+ }
57
+ /**
58
+ * Configuration options for rate limiting.
59
+ */
60
+ interface RateLimitOptions {
61
+ /**
62
+ * Maximum number of requests allowed in the time window.
63
+ * @default 100
64
+ */
65
+ limit?: number;
66
+ /**
67
+ * Time window in milliseconds.
68
+ * @default 60000 (1 minute)
69
+ */
70
+ windowMs?: number;
71
+ /**
72
+ * Function to extract the rate limit key from the request.
73
+ * Defaults to using the client IP address.
74
+ */
75
+ keyGenerator?: (ctx: Context) => string | Promise<string>;
76
+ /**
77
+ * Rate limit store implementation.
78
+ * Defaults to in-memory store.
79
+ */
80
+ store?: RateLimitStore;
81
+ /**
82
+ * Whether to skip rate limiting for certain requests.
83
+ */
84
+ skip?: (ctx: Context) => boolean | Promise<boolean>;
85
+ /**
86
+ * Custom handler when rate limit is exceeded.
87
+ */
88
+ onRateLimited?: (ctx: Context, retryAfter: number) => Response | Promise<Response>;
89
+ /**
90
+ * Whether to add rate limit headers to all responses.
91
+ * @default true
92
+ */
93
+ headers?: boolean;
94
+ /**
95
+ * Custom message when rate limit is exceeded.
96
+ * @default 'Too many requests, please try again later.'
97
+ */
98
+ message?: string;
99
+ /**
100
+ * HTTP status code when rate limit is exceeded.
101
+ * @default 429
102
+ */
103
+ statusCode?: number;
104
+ /**
105
+ * Prefix for rate limit keys.
106
+ * @default 'rl:'
107
+ */
108
+ keyPrefix?: string;
109
+ /**
110
+ * Trust reverse-proxy headers for client IP resolution, checked in order:
111
+ * `CF-Connecting-IP`, `True-Client-IP`, `X-Real-IP`, then the first entry
112
+ * of `X-Forwarded-For`. Falls back to `server.requestIP()` when none are set.
113
+ *
114
+ * Enable ONLY when every request passes through a proxy that sets or strips
115
+ * these headers — on direct deployments clients can spoof them to bypass
116
+ * per-client limits. Ignored when a custom `keyGenerator` is supplied.
117
+ * @default false
118
+ */
119
+ trustProxy?: boolean;
120
+ }
121
+ /**
122
+ * Create a rate limiting middleware.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * // Basic usage - 100 requests per minute per IP
127
+ * app.use('*', createRateLimitMiddleware())
128
+ *
129
+ * // Stricter limit for login endpoint
130
+ * router.post('/login', [AuthController, 'login'],
131
+ * createRateLimitMiddleware({
132
+ * limit: 5,
133
+ * windowMs: 15 * 60 * 1000, // 15 minutes
134
+ * })
135
+ * )
136
+ *
137
+ * // Custom key based on authenticated user
138
+ * app.use('/api/*', createRateLimitMiddleware({
139
+ * limit: 1000,
140
+ * windowMs: 60 * 60 * 1000, // 1 hour
141
+ * keyGenerator: async (ctx) => {
142
+ * const user = await ctx.get('user')
143
+ * return user?.id?.toString() ?? defaultKeyGenerator(ctx)
144
+ * },
145
+ * }))
146
+ * ```
147
+ */
148
+ declare function createRateLimitMiddleware(options?: RateLimitOptions): MiddlewareHandler;
149
+ /**
150
+ * Rate limit result information.
151
+ */
152
+ interface RateLimitInfo {
153
+ limit: number;
154
+ remaining: number;
155
+ resetAt: Date;
156
+ isLimited: boolean;
157
+ }
158
+ /**
159
+ * Get rate limit information for a key without incrementing.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * const info = await getRateLimitInfo('user:123', store, { limit: 100 })
164
+ * console.log(`${info.remaining} requests remaining`)
165
+ * ```
166
+ */
167
+ declare function getRateLimitInfo(key: string, store: RateLimitStore, options?: {
168
+ limit: number;
169
+ keyPrefix?: string;
170
+ }): Promise<RateLimitInfo>;
171
+ /**
172
+ * Reset rate limit for a specific key.
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * // Reset rate limit after successful captcha
177
+ * await resetRateLimit(clientIp, store)
178
+ * ```
179
+ */
180
+ declare function resetRateLimit(key: string, store: RateLimitStore, options?: {
181
+ keyPrefix?: string;
182
+ }): Promise<void>;
183
+ /**
184
+ * Sliding window rate limit store.
185
+ * More accurate than fixed window but uses more memory.
186
+ */
187
+ declare class SlidingWindowRateLimitStore extends BaseMemoryStore {
188
+ private requests;
189
+ get(key: string): Promise<RateLimitEntry | null>;
190
+ increment(key: string, windowMs: number): Promise<RateLimitEntry>;
191
+ reset(key: string): Promise<void>;
192
+ cleanup(): void;
193
+ clear(): void;
194
+ get size(): number;
195
+ }
196
+
197
+ /**
198
+ * Options for creating a Redis client.
199
+ */
200
+ interface RedisClientOptions extends RedisOptions {
201
+ /**
202
+ * Redis connection URL (e.g., 'redis://localhost:6379').
203
+ * If provided, overrides host/port/password.
204
+ */
205
+ url?: string;
206
+ /**
207
+ * Key prefix for all operations.
208
+ * @default ''
209
+ */
210
+ keyPrefix?: string;
211
+ }
212
+ /**
213
+ * Create a Redis client with the given options.
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * // Using URL
218
+ * const redis = createRedisClient({ url: 'redis://localhost:6379' })
219
+ *
220
+ * // Using host/port
221
+ * const redis = createRedisClient({ host: 'localhost', port: 6379 })
222
+ *
223
+ * // With key prefix
224
+ * const redis = createRedisClient({
225
+ * url: process.env.REDIS_URL,
226
+ * keyPrefix: 'myapp:',
227
+ * })
228
+ * ```
229
+ */
230
+ declare function createRedisClient(options?: RedisClientOptions): Redis;
231
+
232
+ export { MemoryRateLimitStore as M, type RateLimitStore as R, SlidingWindowRateLimitStore as S, type RateLimitEntry as a, type RedisClientOptions as b, createRedisClient as c, type RateLimitInfo as d, type RateLimitOptions as e, createRateLimitMiddleware as f, getRateLimitInfo as g, resetRateLimit as r };