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