tiny-essentials 1.8.4 → 1.9.0
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/TinyBasicsEs.js +30 -0
- package/dist/TinyBasicsEs.min.js +1 -1
- package/dist/TinyEssentials.js +229 -0
- package/dist/TinyEssentials.min.js +1 -1
- package/dist/TinyRateLimiter.js +236 -0
- package/dist/TinyRateLimiter.min.js +1 -0
- package/dist/legacy/crypto/decrypt.cjs +1 -1
- package/dist/legacy/crypto/decrypt.mjs +3 -3
- package/dist/legacy/crypto/default.cjs +0 -2
- package/dist/legacy/crypto/default.mjs +0 -1
- package/dist/legacy/crypto/encrypt.cjs +1 -2
- package/dist/legacy/crypto/encrypt.mjs +3 -4
- package/dist/legacy/crypto/index.cjs +1 -1
- package/dist/legacy/crypto/index.mjs +0 -1
- package/dist/legacy/firebase/database/presence.cjs +4 -1
- package/dist/legacy/firebase/database/presence.d.mts +3 -0
- package/dist/legacy/firebase/database/presence.mjs +4 -1
- package/dist/legacy/firebase/databaseLogger.cjs +2 -2
- package/dist/legacy/firebase/discord/get/cookie-session.cjs +2 -2
- package/dist/legacy/firebase/discord/get/errorValidator.cjs +2 -2
- package/dist/legacy/firebase/discord/http/login.cjs +7 -7
- package/dist/legacy/firebase/discord/http/logout.cjs +4 -4
- package/dist/legacy/firebase/discord/http/redirect.cjs +7 -7
- package/dist/legacy/firebase/discord/http/refreshToken.cjs +5 -5
- package/dist/legacy/firebase/discord/template/cookie-session.cjs +8 -8
- package/dist/legacy/firebase/logger.cjs +7 -7
- package/dist/legacy/firebase/mySQL.cjs +1 -0
- package/dist/legacy/firebase/mysqlConnector/sameUser.cjs +2 -2
- package/dist/legacy/get/countObj.cjs +2 -22
- package/dist/legacy/get/countObj.d.mts +2 -11
- package/dist/legacy/get/countObj.mjs +2 -22
- package/dist/legacy/get/decimalColor.cjs +10 -11
- package/dist/legacy/get/decimalColor.mjs +10 -10
- package/dist/legacy/get/objType.cjs +2 -40
- package/dist/legacy/get/objType.d.mts +2 -19
- package/dist/legacy/get/objType.mjs +2 -41
- package/dist/legacy/get/pagination.cjs +30 -25
- package/dist/legacy/get/pagination.d.mts +29 -12
- package/dist/legacy/get/pagination.mjs +30 -23
- package/dist/legacy/get/queryUrlByName.cjs +0 -2
- package/dist/legacy/get/queryUrlByName.mjs +0 -1
- package/dist/legacy/get/queryUrlJSON.cjs +2 -2
- package/dist/legacy/get/queryUrlJSON.mjs +1 -1
- package/dist/legacy/get/super_string_filter.cjs +14 -6
- package/dist/legacy/get/super_string_filter.mjs +11 -1
- package/dist/legacy/get/versionCheck.cjs +18 -19
- package/dist/legacy/get/versionCheck.d.mts +15 -5
- package/dist/legacy/get/versionCheck.mjs +16 -16
- package/dist/legacy/http/HTTP-1.0.cjs +2 -4
- package/dist/legacy/http/HTTP-1.0.d.mts +1 -1
- package/dist/legacy/http/HTTP-1.0.mjs +2 -3
- package/dist/legacy/http/auth.cjs +2 -4
- package/dist/legacy/http/auth.d.mts +4 -4
- package/dist/legacy/http/auth.mjs +2 -3
- package/dist/legacy/http/check_domain.cjs +15 -9
- package/dist/legacy/http/check_domain.d.mts +5 -6
- package/dist/legacy/http/check_domain.mjs +12 -8
- package/dist/legacy/http/csrfTokenAnalyze.cjs +5 -4
- package/dist/legacy/http/csrfTokenAnalyze.d.mts +3 -3
- package/dist/legacy/http/csrfTokenAnalyze.mjs +7 -4
- package/dist/legacy/http/domainValidator.cjs +13 -9
- package/dist/legacy/http/domainValidator.d.mts +15 -6
- package/dist/legacy/http/domainValidator.mjs +11 -6
- package/dist/legacy/http/errorsCallback.cjs +10 -4
- package/dist/legacy/http/errorsCallback.d.mts +13 -3
- package/dist/legacy/http/errorsCallback.mjs +12 -4
- package/dist/legacy/http/fetch/json.cjs +1 -3
- package/dist/legacy/http/fetch/json.mjs +1 -1
- package/dist/legacy/http/fetch/text.cjs +1 -3
- package/dist/legacy/http/fetch/text.mjs +1 -1
- package/dist/legacy/http/fileCache.cjs +2 -5
- package/dist/legacy/http/fileCache.d.mts +3 -3
- package/dist/legacy/http/fileCache.mjs +2 -3
- package/dist/legacy/http/getDomainURL.cjs +4 -7
- package/dist/legacy/http/getDomainURL.d.mts +2 -2
- package/dist/legacy/http/getDomainURL.mjs +4 -5
- package/dist/legacy/http/userIP.cjs +7 -5
- package/dist/legacy/http/userIP.d.mts +10 -4
- package/dist/legacy/http/userIP.mjs +7 -4
- package/dist/legacy/index.cjs +3 -4
- package/dist/legacy/index.d.mts +8 -9
- package/dist/legacy/libs/arraySortPositions.cjs +1 -3
- package/dist/legacy/libs/arraySortPositions.d.mts +2 -2
- package/dist/legacy/libs/arraySortPositions.mjs +1 -2
- package/dist/legacy/libs/capitalize.cjs +0 -2
- package/dist/legacy/libs/capitalize.mjs +0 -1
- package/dist/legacy/libs/convertBytes.cjs +1 -3
- package/dist/legacy/libs/convertBytes.mjs +1 -2
- package/dist/legacy/libs/custom_module_loader.cjs +13 -9
- package/dist/legacy/libs/custom_module_loader.d.mts +1 -1
- package/dist/legacy/libs/custom_module_loader.mjs +10 -5
- package/dist/legacy/libs/dice.cjs +0 -2
- package/dist/legacy/libs/dice.mjs +0 -1
- package/dist/legacy/libs/markdown.cjs +13 -4
- package/dist/legacy/libs/markdown.d.mts +7 -71
- package/dist/legacy/libs/markdown.mjs +13 -3
- package/dist/legacy/libs/percentage.cjs +0 -2
- package/dist/legacy/libs/percentage.mjs +0 -1
- package/dist/legacy/libs/regex/getLetter.cjs +0 -2
- package/dist/legacy/libs/regex/getLetter.mjs +0 -1
- package/dist/legacy/libs/rule3.cjs +0 -2
- package/dist/legacy/libs/rule3.mjs +0 -1
- package/dist/legacy/momentjs/getAge.cjs +0 -3
- package/dist/legacy/momentjs/getAge.d.mts +1 -0
- package/dist/legacy/momentjs/getAge.mjs +0 -1
- package/dist/legacy/momentjs/index.cjs +1 -1
- package/dist/legacy/momentjs/index.mjs +0 -1
- package/dist/legacy/momentjs/timeDuration.cjs +1 -3
- package/dist/legacy/momentjs/timeDuration.d.mts +1 -0
- package/dist/legacy/momentjs/timeDuration.mjs +1 -1
- package/dist/legacy/socket.io/antiFlood/index.cjs +1 -1
- package/dist/legacy/socket.io/antiFlood/index.mjs +0 -1
- package/dist/legacy/socket.io/antiFlood/install.cjs +3 -5
- package/dist/legacy/socket.io/antiFlood/install.d.mts +5 -3
- package/dist/legacy/socket.io/antiFlood/install.mjs +3 -3
- package/dist/legacy/socket.io/antiFlood/verify.cjs +10 -6
- package/dist/legacy/socket.io/antiFlood/verify.d.mts +8 -3
- package/dist/legacy/socket.io/antiFlood/verify.mjs +10 -6
- package/dist/legacy/socket.io/cookie-session.cjs +1 -2
- package/dist/legacy/socket.io/cookie-session.mjs +1 -1
- package/dist/legacy/socket.io/discord.cjs +0 -3
- package/dist/legacy/socket.io/discord.mjs +0 -1
- package/dist/legacy/socket.io/index.cjs +0 -3
- package/dist/legacy/socket.io/index.mjs +0 -1
- package/dist/v1/basics/index.cjs +2 -0
- package/dist/v1/basics/index.d.mts +2 -1
- package/dist/v1/basics/index.mjs +2 -1
- package/dist/v1/build/TinyRateLimiter.cjs +7 -0
- package/dist/v1/build/TinyRateLimiter.d.mts +3 -0
- package/dist/v1/build/TinyRateLimiter.mjs +2 -0
- package/dist/v1/index.cjs +4 -0
- package/dist/v1/index.d.mts +3 -1
- package/dist/v1/index.mjs +3 -1
- package/dist/v1/libs/TinyRateLimit.cjs +196 -0
- package/dist/v1/libs/TinyRateLimit.d.mts +86 -0
- package/dist/v1/libs/TinyRateLimit.mjs +171 -0
- package/dist/v1/libs/TinyRateLimiter.cjs +197 -0
- package/dist/v1/libs/TinyRateLimiter.d.mts +86 -0
- package/dist/v1/libs/TinyRateLimiter.mjs +173 -0
- package/docs/README.md +1 -0
- package/docs/basics/array.md +61 -0
- package/docs/libs/TinyRateLimiter.md +156 -0
- package/package.json +9 -2
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var moment = require('moment');
|
|
4
4
|
|
|
5
|
-
// @ts-nocheck
|
|
6
|
-
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
6
|
* Calculates the time duration between the current time and a given time offset.
|
|
10
7
|
*
|
|
@@ -19,6 +16,7 @@ function timeDuration(timeData = 0, durationType = 'asSeconds', now = null) {
|
|
|
19
16
|
if (!now) now = moment();
|
|
20
17
|
|
|
21
18
|
var duration = moment.duration(now.clone().add(timeData, 'milliseconds').diff(now.clone()));
|
|
19
|
+
// @ts-ignore
|
|
22
20
|
const result = duration[durationType]();
|
|
23
21
|
|
|
24
22
|
// Complete
|
|
@@ -7,4 +7,5 @@
|
|
|
7
7
|
* @returns {number|null} The calculated duration in the specified unit (default: seconds), or `null` if `timeData` is not provided.
|
|
8
8
|
*/
|
|
9
9
|
export default function timeDuration(timeData?: number, durationType?: string, now?: moment.Moment | null): number | null;
|
|
10
|
+
import moment from 'moment';
|
|
10
11
|
//# sourceMappingURL=timeDuration.d.mts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import moment from 'moment';
|
|
3
2
|
/**
|
|
4
3
|
* Calculates the time duration between the current time and a given time offset.
|
|
@@ -14,6 +13,7 @@ export default function timeDuration(timeData = 0, durationType = 'asSeconds', n
|
|
|
14
13
|
if (!now)
|
|
15
14
|
now = moment();
|
|
16
15
|
var duration = moment.duration(now.clone().add(timeData, 'milliseconds').diff(now.clone()));
|
|
16
|
+
// @ts-ignore
|
|
17
17
|
const result = duration[durationType]();
|
|
18
18
|
// Complete
|
|
19
19
|
return result;
|
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
var userIP = require('../../http/userIP.cjs');
|
|
4
4
|
|
|
5
|
-
// @ts-nocheck
|
|
6
|
-
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
6
|
* Installs the authorization middleware for socket connections.
|
|
10
7
|
*
|
|
11
8
|
* This middleware checks the user's IP address and allows or denies the socket connection based on whether
|
|
12
9
|
* the IP is in the block list or not.
|
|
13
10
|
*
|
|
14
|
-
* @param {
|
|
15
|
-
* @param {
|
|
11
|
+
* @param {*} io - The Socket.IO server instance.
|
|
12
|
+
* @param {Object} ioCache - The cache object containing blocked IPs.
|
|
16
13
|
* @param {Array<*>} ioCache.blocklick - The list of blocked IP addresses.
|
|
17
14
|
* @returns {void} This function does not return a value, it just sets the authorization logic for socket connections.
|
|
18
15
|
*/
|
|
19
16
|
function install(io, ioCache) {
|
|
17
|
+
// @ts-ignore
|
|
20
18
|
io.set('authorization', function (socket, callback) {
|
|
21
19
|
// Get User IP
|
|
22
20
|
const ip = userIP(socket.handshake);
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
* This middleware checks the user's IP address and allows or denies the socket connection based on whether
|
|
5
5
|
* the IP is in the block list or not.
|
|
6
6
|
*
|
|
7
|
-
* @param {
|
|
8
|
-
* @param {
|
|
7
|
+
* @param {*} io - The Socket.IO server instance.
|
|
8
|
+
* @param {Object} ioCache - The cache object containing blocked IPs.
|
|
9
9
|
* @param {Array<*>} ioCache.blocklick - The list of blocked IP addresses.
|
|
10
10
|
* @returns {void} This function does not return a value, it just sets the authorization logic for socket connections.
|
|
11
11
|
*/
|
|
12
|
-
export default function install(io:
|
|
12
|
+
export default function install(io: any, ioCache: {
|
|
13
|
+
blocklick: Array<any>;
|
|
14
|
+
}): void;
|
|
13
15
|
//# sourceMappingURL=install.d.mts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import userIp from '../../http/userIP.mjs';
|
|
3
2
|
/**
|
|
4
3
|
* Installs the authorization middleware for socket connections.
|
|
@@ -6,12 +5,13 @@ import userIp from '../../http/userIP.mjs';
|
|
|
6
5
|
* This middleware checks the user's IP address and allows or denies the socket connection based on whether
|
|
7
6
|
* the IP is in the block list or not.
|
|
8
7
|
*
|
|
9
|
-
* @param {
|
|
10
|
-
* @param {
|
|
8
|
+
* @param {*} io - The Socket.IO server instance.
|
|
9
|
+
* @param {Object} ioCache - The cache object containing blocked IPs.
|
|
11
10
|
* @param {Array<*>} ioCache.blocklick - The list of blocked IP addresses.
|
|
12
11
|
* @returns {void} This function does not return a value, it just sets the authorization logic for socket connections.
|
|
13
12
|
*/
|
|
14
13
|
export default function install(io, ioCache) {
|
|
14
|
+
// @ts-ignore
|
|
15
15
|
io.set('authorization', function (socket, callback) {
|
|
16
16
|
// Get User IP
|
|
17
17
|
const ip = userIp(socket.handshake);
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var userIP = require('../../http/userIP.cjs');
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/** @typedef {Record<string, { timeout: number, tries: number }>} FloodTimeout */
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Panel
|
|
9
|
+
*
|
|
10
|
+
* @type {FloodTimeout}
|
|
11
|
+
*/
|
|
7
12
|
|
|
8
|
-
// Panel
|
|
9
13
|
const floodPanel = {};
|
|
10
14
|
|
|
11
15
|
/**
|
|
@@ -27,14 +31,14 @@ setInterval(function () {
|
|
|
27
31
|
* If the attempts exceed a threshold, the IP is temporarily banned and disconnected.
|
|
28
32
|
*
|
|
29
33
|
* @param {Record<string, any>} socket - The socket object representing the connection.
|
|
30
|
-
* @param {
|
|
34
|
+
* @param {Object} ioCache - The cache object that holds the blocklist and flood panel data.
|
|
31
35
|
* @param {Array<*>} ioCache.blocklick - The list of blocked IPs.
|
|
32
|
-
* @param {Record<string, any>} floodPanel - The object tracking flooding attempts and timeouts for each IP.
|
|
33
36
|
* @returns {void} This function does not return anything, it modifies the floodPanel and blocklist.
|
|
34
37
|
*/
|
|
35
38
|
function verify(socket, ioCache) {
|
|
36
39
|
// Get User IP
|
|
37
|
-
const
|
|
40
|
+
const ipData = userIP(socket.handshake);
|
|
41
|
+
const ip = ipData.value ? ipData.value[0] : '';
|
|
38
42
|
|
|
39
43
|
/**
|
|
40
44
|
* Verifies the IP for flooding attempts and manages timeout and blocklist.
|
|
@@ -71,7 +75,7 @@ function verify(socket, ioCache) {
|
|
|
71
75
|
|
|
72
76
|
// Catch-all Event Listener
|
|
73
77
|
var onevent = socket.onevent;
|
|
74
|
-
socket.onevent = function (packet) {
|
|
78
|
+
socket.onevent = function (/** @type {{ data: string[]; }} */ packet) {
|
|
75
79
|
var args = packet.data || [];
|
|
76
80
|
onevent.call(this, packet); // original call
|
|
77
81
|
packet.data = ['*'].concat(args);
|
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
* If the attempts exceed a threshold, the IP is temporarily banned and disconnected.
|
|
6
6
|
*
|
|
7
7
|
* @param {Record<string, any>} socket - The socket object representing the connection.
|
|
8
|
-
* @param {
|
|
8
|
+
* @param {Object} ioCache - The cache object that holds the blocklist and flood panel data.
|
|
9
9
|
* @param {Array<*>} ioCache.blocklick - The list of blocked IPs.
|
|
10
|
-
* @param {Record<string, any>} floodPanel - The object tracking flooding attempts and timeouts for each IP.
|
|
11
10
|
* @returns {void} This function does not return anything, it modifies the floodPanel and blocklist.
|
|
12
11
|
*/
|
|
13
|
-
export default function verify(socket: Record<string, any>, ioCache:
|
|
12
|
+
export default function verify(socket: Record<string, any>, ioCache: {
|
|
13
|
+
blocklick: Array<any>;
|
|
14
|
+
}): void;
|
|
15
|
+
export type FloodTimeout = Record<string, {
|
|
16
|
+
timeout: number;
|
|
17
|
+
tries: number;
|
|
18
|
+
}>;
|
|
14
19
|
//# sourceMappingURL=verify.d.mts.map
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import userIp from '../../http/userIP.mjs';
|
|
3
|
-
|
|
2
|
+
/** @typedef {Record<string, { timeout: number, tries: number }>} FloodTimeout */
|
|
3
|
+
/**
|
|
4
|
+
* Panel
|
|
5
|
+
*
|
|
6
|
+
* @type {FloodTimeout}
|
|
7
|
+
*/
|
|
4
8
|
const floodPanel = {};
|
|
5
9
|
/**
|
|
6
10
|
* Periodically decrements the timeout for each IP in the flood panel and removes expired entries.
|
|
@@ -21,14 +25,14 @@ setInterval(function () {
|
|
|
21
25
|
* If the attempts exceed a threshold, the IP is temporarily banned and disconnected.
|
|
22
26
|
*
|
|
23
27
|
* @param {Record<string, any>} socket - The socket object representing the connection.
|
|
24
|
-
* @param {
|
|
28
|
+
* @param {Object} ioCache - The cache object that holds the blocklist and flood panel data.
|
|
25
29
|
* @param {Array<*>} ioCache.blocklick - The list of blocked IPs.
|
|
26
|
-
* @param {Record<string, any>} floodPanel - The object tracking flooding attempts and timeouts for each IP.
|
|
27
30
|
* @returns {void} This function does not return anything, it modifies the floodPanel and blocklist.
|
|
28
31
|
*/
|
|
29
32
|
export default function verify(socket, ioCache) {
|
|
30
33
|
// Get User IP
|
|
31
|
-
const
|
|
34
|
+
const ipData = userIp(socket.handshake);
|
|
35
|
+
const ip = ipData.value ? ipData.value[0] : '';
|
|
32
36
|
/**
|
|
33
37
|
* Verifies the IP for flooding attempts and manages timeout and blocklist.
|
|
34
38
|
*/
|
|
@@ -59,7 +63,7 @@ export default function verify(socket, ioCache) {
|
|
|
59
63
|
}
|
|
60
64
|
// Catch-all Event Listener
|
|
61
65
|
var onevent = socket.onevent;
|
|
62
|
-
socket.onevent = function (packet) {
|
|
66
|
+
socket.onevent = function (/** @type {{ data: string[]; }} */ packet) {
|
|
63
67
|
var args = packet.data || [];
|
|
64
68
|
onevent.call(this, packet); // original call
|
|
65
69
|
packet.data = ['*'].concat(args);
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// @ts-nocheck
|
|
4
|
-
|
|
5
3
|
/**
|
|
6
4
|
* Handles the cookie session for a socket connection by simulating an Express request and response.
|
|
7
5
|
* This function uses the provided session module to manage session data for the socket connection.
|
|
@@ -13,6 +11,7 @@
|
|
|
13
11
|
function cookieSession(socket, sessionModule) {
|
|
14
12
|
return new Promise((resolve) => {
|
|
15
13
|
// Express Simulator
|
|
14
|
+
/** @type {Record<*,*>} */
|
|
16
15
|
let req = {
|
|
17
16
|
connection: { encrypted: false },
|
|
18
17
|
headers: { cookie: socket.request.headers.cookie },
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
/**
|
|
3
2
|
* Handles the cookie session for a socket connection by simulating an Express request and response.
|
|
4
3
|
* This function uses the provided session module to manage session data for the socket connection.
|
|
@@ -10,6 +9,7 @@
|
|
|
10
9
|
export default function cookieSession(socket, sessionModule) {
|
|
11
10
|
return new Promise((resolve) => {
|
|
12
11
|
// Express Simulator
|
|
12
|
+
/** @type {Record<*,*>} */
|
|
13
13
|
let req = {
|
|
14
14
|
connection: { encrypted: false },
|
|
15
15
|
headers: { cookie: socket.request.headers.cookie },
|
package/dist/v1/basics/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var arraySortPositions = require('../../legacy/libs/arraySortPositions.cjs');
|
|
3
4
|
var replaceAsync = require('../../legacy/libs/replaceAsync.cjs');
|
|
4
5
|
var array = require('./array.cjs');
|
|
5
6
|
var clock = require('./clock.cjs');
|
|
@@ -9,6 +10,7 @@ var text = require('./text.cjs');
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
exports.arraySortPositions = arraySortPositions;
|
|
12
14
|
exports.asyncReplace = replaceAsync;
|
|
13
15
|
exports.shuffleArray = array.shuffleArray;
|
|
14
16
|
exports.formatCustomTimer = clock.formatCustomTimer;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import arraySortPositions from '../../legacy/libs/arraySortPositions.mjs';
|
|
1
2
|
import { formatBytes } from './simpleMath.mjs';
|
|
2
3
|
import { addAiMarkerShortcut } from './text.mjs';
|
|
3
4
|
import { extendObjType } from './objFilter.mjs';
|
|
@@ -16,5 +17,5 @@ import { getTimeDuration } from './clock.mjs';
|
|
|
16
17
|
import { shuffleArray } from './array.mjs';
|
|
17
18
|
import { toTitleCase } from './text.mjs';
|
|
18
19
|
import { toTitleCaseLowerFirst } from './text.mjs';
|
|
19
|
-
export { formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
20
|
+
export { arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
20
21
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/v1/basics/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import arraySortPositions from '../../legacy/libs/arraySortPositions.mjs';
|
|
1
2
|
import asyncReplace from '../../legacy/libs/replaceAsync.mjs';
|
|
2
3
|
import { shuffleArray } from './array.mjs';
|
|
3
4
|
import { formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration } from './clock.mjs';
|
|
4
5
|
import { countObj, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, } from './objFilter.mjs';
|
|
5
6
|
import { formatBytes, getAge, getSimplePerc, ruleOfThree } from './simpleMath.mjs';
|
|
6
7
|
import { addAiMarkerShortcut, toTitleCase, toTitleCaseLowerFirst } from './text.mjs';
|
|
7
|
-
export { formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
|
|
8
|
+
export { arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
|
package/dist/v1/index.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var replaceAsync = require('../legacy/libs/replaceAsync.cjs');
|
|
4
4
|
var userLevel = require('../legacy/libs/userLevel.cjs');
|
|
5
|
+
var arraySortPositions = require('../legacy/libs/arraySortPositions.cjs');
|
|
5
6
|
var array = require('./basics/array.cjs');
|
|
6
7
|
var clock = require('./basics/clock.cjs');
|
|
7
8
|
var objFilter = require('./basics/objFilter.cjs');
|
|
@@ -9,11 +10,13 @@ var simpleMath = require('./basics/simpleMath.cjs');
|
|
|
9
10
|
var text = require('./basics/text.cjs');
|
|
10
11
|
var ColorSafeStringify = require('./libs/ColorSafeStringify.cjs');
|
|
11
12
|
var TinyPromiseQueue = require('./libs/TinyPromiseQueue.cjs');
|
|
13
|
+
var TinyRateLimiter = require('./libs/TinyRateLimiter.cjs');
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
exports.asyncReplace = replaceAsync;
|
|
16
18
|
exports.TinyLevelUp = userLevel;
|
|
19
|
+
exports.arraySortPositions = arraySortPositions;
|
|
17
20
|
exports.shuffleArray = array.shuffleArray;
|
|
18
21
|
exports.formatCustomTimer = clock.formatCustomTimer;
|
|
19
22
|
exports.formatDayTimer = clock.formatDayTimer;
|
|
@@ -34,3 +37,4 @@ exports.toTitleCase = text.toTitleCase;
|
|
|
34
37
|
exports.toTitleCaseLowerFirst = text.toTitleCaseLowerFirst;
|
|
35
38
|
exports.ColorSafeStringify = ColorSafeStringify;
|
|
36
39
|
exports.TinyPromiseQueue = TinyPromiseQueue;
|
|
40
|
+
exports.TinyRateLimiter = TinyRateLimiter;
|
package/dist/v1/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import TinyRateLimiter from './libs/TinyRateLimiter.mjs';
|
|
1
2
|
import ColorSafeStringify from './libs/ColorSafeStringify.mjs';
|
|
2
3
|
import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
|
|
3
4
|
import TinyLevelUp from '../legacy/libs/userLevel.mjs';
|
|
5
|
+
import arraySortPositions from '../legacy/libs/arraySortPositions.mjs';
|
|
4
6
|
import { formatBytes } from './basics/simpleMath.mjs';
|
|
5
7
|
import { addAiMarkerShortcut } from './basics/text.mjs';
|
|
6
8
|
import { extendObjType } from './basics/objFilter.mjs';
|
|
@@ -20,5 +22,5 @@ import { getTimeDuration } from './basics/clock.mjs';
|
|
|
20
22
|
import { shuffleArray } from './basics/array.mjs';
|
|
21
23
|
import { toTitleCase } from './basics/text.mjs';
|
|
22
24
|
import { toTitleCaseLowerFirst } from './basics/text.mjs';
|
|
23
|
-
export { ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
25
|
+
export { TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
24
26
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/v1/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import asyncReplace from '../legacy/libs/replaceAsync.mjs';
|
|
2
2
|
import TinyLevelUp from '../legacy/libs/userLevel.mjs';
|
|
3
|
+
import arraySortPositions from '../legacy/libs/arraySortPositions.mjs';
|
|
3
4
|
import { shuffleArray } from './basics/array.mjs';
|
|
4
5
|
import { formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, } from './basics/clock.mjs';
|
|
5
6
|
import { countObj, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, checkObj, } from './basics/objFilter.mjs';
|
|
@@ -7,4 +8,5 @@ import { formatBytes, getAge, getSimplePerc, ruleOfThree } from './basics/simple
|
|
|
7
8
|
import { addAiMarkerShortcut, toTitleCase, toTitleCaseLowerFirst } from './basics/text.mjs';
|
|
8
9
|
import ColorSafeStringify from './libs/ColorSafeStringify.mjs';
|
|
9
10
|
import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
|
|
10
|
-
|
|
11
|
+
import TinyRateLimiter from './libs/TinyRateLimiter.mjs';
|
|
12
|
+
export { TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Class representing a flexible rate limiter per user.
|
|
5
|
+
*
|
|
6
|
+
* This rate limiter can be configured by maximum number of hits,
|
|
7
|
+
* time interval, or a combination of both. It supports automatic
|
|
8
|
+
* cleanup of inactive users to optimize memory usage.
|
|
9
|
+
*
|
|
10
|
+
* @class
|
|
11
|
+
*/
|
|
12
|
+
class TinyRateLimiter {
|
|
13
|
+
/**
|
|
14
|
+
* @param {Object} options
|
|
15
|
+
* @param {number} [options.maxHits] - Max interactions allowed
|
|
16
|
+
* @param {number} [options.interval] - Time window in milliseconds
|
|
17
|
+
* @param {number} [options.cleanupInterval=60000] - Interval for automatic cleanup (ms)
|
|
18
|
+
* @param {number} [options.maxIdle=300000] - Max idle time for a user before being cleaned (ms)
|
|
19
|
+
*/
|
|
20
|
+
constructor({ maxHits, interval, cleanupInterval = 60000, maxIdle = 300000 }) {
|
|
21
|
+
/** @param {number|undefined} val */
|
|
22
|
+
const isPositiveInteger = (val) =>
|
|
23
|
+
typeof val === 'number' && Number.isFinite(val) && val >= 1 && Number.isInteger(val);
|
|
24
|
+
|
|
25
|
+
const isMaxHitsValid = isPositiveInteger(maxHits);
|
|
26
|
+
const isIntervalValid = isPositiveInteger(interval);
|
|
27
|
+
const isCleanupValid = isPositiveInteger(cleanupInterval);
|
|
28
|
+
const isMaxIdleValid = isPositiveInteger(maxIdle);
|
|
29
|
+
|
|
30
|
+
if (!isMaxHitsValid && !isIntervalValid)
|
|
31
|
+
throw new Error("RateLimiter requires at least one valid option: 'maxHits' or 'interval'.");
|
|
32
|
+
if (maxHits !== undefined && !isMaxHitsValid)
|
|
33
|
+
throw new Error("'maxHits' must be a positive integer if defined.");
|
|
34
|
+
if (interval !== undefined && !isIntervalValid)
|
|
35
|
+
throw new Error("'interval' must be a positive integer in milliseconds if defined.");
|
|
36
|
+
if (!isCleanupValid)
|
|
37
|
+
throw new Error("'cleanupInterval' must be a positive integer in milliseconds.");
|
|
38
|
+
if (!isMaxIdleValid) throw new Error("'maxIdle' must be a positive integer in milliseconds.");
|
|
39
|
+
|
|
40
|
+
this.maxHits = isMaxHitsValid ? maxHits : null;
|
|
41
|
+
this.interval = isIntervalValid ? interval : null;
|
|
42
|
+
this.cleanupInterval = cleanupInterval;
|
|
43
|
+
this.maxIdle = maxIdle;
|
|
44
|
+
|
|
45
|
+
/** @type {Map<string, number[]>} */
|
|
46
|
+
this.userData = new Map();
|
|
47
|
+
|
|
48
|
+
/** @type {Map<string, number>} */
|
|
49
|
+
this.lastSeen = new Map();
|
|
50
|
+
|
|
51
|
+
// Start automatic cleanup
|
|
52
|
+
this._cleanupTimer = setInterval(() => this._cleanup(), this.cleanupInterval);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the interval window in milliseconds.
|
|
57
|
+
*
|
|
58
|
+
* @returns {number} The interval value.
|
|
59
|
+
* @throws {Error} If interval is not a valid finite number.
|
|
60
|
+
*/
|
|
61
|
+
getInterval() {
|
|
62
|
+
if (typeof this.interval !== 'number' || !Number.isFinite(this.interval))
|
|
63
|
+
throw new Error("'interval' is not a valid finite number.");
|
|
64
|
+
return this.interval;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the maximum number of allowed hits.
|
|
69
|
+
*
|
|
70
|
+
* @returns {number} The maxHits value.
|
|
71
|
+
* @throws {Error} If maxHits is not a valid finite number.
|
|
72
|
+
*/
|
|
73
|
+
getMaxHits() {
|
|
74
|
+
if (typeof this.maxHits !== 'number' || !Number.isFinite(this.maxHits)) {
|
|
75
|
+
throw new Error("'maxHits' is not a valid finite number.");
|
|
76
|
+
}
|
|
77
|
+
return this.maxHits;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Register a hit for a specific user
|
|
82
|
+
* @param {string} userId
|
|
83
|
+
*/
|
|
84
|
+
hit(userId) {
|
|
85
|
+
const now = Date.now();
|
|
86
|
+
|
|
87
|
+
if (!this.userData.has(userId)) {
|
|
88
|
+
this.userData.set(userId, []);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const history = this.userData.get(userId);
|
|
92
|
+
if (!history) throw new Error(`No data found for userId: ${userId}`);
|
|
93
|
+
|
|
94
|
+
history.push(now);
|
|
95
|
+
this.lastSeen.set(userId, now);
|
|
96
|
+
|
|
97
|
+
// Clean up old entries
|
|
98
|
+
if (this.interval !== null) {
|
|
99
|
+
const interval = this.getInterval();
|
|
100
|
+
const cutoff = now - interval;
|
|
101
|
+
while (history.length && history[0] < cutoff) {
|
|
102
|
+
history.shift();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Optional: keep only the last N entries for memory optimization
|
|
107
|
+
if (this.maxHits !== null) {
|
|
108
|
+
const maxHits = this.getMaxHits();
|
|
109
|
+
if (history.length > maxHits) {
|
|
110
|
+
history.splice(0, history.length - maxHits);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Check if the user is currently rate limited
|
|
117
|
+
* @param {string} userId
|
|
118
|
+
* @returns {boolean}
|
|
119
|
+
*/
|
|
120
|
+
isRateLimited(userId) {
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
|
|
123
|
+
if (!this.userData.has(userId)) return false;
|
|
124
|
+
|
|
125
|
+
const history = this.userData.get(userId);
|
|
126
|
+
if (!history) throw new Error(`No data found for userId: ${userId}`);
|
|
127
|
+
|
|
128
|
+
if (this.interval !== null) {
|
|
129
|
+
const interval = this.getInterval();
|
|
130
|
+
const recent = history.filter((t) => t > now - interval);
|
|
131
|
+
if (this.maxHits !== null) {
|
|
132
|
+
return recent.length >= this.getMaxHits();
|
|
133
|
+
}
|
|
134
|
+
return recent.length > 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (this.maxHits !== null) {
|
|
138
|
+
return history.length >= this.getMaxHits();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Manually reset user data
|
|
146
|
+
* @param {string} userId
|
|
147
|
+
*/
|
|
148
|
+
reset(userId) {
|
|
149
|
+
this.userData.delete(userId);
|
|
150
|
+
this.lastSeen.delete(userId);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Set hit timestamps for a user
|
|
155
|
+
* @param {string} userId
|
|
156
|
+
* @param {number[]} timestamps
|
|
157
|
+
*/
|
|
158
|
+
setData(userId, timestamps) {
|
|
159
|
+
this.userData.set(userId, timestamps);
|
|
160
|
+
this.lastSeen.set(userId, Date.now());
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Get timestamps from user
|
|
165
|
+
* @param {string} userId
|
|
166
|
+
* @returns {number[]}
|
|
167
|
+
*/
|
|
168
|
+
getData(userId) {
|
|
169
|
+
return this.userData.get(userId) || [];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Cleanup old/inactive users
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
_cleanup() {
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
for (const [userId, last] of this.lastSeen.entries()) {
|
|
179
|
+
if (now - last > this.maxIdle) {
|
|
180
|
+
this.userData.delete(userId);
|
|
181
|
+
this.lastSeen.delete(userId);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Destroy the rate limiter, stopping all intervals
|
|
188
|
+
*/
|
|
189
|
+
destroy() {
|
|
190
|
+
clearInterval(this._cleanupTimer);
|
|
191
|
+
this.userData.clear();
|
|
192
|
+
this.lastSeen.clear();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
module.exports = TinyRateLimiter;
|