cahita 1.2.2 → 1.2.3

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.
@@ -1,8 +1,11 @@
1
- import type { Middleware } from '../types';
1
+ import type { Middleware, Request } from '../types';
2
2
  interface RateLimitOptions {
3
3
  windowMs: number;
4
4
  max: number;
5
5
  message?: string;
6
+ skip?: (req: Request) => boolean;
7
+ keyGenerator?: (req: Request) => string;
8
+ maxEntries?: number;
6
9
  }
7
10
  export declare const rateLimit: (options: RateLimitOptions) => Middleware;
8
11
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middlewares/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAmC,MAAM,SAAS,CAAC;AAE3E,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,SAAS,GAAI,SAAS,gBAAgB,KAAG,UA2CrD,CAAC"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middlewares/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAgB,OAAO,EAAY,MAAM,SAAS,CAAC;AAE3E,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GAAI,SAAS,gBAAgB,KAAG,UAwErD,CAAC"}
@@ -2,35 +2,51 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.rateLimit = void 0;
4
4
  const rateLimit = (options) => {
5
- const { windowMs, max, message = 'Too many requests, please try again later.' } = options;
5
+ const { windowMs, max, message = 'Too many requests, please try again later.', skip = () => false, keyGenerator, maxEntries = 100_000, } = options;
6
+ if (windowMs < 1000) {
7
+ console.warn('🌵 Cahita Warning: windowMs is very low (< 1s). This might cause precision issues.');
8
+ }
6
9
  const hits = new Map();
10
+ const cleanupInterval = Math.max(windowMs, 30_000);
7
11
  setInterval(() => {
8
12
  const now = Date.now();
9
- for (const [ip, data] of hits.entries()) {
13
+ for (const [key, data] of hits.entries()) {
10
14
  if (now > data.resetTime)
11
- hits.delete(ip);
15
+ hits.delete(key);
12
16
  }
13
- }, windowMs);
17
+ }, cleanupInterval).unref();
14
18
  return (req, res, next) => {
19
+ if (skip(req))
20
+ return next();
15
21
  const forwarded = req.headers['x-forwarded-for'];
16
22
  const ip = typeof forwarded === 'string' ? forwarded.split(',')[0].trim() : (req.socket.remoteAddress ?? 'unknown');
23
+ const key = keyGenerator ? keyGenerator(req) : ip;
17
24
  const now = Date.now();
18
- let clientData = hits.get(ip);
25
+ let clientData = hits.get(key);
19
26
  if (clientData && now > clientData.resetTime) {
20
- hits.delete(ip);
27
+ hits.delete(key);
21
28
  clientData = undefined;
22
29
  }
23
30
  if (!clientData) {
24
31
  clientData = { count: 0, resetTime: now + windowMs };
25
32
  }
26
33
  clientData.count++;
27
- hits.set(ip, clientData);
34
+ hits.set(key, clientData);
35
+ if (hits.size > maxEntries) {
36
+ hits.clear();
37
+ }
38
+ const remaining = Math.max(0, max - clientData.count);
39
+ const resetSeconds = Math.ceil((clientData.resetTime - now) / 1000);
28
40
  res.setHeader('X-RateLimit-Limit', String(max));
29
- res.setHeader('X-RateLimit-Remaining', String(Math.max(0, max - clientData.count)));
30
- res.setHeader('X-RateLimit-Reset', Math.ceil(clientData.resetTime / 1000));
41
+ res.setHeader('X-RateLimit-Remaining', String(remaining));
42
+ res.setHeader('X-RateLimit-Reset', String(resetSeconds));
31
43
  if (clientData.count > max) {
32
- res.setHeader('Retry-After', Math.ceil((clientData.resetTime - now) / 1000));
33
- res.status(429).json({ error: message });
44
+ res.setHeader('Retry-After', String(resetSeconds));
45
+ res.status(429).json({
46
+ error: 'Too Many Requests',
47
+ message,
48
+ retryAfterSeconds: resetSeconds,
49
+ });
34
50
  return;
35
51
  }
36
52
  next();
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/middlewares/rate-limit.ts"],"names":[],"mappings":";;;AAQO,MAAM,SAAS,GAAG,CAAC,OAAyB,EAAc,EAAE;IACjE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,4CAA4C,EAAE,GAAG,OAAO,CAAC;IAE1F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAgD,CAAC;IAErE,WAAW,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACxC,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEb,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjD,MAAM,EAAE,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC,CAAC;QAEpH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE9B,IAAI,UAAU,IAAI,GAAG,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChB,UAAU,GAAG,SAAS,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAC;QACvD,CAAC;QAED,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAEzB,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpF,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC;QAE3E,IAAI,UAAU,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;YAC3B,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAC7E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC,CAAC;AA3CW,QAAA,SAAS,aA2CpB"}
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/middlewares/rate-limit.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cahita",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A high-performance, async-first web framework for Node.js",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",