@adonisjs/limiter
Version:
Rate limiting package for AdonisJS framework
147 lines (146 loc) • 5.23 kB
TypeScript
import type { HttpContext } from '@adonisjs/core/http';
import type { MiddlewareFn } from '@adonisjs/core/types/http';
import { Limiter } from './limiter.ts';
import { HttpLimiter } from './http_limiter.ts';
import type { LimiterConsumptionOptions, LimiterManagerStoreFactory } from './types.ts';
import { MultiLimiter } from './multi_limiter.ts';
/**
* Manages multiple rate limiter stores and creates limiter instances.
* Supports creating limiters with runtime configuration for requests,
* duration, and block duration.
*
* Limiter instances are cached based on their configuration to optimize performance.
*/
export declare class LimiterManager<KnownStores extends Record<string, LimiterManagerStoreFactory>> {
#private;
config: {
default: keyof KnownStores;
stores: KnownStores;
};
constructor(config: {
default: keyof KnownStores;
stores: KnownStores;
});
/**
* Generates a unique cache key for a limiter instance based on its configuration.
* Used internally to cache and reuse limiter instances.
*
* @param store - The store name
* @param options - Consumption options for the limiter
*/
protected makeLimiterKey(store: keyof KnownStores, options: LimiterConsumptionOptions): string;
/**
* Creates a multi-limiter that can execute operations across multiple limiters atomically.
* Useful for applying rate limits across different dimensions (e.g., per user and per IP).
*
* @param store - Store name or array of limiter options with keys
* @param options - Array of limiter options with keys (when store is specified)
*
* @example
* ```ts
* const multi = limiter.multi([
* { key: 'user:123', requests: 100, duration: '1 hour' },
* { key: 'ip:192.168.1.1', requests: 1000, duration: '1 hour' }
* ])
*
* await multi.consume()
* ```
*/
multi(options: (LimiterConsumptionOptions & {
key: string | number;
})[]): MultiLimiter;
multi<K extends keyof KnownStores>(store: K, options: (LimiterConsumptionOptions & {
key: string | number;
})[]): MultiLimiter;
/**
* Creates or retrieves a cached limiter instance with the specified configuration.
* Instances are cached for the lifetime of the process based on their unique configuration.
*
* @param store - Store name or consumption options
* @param options - Consumption options (when store is specified)
*
* @example
* ```ts
* // Use default store
* const limiter = limiterManager.use({
* requests: 100,
* duration: '1 hour'
* })
*
* // Use specific store
* const redisLimiter = limiterManager.use('redis', {
* requests: 1000,
* duration: '1 day'
* })
* ```
*/
use(options: LimiterConsumptionOptions): Limiter;
use<K extends keyof KnownStores>(store: K, options: LimiterConsumptionOptions): Limiter;
/**
* Clears rate limit data from the specified stores or all stores.
*
* @param stores - Optional array of store names to clear. Clears all stores if not specified.
*
* @example
* ```ts
* // Clear all stores
* await limiterManager.clear()
*
* // Clear specific stores
* await limiterManager.clear(['redis', 'memory'])
* ```
*/
clear(stores?: Extract<keyof KnownStores, string>[]): Promise<void>;
/**
* Creates an HTTP limiter builder with the specified number of allowed requests.
* This is the starting point for defining HTTP rate limiting middleware.
*
* @param requests - Number of requests to allow
*
* @example
* ```ts
* const httpLimiter = limiterManager
* .allowRequests(100)
* .every('1 hour')
* ```
*/
allowRequests(requests: number): HttpLimiter<KnownStores>;
/**
* Returns null to disable rate limiting for specific routes or users.
* Useful in middleware when you want to conditionally skip rate limiting.
*
* @example
* ```ts
* router.get('/api/data', [
* limiter.define('api', async (ctx) => {
* if (ctx.auth.user?.isAdmin) {
* return limiter.noLimit()
* }
* return limiter.allowRequests(100).every('1 hour')
* })
* ])
* ```
*/
noLimit(): null;
/**
* Defines a named rate limiting middleware for HTTP routes.
* The builder function is called for each request to determine rate limiting behavior.
*
* @param name - Unique name for the middleware (used as key prefix)
* @param builder - Function that returns an HttpLimiter or null to skip limiting
*
* @example
* ```ts
* export const apiLimiter = limiter.define('api', (ctx) => {
* return limiter
* .allowRequests(100)
* .every('1 hour')
* .usingKey(ctx.auth.user.id)
* })
*
* // Apply to routes
* router.get('/api/data', [apiLimiter], controller.index)
* ```
*/
define(name: string, builder: (ctx: HttpContext) => HttpLimiter<any> | null | Promise<HttpLimiter<any>> | Promise<null>): MiddlewareFn;
}