@20syldev/api 4.8.0 → 5.0.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.
Files changed (126) hide show
  1. package/README.md +93 -55
  2. package/dist/config/versions.js +16 -0
  3. package/dist/config/versions.js.map +1 -1
  4. package/dist/constants.js +5 -0
  5. package/dist/constants.js.map +1 -1
  6. package/dist/modules/v5/chart.js +379 -0
  7. package/dist/modules/v5/chart.js.map +1 -0
  8. package/dist/modules/v5/evaluate.js +281 -0
  9. package/dist/modules/v5/evaluate.js.map +1 -0
  10. package/dist/modules/v5/matrix.js +238 -0
  11. package/dist/modules/v5/matrix.js.map +1 -0
  12. package/dist/modules/v5.js +5 -0
  13. package/dist/modules/v5.js.map +1 -0
  14. package/dist/routes/get.js +191 -162
  15. package/dist/routes/get.js.map +1 -1
  16. package/dist/routes/post.js +69 -0
  17. package/dist/routes/post.js.map +1 -1
  18. package/package.json +4 -2
  19. package/recap.md +98 -0
  20. package/.github/FUNDING.yml +0 -1
  21. package/.prettierrc +0 -7
  22. package/eslint.config.js +0 -24
  23. package/robots.txt +0 -74
  24. package/src/app.ts +0 -53
  25. package/src/config/env.ts +0 -87
  26. package/src/config/plans.ts +0 -61
  27. package/src/config/versions.ts +0 -121
  28. package/src/constants.ts +0 -61
  29. package/src/favicon.ico +0 -0
  30. package/src/middleware/cors.ts +0 -23
  31. package/src/middleware/error.ts +0 -16
  32. package/src/middleware/json.ts +0 -9
  33. package/src/middleware/logger.ts +0 -32
  34. package/src/middleware/ratelimit.ts +0 -89
  35. package/src/middleware/version.ts +0 -40
  36. package/src/modules/v3/algorithms.js +0 -218
  37. package/src/modules/v3/captcha.js +0 -60
  38. package/src/modules/v3/chat.js +0 -111
  39. package/src/modules/v3/color.js +0 -60
  40. package/src/modules/v3/convert.js +0 -39
  41. package/src/modules/v3/domain.js +0 -86
  42. package/src/modules/v3/hash.js +0 -16
  43. package/src/modules/v3/hyperplanning.js +0 -56
  44. package/src/modules/v3/levenshtein.js +0 -46
  45. package/src/modules/v3/personal.js +0 -139
  46. package/src/modules/v3/qrcode.js +0 -20
  47. package/src/modules/v3/tic_tac_toe.js +0 -242
  48. package/src/modules/v3/time.js +0 -98
  49. package/src/modules/v3/token.js +0 -54
  50. package/src/modules/v3/username.js +0 -94
  51. package/src/modules/v3/utils.js +0 -77
  52. package/src/modules/v3.js +0 -15
  53. package/src/modules/v4/address.ts +0 -412
  54. package/src/modules/v4/agent.ts +0 -104
  55. package/src/modules/v4/algorithms.ts +0 -276
  56. package/src/modules/v4/captcha.ts +0 -114
  57. package/src/modules/v4/chat.ts +0 -130
  58. package/src/modules/v4/color.ts +0 -75
  59. package/src/modules/v4/convert.ts +0 -127
  60. package/src/modules/v4/cron.ts +0 -221
  61. package/src/modules/v4/dice.ts +0 -46
  62. package/src/modules/v4/domain.ts +0 -86
  63. package/src/modules/v4/encode.ts +0 -241
  64. package/src/modules/v4/geo.ts +0 -64
  65. package/src/modules/v4/hash.ts +0 -32
  66. package/src/modules/v4/hyperplanning.ts +0 -93
  67. package/src/modules/v4/ip.ts +0 -134
  68. package/src/modules/v4/levenshtein.ts +0 -46
  69. package/src/modules/v4/palette.ts +0 -71
  70. package/src/modules/v4/password.ts +0 -379
  71. package/src/modules/v4/personal.ts +0 -140
  72. package/src/modules/v4/placeholder.ts +0 -197
  73. package/src/modules/v4/qrcode.ts +0 -121
  74. package/src/modules/v4/regex.ts +0 -67
  75. package/src/modules/v4/statistics.ts +0 -62
  76. package/src/modules/v4/text.ts +0 -330
  77. package/src/modules/v4/tic_tac_toe.ts +0 -264
  78. package/src/modules/v4/time.ts +0 -149
  79. package/src/modules/v4/token.ts +0 -53
  80. package/src/modules/v4/username.ts +0 -94
  81. package/src/modules/v4/validate.ts +0 -76
  82. package/src/modules/v4.ts +0 -29
  83. package/src/routes/delete.ts +0 -72
  84. package/src/routes/get.ts +0 -856
  85. package/src/routes/index.ts +0 -59
  86. package/src/routes/patch.ts +0 -45
  87. package/src/routes/post.ts +0 -209
  88. package/src/storage/index.ts +0 -16
  89. package/src/types/express.d.ts +0 -17
  90. package/src/types/storage.ts +0 -48
  91. package/src/utils/colors.ts +0 -91
  92. package/src/utils/helpers.ts +0 -90
  93. package/src/utils/response.ts +0 -28
  94. package/tests/integration/api.test.ts +0 -772
  95. package/tests/tsconfig.json +0 -3
  96. package/tests/unit/address.test.ts +0 -84
  97. package/tests/unit/agent.test.ts +0 -113
  98. package/tests/unit/algorithms.test.ts +0 -121
  99. package/tests/unit/captcha.test.ts +0 -62
  100. package/tests/unit/chat.test.ts +0 -54
  101. package/tests/unit/color.test.ts +0 -54
  102. package/tests/unit/convert.test.ts +0 -68
  103. package/tests/unit/cron.test.ts +0 -110
  104. package/tests/unit/dice.test.ts +0 -58
  105. package/tests/unit/domain.test.ts +0 -48
  106. package/tests/unit/encode.test.ts +0 -109
  107. package/tests/unit/geo.test.ts +0 -46
  108. package/tests/unit/hash.test.ts +0 -45
  109. package/tests/unit/hyperplanning.test.ts +0 -97
  110. package/tests/unit/ip.test.ts +0 -140
  111. package/tests/unit/levenshtein.test.ts +0 -35
  112. package/tests/unit/palette.test.ts +0 -54
  113. package/tests/unit/password.test.ts +0 -86
  114. package/tests/unit/personal.test.ts +0 -66
  115. package/tests/unit/placeholder.test.ts +0 -58
  116. package/tests/unit/qrcode.test.ts +0 -83
  117. package/tests/unit/regex.test.ts +0 -95
  118. package/tests/unit/statistics.test.ts +0 -58
  119. package/tests/unit/text.test.ts +0 -108
  120. package/tests/unit/tic_tac_toe.test.ts +0 -56
  121. package/tests/unit/time.test.ts +0 -115
  122. package/tests/unit/token.test.ts +0 -62
  123. package/tests/unit/username.test.ts +0 -35
  124. package/tests/unit/validate.test.ts +0 -72
  125. package/tsconfig.json +0 -17
  126. package/tsconfig.test.json +0 -9
