@routup/rate-limit
Version:
Routup rate limiter.
241 lines (240 loc) • 7.3 kB
text/typescript
import * as _$routup from "routup";
import { Handler, IAppEvent } from "routup";
//#region src/store/type.d.ts
/**
* An interface that all stores must implement.
*/
interface Store {
/**
* Method that initializes the store, and has access to the options passed to
* the middleware too.
*
* @param options {Options} - The options used to setup the middleware.
*/
init?: (options: Options) => void;
/**
* Method to increment a client's hit counter.
*
* @param key {string} - The identifier for a client.
*
* @returns {IncrementResponse} - The number of hits and reset time for that client.
*/
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
/**
* Method to decrement a client's hit counter.
*
* @param key {string} - The identifier for a client.
*/
decrement: (key: string) => Promise<void> | void;
/**
* Method to reset a client's hit counter.
*
* @param key {string} - The identifier for a client.
*/
reset: (key: string) => Promise<void> | void;
}
//#endregion
//#region src/store/memory.d.ts
declare class MemoryStore implements Store {
/**
* The duration of time before which all hit counts are reset (in milliseconds).
*/
windowMs: number;
/**
* The map that stores the number of hits for each client in memory.
*/
hits: {
[key: string]: number | undefined;
};
/**
* The time at which all hit counts will be reset.
*/
resetTime: Date;
/**
* Reference to the active timer.
*/
interval?: NodeJS.Timeout;
/**
* Method that initializes the store.
*
* @param options {Options} - The options used to setup the middleware.
*/
init(options: Options): void;
/**
* Method to increment a client's hit counter.
*
* @param key {string} - The identifier for a client.
*
* @returns {IncrementResponse} - The number of hits and reset time for that client.
*
* @public
*/
increment(key: string): Promise<IncrementResponse>;
/**
* Method to decrement a client's hit counter.
*
* @param key {string} - The identifier for a client.
*
* @public
*/
decrement(key: string): Promise<void>;
/**
* Method to reset a client's hit counter.
*
* @param key {string} - The identifier for a client.
*
* @public
*/
reset(key: string): Promise<void>;
/**
* Method to reset everyone's hit counter.
*
* @public
*/
resetAll(): Promise<void>;
}
//#endregion
//#region src/store/utils.d.ts
declare function calculateNextResetTime(windowMs: number): Date;
//#endregion
//#region src/type.d.ts
/**
* Request rate limit info record.
*/
type RateLimitInfo = {
limit: number;
current: number;
remaining: number;
resetTime?: Date;
};
/**
* Method to generate/retrieve a value based on the incoming event.
*
* @param event {IAppEvent} - The routup event.
*
* @returns T - The value needed.
*/
type ValueDeterminingMiddleware<T> = (event: IAppEvent) => T | Promise<T>;
/**
* Handler that sends back a response when a client is rate-limited.
*
* @param event {IAppEvent} - The routup event.
* @param options {Options} - The options used to set up the middleware.
*/
type RateLimitExceededEventHandler = (event: IAppEvent, options: Options) => unknown | Promise<unknown>;
/**
* Data returned from the `Store` when a client's hit counter is incremented.
*/
type IncrementResponse = {
/**
* The number of hits for that client so far.
*/
totalHits: number;
/**
* The time when the counter resets.
*/
resetTime: Date | undefined;
};
type Options = {
/**
* How long we should remember the requests.
*
* Defaults to `60000` ms (= 1 minute).
*/
windowMs: number;
/**
* The maximum number of connections to allow during the `window` before
* rate limiting the client.
*
* Can be the limit itself as a number or a function that receives
* the event and returns the limit.
*
* Defaults to `5`.
*/
max: number | ValueDeterminingMiddleware<number>;
/**
* The response body to send back when a client is rate limited.
*
* Defaults to `'Too many requests, please try again later.'`
*/
message: any | ValueDeterminingMiddleware<any>;
/**
* The HTTP status code to send back when a client is rate limited.
*
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
*/
statusCode: number;
/**
* If `true`, the library will (by default) skip all requests that have a 4XX
* or 5XX status.
*
* Defaults to `false`.
*/
skipFailedRequest: boolean;
/**
* If `true`, the library will (by default) skip all requests that have a
* status code less than 400.
*
* Defaults to `false`.
*/
skipSuccessfulRequest: boolean;
/**
* Method to generate custom identifiers for clients.
*
* By default, the client's IP address is used.
*/
keyGenerator: ValueDeterminingMiddleware<string>;
/**
* Handler that sends back a response when a client is
* rate-limited.
*
* By default, sends back the `statusCode` and `message` set via the options.
*/
handler: RateLimitExceededEventHandler;
/**
* Method to determine whether or not this request
* counts towards a client's quota.
*
* By default, skips no requests.
*/
skip: ValueDeterminingMiddleware<boolean>;
/**
* Method to determine whether the request counts as 'successful'. Used
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
*
* By default, requests with a response status code less than 400 are considered
* successful.
*/
requestWasSuccessful: (event: IAppEvent, response: Response) => boolean;
/**
* The `Store` to use to store the hit count for each client.
*
* By default, the built-in `MemoryStore` will be used.
*/
store: Store;
};
type OptionsInput = Partial<Options>;
//#endregion
//#region src/module.d.ts
declare function rateLimit(options?: OptionsInput): Handler;
//#endregion
//#region src/constants.d.ts
declare const RETRY_AGAIN_MESSAGE = "Too many requests, please try again later.";
//#endregion
//#region src/handler.d.ts
declare function createHandler(input?: OptionsInput): _$routup.Handler;
//#endregion
//#region src/request.d.ts
declare function useRequestRateLimitInfo(event: IAppEvent): Partial<RateLimitInfo>;
declare function useRequestRateLimitInfo<K extends keyof RateLimitInfo>(event: IAppEvent, key: K): RateLimitInfo[K] | undefined;
declare function setRequestRateLimitInfo<K extends keyof RateLimitInfo>(event: IAppEvent, key: K, value: RateLimitInfo[K]): void;
declare function setRequestRateLimitInfo(event: IAppEvent, record: RateLimitInfo): void;
//#endregion
//#region src/utils/is-object.d.ts
declare function isObject(item: unknown): item is Record<string, any>;
//#endregion
//#region src/utils/options.d.ts
declare function normalizeHandlerOptions(input?: OptionsInput): Options;
//#endregion
export { IncrementResponse, MemoryStore, Options, OptionsInput, RETRY_AGAIN_MESSAGE, RateLimitExceededEventHandler, RateLimitInfo, Store, ValueDeterminingMiddleware, calculateNextResetTime, createHandler, rateLimit as default, rateLimit, isObject, normalizeHandlerOptions, setRequestRateLimitInfo, useRequestRateLimitInfo };
//# sourceMappingURL=index.d.mts.map