UNPKG

@routup/rate-limit

Version:
241 lines (240 loc) 7.3 kB
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