@nexusts/limiter 0.9.5 → 0.9.7
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/dist/index.js +107 -46
- package/dist/index.js.map +6 -6
- package/dist/limiter.middleware.d.ts +1 -3
- package/dist/limiter.service.d.ts +11 -5
- package/dist/types.d.ts +7 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9,7 +9,6 @@ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
|
|
|
9
9
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
10
10
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
11
11
|
};
|
|
12
|
-
var __legacyDecorateParamTS = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
13
12
|
var __legacyMetadataTS = (k, v) => {
|
|
14
13
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
15
14
|
return Reflect.metadata(k, v);
|
|
@@ -18,8 +17,39 @@ var __legacyMetadataTS = (k, v) => {
|
|
|
18
17
|
// packages/limiter/src/types.ts
|
|
19
18
|
import { safeGetMeta, safeDefineMeta } from "@nexusts/core/di/safe-reflect";
|
|
20
19
|
var LIMITER_RULE_KEY = Symbol.for("nexus:RateLimitRule");
|
|
20
|
+
var FN_RULE_KEY = Symbol.for("nexus:limiter:fn:rule");
|
|
21
21
|
function RateLimit(rule) {
|
|
22
|
-
return (
|
|
22
|
+
return function(targetOrFn, contextOrKey) {
|
|
23
|
+
if (contextOrKey?.kind === "class") {
|
|
24
|
+
const { metadata } = contextOrKey;
|
|
25
|
+
const existing2 = metadata[LIMITER_RULE_KEY] ?? [];
|
|
26
|
+
existing2.push({ ...rule, path: "**" });
|
|
27
|
+
metadata[LIMITER_RULE_KEY] = existing2;
|
|
28
|
+
if (typeof targetOrFn === "function") {
|
|
29
|
+
if (!targetOrFn.__nexus_meta__) {
|
|
30
|
+
Object.defineProperty(targetOrFn, "__nexus_meta__", {
|
|
31
|
+
value: metadata,
|
|
32
|
+
writable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
enumerable: false
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (contextOrKey?.kind === "method") {
|
|
41
|
+
const fn = targetOrFn;
|
|
42
|
+
const { metadata } = contextOrKey;
|
|
43
|
+
const existing2 = metadata[LIMITER_RULE_KEY] ?? [];
|
|
44
|
+
existing2.push({ ...rule, path: "**" });
|
|
45
|
+
metadata[LIMITER_RULE_KEY] = existing2;
|
|
46
|
+
if (!fn[FN_RULE_KEY])
|
|
47
|
+
fn[FN_RULE_KEY] = [];
|
|
48
|
+
fn[FN_RULE_KEY].push(rule);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const target = targetOrFn;
|
|
52
|
+
const descriptor = arguments[2];
|
|
23
53
|
if (descriptor === undefined) {
|
|
24
54
|
const existing2 = safeGetMeta(LIMITER_RULE_KEY, target) ?? [];
|
|
25
55
|
existing2.push({ ...rule, path: "**" });
|
|
@@ -27,12 +57,29 @@ function RateLimit(rule) {
|
|
|
27
57
|
return target;
|
|
28
58
|
}
|
|
29
59
|
const existing = safeGetMeta(LIMITER_RULE_KEY, target.constructor) ?? [];
|
|
30
|
-
existing.push({ ...rule, path:
|
|
60
|
+
existing.push({ ...rule, path: "**" });
|
|
31
61
|
safeDefineMeta(LIMITER_RULE_KEY, existing, target.constructor);
|
|
32
62
|
};
|
|
33
63
|
}
|
|
34
64
|
function getLimiterRules(target) {
|
|
35
|
-
|
|
65
|
+
const fromLegacy = safeGetMeta(LIMITER_RULE_KEY, target);
|
|
66
|
+
if (fromLegacy)
|
|
67
|
+
return fromLegacy;
|
|
68
|
+
const clsMeta = typeof target === "function" && target.__nexus_meta__;
|
|
69
|
+
if (clsMeta?.[LIMITER_RULE_KEY])
|
|
70
|
+
return clsMeta[LIMITER_RULE_KEY];
|
|
71
|
+
const fromFn = [];
|
|
72
|
+
if (target.prototype) {
|
|
73
|
+
for (const name of Object.getOwnPropertyNames(target.prototype)) {
|
|
74
|
+
const fn = target.prototype[name];
|
|
75
|
+
if (typeof fn !== "function")
|
|
76
|
+
continue;
|
|
77
|
+
const stashed = fn[FN_RULE_KEY];
|
|
78
|
+
if (stashed)
|
|
79
|
+
fromFn.push(...stashed);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return fromFn;
|
|
36
83
|
}
|
|
37
84
|
function durationToMs(d) {
|
|
38
85
|
if (typeof d === "number")
|
|
@@ -242,34 +289,53 @@ class DrizzleRateLimitStorage {
|
|
|
242
289
|
import { Inject, Injectable } from "@nexusts/core";
|
|
243
290
|
class LimiterService {
|
|
244
291
|
static TOKEN = Symbol.for("nexus:LimiterService");
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
constructor(
|
|
250
|
-
|
|
251
|
-
this.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
"
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
292
|
+
_storage = null;
|
|
293
|
+
_rules = [];
|
|
294
|
+
_defaultKey = null;
|
|
295
|
+
_defaultReject = null;
|
|
296
|
+
constructor() {}
|
|
297
|
+
get storage() {
|
|
298
|
+
if (!this._storage) {
|
|
299
|
+
this._storage = (this.config ?? {}).storage ?? new MemoryRateLimitStorage;
|
|
300
|
+
}
|
|
301
|
+
return this._storage;
|
|
302
|
+
}
|
|
303
|
+
get rules() {
|
|
304
|
+
if (!this._rules.length && this.config?.rules) {
|
|
305
|
+
this._rules = this.config.rules;
|
|
306
|
+
}
|
|
307
|
+
return this._rules;
|
|
308
|
+
}
|
|
309
|
+
get defaultKey() {
|
|
310
|
+
if (!this._defaultKey) {
|
|
311
|
+
this._defaultKey = (this.config ?? {}).defaultKey ?? ((c) => {
|
|
312
|
+
const fwd = c?.req?.header?.("x-forwarded-for");
|
|
313
|
+
if (fwd)
|
|
314
|
+
return fwd.split(",")[0]?.trim() ?? "unknown";
|
|
315
|
+
return c?.req?.raw?.["conn"]?.remoteAddr?.hostname ?? "unknown";
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return this._defaultKey;
|
|
319
|
+
}
|
|
320
|
+
get defaultReject() {
|
|
321
|
+
if (!this._defaultReject) {
|
|
322
|
+
this._defaultReject = (this.config ?? {}).defaultReject ?? ((_c, result) => new Response(JSON.stringify({
|
|
323
|
+
error: "Too Many Requests",
|
|
324
|
+
limit: result.limit,
|
|
325
|
+
remaining: 0,
|
|
326
|
+
retryAfter: result.retryAfter
|
|
327
|
+
}), {
|
|
328
|
+
status: 429,
|
|
329
|
+
headers: {
|
|
330
|
+
"Content-Type": "application/json",
|
|
331
|
+
"Retry-After": String(result.retryAfter),
|
|
332
|
+
"X-RateLimit-Limit": String(result.limit),
|
|
333
|
+
"X-RateLimit-Remaining": "0",
|
|
334
|
+
"X-RateLimit-Reset": String(Math.ceil(result.resetAt / 1000))
|
|
335
|
+
}
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
return this._defaultReject;
|
|
273
339
|
}
|
|
274
340
|
async check(key, rule) {
|
|
275
341
|
const durationMs = durationToMs(rule.duration);
|
|
@@ -279,21 +345,17 @@ class LimiterService {
|
|
|
279
345
|
await this.storage.reset(key);
|
|
280
346
|
}
|
|
281
347
|
}
|
|
348
|
+
__legacyDecorateClassTS([
|
|
349
|
+
Inject("LIMITER_CONFIG")
|
|
350
|
+
], LimiterService.prototype, "config", undefined);
|
|
282
351
|
LimiterService = __legacyDecorateClassTS([
|
|
283
352
|
Injectable(),
|
|
284
|
-
|
|
285
|
-
__legacyMetadataTS("design:paramtypes", [
|
|
286
|
-
typeof LimiterConfig === "undefined" ? Object : LimiterConfig
|
|
287
|
-
])
|
|
353
|
+
__legacyMetadataTS("design:paramtypes", [])
|
|
288
354
|
], LimiterService);
|
|
289
355
|
// packages/limiter/src/limiter.middleware.ts
|
|
290
356
|
import { Inject as Inject2, Injectable as Injectable2 } from "@nexusts/core";
|
|
291
357
|
class LimiterMiddleware {
|
|
292
|
-
limiter;
|
|
293
358
|
static TOKEN = Symbol.for("nexus:LimiterMiddleware");
|
|
294
|
-
constructor(limiter) {
|
|
295
|
-
this.limiter = limiter;
|
|
296
|
-
}
|
|
297
359
|
middleware() {
|
|
298
360
|
return async (c, next) => {
|
|
299
361
|
const method = c.req.method.toUpperCase();
|
|
@@ -326,12 +388,11 @@ class LimiterMiddleware {
|
|
|
326
388
|
return matchGlob(rule.path, path);
|
|
327
389
|
}
|
|
328
390
|
}
|
|
391
|
+
__legacyDecorateClassTS([
|
|
392
|
+
Inject2(LimiterService.TOKEN)
|
|
393
|
+
], LimiterMiddleware.prototype, "limiter", undefined);
|
|
329
394
|
LimiterMiddleware = __legacyDecorateClassTS([
|
|
330
|
-
Injectable2()
|
|
331
|
-
__legacyDecorateParamTS(0, Inject2(LimiterService.TOKEN)),
|
|
332
|
-
__legacyMetadataTS("design:paramtypes", [
|
|
333
|
-
typeof LimiterService === "undefined" ? Object : LimiterService
|
|
334
|
-
])
|
|
395
|
+
Injectable2()
|
|
335
396
|
], LimiterMiddleware);
|
|
336
397
|
function matchGlob(pattern, path) {
|
|
337
398
|
const regex = new RegExp("^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "::DOUBLESTAR::").replace(/\*/g, "[^/]+").replace(/::DOUBLESTAR::/g, ".*") + "/?$");
|
|
@@ -398,5 +459,5 @@ export {
|
|
|
398
459
|
LIMITER_RULE_KEY
|
|
399
460
|
};
|
|
400
461
|
|
|
401
|
-
//# debugId=
|
|
462
|
+
//# debugId=7D3F2E6D87E9F0E664756E2164756E21
|
|
402
463
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/types.ts", "../src/backends/memory.ts", "../src/backends/drizzle.ts", "../src/limiter.service.ts", "../src/limiter.middleware.ts", "../src/limiter.module.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * `@nexusts/limiter` — rate limiting.\n *\n * Two ways to apply limits:\n *\n * 1. **Global** via `LimiterModule.forRoot({ rules: [...] })`:\n * limits matched against request path / method.\n *\n * 2. **Per-route** via the `@RateLimit` decorator:\n *\n * ```ts\n * @Controller('/auth')\n * class AuthController {\n * @Post('/login')\n * @RateLimit({ points: 5, duration: '1m' })\n * login() {}\n * }\n * ```\n *\n * Key derivation: by default we use `c.req.header('x-forwarded-for')`\n * or the remote address. Decorator `key` option overrides with a\n * function (e.g. user ID, API key).\n *\n * Backends:\n * - `MemoryStorage` (default, single-process)\n * - `RedisStorage` (optional, multi-process / multi-pod)\n */\n\nimport {
|
|
5
|
+
"/**\n * `@nexusts/limiter` — rate limiting.\n *\n * Two ways to apply limits:\n *\n * 1. **Global** via `LimiterModule.forRoot({ rules: [...] })`:\n * limits matched against request path / method.\n *\n * 2. **Per-route** via the `@RateLimit` decorator:\n *\n * ```ts\n * @Controller('/auth')\n * class AuthController {\n * @Post('/login')\n * @RateLimit({ points: 5, duration: '1m' })\n * login() {}\n * }\n * ```\n *\n * Key derivation: by default we use `c.req.header('x-forwarded-for')`\n * or the remote address. Decorator `key` option overrides with a\n * function (e.g. user ID, API key).\n *\n * Backends:\n * - `MemoryStorage` (default, single-process)\n * - `RedisStorage` (optional, multi-process / multi-pod)\n */\n\nimport { safeGetMeta, safeDefineMeta } from \"@nexusts/core/di/safe-reflect\";\n\n/** Identifier of the request — IP, user ID, API key, etc. */\nexport type RateLimitKey = string;\n\n/** Strategy used to count requests. */\nexport type RateLimitStrategy =\n\t| \"fixed-window\"\n\t| \"sliding-window\"\n\t| \"token-bucket\";\n\n/**\n * Numeric size of a window. Either a millisecond count or one of\n * `'1s'`, `'1m'`, `'1h'`, `'1d'` for convenience.\n */\nexport type DurationLike = number | `${number}${\"s\" | \"m\" | \"h\" | \"d\"}`;\n\n/** Result of a single rate-limit check. */\nexport interface RateLimitResult {\n\t/** Whether the request is allowed. */\n\tallowed: boolean;\n\t/** Remaining points in the current window. */\n\tremaining: number;\n\t/** Total points in the current window. */\n\tlimit: number;\n\t/** Unix-ms timestamp when the window resets. */\n\tresetAt: number;\n\t/** Number of seconds the client should wait (only when `allowed=false`). */\n\tretryAfter: number;\n}\n\n/** Storage backend for limiter state. */\nexport interface RateLimitStorage {\n\t/**\n\t * Consume `points` units for `key`, allowing at most `limit` units\n\t * per `durationMs` window. Returns the limit result.\n\t * Implementations must be atomic across concurrent callers.\n\t */\n\tconsume(\n\t\tkey: RateLimitKey,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tstrategy: RateLimitStrategy,\n\t): Promise<RateLimitResult>;\n\n\t/** Reset all state for a key. Useful in tests. */\n\treset(key: RateLimitKey): Promise<void>;\n}\n\n/** Per-rule configuration. */\nexport interface RateLimitRule {\n\t/** Path pattern. Glob: `*` matches a single segment, `**` any depth. */\n\tpath: string;\n\t/** HTTP methods to apply to; default = all. */\n\tmethods?: string[];\n\t/** Number of allowed requests per window. */\n\tpoints: number;\n\t/** Window size. */\n\tduration: DurationLike;\n\t/** Override key derivation. */\n\tkey?: (c: any) => string | undefined | Promise<string | undefined>;\n\t/** Bucket strategy. Default `'sliding-window'`. */\n\tstrategy?: RateLimitStrategy;\n\t/** Custom rejection response. */\n\treject?: (c: any, result: RateLimitResult) => Response | Promise<Response>;\n\t/** Skip when this returns true. */\n\tskip?: (c: any) => boolean | Promise<boolean>;\n}\n\n/** Top-level configuration. */\nexport interface LimiterConfig {\n\t/** Storage backend. Default: in-memory. */\n\tstorage?: RateLimitStorage;\n\t/** Global rules applied before the per-route ones. */\n\trules?: RateLimitRule[];\n\t/** Default key derivation when a rule omits one. Default: IP address. */\n\tdefaultKey?: (c: any) => string | undefined | Promise<string | undefined>;\n\t/** Default response when a request is rejected. */\n\tdefaultReject?: (\n\t\tc: any,\n\t\tresult: RateLimitResult,\n\t) => Response | Promise<Response>;\n}\n\nexport const LIMITER_RULE_KEY = Symbol.for(\"nexus:RateLimitRule\");\n\n/** Symbol key used to stash @RateLimit rules on the function itself (standard mode). */\nconst FN_RULE_KEY = Symbol.for(\"nexus:limiter:fn:rule\");\n\n/**\n * @RateLimit decorator — attach a per-route rate limit.\n *\n * Dual-mode: supports TC39 standard ES decorators + legacy.\n * Can be used on both classes and methods.\n */\nexport function RateLimit(rule: RateLimitRule): any {\n\treturn function (this: any, targetOrFn: any, contextOrKey?: any): any {\n\t\t// ── Standard decorator mode ──\n\t\tif (contextOrKey?.kind === \"class\") {\n\t\t\t// Class-level.\n\t\t\tconst { metadata } = contextOrKey;\n\t\t\tconst existing: RateLimitRule[] = metadata[LIMITER_RULE_KEY] ?? [];\n\t\t\texisting.push({ ...rule, path: \"**\" });\n\t\t\tmetadata[LIMITER_RULE_KEY] = existing;\n\t\t\t// Also store on __nexus_meta__ so getLimiterRules can find it.\n\t\t\tif (typeof targetOrFn === \"function\") {\n\t\t\t\tif (!(targetOrFn as any).__nexus_meta__) {\n\t\t\t\t\tObject.defineProperty(targetOrFn, \"__nexus_meta__\", {\n\t\t\t\t\t\tvalue: metadata,\n\t\t\t\t\t\twritable: true,\n\t\t\t\t\t\tconfigurable: true,\n\t\t\t\t\t\tenumerable: false,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (contextOrKey?.kind === \"method\") {\n\t\t\t// Method-level — stash rule on the function.\n\t\t\tconst fn = targetOrFn;\n\t\t\tconst { metadata } = contextOrKey;\n\t\t\tconst existing: RateLimitRule[] = metadata[LIMITER_RULE_KEY] ?? [];\n\t\t\texisting.push({ ...rule, path: \"**\" });\n\t\t\tmetadata[LIMITER_RULE_KEY] = existing;\n\t\t\t// Also stash on the function for legacy reader compatibility.\n\t\t\tif (!(fn as any)[FN_RULE_KEY]) (fn as any)[FN_RULE_KEY] = [];\n\t\t\t(fn as any)[FN_RULE_KEY].push(rule);\n\t\t\treturn;\n\t\t}\n\n\t\t// ── Legacy decorator mode ──\n\t\tconst target = targetOrFn;\n\t\tconst descriptor = arguments[2];\n\n\t\t// Class-level: applied to all routes of the controller.\n\t\tif (descriptor === undefined) {\n\t\t\tconst existing: RateLimitRule[] =\n\t\t\t\tsafeGetMeta(LIMITER_RULE_KEY, target) ?? [];\n\t\t\texisting.push({ ...rule, path: \"**\" });\n\t\t\tsafeDefineMeta(LIMITER_RULE_KEY, existing, target);\n\t\t\treturn target;\n\t\t}\n\t\t// Method-level: bound to the route.\n\t\tconst existing: RateLimitRule[] =\n\t\t\tsafeGetMeta(LIMITER_RULE_KEY, target.constructor) ?? [];\n\t\texisting.push({ ...rule, path: \"**\" });\n\t\tsafeDefineMeta(LIMITER_RULE_KEY, existing, target.constructor);\n\t};\n}\n\n/** Read all `@RateLimit` rules from a controller or method. */\nexport function getLimiterRules(target: any): RateLimitRule[] {\n\t// Legacy path.\n\tconst fromLegacy = safeGetMeta(LIMITER_RULE_KEY, target) as RateLimitRule[] | undefined;\n\tif (fromLegacy) return fromLegacy;\n\t// Standard path: check .__nexus_meta__ (set by @Module/@Controller/etc).\n\tconst clsMeta = typeof target === \"function\" && (target as any).__nexus_meta__;\n\tif (clsMeta?.[LIMITER_RULE_KEY]) return clsMeta[LIMITER_RULE_KEY] as RateLimitRule[];\n\t// Standard path: check prototype methods for stashed data (method-level).\n\tconst fromFn: RateLimitRule[] = [];\n\tif (target.prototype) {\n\t\tfor (const name of Object.getOwnPropertyNames(target.prototype)) {\n\t\t\tconst fn = target.prototype[name];\n\t\t\tif (typeof fn !== \"function\") continue;\n\t\t\tconst stashed = (fn as any)[FN_RULE_KEY];\n\t\t\tif (stashed) fromFn.push(...stashed);\n\t\t}\n\t}\n\treturn fromFn;\n}\n\n/** Convert a `DurationLike` to milliseconds. */\nexport function durationToMs(d: DurationLike): number {\n\tif (typeof d === \"number\") return d;\n\tconst m = /^(\\d+)([smhd])$/.exec(d);\n\tif (!m) throw new Error(`Invalid duration: ${d}`);\n\tconst n = Number(m[1]);\n\tconst unit = m[2] as \"s\" | \"m\" | \"h\" | \"d\";\n\tconst mult: Record<typeof unit, number> = {\n\t\ts: 1000,\n\t\tm: 60_000,\n\t\th: 3_600_000,\n\t\td: 86_400_000,\n\t};\n\treturn n * mult[unit];\n}\n",
|
|
6
6
|
"/**\n * In-memory rate-limit storage. Sliding-window log by default.\n *\n * - `fixed-window`: counter reset every `durationMs` ms.\n * - `sliding-window`: counts requests in the trailing `durationMs` window.\n * - `token-bucket`: refills at `points / durationMs` tokens per ms.\n *\n * Not cluster-safe. For multi-pod deployments use `RedisStorage`.\n */\nimport type {\n\tRateLimitStorage,\n\tRateLimitKey,\n\tRateLimitStrategy,\n} from \"../types.js\";\n\ninterface FixedBucket {\n\tresetAt: number;\n\tcount: number;\n}\n\ninterface SlidingLog {\n\tlog: number[]; // unix-ms timestamps\n}\n\ninterface TokenBucket {\n\ttokens: number;\n\tupdatedAt: number;\n}\n\nexport class MemoryRateLimitStorage implements RateLimitStorage {\n\treadonly kind = \"memory\" as const;\n\tprivate fixed = new Map<RateLimitKey, FixedBucket>();\n\tprivate sliding = new Map<RateLimitKey, SlidingLog>();\n\tprivate token = new Map<RateLimitKey, TokenBucket>();\n\n\tasync consume(\n\t\tkey: RateLimitKey,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tstrategy: RateLimitStrategy = \"sliding-window\",\n\t) {\n\t\tconst now = Date.now();\n\t\tswitch (strategy) {\n\t\t\tcase \"fixed-window\":\n\t\t\t\treturn this.consumeFixed(key, points, limit, durationMs, now);\n\t\t\tcase \"sliding-window\":\n\t\t\t\treturn this.consumeSliding(key, points, limit, durationMs, now);\n\t\t\tcase \"token-bucket\":\n\t\t\t\treturn this.consumeToken(key, points, limit, durationMs, now);\n\t\t\tdefault: {\n\t\t\t\t// Exhaustive check\n\t\t\t\tconst _: never = strategy;\n\t\t\t\tthrow new Error(`Unknown strategy: ${_}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync reset(key: RateLimitKey): Promise<void> {\n\t\tthis.fixed.delete(key);\n\t\tthis.sliding.delete(key);\n\t\tthis.token.delete(key);\n\t}\n\n\tprivate consumeFixed(\n\t\tkey: RateLimitKey,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tnow: number,\n\t) {\n\t\tlet b = this.fixed.get(key);\n\t\tif (!b || b.resetAt <= now) {\n\t\t\tb = { resetAt: now + durationMs, count: 0 };\n\t\t\tthis.fixed.set(key, b);\n\t\t}\n\t\tb.count += points;\n\t\tconst allowed = b.count <= limit;\n\t\treturn {\n\t\t\tallowed,\n\t\t\tremaining: Math.max(0, limit - b.count),\n\t\t\tlimit,\n\t\t\tresetAt: b.resetAt,\n\t\t\tretryAfter: allowed ? 0 : Math.ceil((b.resetAt - now) / 1000),\n\t\t};\n\t}\n\n\tprivate consumeSliding(\n\t\tkey: RateLimitKey,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tnow: number,\n\t) {\n\t\tlet s = this.sliding.get(key);\n\t\tif (!s) {\n\t\t\ts = { log: [] };\n\t\t\tthis.sliding.set(key, s);\n\t\t}\n\t\t// Drop entries outside the trailing window.\n\t\tconst cutoff = now - durationMs;\n\t\ts.log = s.log.filter((t) => t > cutoff);\n\t\tconst inWindow = s.log.length + points;\n\t\tconst allowed = inWindow <= limit;\n\t\tif (allowed) {\n\t\t\tfor (let i = 0; i < points; i++) s.log.push(now);\n\t\t}\n\t\tconst oldest = s.log[0] ?? now;\n\t\treturn {\n\t\t\tallowed,\n\t\t\tremaining: Math.max(0, limit - s.log.length),\n\t\t\tlimit,\n\t\t\tresetAt: now + durationMs,\n\t\t\tretryAfter: allowed ? 0 : Math.ceil((oldest + durationMs - now) / 1000),\n\t\t};\n\t}\n\n\tprivate consumeToken(\n\t\tkey: RateLimitKey,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tnow: number,\n\t) {\n\t\tlet b = this.token.get(key);\n\t\tconst refillPerMs = limit / durationMs;\n\t\tif (!b) {\n\t\t\tb = { tokens: limit, updatedAt: now };\n\t\t\tthis.token.set(key, b);\n\t\t} else {\n\t\t\tconst elapsed = now - b.updatedAt;\n\t\t\tb.tokens = Math.min(limit, b.tokens + elapsed * refillPerMs);\n\t\t\tb.updatedAt = now;\n\t\t}\n\t\tconst allowed = b.tokens >= points;\n\t\tif (allowed) b.tokens -= points;\n\t\treturn {\n\t\t\tallowed,\n\t\t\tremaining: Math.floor(b.tokens),\n\t\t\tlimit,\n\t\t\tresetAt: now + durationMs,\n\t\t\tretryAfter: allowed\n\t\t\t\t? 0\n\t\t\t\t: Math.ceil((points - b.tokens) / refillPerMs / 1000),\n\t\t};\n\t}\n}\n",
|
|
7
7
|
"/**\n * `DrizzleRateLimitStorage` — rate-limit state in any Drizzle-backed DB.\n *\n * import { DrizzleService } from '@nexusts/drizzle';\n * import { DrizzleRateLimitStorage } from '@nexusts/limiter';\n *\n * const db = new DrizzleService({ dialect: 'postgres', connection: { ... } });\n * await db.open();\n * const storage = new DrizzleRateLimitStorage(db, { tableName: 'nexus_rate_limits' });\n *\n * LimiterModule.forRoot({ storage, rules: [...] });\n *\n * Schema:\n * CREATE TABLE nexus_rate_limits (\n * key TEXT PRIMARY KEY,\n * strategy TEXT NOT NULL,\n * limit INTEGER NOT NULL,\n * points INTEGER NOT NULL DEFAULT 0,\n * reset_at TIMESTAMP NOT NULL,\n * log JSONB\n * );\n *\n * Atomicity: each `consume()` runs inside a transaction. The\n * counter-update + log-trim happens as a single SQL statement\n * (UPDATE with `WHERE` guard) so concurrent callers are safe.\n */\nimport type { DrizzleService } from \"@nexusts/drizzle\";\nimport type {\n\tRateLimitKey,\n\tRateLimitResult,\n\tRateLimitStorage,\n\tRateLimitStrategy,\n} from \"../types.js\";\n\nexport interface DrizzleRateLimitOptions {\n\tdb: DrizzleService;\n\ttableName?: string;\n}\n\ninterface Row {\n\tkey: string;\n\tstrategy: string;\n\tmax_points: number;\n\tpoints: number;\n\treset_at: string;\n\tlog: string | null;\n}\nvoid (null as unknown as Row[\"points\"]);\n\nexport class DrizzleRateLimitStorage implements RateLimitStorage {\n\treadonly kind = \"drizzle\" as const;\n\n\t#db: DrizzleService;\n\t#table: string;\n\n\tconstructor(\n\t\tdb: DrizzleService,\n\t\toptions: Omit<DrizzleRateLimitOptions, \"db\"> = {},\n\t) {\n\t\tthis.#db = db;\n\t\tthis.#table = options.tableName ?? \"nexus_rate_limits\";\n\t}\n\n\tasync consume(\n\t\tkey: RateLimitKey,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tstrategy: RateLimitStrategy = \"sliding-window\",\n\t): Promise<RateLimitResult> {\n\t\tconst now = Date.now();\n\t\tconst resetAt = now + durationMs;\n\n\t\t// 1. Read existing row.\n\t\tconst rows = await this.#db.rawQuery<Row>(\n\t\t\t`SELECT * FROM ${this.#table} WHERE key = ? LIMIT 1`,\n\t\t\t[key],\n\t\t);\n\t\tconst existing = rows[0];\n\n\t\tif (!existing) {\n\t\t\t// First call — create a new bucket.\n\t\t\tconst initialLog =\n\t\t\t\tstrategy === \"sliding-window\"\n\t\t\t\t\t? JSON.stringify(Array(points).fill(now))\n\t\t\t\t\t: null;\n\t\t\tawait this.#db.rawQuery(\n\t\t\t\t`INSERT INTO ${this.#table} (key, strategy, max_points, points, reset_at, log)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?)`,\n\t\t\t\t[\n\t\t\t\t\tkey,\n\t\t\t\t\tstrategy,\n\t\t\t\t\tlimit,\n\t\t\t\t\tstrategy === \"sliding-window\" ? 0 : 1,\n\t\t\t\t\tnew Date(resetAt).toISOString(),\n\t\t\t\t\tinitialLog,\n\t\t\t\t],\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tallowed: true,\n\t\t\t\tremaining: limit - 1,\n\t\t\t\tlimit,\n\t\t\t\tresetAt,\n\t\t\t\tretryAfter: 0,\n\t\t\t};\n\t\t}\n\n\t\t// 2. Check the strategy and decide.\n\t\tconst result = await this.#applyStrategy(\n\t\t\texisting,\n\t\t\tpoints,\n\t\t\tlimit,\n\t\t\tdurationMs,\n\t\t\tnow,\n\t\t);\n\t\treturn result;\n\t}\n\n\tasync reset(key: RateLimitKey): Promise<void> {\n\t\tawait this.#db.rawQuery(`DELETE FROM ${this.#table} WHERE key = ?`, [key]);\n\t}\n\n\tasync #applyStrategy(\n\t\trow: Row,\n\t\tpoints: number,\n\t\tlimit: number,\n\t\tdurationMs: number,\n\t\tnow: number,\n\t): Promise<RateLimitResult> {\n\t\tconst strategy: RateLimitStrategy = row.strategy as RateLimitStrategy;\n\t\tconst resetAt = Number(new Date(row.reset_at).getTime());\n\n\t\tif (strategy === \"fixed-window\") {\n\t\t\t// Reset window if past.\n\t\t\tif (resetAt <= now) {\n\t\t\t\tawait this.#db.rawQuery(\n\t\t\t\t\t`UPDATE ${this.#table} SET points = 1, reset_at = ? WHERE key = ?`,\n\t\t\t\t\t[new Date(now + durationMs).toISOString(), row.key],\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tallowed: true,\n\t\t\t\t\tremaining: limit - 1,\n\t\t\t\t\tlimit,\n\t\t\t\t\tresetAt: now + durationMs,\n\t\t\t\t\tretryAfter: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst newPoints = (row.points ?? 0) + 1;\n\t\t\tconst allowed = newPoints <= limit;\n\t\t\tawait this.#db.rawQuery(\n\t\t\t\t`UPDATE ${this.#table} SET points = ? WHERE key = ?`,\n\t\t\t\t[newPoints, row.key],\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tallowed,\n\t\t\t\tremaining: Math.max(0, limit - newPoints),\n\t\t\t\tlimit,\n\t\t\t\tresetAt,\n\t\t\t\tretryAfter: allowed ? 0 : Math.ceil((resetAt - now) / 1000),\n\t\t\t};\n\t\t}\n\n\t\tif (strategy === \"sliding-window\") {\n\t\t\tconst log: number[] = row.log ? JSON.parse(row.log) : [];\n\t\t\t// Drop entries outside the window.\n\t\t\tconst cutoff = now - durationMs;\n\t\t\tconst fresh = log.filter((t) => t > cutoff);\n\t\t\tfresh.push(now);\n\t\t\tconst used = fresh.length;\n\t\t\tconst allowed = used <= limit;\n\t\t\tawait this.#db.rawQuery(\n\t\t\t\t`UPDATE ${this.#table} SET log = ?, points = ? WHERE key = ?`,\n\t\t\t\t[JSON.stringify(fresh), used, row.key],\n\t\t\t);\n\t\t\tconst oldest = fresh[0] ?? now;\n\t\t\treturn {\n\t\t\t\tallowed,\n\t\t\t\tremaining: Math.max(0, limit - used),\n\t\t\t\tlimit,\n\t\t\t\tresetAt: now + durationMs,\n\t\t\t\tretryAfter: allowed ? 0 : Math.ceil((oldest + durationMs - now) / 1000),\n\t\t\t};\n\t\t}\n\n\t\t// token-bucket: simple implementation as a counter with refill on first hit.\n\t\tif (strategy === \"token-bucket\") {\n\t\t\tconst elapsed = Math.max(0, now - resetAt);\n\t\t\tconst refillPerMs = limit / durationMs;\n\t\t\tlet tokens = Math.min(limit, (row.points ?? 0) + elapsed * refillPerMs);\n\t\t\tconst allowed = tokens >= 1;\n\t\t\tif (allowed) tokens -= 1;\n\t\t\tawait this.#db.rawQuery(\n\t\t\t\t`UPDATE ${this.#table} SET points = ?, reset_at = ? WHERE key = ?`,\n\t\t\t\t[tokens, new Date(now).toISOString(), row.key],\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tallowed,\n\t\t\t\tremaining: Math.floor(tokens),\n\t\t\t\tlimit,\n\t\t\t\tresetAt: now + durationMs,\n\t\t\t\tretryAfter: allowed ? 0 : Math.ceil((1 - tokens) / refillPerMs / 1000),\n\t\t\t};\n\t\t}\n\n\t\tthrow new Error(`Unknown strategy: ${strategy}`);\n\t}\n}\n",
|
|
8
|
-
"/**\n * `LimiterService` — single entry point for in-process rate-limit checks.\n *\n * Holds a `RateLimitStorage` and the global `LimiterConfig` so the\n * middleware and the `@RateLimit` decorator share one source of truth.\n *\n * const svc = new LimiterService({ storage: new MemoryRateLimitStorage() });\n * await svc.check('ip:1.2.3.4', { points: 5, duration: '1m' });\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport { MemoryRateLimitStorage } from \"./backends/memory.js\";\nimport type {\n\tLimiterConfig,\n\tRateLimitResult,\n\tRateLimitRule,\n\tRateLimitStorage,\n} from \"./types.js\";\nimport { durationToMs } from \"./types.js\";\n\n@Injectable()\nexport class LimiterService {\n\t/** DI token — `@Inject(LimiterService.TOKEN)`. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:LimiterService\");\n\n\
|
|
9
|
-
"/**\n * Hono middleware factory. Applies all matching global rules in order;\n * the first one that rejects wins. Used by the framework's mount pipeline.\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport { LimiterService } from \"./limiter.service.js\";\nimport type { RateLimitRule } from \"./types.js\";\n\n@Injectable()\nexport class LimiterMiddleware {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:LimiterMiddleware\");\n\n\
|
|
10
|
-
"/**\n * `LimiterModule` — drop-in rate limiter.\n *\n * @Module({\n * imports: [\n * LimiterModule.forRoot({\n * rules: [\n * { path: '/api/*', points: 100, duration: '1m' },\n * { path: '/login', points: 5, duration: '1m' },\n * ],\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { LimiterService } from \"./limiter.service.js\";\nimport { LimiterMiddleware } from \"./limiter.middleware.js\";\nimport { MemoryRateLimitStorage } from \"./backends/memory.js\";\nimport type { LimiterConfig } from \"./types.js\";\
|
|
8
|
+
"/**\n * `LimiterService` — single entry point for in-process rate-limit checks.\n *\n * Holds a `RateLimitStorage` and the global `LimiterConfig` so the\n * middleware and the `@RateLimit` decorator share one source of truth.\n *\n * const svc = new LimiterService({ storage: new MemoryRateLimitStorage() });\n * await svc.check('ip:1.2.3.4', { points: 5, duration: '1m' });\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport { MemoryRateLimitStorage } from \"./backends/memory.js\";\nimport type {\n\tLimiterConfig,\n\tRateLimitResult,\n\tRateLimitRule,\n\tRateLimitStorage,\n} from \"./types.js\";\nimport { durationToMs } from \"./types.js\";\n\n@Injectable()\nexport class LimiterService {\n\t/** DI token — `@Inject(LimiterService.TOKEN)`. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:LimiterService\");\n\n\t/** Rate-limit config — injected by DI container. */\n\t@Inject(\"LIMITER_CONFIG\") declare private config: LimiterConfig;\n\n\tprivate _storage: RateLimitStorage | null = null;\n\tprivate _rules: RateLimitRule[] = [];\n\tprivate _defaultKey: NonNullable<LimiterConfig[\"defaultKey\"]> | null = null;\n\tprivate _defaultReject: NonNullable<LimiterConfig[\"defaultReject\"]> | null = null;\n\n\tconstructor() {\n\t\t// DI sets @Inject fields before first use.\n\t}\n\n\tget storage(): RateLimitStorage {\n\t\tif (!this._storage) {\n\t\t\tthis._storage = (this.config ?? {}).storage ?? new MemoryRateLimitStorage();\n\t\t}\n\t\treturn this._storage;\n\t}\n\n\tget rules(): RateLimitRule[] {\n\t\tif (!this._rules.length && this.config?.rules) {\n\t\t\tthis._rules = this.config.rules;\n\t\t}\n\t\treturn this._rules;\n\t}\n\n\tget defaultKey(): NonNullable<LimiterConfig[\"defaultKey\"]> {\n\t\tif (!this._defaultKey) {\n\t\t\tthis._defaultKey =\n\t\t\t\t(this.config ?? {}).defaultKey ??\n\t\t\t\t((c: any) => {\n\t\t\t\t\tconst fwd = c?.req?.header?.(\"x-forwarded-for\");\n\t\t\t\t\tif (fwd) return fwd.split(\",\")[0]?.trim() ?? \"unknown\";\n\t\t\t\t\treturn c?.req?.raw?.[\"conn\"]?.remoteAddr?.hostname ?? \"unknown\";\n\t\t\t\t});\n\t\t}\n\t\treturn this._defaultKey;\n\t}\n\n\tget defaultReject(): NonNullable<LimiterConfig[\"defaultReject\"]> {\n\t\tif (!this._defaultReject) {\n\t\t\tthis._defaultReject =\n\t\t\t\t(this.config ?? {}).defaultReject ??\n\t\t\t\t((_c, result) =>\n\t\t\t\t\tnew Response(\n\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\terror: \"Too Many Requests\",\n\t\t\t\t\t\t\tlimit: result.limit,\n\t\t\t\t\t\t\tremaining: 0,\n\t\t\t\t\t\t\tretryAfter: result.retryAfter,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: 429,\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t\t\"Retry-After\": String(result.retryAfter),\n\t\t\t\t\t\t\t\t\"X-RateLimit-Limit\": String(result.limit),\n\t\t\t\t\t\t\t\t\"X-RateLimit-Remaining\": \"0\",\n\t\t\t\t\t\t\t\t\"X-RateLimit-Reset\": String(Math.ceil(result.resetAt / 1000)),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t));\n\t\t}\n\t\treturn this._defaultReject;\n\t}\n\n\t/**\n\t * Check a single rule against `key`. Always consumes one point\n\t * (or rejects).\n\t */\n\tasync check(key: string, rule: RateLimitRule): Promise<RateLimitResult> {\n\t\tconst durationMs = durationToMs(rule.duration);\n\t\treturn this.storage.consume(\n\t\t\tkey,\n\t\t\t1,\n\t\t\trule.points,\n\t\t\tdurationMs,\n\t\t\trule.strategy ?? \"sliding-window\",\n\t\t);\n\t}\n\n\t/** Reset the state for a given key. */\n\tasync reset(key: string): Promise<void> {\n\t\tawait this.storage.reset(key);\n\t}\n}\n",
|
|
9
|
+
"/**\n * Hono middleware factory. Applies all matching global rules in order;\n * the first one that rejects wins. Used by the framework's mount pipeline.\n */\nimport { Inject, Injectable } from \"@nexusts/core\";\nimport { LimiterService } from \"./limiter.service.js\";\nimport type { RateLimitRule } from \"./types.js\";\n\n@Injectable()\nexport class LimiterMiddleware {\n\t/** DI token. */\n\tstatic readonly TOKEN = Symbol.for(\"nexus:LimiterMiddleware\");\n\n\t@Inject(LimiterService.TOKEN) declare private readonly limiter: LimiterService;\n\n\t/** Returns a Hono middleware. */\n\tmiddleware() {\n\t\treturn async (c: any, next: () => Promise<any>) => {\n\t\t\tconst method = c.req.method.toUpperCase();\n\t\t\tfor (const rule of this.limiter.rules) {\n\t\t\t\tif (!this.matches(rule, method, c.req.path)) continue;\n\t\t\t\tif (rule.skip && (await rule.skip(c))) continue;\n\t\t\t\tconst keyFn = rule.key ?? this.limiter.defaultKey;\n\t\t\t\tconst key = (await keyFn(c)) ?? \"unknown\";\n\t\t\t\tconst result = await this.limiter.check(key, rule);\n\t\t\t\tc.header?.(\"X-RateLimit-Limit\", String(result.limit));\n\t\t\t\tc.header?.(\"X-RateLimit-Remaining\", String(result.remaining));\n\t\t\t\tc.header?.(\"X-RateLimit-Reset\", String(Math.ceil(result.resetAt / 1000)));\n\t\t\t\tif (!result.allowed) {\n\t\t\t\t\tconst reject = rule.reject ?? this.limiter.defaultReject;\n\t\t\t\t\treturn reject(c, result);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn next();\n\t\t};\n\t}\n\n\tprivate matches(rule: RateLimitRule, method: string, path: string): boolean {\n\t\tif (rule.methods && rule.methods.length > 0) {\n\t\t\tif (!rule.methods.map((m) => m.toUpperCase()).includes(method)) return false;\n\t\t}\n\t\tif (rule.path === \"**\") return true;\n\t\treturn matchGlob(rule.path, path);\n\t}\n}\n\n/** Glob match: `*` = one segment, `**` = any depth. */\nfunction matchGlob(pattern: string, path: string): boolean {\n\tconst regex = new RegExp(\n\t\t\"^\" +\n\t\t\tpattern\n\t\t\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t\t\t.replace(/\\*\\*/g, \"::DOUBLESTAR::\")\n\t\t\t\t.replace(/\\*/g, \"[^/]+\")\n\t\t\t\t.replace(/::DOUBLESTAR::/g, \".*\") +\n\t\t\t\"/?$\",\n\t);\n\treturn regex.test(path);\n}\n",
|
|
10
|
+
"/**\n * `LimiterModule` — drop-in rate limiter.\n *\n * @Module({\n * imports: [\n * LimiterModule.forRoot({\n * rules: [\n * { path: '/api/*', points: 100, duration: '1m' },\n * { path: '/login', points: 5, duration: '1m' },\n * ],\n * }),\n * ],\n * })\n * export class AppModule {}\n */\nimport { Module } from \"@nexusts/core\";\nimport { LimiterService } from \"./limiter.service.js\";\nimport { LimiterMiddleware } from \"./limiter.middleware.js\";\nimport { MemoryRateLimitStorage } from \"./backends/memory.js\";\nimport type { LimiterConfig } from \"./types.js\";\n\n@Module({\n\tproviders: [\n\t\tLimiterService,\n\t\t{ provide: LimiterService.TOKEN, useExisting: LimiterService },\n\t\tLimiterMiddleware,\n\t\t{ provide: LimiterMiddleware.TOKEN, useExisting: LimiterMiddleware },\n\t],\n\texports: [\n\t\tLimiterService,\n\t\tLimiterService.TOKEN,\n\t\tLimiterMiddleware,\n\t\tLimiterMiddleware.TOKEN,\n\t],\n})\nexport class LimiterModule {\n\tstatic forRoot(config: LimiterConfig = {}) {\n\t\t// Default to an in-memory storage if the user didn't supply one.\n\t\tconst cfg: LimiterConfig = {\n\t\t\tstorage: new MemoryRateLimitStorage(),\n\t\t\t...config,\n\t\t};\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tLimiterService,\n\t\t\t\t{ provide: LimiterService.TOKEN, useExisting: LimiterService },\n\t\t\t\tLimiterMiddleware,\n\t\t\t\t{ provide: LimiterMiddleware.TOKEN, useExisting: LimiterMiddleware },\n\t\t\t\t{ provide: \"LIMITER_CONFIG\", useValue: cfg },\n\t\t\t],\n\t\t\texports: [\n\t\t\t\tLimiterService,\n\t\t\t\tLimiterService.TOKEN,\n\t\t\t\tLimiterMiddleware,\n\t\t\t\tLimiterMiddleware.TOKEN,\n\t\t\t],\n\t\t})\n\t\tclass ConfiguredLimiterModule {}\n\t\tObject.defineProperty(ConfiguredLimiterModule, \"name\", {\n\t\t\tvalue: \"ConfiguredLimiterModule\",\n\t\t});\n\t\treturn ConfiguredLimiterModule;\n\t}\n}\n"
|
|
11
11
|
],
|
|
12
|
-
"mappings": "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",
|
|
13
|
-
"debugId": "
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "7D3F2E6D87E9F0E664756E2164756E21",
|
|
14
14
|
"names": []
|
|
15
15
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { LimiterService } from "./limiter.service.js";
|
|
2
1
|
export declare class LimiterMiddleware {
|
|
3
|
-
private readonly limiter;
|
|
4
2
|
/** DI token. */
|
|
5
3
|
static readonly TOKEN: unique symbol;
|
|
6
|
-
|
|
4
|
+
private readonly limiter;
|
|
7
5
|
/** Returns a Hono middleware. */
|
|
8
6
|
middleware(): (c: any, next: () => Promise<any>) => Promise<any>;
|
|
9
7
|
private matches;
|
|
@@ -2,11 +2,17 @@ import type { LimiterConfig, RateLimitResult, RateLimitRule, RateLimitStorage }
|
|
|
2
2
|
export declare class LimiterService {
|
|
3
3
|
/** DI token — `@Inject(LimiterService.TOKEN)`. */
|
|
4
4
|
static readonly TOKEN: unique symbol;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
/** Rate-limit config — injected by DI container. */
|
|
6
|
+
private config;
|
|
7
|
+
private _storage;
|
|
8
|
+
private _rules;
|
|
9
|
+
private _defaultKey;
|
|
10
|
+
private _defaultReject;
|
|
11
|
+
constructor();
|
|
12
|
+
get storage(): RateLimitStorage;
|
|
13
|
+
get rules(): RateLimitRule[];
|
|
14
|
+
get defaultKey(): NonNullable<LimiterConfig["defaultKey"]>;
|
|
15
|
+
get defaultReject(): NonNullable<LimiterConfig["defaultReject"]>;
|
|
10
16
|
/**
|
|
11
17
|
* Check a single rule against `key`. Always consumes one point
|
|
12
18
|
* (or rejects).
|
package/dist/types.d.ts
CHANGED
|
@@ -89,8 +89,13 @@ export interface LimiterConfig {
|
|
|
89
89
|
defaultReject?: (c: any, result: RateLimitResult) => Response | Promise<Response>;
|
|
90
90
|
}
|
|
91
91
|
export declare const LIMITER_RULE_KEY: unique symbol;
|
|
92
|
-
/**
|
|
93
|
-
|
|
92
|
+
/**
|
|
93
|
+
* @RateLimit decorator — attach a per-route rate limit.
|
|
94
|
+
*
|
|
95
|
+
* Dual-mode: supports TC39 standard ES decorators + legacy.
|
|
96
|
+
* Can be used on both classes and methods.
|
|
97
|
+
*/
|
|
98
|
+
export declare function RateLimit(rule: RateLimitRule): any;
|
|
94
99
|
/** Read all `@RateLimit` rules from a controller or method. */
|
|
95
100
|
export declare function getLimiterRules(target: any): RateLimitRule[];
|
|
96
101
|
/** Convert a `DurationLike` to milliseconds. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexusts/limiter",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"description": "Rate limiting (fixed / sliding / token-bucket)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@nexusts/core": "^0.9.
|
|
29
|
+
"@nexusts/core": "^0.9.7"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|