UNPKG

@adonisjs/limiter

Version:

Rate limiting package for AdonisJS framework

165 lines (164 loc) 5.88 kB
import { type LimiterResponse } from './response.ts'; import type { LimiterStoreContract } from './types.ts'; import { type ThrottleException } from './errors.ts'; /** * Limiter provides a high-level API for rate limiting operations. * It wraps limiter stores and adds convenience methods like attempt() and penalize(). */ export declare class Limiter implements LimiterStoreContract { #private; get name(): string; /** * The number of configured requests on the store */ get requests(): number; /** * The duration (in seconds) for which the requests are configured */ get duration(): number; /** * The duration (in seconds) for which to block the key */ get blockDuration(): number; constructor(store: LimiterStoreContract); /** * Consumes one request for the given key. Throws a ThrottleException * when the rate limit is exceeded or the key is blocked. * * @param key - Unique identifier for the rate limit */ consume(key: string | number, amount?: number): Promise<LimiterResponse>; /** * Increments the consumed request count for the given key. * Unlike consume(), this method does not throw when the limit is reached. * * @param key - Unique identifier for the rate limit * @param amount - Number of requests to increment (default: 1) */ increment(key: string | number, amount?: number): Promise<LimiterResponse>; /** * Decrements the consumed request count for the given key. * Will not decrement below zero. * * @param key - Unique identifier for the rate limit * @param amount - Number of requests to decrement (default: 1) */ decrement(key: string | number, amount?: number): Promise<LimiterResponse>; /** * Attempts to consume one request and execute the callback if successful. * Returns undefined if the rate limit is exceeded. * * @param key - Unique identifier for the rate limit * @param callback - Function to execute if rate limit allows * * @example * ```ts * const result = await limiter.attempt('user:123', async () => { * return await performExpensiveOperation() * }) * * if (!result) { * console.log('Rate limit exceeded') * } * ``` */ attempt<T>(key: string | number, callback: () => T | Promise<T>, amount?: number): Promise<T | undefined>; /** * Executes the callback and penalizes on failure by consuming a request. * Useful for rate limiting failed operations (e.g., login attempts). * * - Returns error if rate limit is exhausted * - Executes callback if requests are available * - Increments counter and blocks key on callback failure * - Resets key on callback success * * @param key - Unique identifier for the rate limit * @param callback - Function to execute * * @example * ```ts * const [error, user] = await limiter.penalize('login:user@example.com', async () => { * return await attemptLogin(credentials) * }) * * if (error) { * throw error * } * ``` */ penalize<T>(key: string | number, callback: () => T | Promise<T>, amount?: number): Promise<[null, T] | [ThrottleException, null]>; /** * Blocks the given key for the specified duration, preventing any requests. * * @param key - Unique identifier for the rate limit * @param duration - Block duration in seconds or as a time expression */ block(key: string | number, duration: string | number): Promise<LimiterResponse>; /** * Manually sets the number of consumed requests for a given key. * * @param key - Unique identifier for the rate limit * @param requests - Number of requests consumed * @param duration - Optional duration in seconds or time expression */ set(key: string | number, requests: number, duration?: string | number): Promise<LimiterResponse>; /** * Deletes the given key, resetting its rate limit state. * * @param key - Unique identifier for the rate limit */ delete(key: string | number): Promise<boolean>; /** * Deletes all keys that are blocked in memory. * Only applicable for stores with in-memory blocking enabled. */ deleteInMemoryBlockedKeys(): void; /** * Retrieves the current rate limit state for the given key. * * @param key - Unique identifier for the rate limit */ get(key: string | number): Promise<LimiterResponse | null>; /** * Returns the number of remaining requests for the given key. * * @param key - Unique identifier for the rate limit * * @example * ```ts * const remaining = await limiter.remaining('user:123') * console.log(`You have ${remaining} requests left`) * ``` */ remaining(key: string | number): Promise<number>; /** * Returns the number of seconds until the key will be available for new requests. * Returns 0 if requests are currently available. * * @param key - Unique identifier for the rate limit * * @example * ```ts * const seconds = await limiter.availableIn('user:123') * console.log(`Try again in ${seconds} seconds`) * ``` */ availableIn(key: string | number): Promise<number>; /** * Checks if the given key is currently blocked (rate limit exceeded). * * @param key - Unique identifier for the rate limit * * @example * ```ts * if (await limiter.isBlocked('user:123')) { * console.log('Rate limit exceeded') * } * ``` */ isBlocked(key: string | number): Promise<boolean>; /** * Clears the entire storage, removing all rate limit data. */ clear(): Promise<void>; }