@adonisjs/limiter
Version:
Rate limiting package for AdonisJS framework
136 lines (135 loc) • 4.75 kB
TypeScript
import { RateLimiterRes, type RateLimiterAbstract, type RateLimiterStoreAbstract } from 'rate-limiter-flexible';
import { LimiterResponse } from '../response.ts';
import type { LimiterStoreContract } from '../types.ts';
/**
* Bridge class that adapts rate-limiter-flexible stores to work with AdonisJS limiter.
* This class provides a consistent interface for all limiter stores.
*
* When creating custom stores that wrap rate-limiter-flexible implementations,
* extend this class to inherit the standard AdonisJS limiter behavior.
*/
export default abstract class RateLimiterBridge implements LimiterStoreContract {
protected rateLimiter: RateLimiterStoreAbstract | RateLimiterAbstract;
/**
* A unique name for the store
*/
abstract readonly 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(rateLimiter: RateLimiterStoreAbstract | RateLimiterAbstract);
/**
* Clears the store database, removing all rate limit data.
* Implementation varies by store type.
*/
abstract clear(): Promise<void>;
/**
* Transforms a rate-limiter-flexible response into an AdonisJS LimiterResponse.
*
* @param response - Raw response from rate-limiter-flexible
*/
protected makeLimiterResponse(response: RateLimiterRes): LimiterResponse;
/**
* 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 (e.g., user ID, IP address)
*
* @example
* ```ts
* const response = await limiter.consume('user:123')
* console.log(`Remaining: ${response.remaining}`)
* ```
*/
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
*
* @example
* ```ts
* const response = await limiter.increment('user:123')
* ```
*/
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
*
* @example
* ```ts
* const response = await limiter.decrement('user:123')
* ```
*/
decrement(key: string | number, amount?: number): Promise<LimiterResponse>;
/**
* 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 (e.g., '5 mins')
*
* @example
* ```ts
* await limiter.block('user:123', '10 mins')
* await limiter.block('ip:192.168.1.1', 600)
* ```
*/
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
*
* @example
* ```ts
* // Set that user has consumed 20 requests out of 25 allowed
* await limiter.set('user:123', 20, '1 minute')
* ```
*/
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
*
* @example
* ```ts
* await limiter.delete('user:123')
* ```
*/
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
*
* @example
* ```ts
* const response = await limiter.get('user:123')
* if (response) {
* console.log(`Remaining: ${response.remaining}`)
* }
* ```
*/
get(key: string | number): Promise<LimiterResponse | null>;
}