@joint-ops/hitlimit 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
7
7
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@joint-ops/hitlimit)](https://bundlephobia.com/package/@joint-ops/hitlimit)
8
8
 
9
- > The fastest rate limiter for Node.js - Express, NestJS, and native HTTP | express-rate-limit alternative
9
+ > The fastest rate limiter for Node.js - Express, Fastify, NestJS, and native HTTP | express-rate-limit alternative
10
10
 
11
11
  **hitlimit** is a high-performance rate limiting middleware for Node.js applications. Protect your APIs from abuse, prevent brute force attacks, and throttle requests with sub-millisecond overhead. A faster, lighter alternative to express-rate-limit and rate-limiter-flexible.
12
12
 
@@ -76,6 +76,12 @@ pnpm add @joint-ops/hitlimit
76
76
  yarn add @joint-ops/hitlimit
77
77
  ```
78
78
 
79
+ For Fastify, also install peer dependencies:
80
+
81
+ ```bash
82
+ npm install fastify fastify-plugin
83
+ ```
84
+
79
85
  ## Quick Start
80
86
 
81
87
  ### Express Rate Limiting
@@ -99,6 +105,23 @@ app.get('/api', (req, res) => res.json({ status: 'ok' }))
99
105
  app.listen(3000)
100
106
  ```
101
107
 
108
+ ### Fastify Rate Limiting
109
+
110
+ ```typescript
111
+ import Fastify from 'fastify'
112
+ import { hitlimit } from '@joint-ops/hitlimit/fastify'
113
+
114
+ const app = Fastify()
115
+
116
+ await app.register(hitlimit, {
117
+ limit: 100,
118
+ window: '1m'
119
+ })
120
+
121
+ app.get('/api', () => ({ status: 'ok' }))
122
+ await app.listen({ port: 3000 })
123
+ ```
124
+
102
125
  ### NestJS Rate Limiting
103
126
 
104
127
  ```typescript
@@ -400,4 +423,4 @@ MIT - Use freely in personal and commercial projects.
400
423
 
401
424
  ## Keywords
402
425
 
403
- rate limit, rate limiter, rate limiting, express rate limit, express middleware, express-rate-limit, express-rate-limit alternative, nestjs rate limit, nestjs throttler, @nestjs/throttler alternative, nestjs guard, nodejs rate limit, node rate limiter, api rate limiting, throttle requests, request throttling, api throttling, ddos protection, brute force protection, redis rate limit, memory rate limit, sqlite rate limit, sliding window, fixed window, token bucket, leaky bucket, rate-limiter-flexible alternative, api security, request limiter, http rate limit, express slow down, api protection, login protection, authentication rate limit
426
+ rate limit, rate limiter, rate limiting, express rate limit, express middleware, express-rate-limit, express-rate-limit alternative, fastify rate limit, fastify plugin, fastify-rate-limit alternative, nestjs rate limit, nestjs throttler, @nestjs/throttler alternative, nestjs guard, nodejs rate limit, node rate limiter, api rate limiting, throttle requests, request throttling, api throttling, ddos protection, brute force protection, redis rate limit, memory rate limit, sqlite rate limit, sliding window, fixed window, token bucket, leaky bucket, rate-limiter-flexible alternative, api security, request limiter, http rate limit, express slow down, api protection, login protection, authentication rate limit
@@ -0,0 +1,6 @@
1
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
2
+ import type { HitLimitOptions } from '@joint-ops/hitlimit-types';
3
+ declare function hitlimitPlugin(fastify: FastifyInstance, options: HitLimitOptions<FastifyRequest>): Promise<void>;
4
+ export declare const hitlimit: typeof hitlimitPlugin;
5
+ export {};
6
+ //# sourceMappingURL=fastify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../src/fastify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAgB,MAAM,SAAS,CAAA;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAShE,iBAAe,cAAc,CAC3B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,eAAe,CAAC,cAAc,CAAC,iBA8BzC;AAED,eAAO,MAAM,QAAQ,uBAGnB,CAAA"}
@@ -0,0 +1,40 @@
1
+ import fp from 'fastify-plugin';
2
+ import { resolveConfig } from './core/config.js';
3
+ import { checkLimit } from './core/limiter.js';
4
+ import { memoryStore } from './stores/memory.js';
5
+ function getDefaultKey(req) {
6
+ return req.ip || 'unknown';
7
+ }
8
+ async function hitlimitPlugin(fastify, options) {
9
+ const store = options.store ?? memoryStore();
10
+ const config = resolveConfig(options, store, getDefaultKey);
11
+ fastify.addHook('onRequest', async (request, reply) => {
12
+ if (config.skip) {
13
+ const shouldSkip = await config.skip(request);
14
+ if (shouldSkip)
15
+ return;
16
+ }
17
+ try {
18
+ const result = await checkLimit(config, request);
19
+ for (const [key, value] of Object.entries(result.headers)) {
20
+ reply.header(key, value);
21
+ }
22
+ if (!result.allowed) {
23
+ reply.status(429).send(result.body);
24
+ return;
25
+ }
26
+ }
27
+ catch (error) {
28
+ const action = await config.onStoreError(error, request);
29
+ if (action === 'deny') {
30
+ reply.status(429).send({ hitlimit: true, message: 'Rate limit error' });
31
+ return;
32
+ }
33
+ }
34
+ });
35
+ }
36
+ export const hitlimit = fp(hitlimitPlugin, {
37
+ name: 'hitlimit',
38
+ fastify: '>=4.0.0'
39
+ });
40
+ //# sourceMappingURL=fastify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../src/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAG/B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,SAAS,aAAa,CAAC,GAAmB;IACxC,OAAO,GAAG,CAAC,EAAE,IAAI,SAAS,CAAA;AAC5B,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,OAAwB,EACxB,OAAwC;IAExC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAA;IAE3D,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;QAClF,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC7C,IAAI,UAAU;gBAAE,OAAM;QACxB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YAEhD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1D,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YAC1B,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBACnC,OAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,KAAc,EAAE,OAAO,CAAC,CAAA;YACjE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAA;gBACvE,OAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC,cAAc,EAAE;IACzC,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,SAAS;CACnB,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@joint-ops/hitlimit",
3
- "version": "1.0.4",
4
- "description": "Fast rate limiting middleware for Express, NestJS & Node.js - API throttling, brute force protection, request limiting",
3
+ "version": "1.0.5",
4
+ "description": "Fast rate limiting middleware for Express, Fastify, NestJS & Node.js - API throttling, brute force protection, request limiting",
5
5
  "author": {
6
6
  "name": "Shayan M Hussain",
7
7
  "email": "shayanhussain48@gmail.com",
@@ -32,6 +32,8 @@
32
32
  "nest-throttler",
33
33
  "fastify",
34
34
  "fastify-rate-limit",
35
+ "fastify-plugin",
36
+ "fastify-middleware",
35
37
  "hono",
36
38
  "hono-rate-limit",
37
39
  "hono-middleware",
@@ -87,6 +89,14 @@
87
89
  "types": "./dist/node.d.ts",
88
90
  "import": "./dist/node.js"
89
91
  },
92
+ "./fastify": {
93
+ "types": "./dist/fastify.d.ts",
94
+ "import": "./dist/fastify.js"
95
+ },
96
+ "./stores/memory": {
97
+ "types": "./dist/stores/memory.d.ts",
98
+ "import": "./dist/stores/memory.js"
99
+ },
90
100
  "./stores/sqlite": {
91
101
  "types": "./dist/stores/sqlite.d.ts",
92
102
  "import": "./dist/stores/sqlite.js"
@@ -119,11 +129,13 @@
119
129
  "test:watch": "vitest"
120
130
  },
121
131
  "dependencies": {
122
- "@joint-ops/hitlimit-types": "1.0.4"
132
+ "@joint-ops/hitlimit-types": "1.0.5"
123
133
  },
124
134
  "peerDependencies": {
125
135
  "@nestjs/common": ">=8.0.0",
126
136
  "@nestjs/core": ">=8.0.0",
137
+ "fastify": ">=4.0.0",
138
+ "fastify-plugin": ">=4.0.0",
127
139
  "better-sqlite3": ">=9.0.0",
128
140
  "ioredis": ">=5.0.0",
129
141
  "pino": ">=8.0.0",
@@ -136,6 +148,12 @@
136
148
  "@nestjs/core": {
137
149
  "optional": true
138
150
  },
151
+ "fastify": {
152
+ "optional": true
153
+ },
154
+ "fastify-plugin": {
155
+ "optional": true
156
+ },
139
157
  "better-sqlite3": {
140
158
  "optional": true
141
159
  },
@@ -160,6 +178,8 @@
160
178
  "@types/supertest": "^6.0.0",
161
179
  "better-sqlite3": "^11.0.0",
162
180
  "express": "^4.18.0",
181
+ "fastify": "^5.7.4",
182
+ "fastify-plugin": "^5.1.0",
163
183
  "ioredis": "^5.3.0",
164
184
  "pino": "^10.3.0",
165
185
  "reflect-metadata": "^0.2.0",