From 449a5e2d87e20f1dc33944eee4debb473a15045d Mon Sep 17 00:00:00 2001 From: Jonas L Date: Wed, 9 May 2018 15:20:01 +0200 Subject: [PATCH] Add rolling rate limiter --- types/rolling-rate-limiter/index.d.ts | 38 +++++++++++++++++++ .../rolling-rate-limiter-tests.ts | 36 ++++++++++++++++++ types/rolling-rate-limiter/tsconfig.json | 23 +++++++++++ types/rolling-rate-limiter/tslint.json | 1 + 4 files changed, 98 insertions(+) create mode 100644 types/rolling-rate-limiter/index.d.ts create mode 100644 types/rolling-rate-limiter/rolling-rate-limiter-tests.ts create mode 100644 types/rolling-rate-limiter/tsconfig.json create mode 100644 types/rolling-rate-limiter/tslint.json diff --git a/types/rolling-rate-limiter/index.d.ts b/types/rolling-rate-limiter/index.d.ts new file mode 100644 index 0000000000..0de8235fc2 --- /dev/null +++ b/types/rolling-rate-limiter/index.d.ts @@ -0,0 +1,38 @@ +// Type definitions for rolling-rate-limiter 0.1 +// Project: https://github.com/peterkhayes/rolling-rate-limiter +// Definitions by: Jonas Lochmann +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export = RollingRateLimiter; + +declare function RollingRateLimiter(options: RollingRateLimiter.InMemoryOptions): RollingRateLimiter.SyncOrAsyncLimiter; +declare function RollingRateLimiter(options: RollingRateLimiter.WithRedisOptions): RollingRateLimiter.AsyncLimiter; + +declare namespace RollingRateLimiter { + interface GeneralOptions { + interval: number; + maxInInterval: number; + minDifference?: number; + } + + interface RedisOptions { + redis: CompatibleRedisClient; + namespace?: string; + } + + interface CompatibleRedisClient { + multi: () => any; + } + + type InMemoryOptions = GeneralOptions; + type WithRedisOptions = GeneralOptions & RedisOptions; + + type AsyncLimiterWithToken = (token: string, callback: AsyncLimiterCallback) => void; + type AsyncLimiterWithoutToken = (callback: AsyncLimiterCallback) => void; + type AsyncLimiterCallback = (err: any, timeLeft: number, actionsLeft: number) => void; + type AsyncLimiter = AsyncLimiterWithToken & AsyncLimiterWithToken; + + type SyncLimiter = (token?: string) => number; + + type SyncOrAsyncLimiter = SyncLimiter & AsyncLimiter; +} diff --git a/types/rolling-rate-limiter/rolling-rate-limiter-tests.ts b/types/rolling-rate-limiter/rolling-rate-limiter-tests.ts new file mode 100644 index 0000000000..1318b8d425 --- /dev/null +++ b/types/rolling-rate-limiter/rolling-rate-limiter-tests.ts @@ -0,0 +1,36 @@ +import * as RateLimiter from 'rolling-rate-limiter'; + +/* + Setup: +*/ + +const limiter = RateLimiter({ + // in miliseconds + interval: 1000, + maxInInterval: 10, + // optional: the minimum time (in miliseconds) between any two actions + minDifference: 100 +}); + +/* + Action: +*/ + +function attemptAction(userId: string) { + // Argument should be a unique identifier for a user if one exists. + // If none is provided, the limiter will not differentiate between users. + const timeLeft = limiter(userId); + + if (timeLeft > 0) { + // limit was exceeded, action should not be allowed + // timeLeft is the number of ms until the next action will be allowed + // note that this can be treated as a boolean, since 0 is falsy + } else { + // limit was not exceeded, action should be allowed + } +} + +/* + Note that the in-memory version can also operate asynchronously. + The syntax is identical to the redis implementation below. +*/ diff --git a/types/rolling-rate-limiter/tsconfig.json b/types/rolling-rate-limiter/tsconfig.json new file mode 100644 index 0000000000..0b526f946e --- /dev/null +++ b/types/rolling-rate-limiter/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "rolling-rate-limiter-tests.ts" + ] +} diff --git a/types/rolling-rate-limiter/tslint.json b/types/rolling-rate-limiter/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/rolling-rate-limiter/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }