Files
Andrei 58f8093689 Rebrand from 'Redirect Intelligence v2' to 'URL Tracker Tool V2' throughout UI
- Updated all component headers and documentation
- Changed navbar and footer branding
- Updated homepage hero badge
- Modified page title in index.html
- Simplified footer text to 'Built with ❤️'
- Consistent V2 capitalization across all references
2025-08-19 19:12:23 +00:00

408 lines
13 KiB
TypeScript

export interface IRateLimiterRes {
msBeforeNext?: number;
remainingPoints?: number;
consumedPoints?: number;
isFirstInDuration?: boolean;
}
export class RateLimiterRes {
constructor(
remainingPoints?: number,
msBeforeNext?: number,
consumedPoints?: number,
isFirstInDuration?: boolean
);
readonly msBeforeNext: number;
readonly remainingPoints: number;
readonly consumedPoints: number;
readonly isFirstInDuration: boolean;
toString(): string;
toJSON(): {
remainingPoints: number;
msBeforeNext: number;
consumedPoints: number;
isFirstInDuration: boolean;
};
}
export class RateLimiterAbstract {
constructor(opts: IRateLimiterOptions);
/**
* Maximum number of points can be consumed over duration. Limiter compares this number with
* number of consumed points by key to decide if an operation should be rejected or resolved.
*/
points: number;
/**
* Number of seconds before consumed points are reset.
* Keys never expire, if duration is 0.
*/
duration: number;
/**
* duration in milliseconds
*/
get msDuration(): number;
/**
* If positive number and consumed more than points in current duration, block for blockDuration
* seconds.
*/
blockDuration: number;
/**
* blockDuration in milliseconds
*/
get msBlockDuration(): number;
/**
* Delay action to be executed evenly over duration First action in duration is executed without
* delay. All next allowed actions in current duration are delayed by formula
* msBeforeDurationEnd / (remainingPoints + 2) with minimum delay of duration * 1000 / points.
* It allows to cut off load peaks similar way to Leaky Bucket.
*
* Note: it isn't recommended to use it for long duration and few points, as it may delay action
* for too long with default execEvenlyMinDelayMs.
*/
execEvenly: boolean;
/**
* Sets minimum delay in milliseconds, when action is delayed with execEvenly
*/
execEvenlyMinDelayMs: number;
/**
* If you need to create several limiters for different purpose.
* Set to empty string '', if keys should be stored without prefix.
*/
keyPrefix: string;
/**
* Returns internal key prefixed with keyPrefix option as it is saved in store.
*/
getKey(key: string | number): string;
/**
* Returns internal key without the keyPrefix.
*/
parseKey(rlKey: string): string;
/**
* @param key is usually IP address or some unique client id
* @param pointsToConsume number of points consumed. default: 1
* @param options is object with additional settings:
* - customDuration expire in seconds for this operation only overwrites limiter's duration. It doesn't work, if key already created.
* @returns Returns Promise, which:
* - `resolved` with `RateLimiterRes` when point(s) is consumed, so action can be done
* - `rejected` only for store and database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
* - `rejected` when there is no points to be consumed, where reject reason `rejRes` is `RateLimiterRes` object
* - `rejected` when key is blocked (if block strategy is set up), where reject reason `rejRes` is `RateLimiterRes` object
*/
consume(
key: string | number,
pointsToConsume?: number,
options?: { [key: string]: any }
): Promise<RateLimiterRes>;
/**
* Fine key by points number of points for one duration.
*
* Note: Depending on time penalty may go to next durations
*
* @returns Returns Promise, which:
* - `resolved` with RateLimiterRes
* - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
*/
penalty(
key: string | number,
points?: number,
options?: { [key: string]: any }
): Promise<RateLimiterRes>;
/**
* Reward key by points number of points for one duration.
* Note: Depending on time reward may go to next durations
* @returns Promise, which:
* - `resolved` with RateLimiterRes
* - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
*/
reward(
key: string | number,
points?: number,
options?: { [key: string]: any }
): Promise<RateLimiterRes>;
/**
* Get RateLimiterRes in current duration. It always returns RateLimiterRes.isFirstInDuration=false.
* @param key is usually IP address or some unique client id
* @param options
* @returns Promise, which:
* - `resolved` with RateLimiterRes if key is set
* - `resolved` with null if key is NOT set or expired
* - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
*/
get(
key: string | number,
options?: { [key: string]: any }
): Promise<RateLimiterRes | null>;
/**
* Set points to key for secDuration seconds.
* Store it forever, if secDuration is 0.
* @param key
* @param points
* @param secDuration
* @param options
* @returns Promise, which:
* - `resolved` with RateLimiterRes
* - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
*/
set(
key: string | number,
points: number,
secDuration: number,
options?: { [key: string]: any }
): Promise<RateLimiterRes>;
/**
* Block key by setting consumed points to points + 1 for secDuration seconds.
*
* It force updates expire, if there is already key.
*
* Blocked key never expires, if secDuration is 0.
* @returns Promise, which:
* - `resolved` with RateLimiterRes
* - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
*/
block(
key: string | number,
secDuration: number,
options?: { [key: string]: any }
): Promise<RateLimiterRes>;
/**
* Delete all data related to key.
*
* For example, previously blocked key is not blocked after delete as there is no data anymore.
* @returns Promise, which:
* - `resolved` with boolean, true if data is removed by key, false if there is no such key.
* - `rejected` only for database limiters if insuranceLimiter isn't setup: when some error happened, where reject reason `rejRes` is Error object
* - `rejected` only for RateLimiterCluster if insuranceLimiter isn't setup: when timeoutMs exceeded, where reject reason `rejRes` is Error object
*/
delete(
key: string | number,
options?: { [key: string]: any }
): Promise<boolean>;
}
export class RateLimiterStoreAbstract extends RateLimiterAbstract {
constructor(opts: IRateLimiterStoreOptions);
/**
* Cleanup keys blocked in current process memory
*/
deleteInMemoryBlockedAll(): void;
}
interface IRateLimiterOptions {
keyPrefix?: string;
points?: number;
duration?: number;
execEvenly?: boolean;
execEvenlyMinDelayMs?: number;
blockDuration?: number;
}
interface IRateLimiterClusterOptions extends IRateLimiterOptions {
timeoutMs?: number;
}
interface IRateLimiterStoreOptions extends IRateLimiterOptions {
storeClient: any;
storeType?: string;
inMemoryBlockOnConsumed?: number;
inMemoryBlockDuration?: number;
insuranceLimiter?: RateLimiterAbstract;
dbName?: string;
tableName?: string;
tableCreated?: boolean;
}
interface IRateLimiterStoreNoAutoExpiryOptions extends IRateLimiterStoreOptions {
clearExpiredByTimeout?: boolean;
}
interface IRateLimiterMongoOptions extends IRateLimiterStoreOptions {
indexKeyPrefix?: {
[key: string]: any;
};
}
interface IRateLimiterPostgresOptions extends IRateLimiterStoreNoAutoExpiryOptions {
schemaName?: string;
}
interface IRateLimiterRedisOptions extends IRateLimiterStoreOptions {
rejectIfRedisNotReady?: boolean;
useRedisPackage?: boolean;
useRedis3AndLowerPackage?: boolean;
customIncrTtlLuaScript?: string;
}
interface ICallbackReady {
(error?: Error): void;
}
interface IRLWrapperBlackAndWhiteOptions {
limiter: RateLimiterAbstract;
blackList?: string[] | number[];
whiteList?: string[] | number[];
isBlackListed?(key: any): boolean;
isWhiteListed?(key: any): boolean;
runActionAnyway?: boolean;
}
export class RateLimiterMemory extends RateLimiterAbstract {
constructor(opts: IRateLimiterOptions);
}
export class RateLimiterCluster extends RateLimiterAbstract {
constructor(opts: IRateLimiterClusterOptions);
}
export class RateLimiterClusterMaster {
constructor();
}
export class RateLimiterClusterMasterPM2 {
constructor(pm2: any);
}
export class RateLimiterRedis extends RateLimiterStoreAbstract {
constructor(opts: IRateLimiterRedisOptions);
}
export interface IRateLimiterMongoFunctionOptions {
attrs: { [key: string]: any };
}
export class RateLimiterMongo extends RateLimiterStoreAbstract {
constructor(opts: IRateLimiterMongoOptions);
indexKeyPrefix(): Object;
indexKeyPrefix(obj?: Object): void;
consume(
key: string | number,
pointsToConsume?: number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes>;
penalty(
key: string | number,
points?: number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes>;
reward(
key: string | number,
points?: number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes>;
block(
key: string | number,
secDuration: number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes>;
get(
key: string | number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes | null>;
set(
key: string | number,
points: number,
secDuration: number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes>;
delete(
key: string | number,
options?: IRateLimiterMongoFunctionOptions
): Promise<boolean>;
}
export class RateLimiterMySQL extends RateLimiterStoreAbstract {
constructor(opts: IRateLimiterStoreNoAutoExpiryOptions, cb?: ICallbackReady);
}
export class RateLimiterPostgres extends RateLimiterStoreAbstract {
constructor(opts: IRateLimiterPostgresOptions, cb?: ICallbackReady);
}
export class RateLimiterPrisma extends RateLimiterStoreAbstract {
constructor(opts: IRateLimiterStoreNoAutoExpiryOptions, cb?: ICallbackReady);
}
export class RateLimiterMemcache extends RateLimiterStoreAbstract { }
export class RateLimiterUnion {
constructor(...limiters: RateLimiterAbstract[]);
consume(key: string | number, points?: number): Promise<Record<string, RateLimiterRes>>;
}
export class RLWrapperBlackAndWhite extends RateLimiterAbstract {
constructor(opts: IRLWrapperBlackAndWhiteOptions);
}
interface IRateLimiterQueueOpts {
maxQueueSize?: number;
}
export class RateLimiterQueue {
constructor(
limiterFlexible: RateLimiterAbstract | BurstyRateLimiter,
opts?: IRateLimiterQueueOpts
);
getTokensRemaining(key?: string | number): Promise<number>;
removeTokens(tokens: number, key?: string | number): Promise<number>;
}
export class BurstyRateLimiter {
constructor(
rateLimiter: RateLimiterAbstract,
burstLimiter: RateLimiterAbstract
);
consume(
key: string | number,
pointsToConsume?: number,
options?: IRateLimiterMongoFunctionOptions
): Promise<RateLimiterRes>;
}
interface IRateLimiterDynamoOptions extends IRateLimiterStoreOptions {
dynamoTableOpts?: {
readCapacityUnits: number;
writeCapacityUnits: number;
};
ttlSet?: boolean;
}
export class RateLimiterDynamo extends RateLimiterStoreAbstract {
constructor(opts: IRateLimiterDynamoOptions, cb?: ICallbackReady);
}