hono-rate-limiter 0.1.0 → 0.1.1

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
@@ -20,7 +20,8 @@ import { rateLimiter } from "hono-rate-limiter";
20
20
  const limiter = rateLimiter({
21
21
  windowMs: 15 * 60 * 1000, // 15 minutes
22
22
  limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
23
- standardHeaders: "draft-7", // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
23
+ standardHeaders: "draft-6", // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
24
+ keyGenerator: () => "<unique_key>", // Method to generate custom identifiers for clients.
24
25
  // store: ... , // Redis, MemoryStore, etc. See below.
25
26
  });
26
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono-rate-limiter",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@swc/helpers": "~0.5.2"
@@ -8,15 +8,6 @@
8
8
  "peerDependencies": {
9
9
  "hono": "^4.1.1"
10
10
  },
11
- "exports": {
12
- ".": {
13
- "default": "./src/index.js",
14
- "types": "./src/index.d.ts"
15
- },
16
- "./redis": {
17
- "default": "./src/redis/index.js",
18
- "types": "./src/redis/index.d.ts"
19
- }
20
- },
21
- "main": "./src/index.js"
11
+ "main": "./src/index.js",
12
+ "typings": "./src/index.d.ts"
22
13
  }
@@ -1,13 +1,2 @@
1
- import type { Env, Input } from "hono";
2
- import type { ConfigType } from "../types";
3
- /**
4
- *
5
- * Create an instance of IP rate-limiting middleware for Hono.
6
- *
7
- * @param config {ConfigType} - Options to configure the rate limiter.
8
- *
9
- * @returns - The middleware that rate-limits clients based on your configuration.
10
- *
11
- * @public
12
- */
13
- export declare function rateLimiter<E extends Env, P extends string, I extends Input>(config?: Partial<ConfigType<E, P, I>>): import("hono").MiddlewareHandler<E, P, I>;
1
+ export { rateLimiter } from "./limiter";
2
+ export { defaultKeyGenerator } from "./defaultKeyGenerator";
package/src/core/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"rateLimiter",{enumerable:true,get:function(){return rateLimiter}});const _interop_require_default=require("@swc/helpers/_/_interop_require_default");const _factory=require("hono/factory");const _memorystore=_interop_require_default._(require("../memory-store"));const _defaultKeyGenerator=require("./defaultKeyGenerator");const _headers=require("./headers");const _validations=require("./validations");function rateLimiter(config){const{windowMs=6e4,limit=5,message="Too many requests, please try again later.",statusCode=429,standardHeaders="draft-6",requestPropertyName="rateLimit",skipFailedRequests=false,skipSuccessfulRequests=false,keyGenerator=_defaultKeyGenerator.defaultKeyGenerator,skip=()=>false,requestWasSuccessful=c=>c.res.status<400,handler=async(c,_next,options)=>{c.status(options.statusCode);const responseMessage=typeof options.message==="function"?await options.message(c):options.message;if(typeof responseMessage==="string")return c.text(responseMessage);return c.json(responseMessage)},store=new _memorystore.default}=config!=null?config:{};const options={windowMs,limit,message,statusCode,standardHeaders,requestPropertyName,skipFailedRequests,skipSuccessfulRequests,keyGenerator,skip,requestWasSuccessful,handler,store};if(!(0,_validations.isValidStore)(store))throw new Error("The store is not correctly implmented!");if(typeof store.init==="function")store.init(options);return(0,_factory.createMiddleware)(async(c,next)=>{const isSkippable=await skip(c);if(isSkippable){await next();return}const key=await keyGenerator(c);const{totalHits,resetTime}=await store.increment(key);const retrieveLimit=typeof limit==="function"?limit(c):limit;const _limit=await retrieveLimit;const info={limit:_limit,used:totalHits,remaining:Math.max(_limit-totalHits,0),resetTime};c.set(requestPropertyName,info);if(standardHeaders&&!c.finalized){if(standardHeaders==="draft-7"){(0,_headers.setDraft7Headers)(c,info,windowMs)}else{(0,_headers.setDraft6Headers)(c,info,windowMs)}}let decremented=false;const decrementKey=async()=>{if(!decremented){await store.decrement(key);decremented=true}};const shouldSkipRequest=async()=>{if(skipFailedRequests||skipSuccessfulRequests){const wasRequestSuccessful=await requestWasSuccessful(c);if(skipFailedRequests&&!wasRequestSuccessful||skipSuccessfulRequests&&wasRequestSuccessful)await decrementKey()}};if(totalHits>_limit){if(standardHeaders){(0,_headers.setRetryAfterHeader)(c,info,windowMs)}await shouldSkipRequest();return handler(c,next,options)}try{await next();await shouldSkipRequest()}catch(error){if(skipFailedRequests)await decrementKey()}finally{if(!c.finalized)await decrementKey()}})}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:all[name]})}_export(exports,{defaultKeyGenerator:function(){return _defaultKeyGenerator.defaultKeyGenerator},rateLimiter:function(){return _limiter.rateLimiter}});const _limiter=require("./limiter");const _defaultKeyGenerator=require("./defaultKeyGenerator");
@@ -0,0 +1,13 @@
1
+ import type { Env, Input } from "hono";
2
+ import type { ConfigType } from "../types";
3
+ /**
4
+ *
5
+ * Create an instance of IP rate-limiting middleware for Hono.
6
+ *
7
+ * @param config {ConfigType} - Options to configure the rate limiter.
8
+ *
9
+ * @returns - The middleware that rate-limits clients based on your configuration.
10
+ *
11
+ * @public
12
+ */
13
+ export declare function rateLimiter<E extends Env, P extends string, I extends Input>(config: Partial<ConfigType<E, P, I>> & Pick<ConfigType<E, P, I>, "keyGenerator">): import("hono").MiddlewareHandler<E, P, I>;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"rateLimiter",{enumerable:true,get:function(){return rateLimiter}});const _interop_require_default=require("@swc/helpers/_/_interop_require_default");const _factory=require("hono/factory");const _memorystore=_interop_require_default._(require("../memory-store"));const _defaultKeyGenerator=require("./defaultKeyGenerator");const _headers=require("./headers");const _validations=require("./validations");function rateLimiter(config){const{windowMs=6e4,limit=5,message="Too many requests, please try again later.",statusCode=429,standardHeaders="draft-6",requestPropertyName="rateLimit",skipFailedRequests=false,skipSuccessfulRequests=false,keyGenerator=_defaultKeyGenerator.defaultKeyGenerator,skip=()=>false,requestWasSuccessful=c=>c.res.status<400,handler=async(c,_next,options)=>{c.status(options.statusCode);const responseMessage=typeof options.message==="function"?await options.message(c):options.message;if(typeof responseMessage==="string")return c.text(responseMessage);return c.json(responseMessage)},store=new _memorystore.default}=config!=null?config:{};const options={windowMs,limit,message,statusCode,standardHeaders,requestPropertyName,skipFailedRequests,skipSuccessfulRequests,keyGenerator,skip,requestWasSuccessful,handler,store};if(!(0,_validations.isValidStore)(store))throw new Error("The store is not correctly implmented!");if(typeof store.init==="function")store.init(options);return(0,_factory.createMiddleware)(async(c,next)=>{const isSkippable=await skip(c);if(isSkippable){await next();return}const key=await keyGenerator(c);const{totalHits,resetTime}=await store.increment(key);const retrieveLimit=typeof limit==="function"?limit(c):limit;const _limit=await retrieveLimit;const info={limit:_limit,used:totalHits,remaining:Math.max(_limit-totalHits,0),resetTime};c.set(requestPropertyName,info);if(standardHeaders&&!c.finalized){if(standardHeaders==="draft-7"){(0,_headers.setDraft7Headers)(c,info,windowMs)}else{(0,_headers.setDraft6Headers)(c,info,windowMs)}}let decremented=false;const decrementKey=async()=>{if(!decremented){await store.decrement(key);decremented=true}};const shouldSkipRequest=async()=>{if(skipFailedRequests||skipSuccessfulRequests){const wasRequestSuccessful=await requestWasSuccessful(c);if(skipFailedRequests&&!wasRequestSuccessful||skipSuccessfulRequests&&wasRequestSuccessful)await decrementKey()}};if(totalHits>_limit){if(standardHeaders){(0,_headers.setRetryAfterHeader)(c,info,windowMs)}await shouldSkipRequest();return handler(c,next,options)}try{await next();await shouldSkipRequest()}catch(error){if(skipFailedRequests)await decrementKey()}finally{if(!c.finalized)await decrementKey()}})}
package/src/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./core";
2
2
  export type * from "./types";
3
+ export * from "./redis";
package/src/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});const _export_star=require("@swc/helpers/_/_export_star");_export_star._(require("./core"),exports);
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});const _export_star=require("@swc/helpers/_/_export_star");_export_star._(require("./core"),exports);_export_star._(require("./redis"),exports);