@roneysilva25/test 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/algorithms/Algorithm.interface.d.ts +15 -0
- package/dist/algorithms/Algorithm.interface.d.ts.map +1 -0
- package/dist/algorithms/Algorithm.interface.js +2 -0
- package/dist/algorithms/Algorithm.interface.js.map +1 -0
- package/dist/algorithms/FixedWindow.d.ts +10 -0
- package/dist/algorithms/FixedWindow.d.ts.map +1 -0
- package/dist/algorithms/FixedWindow.interfaces.d.ts +6 -0
- package/dist/algorithms/FixedWindow.interfaces.d.ts.map +1 -0
- package/dist/algorithms/FixedWindow.interfaces.js +2 -0
- package/dist/algorithms/FixedWindow.interfaces.js.map +1 -0
- package/dist/algorithms/FixedWindow.js +37 -0
- package/dist/algorithms/FixedWindow.js.map +1 -0
- package/dist/controllers/RateLimiterController.d.ts +7 -0
- package/dist/controllers/RateLimiterController.d.ts.map +1 -0
- package/dist/controllers/RateLimiterController.interfaces.d.ts +26 -0
- package/dist/controllers/RateLimiterController.interfaces.d.ts.map +1 -0
- package/dist/controllers/RateLimiterController.interfaces.js +2 -0
- package/dist/controllers/RateLimiterController.interfaces.js.map +1 -0
- package/dist/controllers/RateLimiterController.js +17 -0
- package/dist/controllers/RateLimiterController.js.map +1 -0
- package/dist/db/Storage.d.ts +10 -0
- package/dist/db/Storage.d.ts.map +1 -0
- package/dist/db/Storage.interfaces.d.ts +6 -0
- package/dist/db/Storage.interfaces.d.ts.map +1 -0
- package/dist/db/Storage.interfaces.js +2 -0
- package/dist/db/Storage.interfaces.js.map +1 -0
- package/dist/db/Storage.js +20 -0
- package/dist/db/Storage.js.map +1 -0
- package/dist/factories/AlgorithmFactory.d.ts +6 -0
- package/dist/factories/AlgorithmFactory.d.ts.map +1 -0
- package/dist/factories/AlgorithmFactory.interfaces.d.ts +11 -0
- package/dist/factories/AlgorithmFactory.interfaces.d.ts.map +1 -0
- package/dist/factories/AlgorithmFactory.interfaces.js +2 -0
- package/dist/factories/AlgorithmFactory.interfaces.js.map +1 -0
- package/dist/factories/AlgorithmFactory.js +12 -0
- package/dist/factories/AlgorithmFactory.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +9 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +2 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/test/FixedWindow.test.d.ts +2 -0
- package/dist/test/FixedWindow.test.d.ts.map +1 -0
- package/dist/test/FixedWindow.test.js +100 -0
- package/dist/test/FixedWindow.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Storage } from "../db/Storage.js";
|
|
2
|
+
import type { PacketPayload } from "./FixedWindow.interfaces.js";
|
|
3
|
+
export interface HandleArgs {
|
|
4
|
+
packetKey: string;
|
|
5
|
+
forwardCb: (packetInfo: PacketPayload) => void;
|
|
6
|
+
dropCb: (packetInfo: PacketPayload) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface Algorithm {
|
|
9
|
+
readonly storage: typeof Storage;
|
|
10
|
+
capacity: number;
|
|
11
|
+
timeWindowInMs: number;
|
|
12
|
+
handle: (args: HandleArgs) => void;
|
|
13
|
+
}
|
|
14
|
+
export type AlgorithmConstructorArgs = Omit<Algorithm, "handle">;
|
|
15
|
+
//# sourceMappingURL=Algorithm.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Algorithm.interface.d.ts","sourceRoot":"","sources":["../../src/algorithms/Algorithm.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,WAAW,UAAU;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,MAAM,EAAC,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,OAAO,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Algorithm.interface.js","sourceRoot":"","sources":["../../src/algorithms/Algorithm.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Storage } from "../db/Storage.js";
|
|
2
|
+
import type { HandleArgs, Algorithm, AlgorithmConstructorArgs } from "./Algorithm.interface.js";
|
|
3
|
+
export declare class FixedWindow implements Algorithm {
|
|
4
|
+
capacity: number;
|
|
5
|
+
timeWindowInMs: number;
|
|
6
|
+
storage: typeof Storage;
|
|
7
|
+
constructor({ capacity, timeWindowInMs, storage, }: AlgorithmConstructorArgs);
|
|
8
|
+
handle({ packetKey, forwardCb, dropCb }: HandleArgs): void;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=FixedWindow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedWindow.d.ts","sourceRoot":"","sources":["../../src/algorithms/FixedWindow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEhG,qBAAa,WAAY,YAAW,SAAS;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,OAAO,CAAC;gBAEZ,EACR,QAAQ,EACR,cAAc,EACd,OAAO,GACV,EAAE,wBAAwB;IAM3B,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU;CA8BtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedWindow.interfaces.d.ts","sourceRoot":"","sources":["../../src/algorithms/FixedWindow.interfaces.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,OAAO,EACH,KAAK,aAAa,GACrB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedWindow.interfaces.js","sourceRoot":"","sources":["../../src/algorithms/FixedWindow.interfaces.ts"],"names":[],"mappings":"AAKA,OAAO,EAEN,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Storage } from "../db/Storage.js";
|
|
2
|
+
export class FixedWindow {
|
|
3
|
+
capacity;
|
|
4
|
+
timeWindowInMs;
|
|
5
|
+
storage;
|
|
6
|
+
constructor({ capacity, timeWindowInMs, storage, }) {
|
|
7
|
+
this.capacity = capacity;
|
|
8
|
+
this.timeWindowInMs = timeWindowInMs;
|
|
9
|
+
this.storage = storage;
|
|
10
|
+
}
|
|
11
|
+
handle({ packetKey, forwardCb, dropCb }) {
|
|
12
|
+
const existingPacket = this.storage.retrieve(packetKey);
|
|
13
|
+
const currentTime = new Date().getTime();
|
|
14
|
+
if (!existingPacket || currentTime - existingPacket.createdAt >= this.timeWindowInMs) {
|
|
15
|
+
const createdPacket = this.storage.store({
|
|
16
|
+
key: packetKey,
|
|
17
|
+
payload: {
|
|
18
|
+
createdAt: currentTime,
|
|
19
|
+
allowance: this.capacity - 1,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
return forwardCb(createdPacket);
|
|
23
|
+
}
|
|
24
|
+
if (existingPacket.allowance - 1 >= 0) {
|
|
25
|
+
const updatedPacket = this.storage.store({
|
|
26
|
+
key: packetKey,
|
|
27
|
+
payload: {
|
|
28
|
+
createdAt: existingPacket.createdAt,
|
|
29
|
+
allowance: existingPacket.allowance - 1,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return forwardCb(updatedPacket);
|
|
33
|
+
}
|
|
34
|
+
return dropCb(existingPacket);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=FixedWindow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedWindow.js","sourceRoot":"","sources":["../../src/algorithms/FixedWindow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,MAAM,OAAO,WAAW;IACpB,QAAQ,CAAS;IACjB,cAAc,CAAS;IACvB,OAAO,CAAiB;IAExB,YAAY,EACR,QAAQ,EACR,cAAc,EACd,OAAO,GACgB;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAc;QAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAgB,SAAS,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QAEzC,IAAI,CAAC,cAAc,IAAI,WAAW,GAAG,cAAc,CAAC,SAAS,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACnF,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAgB;gBACpD,GAAG,EAAE,SAAS;gBACd,OAAO,EAAE;oBACL,SAAS,EAAE,WAAW;oBACtB,SAAS,EAAE,IAAI,CAAC,QAAQ,GAAG,CAAC;iBAC/B;aACJ,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC,aAAa,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,cAAc,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAgB;gBACpD,GAAG,EAAE,SAAS;gBACd,OAAO,EAAE;oBACL,SAAS,EAAE,cAAc,CAAC,SAAS;oBACnC,SAAS,EAAE,cAAc,CAAC,SAAS,GAAG,CAAC;iBAC1C;aACJ,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC,aAAa,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;CACJ"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DropArgs, ForwardArgs } from "./RateLimiterController.interfaces.js";
|
|
2
|
+
export declare class RateLimiterController {
|
|
3
|
+
private configResponseHeaders;
|
|
4
|
+
drop({ res, req, packetInfo, limiterInfo }: DropArgs): import("express").Response<any, Record<string, any>>;
|
|
5
|
+
forward({ req, res, next, packetInfo, limiterInfo }: ForwardArgs): void;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=RateLimiterController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiterController.d.ts","sourceRoot":"","sources":["../../src/controllers/RateLimiterController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,QAAQ,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAE1G,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,qBAAqB;IAOtB,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,QAAQ;IAKpD,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,WAAW;CAI1E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PacketPayload } from "../algorithms/FixedWindow.interfaces.js";
|
|
2
|
+
import type { NextFunction, Response, Request } from "express";
|
|
3
|
+
interface LimiterInfo {
|
|
4
|
+
capacity: number;
|
|
5
|
+
timeWindowInMs: number;
|
|
6
|
+
}
|
|
7
|
+
interface ConfigResponseHeaders {
|
|
8
|
+
res: Response;
|
|
9
|
+
packetInfo: PacketPayload;
|
|
10
|
+
limiterInfo: LimiterInfo;
|
|
11
|
+
}
|
|
12
|
+
interface DropArgs {
|
|
13
|
+
req: Request;
|
|
14
|
+
res: Response;
|
|
15
|
+
packetInfo: PacketPayload;
|
|
16
|
+
limiterInfo: LimiterInfo;
|
|
17
|
+
}
|
|
18
|
+
interface ForwardArgs {
|
|
19
|
+
req: Request;
|
|
20
|
+
res: Response;
|
|
21
|
+
next: NextFunction;
|
|
22
|
+
packetInfo: PacketPayload;
|
|
23
|
+
limiterInfo: LimiterInfo;
|
|
24
|
+
}
|
|
25
|
+
export type { ConfigResponseHeaders, DropArgs, ForwardArgs, };
|
|
26
|
+
//# sourceMappingURL=RateLimiterController.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiterController.interfaces.d.ts","sourceRoot":"","sources":["../../src/controllers/RateLimiterController.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAG,MAAM,SAAS,CAAC;AAEhE,UAAU,WAAW;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,qBAAqB;IAC3B,GAAG,EAAE,QAAQ,CAAC;IACd,UAAU,EAAE,aAAa,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED,UAAU,QAAQ;IACd,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;IACd,UAAU,EAAE,aAAa,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED,UAAU,WAAW;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,aAAa,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED,YAAY,EACR,qBAAqB,EACrB,QAAQ,EACR,WAAW,GACd,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiterController.interfaces.js","sourceRoot":"","sources":["../../src/controllers/RateLimiterController.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class RateLimiterController {
|
|
2
|
+
configResponseHeaders({ limiterInfo, packetInfo, res }) {
|
|
3
|
+
const resetsIn = limiterInfo.timeWindowInMs + packetInfo.createdAt - new Date().getTime();
|
|
4
|
+
res.setHeader("X-RateLimit-Limit", limiterInfo.capacity);
|
|
5
|
+
res.setHeader("X-RateLimit-Remaining", packetInfo.allowance);
|
|
6
|
+
res.setHeader("X-RateLimit-Reset", resetsIn);
|
|
7
|
+
}
|
|
8
|
+
drop({ res, req, packetInfo, limiterInfo }) {
|
|
9
|
+
this.configResponseHeaders({ res, limiterInfo, packetInfo });
|
|
10
|
+
return res.status(429).send();
|
|
11
|
+
}
|
|
12
|
+
forward({ req, res, next, packetInfo, limiterInfo }) {
|
|
13
|
+
this.configResponseHeaders({ res, limiterInfo, packetInfo });
|
|
14
|
+
next();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=RateLimiterController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiterController.js","sourceRoot":"","sources":["../../src/controllers/RateLimiterController.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,qBAAqB;IACtB,qBAAqB,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAA0B;QAClF,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,GAAG,UAAU,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QAC1F,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;QACzD,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7D,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IACjD,CAAC;IAEM,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAY;QACvD,IAAI,CAAC,qBAAqB,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAEM,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAe;QACnE,IAAI,CAAC,qBAAqB,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;QAC7D,IAAI,EAAE,CAAC;IACX,CAAC;CACJ"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { StoreArgs } from "./Storage.interfaces.js";
|
|
2
|
+
export declare class Storage {
|
|
3
|
+
private static instance;
|
|
4
|
+
private storage;
|
|
5
|
+
private constructor();
|
|
6
|
+
private static getInstance;
|
|
7
|
+
static store<Payload>({ key, payload }: StoreArgs<Payload>): Payload;
|
|
8
|
+
static retrieve<Payload>(key: string): Payload | undefined;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=Storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Storage.d.ts","sourceRoot":"","sources":["../../src/db/Storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,qBAAa,OAAO;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAU;IACjC,OAAO,CAAC,OAAO,CAAmB;IAElC,OAAO;IAIP,OAAO,CAAC,MAAM,CAAC,WAAW;WAQZ,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO;WAI7D,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;CAGpE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Storage.interfaces.d.ts","sourceRoot":"","sources":["../../src/db/Storage.interfaces.ts"],"names":[],"mappings":"AAAA,UAAU,SAAS,CAAC,OAAO;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CACpB;AAED,OAAO,EACH,KAAK,SAAS,GACjB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Storage.interfaces.js","sourceRoot":"","sources":["../../src/db/Storage.interfaces.ts"],"names":[],"mappings":"AAKA,OAAO,EAEN,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class Storage {
|
|
2
|
+
static instance;
|
|
3
|
+
storage;
|
|
4
|
+
constructor() {
|
|
5
|
+
this.storage = new Map();
|
|
6
|
+
}
|
|
7
|
+
static getInstance() {
|
|
8
|
+
if (!this.instance) {
|
|
9
|
+
this.instance = new Storage();
|
|
10
|
+
}
|
|
11
|
+
return this.instance;
|
|
12
|
+
}
|
|
13
|
+
static store({ key, payload }) {
|
|
14
|
+
return this.getInstance().storage.set(key, payload).get(key);
|
|
15
|
+
}
|
|
16
|
+
static retrieve(key) {
|
|
17
|
+
return this.getInstance().storage.get(key);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=Storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Storage.js","sourceRoot":"","sources":["../../src/db/Storage.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,OAAO;IACR,MAAM,CAAC,QAAQ,CAAU;IACzB,OAAO,CAAmB;IAElC;QACI,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC7B,CAAC;IAEO,MAAM,CAAC,WAAW;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,EAAE,CAAC;QAClC,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAU,EAAE,GAAG,EAAE,OAAO,EAAsB;QAC7D,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjE,CAAC;IAEM,MAAM,CAAC,QAAQ,CAAU,GAAW;QACvC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;CACJ"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Algorithm } from "../algorithms/Algorithm.interface.js";
|
|
2
|
+
import type { GetArgs, IAlgorithmFactory } from "./AlgorithmFactory.interfaces.js";
|
|
3
|
+
export declare class AlgorithmFactory implements IAlgorithmFactory {
|
|
4
|
+
get({ algorithm, config }: GetArgs): Algorithm;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=AlgorithmFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlgorithmFactory.d.ts","sourceRoot":"","sources":["../../src/factories/AlgorithmFactory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAEnF,qBAAa,gBAAiB,YAAW,iBAAiB;IAC/C,GAAG,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,GAAG,SAAS;CAQxD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Algorithm, AlgorithmConstructorArgs } from "../algorithms/Algorithm.interface.js";
|
|
2
|
+
type Algorithms = "fixed_window";
|
|
3
|
+
interface GetArgs {
|
|
4
|
+
algorithm: Algorithms;
|
|
5
|
+
config: AlgorithmConstructorArgs;
|
|
6
|
+
}
|
|
7
|
+
interface IAlgorithmFactory {
|
|
8
|
+
get(args: GetArgs): Algorithm;
|
|
9
|
+
}
|
|
10
|
+
export { type IAlgorithmFactory, type GetArgs, };
|
|
11
|
+
//# sourceMappingURL=AlgorithmFactory.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlgorithmFactory.interfaces.d.ts","sourceRoot":"","sources":["../../src/factories/AlgorithmFactory.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAEhG,KAAK,UAAU,GAAG,cAAc,CAAC;AAEjC,UAAU,OAAO;IACb,SAAS,EAAE,UAAU,CAAC;IACtB,MAAM,EAAE,wBAAwB,CAAC;CACpC;AAED,UAAU,iBAAiB;IACvB,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,OAAO,GACf,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlgorithmFactory.interfaces.js","sourceRoot":"","sources":["../../src/factories/AlgorithmFactory.interfaces.ts"],"names":[],"mappings":"AAaA,OAAO,EAGN,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FixedWindow } from "../algorithms/FixedWindow.js";
|
|
2
|
+
export class AlgorithmFactory {
|
|
3
|
+
get({ algorithm, config }) {
|
|
4
|
+
switch (algorithm) {
|
|
5
|
+
case "fixed_window":
|
|
6
|
+
return new FixedWindow(config);
|
|
7
|
+
default:
|
|
8
|
+
throw new Error(`Unknown algorithm: ${algorithm}.`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=AlgorithmFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlgorithmFactory.js","sourceRoot":"","sources":["../../src/factories/AlgorithmFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,MAAM,OAAO,gBAAgB;IAClB,GAAG,CAAC,EAAE,SAAS,EAAE,MAAM,EAAW;QACrC,QAAQ,SAAS,EAAE,CAAC;YAChB,KAAK,cAAc;gBACf,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;YACnC;gBACI,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,GAAG,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC;CACJ"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from "express";
|
|
2
|
+
import type { RateLimiterArgs } from "./interfaces.js";
|
|
3
|
+
declare function rateLimiter({ algorithm, capacity, timeWindowInMs, storage }: RateLimiterArgs): {
|
|
4
|
+
limit(req: Request, res: Response, next: NextFunction): void;
|
|
5
|
+
};
|
|
6
|
+
export { rateLimiter, };
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQvD,iBAAS,WAAW,CAAC,EACjB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,OAAiB,EACpB,EAAE,eAAe;eAYC,OAAO,OAAO,QAAQ,QAAQ,YAAY;EA2B5D;AAED,OAAO,EACH,WAAW,GACd,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Storage } from "./db/Storage.js";
|
|
2
|
+
import { RateLimiterController } from "./controllers/RateLimiterController.js";
|
|
3
|
+
import { AlgorithmFactory } from "./factories/AlgorithmFactory.js";
|
|
4
|
+
function validateIP(req, res) {
|
|
5
|
+
if (!req.ip) {
|
|
6
|
+
return res.status(400).send("Invalid IP Address.");
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function rateLimiter({ algorithm, capacity, timeWindowInMs, storage = Storage }) {
|
|
10
|
+
const controller = new RateLimiterController();
|
|
11
|
+
const algFactory = new AlgorithmFactory().get({
|
|
12
|
+
algorithm,
|
|
13
|
+
config: {
|
|
14
|
+
timeWindowInMs,
|
|
15
|
+
storage,
|
|
16
|
+
capacity,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
limit(req, res, next) {
|
|
21
|
+
validateIP(req, res);
|
|
22
|
+
return algFactory.handle({
|
|
23
|
+
packetKey: req.ip,
|
|
24
|
+
dropCb: (packetInfo) => controller.drop({
|
|
25
|
+
req,
|
|
26
|
+
res,
|
|
27
|
+
packetInfo,
|
|
28
|
+
limiterInfo: {
|
|
29
|
+
capacity,
|
|
30
|
+
timeWindowInMs,
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
forwardCb: (packetInfo) => controller.forward({
|
|
34
|
+
req,
|
|
35
|
+
res,
|
|
36
|
+
next,
|
|
37
|
+
packetInfo,
|
|
38
|
+
limiterInfo: {
|
|
39
|
+
capacity,
|
|
40
|
+
timeWindowInMs,
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export { rateLimiter, };
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE,SAAS,UAAU,CAAC,GAAY,EAAE,GAAa;IAC3C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACvD,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,EACjB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,OAAO,GAAG,OAAO,EACH;IACd,MAAM,UAAU,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,gBAAgB,EAAE,CAAC,GAAG,CAAC;QAC1C,SAAS;QACT,MAAM,EAAE;YACJ,cAAc;YACd,OAAO;YACP,QAAQ;SACX;KACJ,CAAC,CAAC;IAEH,OAAO;QACH,KAAK,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;YACjD,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAErB,OAAO,UAAU,CAAC,MAAM,CAAC;gBACrB,SAAS,EAAE,GAAG,CAAC,EAAY;gBAC3B,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;oBACpC,GAAG;oBACH,GAAG;oBACH,UAAU;oBACV,WAAW,EAAE;wBACT,QAAQ;wBACR,cAAc;qBACjB;iBACJ,CAAC;gBACF,SAAS,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;oBAC1C,GAAG;oBACH,GAAG;oBACH,IAAI;oBACJ,UAAU;oBACV,WAAW,EAAE;wBACT,QAAQ;wBACR,cAAc;qBACjB;iBACJ,CAAC;aACL,CAAC,CAAC;QACP,CAAC;KACJ,CAAA;AACL,CAAC;AAED,OAAO,EACH,WAAW,GACd,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,UAAU,eAAe;IACrB,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC;CAC5B;AAED,YAAY,EACR,eAAe,EAClB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedWindow.test.d.ts","sourceRoot":"","sources":["../../src/test/FixedWindow.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { FixedWindow } from "../algorithms/FixedWindow.js";
|
|
2
|
+
describe("FixedWindow", () => {
|
|
3
|
+
afterEach(() => {
|
|
4
|
+
jest.clearAllMocks();
|
|
5
|
+
});
|
|
6
|
+
const mockGetTime = jest.fn();
|
|
7
|
+
const mockStore = jest.fn();
|
|
8
|
+
const mockRetrieve = jest.fn();
|
|
9
|
+
const mockStorage = {
|
|
10
|
+
store: mockStore,
|
|
11
|
+
retrieve: mockRetrieve,
|
|
12
|
+
};
|
|
13
|
+
const mockDropCb = jest.fn();
|
|
14
|
+
const mockForwardCb = jest.fn();
|
|
15
|
+
const fixedWindowArgs = {
|
|
16
|
+
capacity: 200,
|
|
17
|
+
timeWindowInMs: 1000 * 60 * 2,
|
|
18
|
+
storage: mockStorage,
|
|
19
|
+
};
|
|
20
|
+
//@ts-ignore
|
|
21
|
+
const fixedWindow = new FixedWindow(fixedWindowArgs);
|
|
22
|
+
jest.spyOn(Date.prototype, "getTime").mockImplementation(mockGetTime);
|
|
23
|
+
it("should create a packet with maximum allowance, the current timestamp and call forwardCb, all if the packet does not exist yet ", () => {
|
|
24
|
+
const createdPacket = {
|
|
25
|
+
key: "packetKey",
|
|
26
|
+
payload: {
|
|
27
|
+
createdAt: 1,
|
|
28
|
+
allowance: fixedWindowArgs.capacity - 1,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
mockGetTime.mockReturnValueOnce(1);
|
|
32
|
+
mockRetrieve.mockReturnValueOnce(undefined);
|
|
33
|
+
mockStore.mockReturnValueOnce(createdPacket);
|
|
34
|
+
fixedWindow.handle({
|
|
35
|
+
packetKey: "packetKey",
|
|
36
|
+
dropCb: mockDropCb,
|
|
37
|
+
forwardCb: mockForwardCb,
|
|
38
|
+
});
|
|
39
|
+
expect(mockStore).toHaveBeenCalledWith(createdPacket);
|
|
40
|
+
expect(mockForwardCb).toHaveBeenCalledWith(createdPacket);
|
|
41
|
+
});
|
|
42
|
+
it("should update an existing packet with reset allowance and timestamp, and call forwardCb if the time window has passed", () => {
|
|
43
|
+
const resetAllowance = fixedWindowArgs.capacity - 1;
|
|
44
|
+
const updatedPacket = {
|
|
45
|
+
createdAt: fixedWindowArgs.timeWindowInMs,
|
|
46
|
+
allowance: resetAllowance,
|
|
47
|
+
};
|
|
48
|
+
const currentTimestamp = fixedWindowArgs.timeWindowInMs;
|
|
49
|
+
mockGetTime.mockReturnValueOnce(currentTimestamp);
|
|
50
|
+
mockRetrieve.mockReturnValueOnce({
|
|
51
|
+
createdAt: 0,
|
|
52
|
+
allowance: 10,
|
|
53
|
+
});
|
|
54
|
+
mockStore.mockReturnValueOnce(updatedPacket);
|
|
55
|
+
fixedWindow.handle({
|
|
56
|
+
packetKey: "packetKey",
|
|
57
|
+
dropCb: mockDropCb,
|
|
58
|
+
forwardCb: mockForwardCb,
|
|
59
|
+
});
|
|
60
|
+
expect(mockForwardCb).toHaveBeenCalledWith(updatedPacket);
|
|
61
|
+
});
|
|
62
|
+
it("should update an existing packet, decreasing its allowance by 1 and keeping the same createdAt timestamp, when the allowance has not reached 0 (zero)", () => {
|
|
63
|
+
const foundPacket = {
|
|
64
|
+
createdAt: 10,
|
|
65
|
+
allowance: 4,
|
|
66
|
+
};
|
|
67
|
+
const updatedPacket = {
|
|
68
|
+
createdAt: foundPacket.createdAt,
|
|
69
|
+
allowance: 3,
|
|
70
|
+
};
|
|
71
|
+
mockGetTime.mockReturnValueOnce(foundPacket.createdAt + 1);
|
|
72
|
+
mockRetrieve.mockReturnValueOnce(foundPacket);
|
|
73
|
+
mockStore.mockReturnValueOnce(updatedPacket);
|
|
74
|
+
fixedWindow.handle({
|
|
75
|
+
packetKey: "packetKey",
|
|
76
|
+
dropCb: mockDropCb,
|
|
77
|
+
forwardCb: mockForwardCb,
|
|
78
|
+
});
|
|
79
|
+
expect(mockStore).toHaveBeenCalledWith({
|
|
80
|
+
key: "packetKey",
|
|
81
|
+
payload: updatedPacket,
|
|
82
|
+
});
|
|
83
|
+
expect(mockForwardCb).toHaveBeenCalledWith(updatedPacket);
|
|
84
|
+
});
|
|
85
|
+
it("should call the dropCb when the allowance has already reached zero.", () => {
|
|
86
|
+
const foundPacket = {
|
|
87
|
+
createdAt: 10,
|
|
88
|
+
allowance: 0,
|
|
89
|
+
};
|
|
90
|
+
mockGetTime.mockReturnValueOnce(foundPacket.createdAt + 10);
|
|
91
|
+
mockRetrieve.mockReturnValueOnce(foundPacket);
|
|
92
|
+
fixedWindow.handle({
|
|
93
|
+
packetKey: "packetKey",
|
|
94
|
+
dropCb: mockDropCb,
|
|
95
|
+
forwardCb: mockForwardCb,
|
|
96
|
+
});
|
|
97
|
+
expect(mockDropCb).toHaveBeenCalledWith(foundPacket);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=FixedWindow.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedWindow.test.js","sourceRoot":"","sources":["../../src/test/FixedWindow.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roneysilva25/test",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Implementation of the most common rate limiting algorithms: Fixed Window, Sliding Window, Leaky Bucket, Token Bucket. To be used as middleware for express applications.",
|
|
5
5
|
"homepage": "https://github.com/roneysilva25/rate-limiter#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"author": "Roney Silva <roney.diego000@gmail.com> (https://roneysilva25.github.io/portfolio)",
|
|
15
15
|
"type": "module",
|
|
16
|
-
"main": "./index.js",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
17
|
"files": ["dist"],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"test": "npx jest --watch",
|