@@ -1,242 +0,0 @@
1
- import { randomBytes } from 'crypto';
2
-
3
- /**
4
- * Manages a Tic-Tac-Toe game session
5
- *
6
- * @param {string} action - The action to perform ('play', 'fetch', or 'list')
7
- * @param {Object} params - The parameters for the action
8
- * @returns {Object} - The result of the action
9
- * @throws {Error} - If parameters are invalid
10
- */
11
- export default function tic_tac_toe(action, params = {}) {
12
- // In-memory storage
13
- const storage = params.storage || {};
14
-
15
- // Initialize storage
16
- storage.games ??= {};
17
- storage.sessions ??= {};
18
- storage.rateLimits ??= {};
19
-
20
- // Reference the storage properties
21
- const { games, sessions, rateLimits } = storage;
22
-
23
- // List public games
24
- if (action === 'list') return listGames(games);
25
-
26
- // Input validation for common parameters
27
- if (!params.username) throw new Error('Please provide a username');
28
-
29
- const u = params.username.toLowerCase();
30
- const now = Date.now();
31
-
32
- // Rate limiting
33
- rateLimits[u] = (rateLimits[u] || []).filter((ts) => now - ts < 10000);
34
- if (rateLimits[u].length > 50) {
35
- const remainingTime = Math.ceil((rateLimits[u][0] + 10000 - now) / 1000);
36
- throw new Error(`Rate limit exceeded. Try again in ${remainingTime} seconds.`);
37
- }
38
- rateLimits[u].push(now);
39
-
40
- // Handle different actions
41
- if (action === 'play') {
42
- return playMove(params, games, sessions, u, now);
43
- } else if (action === 'fetch') {
44
- return fetchGame(params, games, u);
45
- } else {
46
- throw new Error('Invalid action. Use "play", "fetch", or "list"');
47
- }
48
- }
49
-
50
- /**
51
- * Process a player's move
52
- */
53
- function playMove(params, games, sessions, u, now) {
54
- const { move, session, game } = params;
55
- const validMoves = ['1-1', '1-2', '1-3', '2-1', '2-2', '2-3', '3-1', '3-2', '3-3'];
56
-
57
- // Input validation for play action
58
- if (!move) throw new Error('Please provide a valid move');
59
- if (!session) throw new Error('Please provide a valid session ID');
60
- if (!game) throw new Error('Please provide a valid game ID');
61
- if (!validMoves.includes(move)) throw new Error('Invalid move. Please provide a valid move (e.g., 1-1, 2-2, 3-3).');
62
-
63
- // Session validation
64
- if (sessions[u] && sessions[u].user !== session) {
65
- throw new Error('Session ID mismatch');
66
- }
67
-
68
- // Initialize game if needed
69
- games[game] = games[game] || {
70
- moves: [],
71
- players: [],
72
- private: params.private || false,
73
- creation: Date.now(),
74
- };
75
- const moves = games[game].moves;
76
-
77
- // Check if game is full
78
- const players = [...new Set(moves.map((play) => play.username))];
79
- if (players.length >= 2 && !players.includes(params.username)) {
80
- throw new Error('Game is full, you can only watch.');
81
- }
82
-
83
- // Check if it's player's turn
84
- if (moves.length > 0 && moves[moves.length - 1].username === params.username) {
85
- throw new Error('Please wait for the other player to make a move.');
86
- }
87
-
88
- // Check if move is already made
89
- if (moves.some((play) => play.move === move)) {
90
- throw new Error('Move already made. Please choose a different move.');
91
- }
92
-
93
- // Add move to game
94
- const play = { username: params.username, move, session };
95
- moves.push(play);
96
-
97
- // Check game result
98
- const result = checkGame(moves);
99
- if (result.winner || result.tie) {
100
- setTimeout(() => delete games[game], 600000);
101
- return {
102
- message: `Move sent successfully. ${result.winner ? result.winner + ' wins. ' + result.loser + ' loses.' : "It's a tie."}`,
103
- ...result,
104
- };
105
- }
106
-
107
- // Set cleanup timeout
108
- setTimeout(() => delete games[game], 3600000);
109
-
110
- // Update session
111
- sessions[u] = sessions[u] || { user: session, last: now };
112
- sessions[u].last = now;
113
- setTimeout(() => {
114
- if (now - sessions[u].last >= 3600000) delete sessions[u];
115
- }, 3600000);
116
-
117
- return { message: 'Move sent successfully' };
118
- }
119
-
120
- /**
121
- * Fetch a game state
122
- */
123
- function fetchGame(params, games, u) {
124
- const id = params.game || generateGameId();
125
- if (!games[id]) {
126
- games[id] = {
127
- moves: [],
128
- players: [],
129
- private: params.private || false,
130
- creation: Date.now(),
131
- };
132
- }
133
- if (!games[id].players.includes(u)) {
134
- games[id].players.push(u);
135
- }
136
-
137
- const moves = games[id].moves;
138
- const players = games[id].players;
139
- const privateGame = games[id].private;
140
- const lastPlayer = moves.length ? moves[moves.length - 1].username : null;
141
- const turn = players.find((p) => p !== lastPlayer) || players[0];
142
- const status = players.length >= 2 ? 'ready' : 'waiting';
143
- const result = moves.length ? checkGame(moves) : {};
144
-
145
- return {
146
- id,
147
- moves,
148
- players,
149
- turn,
150
- status,
151
- private: privateGame,
152
- ...result,
153
- };
154
- }
155
-
156
- /**
157
- * List all public games in progress
158
- */
159
- function listGames(games) {
160
- const publicGames = [];
161
- const now = Date.now();
162
-
163
- for (const [gameId, game] of Object.entries(games)) {
164
- // Only include public games
165
- if (!game.private) {
166
- const result = game.moves.length ? checkGame(game.moves) : {};
167
- const isFinished = result.winner || result.tie;
168
-
169
- // Only include active games (not finished)
170
- if (!isFinished) {
171
- const lastPlayer = game.moves.length ? game.moves[game.moves.length - 1].username : null;
172
- const turn = game.players.find((p) => p !== lastPlayer) || game.players[0];
173
- const status = game.players.length >= 2 ? 'ready' : 'waiting';
174
-
175
- publicGames.push({
176
- id: gameId,
177
- players: game.players,
178
- playersCount: game.players.length,
179
- moves: game.moves.length,
180
- turn,
181
- status,
182
- creation: game.creation || now,
183
- });
184
- }
185
- }
186
- }
187
-
188
- // Sort by creation time (newest first)
189
- publicGames.sort((a, b) => b.creation - a.creation);
190
-
191
- return {
192
- message: 'Public games available',
193
- count: publicGames.length,
194
- games: publicGames,
195
- };
196
- }
197
-
198
- /**
199
- * Generate a random game ID
200
- */
201
- function generateGameId() {
202
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
203
- return Array.from(randomBytes(5))
204
- .map((b) => chars[b % chars.length])
205
- .join('');
206
- }
207
-
208
- /**
209
- * Check the game result
210
- */
211
- function checkGame(moves) {
212
- let board = Array(3)
213
- .fill()
214
- .map(() => Array(3).fill(null));
215
- let playerSymbols = {};
216
- let playersOrder = [];
217
-
218
- moves.forEach(({ username, move }) => {
219
- if (!playerSymbols[username]) {
220
- playersOrder.push(username);
221
- playerSymbols[username] = playersOrder.length === 1 ? 'X' : 'O';
222
- }
223
- let [row, col] = move.split('-').map(Number);
224
- board[row - 1][col - 1] = playerSymbols[username];
225
- });
226
-
227
- const checkWinner = (symbol) => {
228
- for (let i = 0; i < 3; i++) {
229
- if (board[i][0] === symbol && board[i][1] === symbol && board[i][2] === symbol) return true;
230
- if (board[0][i] === symbol && board[1][i] === symbol && board[2][i] === symbol) return true;
231
- }
232
- if (board[0][0] === symbol && board[1][1] === symbol && board[2][2] === symbol) return true;
233
- if (board[0][2] === symbol && board[1][1] === symbol && board[2][0] === symbol) return true;
234
- return false;
235
- };
236
-
237
- let winner = Object.keys(playerSymbols).find((player) => checkWinner(playerSymbols[player]));
238
- let isTie = !winner && moves.length === 9;
239
- let loser = winner && playersOrder.length === 2 ? playersOrder.find((player) => player !== winner) : null;
240
-
241
- return { winner, loser, tie: isTie };
242
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * Generate time information based on specified parameters.
3
- *
4
- * @param {string} type - The type of time information ('live' or 'random')
5
- * @param {string} start - Start date for random generation (ISO format)
6
- * @param {string} end - End date for random generation (ISO format)
7
- * @param {string} format - Specific time format to return
8
- * @param {string} timezone - Timezone to use
9
- * @returns {object} - Time information in various formats
10
- * @throws {Error} - If inputs are invalid
11
- */
12
- export default function time(type = 'live', start, end, format, timezone) {
13
- const validFormats = [
14
- 'iso',
15
- 'utc',
16
- 'timestamp',
17
- 'locale',
18
- 'date',
19
- 'time',
20
- 'year',
21
- 'month',
22
- 'day',
23
- 'hour',
24
- 'minute',
25
- 'second',
26
- 'ms',
27
- 'dayOfWeek',
28
- 'dayOfYear',
29
- 'weekNumber',
30
- 'timezone',
31
- 'timezoneOffset',
32
- ];
33
-
34
- const validTimezones = ['UTC', 'America/New_York', 'Europe/Paris', 'Asia/Tokyo', 'Australia/Sydney'];
35
-
36
- // Input validation
37
- if (type !== 'live' && type !== 'random') {
38
- throw new Error('Please provide a valid type (live or random)');
39
- }
40
-
41
- if (start && !Date.parse(start)) {
42
- throw new Error('Please provide a valid start date (YYYY-MM-DD)');
43
- }
44
-
45
- if (end && !Date.parse(end)) {
46
- throw new Error('Please provide a valid end date (YYYY-MM-DD)');
47
- }
48
-
49
- if (format && !validFormats.includes(format)) {
50
- throw new Error(`Please provide a valid format. Options: ${validFormats.join(', ')}`);
51
- }
52
-
53
- if (timezone && !validTimezones.includes(timezone)) {
54
- throw new Error(`Please provide a valid timezone. Options: ${validTimezones.join(', ')}`);
55
- }
56
-
57
- // Helper function to get all time formats for a date
58
- const getTimeFormats = (date, tz) => {
59
- return {
60
- iso: date.toISOString(),
61
- utc: date.toUTCString(),
62
- timestamp: date.getTime(),
63
- locale: date.toLocaleString('en-US', { timeZone: tz, timeZoneName: 'long' }),
64
- date: date.toLocaleDateString('en-US', { timeZone: tz }),
65
- time: date.toLocaleTimeString('en-US', { timeZone: tz }),
66
- year: date.getFullYear(),
67
- month: date.getMonth() + 1,
68
- day: date.getDate(),
69
- hour: date.getHours(),
70
- minute: date.getMinutes(),
71
- second: date.getSeconds(),
72
- ms: date.getMilliseconds(),
73
- dayOfWeek: date.getDay(),
74
- dayOfYear: Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 86400000),
75
- weekNumber: Math.ceil(((date - new Date(date.getFullYear(), 0, 0)) / 86400000 + 1) / 7),
76
- timezone: tz,
77
- timezoneOffset: date.getTimezoneOffset(),
78
- };
79
- };
80
-
81
- // Generate time information based on type
82
- if (type === 'random') {
83
- const startDate = start ? new Date(start).getTime() : new Date('1900-01-01').getTime();
84
- const endDate = end ? new Date(end).getTime() : new Date('2100-12-31').getTime();
85
- const randomDate = new Date(startDate + Math.random() * (endDate - startDate));
86
- const tz = timezone || validTimezones[Math.floor(Math.random() * validTimezones.length)];
87
- const formats = getTimeFormats(randomDate, tz);
88
-
89
- return format ? { date: formats[format] } : formats;
90
- }
91
-
92
- // Live time information
93
- const now = new Date();
94
- const tz = timezone || 'UTC';
95
- const formats = getTimeFormats(now, tz);
96
-
97
- return format ? { date: formats[format] } : formats;
98
- }
@@ -1,54 +0,0 @@
1
- import { randomBytes } from 'crypto';
2
- import { v4 } from 'uuid';
3
-
4
- /**
5
- * Generate a random token of specified length and type.
6
- *
7
- * @param {number} len - Length of the token
8
- * @param {string} type - Type of token to generate
9
- * @returns {string} - The generated token
10
- * @throws {Error} - If inputs are invalid
11
- */
12
- export default function token(len, type = 'alphanum') {
13
- // Input validation
14
- if (isNaN(len) || len < 12) {
15
- throw new Error('Length must be a number greater than or equal to 12');
16
- }
17
-
18
- if (len > 4096) {
19
- throw new Error('Length cannot exceed 4096');
20
- }
21
-
22
- // Helper function to generate token from character set
23
- const genToken = (chars, length) => {
24
- return Array.from({ length }, () => {
25
- return chars[Math.floor(Math.random() * chars.length)];
26
- }).join('');
27
- };
28
-
29
- // Token type definitions
30
- const tokenTypes = {
31
- alpha: () => genToken('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', len),
32
- alphanum: () => genToken('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', len),
33
- base64: () =>
34
- randomBytes(Math.ceil(len * 0.75))
35
- .toString('base64')
36
- .slice(0, len),
37
- hex: () =>
38
- randomBytes(Math.ceil(len * 0.5))
39
- .toString('hex')
40
- .slice(0, len),
41
- num: () => genToken('0123456789', len),
42
- punct: () => genToken('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', len),
43
- urlsafe: () => genToken('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_', len),
44
- uuid: () => v4().replace(/-/g, '').slice(0, len),
45
- };
46
-
47
- // Generate token based on type or default to alphanum
48
- if (!tokenTypes[type.toLowerCase()]) {
49
- throw new Error(`Invalid token type. Valid types: ${Object.keys(tokenTypes).join(', ')}`);
50
- }
51
-
52
- // Generate token based on type or default to alphanum
53
- return (tokenTypes[type.toLowerCase()] || tokenTypes.alphanum)();
54
- }
@@ -1,94 +0,0 @@
1
- import { random, randomNumber } from './utils.js';
2
-
3
- /**
4
- * Generate a random username with related information
5
- *
6
- * @returns {Object} Object containing username and component parts
7
- */
8
- export default function username() {
9
- const adj = [
10
- 'Happy',
11
- 'Silly',
12
- 'Clever',
13
- 'Creative',
14
- 'Brave',
15
- 'Gentle',
16
- 'Kind',
17
- 'Funny',
18
- 'Wise',
19
- 'Charming',
20
- 'Sincere',
21
- 'Resourceful',
22
- 'Patient',
23
- 'Energetic',
24
- 'Adventurous',
25
- 'Ambitious',
26
- 'Courageous',
27
- 'Courteous',
28
- 'Determined',
29
- ];
30
- const ani = [
31
- 'Cat',
32
- 'Dog',
33
- 'Tiger',
34
- 'Elephant',
35
- 'Monkey',
36
- 'Penguin',
37
- 'Dolphin',
38
- 'Lion',
39
- 'Bear',
40
- 'Fox',
41
- 'Owl',
42
- 'Giraffe',
43
- 'Zebra',
44
- 'Koala',
45
- 'Rabbit',
46
- 'Squirrel',
47
- 'Panda',
48
- 'Horse',
49
- 'Wolf',
50
- 'Eagle',
51
- ];
52
- const job = [
53
- 'Writer',
54
- 'Artist',
55
- 'Musician',
56
- 'Explorer',
57
- 'Scientist',
58
- 'Engineer',
59
- 'Athlete',
60
- 'Chef',
61
- 'Doctor',
62
- 'Teacher',
63
- 'Lawyer',
64
- 'Entrepreneur',
65
- 'Actor',
66
- 'Dancer',
67
- 'Photographer',
68
- 'Architect',
69
- 'Pilot',
70
- 'Designer',
71
- 'Journalist',
72
- 'Veterinarian',
73
- ];
74
-
75
- const nombre = randomNumber(0, 99);
76
- const choix = {
77
- adj_num: () => random(adj) + nombre,
78
- ani_num: () => random(ani) + nombre,
79
- pro_num: () => random(job) + nombre,
80
- adj_ani: () => random(adj) + random(ani),
81
- adj_ani_num: () => random(adj) + random(ani) + nombre,
82
- adj_pro: () => random(adj) + random(job),
83
- pro_ani: () => random(job) + random(ani),
84
- pro_ani_num: () => random(job) + random(ani) + nombre,
85
- };
86
-
87
- return {
88
- username: choix[random(Object.keys(choix))](),
89
- number: nombre,
90
- adjective: random(adj),
91
- animal: random(ani),
92
- job: random(job),
93
- };
94
- }
@@ -1,77 +0,0 @@
1
- /**
2
- * Shared utility functions for the API modules
3
- */
4
-
5
- /**
6
- * Return a random element from an array.
7
- *
8
- * @param {Array} arr - The array to choose from.
9
- * @returns {*} - A random element from the array.
10
- */
11
- export function random(arr) {
12
- return arr[Math.floor(Math.random() * arr.length)];
13
- }
14
-
15
- /**
16
- * Return a random number between min and max (inclusive).
17
- *
18
- * @param {number} min - The minimum number.
19
- * @param {number} max - The maximum number.
20
- * @returns {number} - A random number between min and max.
21
- */
22
- export function randomNumber(min, max) {
23
- return Math.floor(Math.random() * (max - min + 1)) + min;
24
- }
25
-
26
- /**
27
- * Generate a random IP address.
28
- *
29
- * @returns {string} - A random IP address in the format "X.X.X.X".
30
- */
31
- export function genIP() {
32
- return `${randomNumber(0, 255)}.${randomNumber(0, 255)}.${randomNumber(0, 255)}.${randomNumber(0, 255)}`;
33
- }
34
-
35
- /**
36
- * Format a JavaScript Date object to ISO format without timezone.
37
- *
38
- * @param {Date} date - Date object to format
39
- * @returns {string} - Formatted date string
40
- */
41
- export function formatDate(date) {
42
- return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().replace('Z', '');
43
- }
44
-
45
- /**
46
- * Parse a space-separated env variable into an array, or return null.
47
- *
48
- * @param {string} key - The environment variable name.
49
- * @returns {string[]|null} - The parsed array or null.
50
- */
51
- export function envList(key) {
52
- const v = process.env[key];
53
- return v && v !== 'undefined' ? v.split(' ') : null;
54
- }
55
-
56
- /**
57
- * Manage rate limiting for users
58
- *
59
- * @param {Object} rateLimits - Rate limits object
60
- * @param {string} userId - User ID
61
- * @param {number} timestamp - Current timestamp
62
- * @param {number} window - Time window in milliseconds
63
- * @param {number} limit - Maximum requests in window
64
- * @returns {boolean} - True if rate limit is exceeded
65
- * @throws {Error} - If rate limit is exceeded
66
- */
67
- export function checkRateLimit(rateLimits, userId, timestamp, window = 10000, limit = 50) {
68
- rateLimits[userId] = (rateLimits[userId] || []).filter((ts) => timestamp - ts < window);
69
-
70
- if (rateLimits[userId].length > limit) {
71
- const remainingTime = Math.ceil((rateLimits[userId][0] + window - timestamp) / 1000);
72
- throw new Error(`Rate limit exceeded. Try again in ${remainingTime} seconds.`);
73
- }
74
-
75
- rateLimits[userId].push(timestamp);
76
- return false;
77
- }
package/src/modules/v3.js DELETED
@@ -1,15 +0,0 @@
1
- export * as algorithms from './v3/algorithms.js';
2
- export { default as captcha } from './v3/captcha.js';
3
- export { default as chat } from './v3/chat.js';
4
- export { default as color } from './v3/color.js';
5
- export { default as convert } from './v3/convert.js';
6
- export { default as domain } from './v3/domain.js';
7
- export { default as hash } from './v3/hash.js';
8
- export { default as hyperplanning } from './v3/hyperplanning.js';
9
- export { default as levenshtein } from './v3/levenshtein.js';
10
- export { default as personal } from './v3/personal.js';
11
- export { default as qrcode } from './v3/qrcode.js';
12
- export { default as tic_tac_toe } from './v3/tic_tac_toe.js';
13
- export { default as time } from './v3/time.js';
14
- export { default as token } from './v3/token.js';
15
- export { default as username } from './v3/username.js';