hono-rate-limiter 0.1.3 → 0.2.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.
- package/package.json +4 -6
- package/src/{core/index.d.ts → core.d.ts} +1 -1
- package/src/core.js +1 -0
- package/src/defaultKeyGenerator.js +1 -0
- package/src/{core/headers.d.ts → headers.d.ts} +1 -1
- package/src/headers.js +1 -0
- package/src/index.d.ts +2 -2
- package/src/index.js +1 -1
- package/src/{memory-store/index.d.ts → memoryStore.d.ts} +1 -1
- package/src/memoryStore.js +1 -0
- package/src/{types/config.d.ts → types.d.ts} +84 -2
- package/src/types.js +1 -0
- package/src/{core/validations.d.ts → validations.d.ts} +1 -1
- package/src/validations.js +1 -0
- package/src/core/defaultKeyGenerator.js +0 -1
- package/src/core/headers.js +0 -1
- package/src/core/index.js +0 -1
- package/src/core/validations.js +0 -1
- package/src/memory-store/index.js +0 -1
- package/src/types/clientRateLimitInfo.d.ts +0 -4
- package/src/types/clientRateLimitInfo.js +0 -1
- package/src/types/config.js +0 -1
- package/src/types/index.d.ts +0 -5
- package/src/types/index.js +0 -1
- package/src/types/promisify.d.ts +0 -1
- package/src/types/promisify.js +0 -1
- package/src/types/rateLimitExceededEventHandler.d.ts +0 -1
- package/src/types/rateLimitExceededEventHandler.js +0 -1
- package/src/types/rateLimitInfo.d.ts +0 -10
- package/src/types/rateLimitInfo.js +0 -1
- package/src/types/store.d.ts +0 -65
- package/src/types/store.js +0 -1
- /package/src/{core/defaultKeyGenerator.d.ts → defaultKeyGenerator.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono-rate-limiter",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"type": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"hono",
|
|
@@ -24,12 +24,10 @@
|
|
|
24
24
|
"bugs": {
|
|
25
25
|
"url": "https://github.com/rhinobase/hono-rate-limiter/issues"
|
|
26
26
|
},
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"@swc/helpers": "~0.5.2"
|
|
29
|
-
},
|
|
30
27
|
"peerDependencies": {
|
|
31
28
|
"hono": "^4.1.1"
|
|
32
29
|
},
|
|
33
30
|
"main": "./src/index.js",
|
|
34
|
-
"typings": "./src/index.d.ts"
|
|
31
|
+
"typings": "./src/index.d.ts",
|
|
32
|
+
"module": "./src/index.js"
|
|
35
33
|
}
|
package/src/core.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createMiddleware}from"hono/factory";import{defaultKeyGenerator}from"./defaultKeyGenerator.js";import{setDraft6Headers,setDraft7Headers,setRetryAfterHeader}from"./headers.js";import MemoryStore from"./memoryStore.js";import{isValidStore}from"./validations.js";export function rateLimiter(config){const{windowMs=6e4,limit=5,message="Too many requests, please try again later.",statusCode=429,standardHeaders="draft-6",requestPropertyName="rateLimit",requestStorePropertyName="rateLimitStore",skipFailedRequests=false,skipSuccessfulRequests=false,keyGenerator=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}=config??{};const options={windowMs,limit,message,statusCode,standardHeaders,requestPropertyName,requestStorePropertyName,skipFailedRequests,skipSuccessfulRequests,keyGenerator,skip,requestWasSuccessful,handler,store};if(!isValidStore(store))throw new Error("The store is not correctly implmented!");if(typeof store.init==="function")store.init(options);return 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);c.set(requestStorePropertyName,{getKey:store.get?.bind(store),resetKey:store.resetKey.bind(store)});if(standardHeaders&&!c.finalized){if(standardHeaders==="draft-7"){setDraft7Headers(c,info,windowMs)}else{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){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()}})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getRuntimeKey}from"hono/adapter";export function defaultKeyGenerator(c){const runtime=getRuntimeKey();let key=null;switch(runtime){case"workerd":key=c.req.raw.headers.get("CF-Connecting-IP");break;case"fastly":key=c.req.raw.headers.get("Fastly-Client-IP");break;case"other":key=c.req.raw.headers.get("x-real-ip");break;default:break}return key??""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Context } from "hono";
|
|
2
|
-
import type { RateLimitInfo } from "
|
|
2
|
+
import type { RateLimitInfo } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Sets `RateLimit-*`` headers based on the sixth draft of the IETF specification.
|
|
5
5
|
* See https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers-06.
|
package/src/headers.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const getResetSeconds=(resetTime,windowMs)=>{let resetSeconds;if(resetTime){const deltaSeconds=Math.ceil((resetTime.getTime()-Date.now())/1e3);resetSeconds=Math.max(0,deltaSeconds)}else if(windowMs){resetSeconds=Math.ceil(windowMs/1e3)}return resetSeconds};export const setDraft6Headers=(context,info,windowMs)=>{if(context.finalized)return;const windowSeconds=Math.ceil(windowMs/1e3);const resetSeconds=getResetSeconds(info.resetTime);context.header("RateLimit-Policy",`${info.limit};w=${windowSeconds}`);context.header("RateLimit-Limit",info.limit.toString());context.header("RateLimit-Remaining",info.remaining.toString());if(resetSeconds)context.header("RateLimit-Reset",resetSeconds.toString())};export const setDraft7Headers=(context,info,windowMs)=>{if(context.finalized)return;const windowSeconds=Math.ceil(windowMs/1e3);const resetSeconds=getResetSeconds(info.resetTime,windowMs);context.header("RateLimit-Policy",`${info.limit};w=${windowSeconds}`);context.header("RateLimit",`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`)};export const setRetryAfterHeader=(context,info,windowMs)=>{if(context.finalized)return;const resetSeconds=getResetSeconds(info.resetTime,windowMs);context.header("Retry-After",resetSeconds?.toString())};
|
package/src/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { rateLimiter as default, rateLimiter } from "./core";
|
|
2
|
-
export type * from "./types";
|
|
1
|
+
export { rateLimiter as default, rateLimiter } from "./core.js";
|
|
2
|
+
export type * from "./types.js";
|
package/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export{rateLimiter as default,rateLimiter}from"./core.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import type { ClientRateLimitInfo, ConfigType, Store } from "
|
|
2
|
+
import type { ClientRateLimitInfo, ConfigType, Store } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* The record that stores information about a client - namely, how many times
|
|
5
5
|
* they have hit the endpoint, and when their hit count resets.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class MemoryStore{init(options){this.windowMs=options.windowMs;if(this.interval)clearInterval(this.interval);this.interval=setInterval(()=>{this.clearExpired()},this.windowMs);if(this.interval.unref)this.interval.unref()}async get(key){return this.current.get(key)??this.previous.get(key)}async increment(key){const client=this.getClient(key);const now=Date.now();if(client.resetTime.getTime()<=now){this.resetClient(client,now)}client.totalHits++;return client}async decrement(key){const client=this.getClient(key);if(client.totalHits>0)client.totalHits--}async resetKey(key){this.current.delete(key);this.previous.delete(key)}async resetAll(){this.current.clear();this.previous.clear()}shutdown(){clearInterval(this.interval);void this.resetAll()}resetClient(client,now=Date.now()){client.totalHits=0;client.resetTime.setTime(now+this.windowMs);return client}getClient(key){if(this.current.has(key))return this.current.get(key);let client;if(this.previous.has(key)){client=this.previous.get(key);this.previous.delete(key)}else{client={totalHits:0,resetTime:new Date};this.resetClient(client)}this.current.set(key,client);return client}clearExpired(){this.previous=this.current;this.current=new Map}constructor(){this.previous=new Map;this.current=new Map;this.localKeys=true}}export default MemoryStore;
|
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
import type { Context, Env, Input, Next } from "hono";
|
|
2
2
|
import type { StatusCode } from "hono/utils/http-status";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Data returned from the `Store` when a client's hit counter is incremented.
|
|
5
|
+
*
|
|
6
|
+
* @property totalHits {number} - The number of hits for that client so far.
|
|
7
|
+
* @property resetTime {Date | undefined} - The time when the counter resets.
|
|
8
|
+
*/
|
|
9
|
+
export type ClientRateLimitInfo = {
|
|
10
|
+
totalHits: number;
|
|
11
|
+
resetTime?: Date;
|
|
12
|
+
};
|
|
13
|
+
export type Promisify<T> = T | Promise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* The rate limit related information for each client included in the
|
|
16
|
+
* Hono context object.
|
|
17
|
+
*/
|
|
18
|
+
export type RateLimitInfo = {
|
|
19
|
+
limit: number;
|
|
20
|
+
used: number;
|
|
21
|
+
remaining: number;
|
|
22
|
+
resetTime: Date | undefined;
|
|
23
|
+
};
|
|
5
24
|
/**
|
|
6
25
|
* Hono request handler that sends back a response when a client is
|
|
7
26
|
* rate-limited.
|
|
@@ -110,3 +129,66 @@ export type ConfigType<E extends Env = any, P extends string = any, I extends In
|
|
|
110
129
|
*/
|
|
111
130
|
store: Store;
|
|
112
131
|
};
|
|
132
|
+
export type IncrementResponse = ClientRateLimitInfo;
|
|
133
|
+
/**
|
|
134
|
+
* An interface that all hit counter stores must implement.
|
|
135
|
+
*/
|
|
136
|
+
export type Store = {
|
|
137
|
+
/**
|
|
138
|
+
* Method that initializes the store, and has access to the options passed to
|
|
139
|
+
* the middleware too.
|
|
140
|
+
*
|
|
141
|
+
* @param options {ConfigType} - The options used to setup the middleware.
|
|
142
|
+
*/
|
|
143
|
+
init?: (options: ConfigType) => void;
|
|
144
|
+
/**
|
|
145
|
+
* Method to fetch a client's hit count and reset time.
|
|
146
|
+
*
|
|
147
|
+
* @param key {string} - The identifier for a client.
|
|
148
|
+
*
|
|
149
|
+
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
|
150
|
+
*/
|
|
151
|
+
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* Method to increment a client's hit counter.
|
|
154
|
+
*
|
|
155
|
+
* @param key {string} - The identifier for a client.
|
|
156
|
+
*
|
|
157
|
+
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
|
158
|
+
*/
|
|
159
|
+
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
|
160
|
+
/**
|
|
161
|
+
* Method to decrement a client's hit counter.
|
|
162
|
+
*
|
|
163
|
+
* @param key {string} - The identifier for a client.
|
|
164
|
+
*/
|
|
165
|
+
decrement: (key: string) => Promise<void> | void;
|
|
166
|
+
/**
|
|
167
|
+
* Method to reset a client's hit counter.
|
|
168
|
+
*
|
|
169
|
+
* @param key {string} - The identifier for a client.
|
|
170
|
+
*/
|
|
171
|
+
resetKey: (key: string) => Promise<void> | void;
|
|
172
|
+
/**
|
|
173
|
+
* Method to reset everyone's hit counter.
|
|
174
|
+
*/
|
|
175
|
+
resetAll?: () => Promise<void> | void;
|
|
176
|
+
/**
|
|
177
|
+
* Method to shutdown the store, stop timers, and release all resources.
|
|
178
|
+
*/
|
|
179
|
+
shutdown?: () => Promise<void> | void;
|
|
180
|
+
/**
|
|
181
|
+
* Flag to indicate that keys incremented in one instance of this store can
|
|
182
|
+
* not affect other instances. Typically false if a database is used, true for
|
|
183
|
+
* MemoryStore.
|
|
184
|
+
*
|
|
185
|
+
* Used to help detect double-counting misconfigurations.
|
|
186
|
+
*/
|
|
187
|
+
localKeys?: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Optional value that the store prepends to keys
|
|
190
|
+
*
|
|
191
|
+
* Used by the double-count check to avoid false-positives when a key is counted twice, but with different prefixes
|
|
192
|
+
*/
|
|
193
|
+
prefix?: string;
|
|
194
|
+
};
|
package/src/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Store } from "
|
|
1
|
+
import type { Store } from "./types";
|
|
2
2
|
export declare const isValidStore: (value: Store) => value is Store;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const isValidStore=value=>!!value?.increment;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"defaultKeyGenerator",{enumerable:true,get:function(){return defaultKeyGenerator}});const _adapter=require("hono/adapter");function defaultKeyGenerator(c){const runtime=(0,_adapter.getRuntimeKey)();let key=null;switch(runtime){case"workerd":key=c.req.raw.headers.get("CF-Connecting-IP");break;case"fastly":key=c.req.raw.headers.get("Fastly-Client-IP");break;case"other":key=c.req.raw.headers.get("x-real-ip");break;default:break}return key??""}
|
package/src/core/headers.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
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,{setDraft6Headers:function(){return setDraft6Headers},setDraft7Headers:function(){return setDraft7Headers},setRetryAfterHeader:function(){return setRetryAfterHeader}});const getResetSeconds=(resetTime,windowMs)=>{let resetSeconds;if(resetTime){const deltaSeconds=Math.ceil((resetTime.getTime()-Date.now())/1e3);resetSeconds=Math.max(0,deltaSeconds)}else if(windowMs){resetSeconds=Math.ceil(windowMs/1e3)}return resetSeconds};const setDraft6Headers=(context,info,windowMs)=>{if(context.finalized)return;const windowSeconds=Math.ceil(windowMs/1e3);const resetSeconds=getResetSeconds(info.resetTime);context.header("RateLimit-Policy",`${info.limit};w=${windowSeconds}`);context.header("RateLimit-Limit",info.limit.toString());context.header("RateLimit-Remaining",info.remaining.toString());if(resetSeconds)context.header("RateLimit-Reset",resetSeconds.toString())};const setDraft7Headers=(context,info,windowMs)=>{if(context.finalized)return;const windowSeconds=Math.ceil(windowMs/1e3);const resetSeconds=getResetSeconds(info.resetTime,windowMs);context.header("RateLimit-Policy",`${info.limit};w=${windowSeconds}`);context.header("RateLimit",`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`)};const setRetryAfterHeader=(context,info,windowMs)=>{if(context.finalized)return;const resetSeconds=getResetSeconds(info.resetTime,windowMs);context.header("Retry-After",resetSeconds?.toString())};
|
package/src/core/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
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",requestStorePropertyName="rateLimitStore",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??{};const options={windowMs,limit,message,statusCode,standardHeaders,requestPropertyName,requestStorePropertyName,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);c.set(requestStorePropertyName,{getKey:store.get?.bind(store),resetKey:store.resetKey.bind(store)});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/core/validations.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"isValidStore",{enumerable:true,get:function(){return isValidStore}});const isValidStore=value=>!!value?.increment;
|
|
@@ -1 +0,0 @@
|
|
|
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,{MemoryStore:function(){return MemoryStore},default:function(){return _default}});let MemoryStore=class MemoryStore{init(options){this.windowMs=options.windowMs;if(this.interval)clearInterval(this.interval);this.interval=setInterval(()=>{this.clearExpired()},this.windowMs);if(this.interval.unref)this.interval.unref()}async get(key){return this.current.get(key)??this.previous.get(key)}async increment(key){const client=this.getClient(key);const now=Date.now();if(client.resetTime.getTime()<=now){this.resetClient(client,now)}client.totalHits++;return client}async decrement(key){const client=this.getClient(key);if(client.totalHits>0)client.totalHits--}async resetKey(key){this.current.delete(key);this.previous.delete(key)}async resetAll(){this.current.clear();this.previous.clear()}shutdown(){clearInterval(this.interval);void this.resetAll()}resetClient(client,now=Date.now()){client.totalHits=0;client.resetTime.setTime(now+this.windowMs);return client}getClient(key){if(this.current.has(key))return this.current.get(key);let client;if(this.previous.has(key)){client=this.previous.get(key);this.previous.delete(key)}else{client={totalHits:0,resetTime:new Date};this.resetClient(client)}this.current.set(key,client);return client}clearExpired(){this.previous=this.current;this.current=new Map}constructor(){this.previous=new Map;this.current=new Map;this.localKeys=true}};const _default=MemoryStore;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
package/src/types/config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
package/src/types/index.d.ts
DELETED
package/src/types/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
package/src/types/promisify.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type Promisify<T> = T | Promise<T>;
|
package/src/types/promisify.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
package/src/types/store.d.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import type { ClientRateLimitInfo } from "./clientRateLimitInfo";
|
|
2
|
-
import type { ConfigType } from "./config";
|
|
3
|
-
export type IncrementResponse = ClientRateLimitInfo;
|
|
4
|
-
/**
|
|
5
|
-
* An interface that all hit counter stores must implement.
|
|
6
|
-
*/
|
|
7
|
-
export type Store = {
|
|
8
|
-
/**
|
|
9
|
-
* Method that initializes the store, and has access to the options passed to
|
|
10
|
-
* the middleware too.
|
|
11
|
-
*
|
|
12
|
-
* @param options {ConfigType} - The options used to setup the middleware.
|
|
13
|
-
*/
|
|
14
|
-
init?: (options: ConfigType) => void;
|
|
15
|
-
/**
|
|
16
|
-
* Method to fetch a client's hit count and reset time.
|
|
17
|
-
*
|
|
18
|
-
* @param key {string} - The identifier for a client.
|
|
19
|
-
*
|
|
20
|
-
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
|
21
|
-
*/
|
|
22
|
-
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
|
23
|
-
/**
|
|
24
|
-
* Method to increment a client's hit counter.
|
|
25
|
-
*
|
|
26
|
-
* @param key {string} - The identifier for a client.
|
|
27
|
-
*
|
|
28
|
-
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
|
29
|
-
*/
|
|
30
|
-
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
|
31
|
-
/**
|
|
32
|
-
* Method to decrement a client's hit counter.
|
|
33
|
-
*
|
|
34
|
-
* @param key {string} - The identifier for a client.
|
|
35
|
-
*/
|
|
36
|
-
decrement: (key: string) => Promise<void> | void;
|
|
37
|
-
/**
|
|
38
|
-
* Method to reset a client's hit counter.
|
|
39
|
-
*
|
|
40
|
-
* @param key {string} - The identifier for a client.
|
|
41
|
-
*/
|
|
42
|
-
resetKey: (key: string) => Promise<void> | void;
|
|
43
|
-
/**
|
|
44
|
-
* Method to reset everyone's hit counter.
|
|
45
|
-
*/
|
|
46
|
-
resetAll?: () => Promise<void> | void;
|
|
47
|
-
/**
|
|
48
|
-
* Method to shutdown the store, stop timers, and release all resources.
|
|
49
|
-
*/
|
|
50
|
-
shutdown?: () => Promise<void> | void;
|
|
51
|
-
/**
|
|
52
|
-
* Flag to indicate that keys incremented in one instance of this store can
|
|
53
|
-
* not affect other instances. Typically false if a database is used, true for
|
|
54
|
-
* MemoryStore.
|
|
55
|
-
*
|
|
56
|
-
* Used to help detect double-counting misconfigurations.
|
|
57
|
-
*/
|
|
58
|
-
localKeys?: boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Optional value that the store prepends to keys
|
|
61
|
-
*
|
|
62
|
-
* Used by the double-count check to avoid false-positives when a key is counted twice, but with different prefixes
|
|
63
|
-
*/
|
|
64
|
-
prefix?: string;
|
|
65
|
-
};
|
package/src/types/store.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});
|
|
File without changes
|