@20syldev/api 5.2.0 → 5.4.0-pre
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/README.md +3 -3
- package/dist/app.js +7 -2
- package/dist/app.js.map +1 -1
- package/dist/config/versions.js +5 -1
- package/dist/config/versions.js.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/middleware/ratelimit.js +1 -1
- package/dist/middleware/ratelimit.js.map +1 -1
- package/dist/modules/v5/address.js +20 -0
- package/dist/modules/v5/address.js.map +1 -0
- package/dist/modules/v5/algorithms.js +39 -0
- package/dist/modules/v5/algorithms.js.map +1 -0
- package/dist/modules/v5/asymmetric.js +10 -3
- package/dist/modules/v5/asymmetric.js.map +1 -1
- package/dist/modules/v5/barcode.js +424 -0
- package/dist/modules/v5/barcode.js.map +1 -0
- package/dist/modules/v5/case.js +57 -0
- package/dist/modules/v5/case.js.map +1 -0
- package/dist/modules/v5/chart.js +16 -10
- package/dist/modules/v5/chart.js.map +1 -1
- package/dist/modules/v5/chat.js +107 -0
- package/dist/modules/v5/chat.js.map +1 -0
- package/dist/modules/v5/evaluate.js +8 -5
- package/dist/modules/v5/evaluate.js.map +1 -1
- package/dist/modules/v5/jwt.js +42 -0
- package/dist/modules/v5/jwt.js.map +1 -0
- package/dist/modules/v5/matrix.js +5 -4
- package/dist/modules/v5/matrix.js.map +1 -1
- package/dist/modules/v5/otp.js +16 -7
- package/dist/modules/v5/otp.js.map +1 -1
- package/dist/modules/v5/symmetric.js +36 -19
- package/dist/modules/v5/symmetric.js.map +1 -1
- package/dist/modules/v5/text.js +12 -0
- package/dist/modules/v5/text.js.map +1 -0
- package/dist/modules/v5/tic_tac_toe.js +226 -0
- package/dist/modules/v5/tic_tac_toe.js.map +1 -0
- package/dist/modules/v5.js +9 -1
- package/dist/modules/v5.js.map +1 -1
- package/dist/routes/get.js +85 -44
- package/dist/routes/get.js.map +1 -1
- package/dist/routes/index.js +4 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/post.js +23 -1
- package/dist/routes/post.js.map +1 -1
- package/dist/utils/helpers.js +6 -1
- package/dist/utils/helpers.js.map +1 -1
- package/package.json +1 -1
- package/dist/modules/v4/colors.js +0 -54
- package/dist/modules/v4/colors.js.map +0 -1
- package/dist/modules/v4/utils.js +0 -26
- package/dist/modules/v4/utils.js.map +0 -1
- package/dist/utils/version.js +0 -3
- package/dist/utils/version.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symmetric.js","sourceRoot":"","sources":["../../../src/modules/v5/symmetric.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"symmetric.js","sourceRoot":"","sources":["../../../src/modules/v5/symmetric.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as v4text from '../v4/text.js';
|
|
2
|
+
export * from '../v4/text.js';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a number to its written form in the given language.
|
|
5
|
+
*/
|
|
6
|
+
export function number(value, lang) {
|
|
7
|
+
const result = v4text.number(value, lang);
|
|
8
|
+
if (lang === 'fr')
|
|
9
|
+
return result.replace(/soixante-onze/g, 'soixante et onze');
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/modules/v5/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,cAAc,eAAe,CAAC;AAE9B;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,IAAY;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { randomBytes } from 'crypto';
|
|
2
|
+
import { GAME_CLEANUP_TTL, RATE_LIMIT_MAX, RATE_LIMIT_WINDOW, SESSION_TTL } from '../../constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handles Tic-Tac-Toe game actions including playing a move, fetching game state, listing games, and forfeiting.
|
|
5
|
+
*
|
|
6
|
+
* @param action - The action to perform: "play", "fetch", "list", or "forfeit"
|
|
7
|
+
* @param params - Game parameters including username, move, session, game ID, and shared storage
|
|
8
|
+
* @returns Game state or action result depending on the action
|
|
9
|
+
* @throws Error if a required parameter is missing, the action is invalid, or a rate limit is exceeded
|
|
10
|
+
*/
|
|
11
|
+
export default function tic_tac_toe(action, params) {
|
|
12
|
+
const storage = params.storage;
|
|
13
|
+
storage.games ??= {};
|
|
14
|
+
storage.sessions ??= {};
|
|
15
|
+
storage.rateLimits ??= {};
|
|
16
|
+
const { games, sessions, rateLimits } = storage;
|
|
17
|
+
if (action === 'list')
|
|
18
|
+
return listGames(games);
|
|
19
|
+
if (!params.username)
|
|
20
|
+
throw new Error('Please provide a username');
|
|
21
|
+
const u = params.username.toLowerCase();
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
rateLimits[u] = (rateLimits[u] ?? []).filter((ts) => now - ts < RATE_LIMIT_WINDOW);
|
|
24
|
+
if (rateLimits[u].length >= RATE_LIMIT_MAX) {
|
|
25
|
+
const remainingTime = Math.ceil((rateLimits[u][0] + RATE_LIMIT_WINDOW - now) / 1000);
|
|
26
|
+
throw new Error(`Rate limit exceeded. Try again in ${remainingTime} seconds.`);
|
|
27
|
+
}
|
|
28
|
+
rateLimits[u].push(now);
|
|
29
|
+
if (action === 'play') {
|
|
30
|
+
return playMove(params, games, sessions, u, now);
|
|
31
|
+
}
|
|
32
|
+
else if (action === 'fetch') {
|
|
33
|
+
return fetchGame(params, games, u);
|
|
34
|
+
}
|
|
35
|
+
else if (action === 'forfeit') {
|
|
36
|
+
return forfeitGame(params, games, sessions);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new Error('Invalid action. Use "play", "fetch", "list", or "forfeit"');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function forfeitGame(params, games, sessions) {
|
|
43
|
+
const { game, session } = params;
|
|
44
|
+
if (!game)
|
|
45
|
+
throw new Error('Please provide a valid game ID');
|
|
46
|
+
if (!session)
|
|
47
|
+
throw new Error('Please provide a valid session ID');
|
|
48
|
+
if (!games[game])
|
|
49
|
+
throw new Error('Game not found');
|
|
50
|
+
const u = params.username.toLowerCase();
|
|
51
|
+
if (sessions[u] && sessions[u].user !== session) {
|
|
52
|
+
throw new Error('Session ID mismatch');
|
|
53
|
+
}
|
|
54
|
+
const players = games[game].players;
|
|
55
|
+
if (!players.includes(u))
|
|
56
|
+
throw new Error('You are not a player in this game');
|
|
57
|
+
const winner = players.find((p) => p !== u) ?? null;
|
|
58
|
+
delete games[game];
|
|
59
|
+
delete sessions[u];
|
|
60
|
+
return {
|
|
61
|
+
message: `${params.username} forfeited the game.${winner ? ` ${winner} wins.` : ''}`,
|
|
62
|
+
winner,
|
|
63
|
+
loser: params.username,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function playMove(params, games, sessions, u, now) {
|
|
67
|
+
const { move, session, game } = params;
|
|
68
|
+
const validMoves = ['1-1', '1-2', '1-3', '2-1', '2-2', '2-3', '3-1', '3-2', '3-3'];
|
|
69
|
+
if (!move)
|
|
70
|
+
throw new Error('Please provide a valid move');
|
|
71
|
+
if (!session)
|
|
72
|
+
throw new Error('Please provide a valid session ID');
|
|
73
|
+
if (!game)
|
|
74
|
+
throw new Error('Please provide a valid game ID');
|
|
75
|
+
if (!validMoves.includes(move))
|
|
76
|
+
throw new Error('Invalid move. Please provide a valid move (e.g., 1-1, 2-2, 3-3).');
|
|
77
|
+
if (sessions[u] && sessions[u].user !== session) {
|
|
78
|
+
throw new Error('Session ID mismatch');
|
|
79
|
+
}
|
|
80
|
+
games[game] = games[game] ?? {
|
|
81
|
+
moves: [],
|
|
82
|
+
players: [],
|
|
83
|
+
private: params.private || false,
|
|
84
|
+
creation: Date.now(),
|
|
85
|
+
};
|
|
86
|
+
const g = games[game];
|
|
87
|
+
const moves = g.moves;
|
|
88
|
+
if (!g.players.includes(u)) {
|
|
89
|
+
if (g.players.length >= 2)
|
|
90
|
+
throw new Error('Game is full, you can only watch.');
|
|
91
|
+
g.players.push(u);
|
|
92
|
+
}
|
|
93
|
+
if (moves.length > 0 && moves[moves.length - 1].username === u) {
|
|
94
|
+
throw new Error('Please wait for the other player to make a move.');
|
|
95
|
+
}
|
|
96
|
+
if (moves.some((play) => play.move === move)) {
|
|
97
|
+
throw new Error('Move already made. Please choose a different move.');
|
|
98
|
+
}
|
|
99
|
+
const play = { username: u, move, session };
|
|
100
|
+
moves.push(play);
|
|
101
|
+
g.last = now;
|
|
102
|
+
const creation = g.creation;
|
|
103
|
+
const result = checkGame(moves);
|
|
104
|
+
if (result.winner || result.tie) {
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
if (games[game] && games[game].creation === creation)
|
|
107
|
+
delete games[game];
|
|
108
|
+
}, GAME_CLEANUP_TTL);
|
|
109
|
+
return {
|
|
110
|
+
message: `Move sent successfully. ${result.winner ? result.winner + ' wins. ' + result.loser + ' loses.' : "It's a tie."}`,
|
|
111
|
+
...result,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
const cur = games[game];
|
|
116
|
+
if (cur && cur.creation === creation && Date.now() - (cur.last ?? cur.creation) >= SESSION_TTL) {
|
|
117
|
+
delete games[game];
|
|
118
|
+
}
|
|
119
|
+
}, SESSION_TTL);
|
|
120
|
+
sessions[u] = sessions[u] ?? { user: session, last: now };
|
|
121
|
+
sessions[u].last = now;
|
|
122
|
+
setTimeout(() => {
|
|
123
|
+
if (sessions[u] && Date.now() - sessions[u].last >= SESSION_TTL)
|
|
124
|
+
delete sessions[u];
|
|
125
|
+
}, SESSION_TTL);
|
|
126
|
+
return { message: 'Move sent successfully' };
|
|
127
|
+
}
|
|
128
|
+
function fetchGame(params, games, u) {
|
|
129
|
+
const id = params.game || generateGameId();
|
|
130
|
+
if (!games[id]) {
|
|
131
|
+
games[id] = {
|
|
132
|
+
moves: [],
|
|
133
|
+
players: [],
|
|
134
|
+
private: params.private || false,
|
|
135
|
+
creation: Date.now(),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (!games[id].players.includes(u)) {
|
|
139
|
+
games[id].players.push(u);
|
|
140
|
+
}
|
|
141
|
+
const moves = games[id].moves;
|
|
142
|
+
const players = games[id].players;
|
|
143
|
+
const privateGame = games[id].private;
|
|
144
|
+
const lastPlayer = moves.length ? moves[moves.length - 1].username : null;
|
|
145
|
+
const turn = players.find((p) => p !== lastPlayer) || players[0];
|
|
146
|
+
const status = players.length >= 2 ? 'ready' : 'waiting';
|
|
147
|
+
const result = moves.length ? checkGame(moves) : {};
|
|
148
|
+
return {
|
|
149
|
+
id,
|
|
150
|
+
moves,
|
|
151
|
+
players,
|
|
152
|
+
turn,
|
|
153
|
+
status,
|
|
154
|
+
private: privateGame,
|
|
155
|
+
...result,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function listGames(games) {
|
|
159
|
+
const publicGames = [];
|
|
160
|
+
const now = Date.now();
|
|
161
|
+
for (const [gameId, game] of Object.entries(games)) {
|
|
162
|
+
if (!game.private) {
|
|
163
|
+
const result = game.moves.length ? checkGame(game.moves) : {};
|
|
164
|
+
const isFinished = result.winner || result.tie;
|
|
165
|
+
if (!isFinished) {
|
|
166
|
+
const lastPlayer = game.moves.length ? game.moves[game.moves.length - 1].username : null;
|
|
167
|
+
const turn = game.players.find((p) => p !== lastPlayer) || game.players[0];
|
|
168
|
+
const status = game.players.length >= 2 ? 'ready' : 'waiting';
|
|
169
|
+
publicGames.push({
|
|
170
|
+
id: gameId,
|
|
171
|
+
players: game.players,
|
|
172
|
+
playersCount: game.players.length,
|
|
173
|
+
moves: game.moves.length,
|
|
174
|
+
turn,
|
|
175
|
+
status,
|
|
176
|
+
creation: game.creation || now,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
publicGames.sort((a, b) => b.creation - a.creation);
|
|
182
|
+
return {
|
|
183
|
+
message: 'Public games available',
|
|
184
|
+
count: publicGames.length,
|
|
185
|
+
games: publicGames,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function generateGameId() {
|
|
189
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
190
|
+
return Array.from(randomBytes(5))
|
|
191
|
+
.map((b) => chars[b % chars.length])
|
|
192
|
+
.join('');
|
|
193
|
+
}
|
|
194
|
+
function checkGame(moves) {
|
|
195
|
+
const board = Array(3)
|
|
196
|
+
.fill(null)
|
|
197
|
+
.map(() => Array(3).fill(null));
|
|
198
|
+
const playerSymbols = {};
|
|
199
|
+
const playersOrder = [];
|
|
200
|
+
moves.forEach(({ username, move }) => {
|
|
201
|
+
if (!playerSymbols[username]) {
|
|
202
|
+
playersOrder.push(username);
|
|
203
|
+
playerSymbols[username] = playersOrder.length === 1 ? 'X' : 'O';
|
|
204
|
+
}
|
|
205
|
+
const [row, col] = move.split('-').map(Number);
|
|
206
|
+
board[row - 1][col - 1] = playerSymbols[username];
|
|
207
|
+
});
|
|
208
|
+
const checkWinner = (symbol) => {
|
|
209
|
+
for (let i = 0; i < 3; i++) {
|
|
210
|
+
if (board[i][0] === symbol && board[i][1] === symbol && board[i][2] === symbol)
|
|
211
|
+
return true;
|
|
212
|
+
if (board[0][i] === symbol && board[1][i] === symbol && board[2][i] === symbol)
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
if (board[0][0] === symbol && board[1][1] === symbol && board[2][2] === symbol)
|
|
216
|
+
return true;
|
|
217
|
+
if (board[0][2] === symbol && board[1][1] === symbol && board[2][0] === symbol)
|
|
218
|
+
return true;
|
|
219
|
+
return false;
|
|
220
|
+
};
|
|
221
|
+
const winner = Object.keys(playerSymbols).find((player) => checkWinner(playerSymbols[player])) ?? null;
|
|
222
|
+
const isTie = !winner && moves.length === 9;
|
|
223
|
+
const loser = winner && playersOrder.length === 2 ? (playersOrder.find((player) => player !== winner) ?? null) : null;
|
|
224
|
+
return { winner, loser, tie: isTie };
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=tic_tac_toe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tic_tac_toe.js","sourceRoot":"","sources":["../../../src/modules/v5/tic_tac_toe.ts"],"names":[],"mappings":"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"}
|
package/dist/modules/v5.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { agent, avatar, captcha, color, convert, credit, cron, dice, domain, encode, geo, hash, hyperplanning, ip, levenshtein, palette, password, personal, placeholder, qrcode, regex, statistics, time, token, username, validate, } from './v4.js';
|
|
2
|
+
export { default as address } from './v5/address.js';
|
|
3
|
+
export * as algorithms from './v5/algorithms.js';
|
|
2
4
|
export { default as asymmetric } from './v5/asymmetric.js';
|
|
5
|
+
export { default as barcode } from './v5/barcode.js';
|
|
6
|
+
export { default as caseConvert } from './v5/case.js';
|
|
3
7
|
export * as chart from './v5/chart.js';
|
|
8
|
+
export { default as chat } from './v5/chat.js';
|
|
4
9
|
export { default as evaluate } from './v5/evaluate.js';
|
|
10
|
+
export { default as jwt } from './v5/jwt.js';
|
|
5
11
|
export * as matrix from './v5/matrix.js';
|
|
6
12
|
export { default as otp } from './v5/otp.js';
|
|
7
13
|
export { default as symmetric } from './v5/symmetric.js';
|
|
14
|
+
export * as text from './v5/text.js';
|
|
15
|
+
export { default as tic_tac_toe } from './v5/tic_tac_toe.js';
|
|
8
16
|
//# sourceMappingURL=v5.js.map
|
package/dist/modules/v5.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v5.js","sourceRoot":"","sources":["../../src/modules/v5.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,
|
|
1
|
+
{"version":3,"file":"v5.js","sourceRoot":"","sources":["../../src/modules/v5.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,MAAM,EACN,GAAG,EACH,IAAI,EACJ,aAAa,EACb,EAAE,EACF,WAAW,EACX,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,MAAM,EACN,KAAK,EACL,UAAU,EACV,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/routes/get.js
CHANGED
|
@@ -8,6 +8,14 @@ import { error } from '../utils/response.js';
|
|
|
8
8
|
const router = Router();
|
|
9
9
|
let activity = [];
|
|
10
10
|
let lastFetch = 0;
|
|
11
|
+
const postOnly = (name) => (req, res) => {
|
|
12
|
+
const available = versions[req.version]?.endpoints.post.some((e) => e.name === name);
|
|
13
|
+
if (!available) {
|
|
14
|
+
error(res, 404, `Endpoint not available in ${req.version}.`, `${req.latest}/${name}`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
error(res, 405, 'This endpoint only supports POST requests.');
|
|
18
|
+
};
|
|
11
19
|
// Display version information
|
|
12
20
|
router.get('/:version', (req, res) => {
|
|
13
21
|
const version = req.params.version;
|
|
@@ -51,6 +59,10 @@ router.get('/:version/address', (req, res) => {
|
|
|
51
59
|
return;
|
|
52
60
|
}
|
|
53
61
|
const parsedCount = count !== undefined ? parseInt(count, 10) : 1;
|
|
62
|
+
if (isNaN(parsedCount)) {
|
|
63
|
+
error(res, 400, 'Please provide a valid count (&count={n})', `${version}/address`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
54
66
|
try {
|
|
55
67
|
const result = addressFn(country, parsedCount);
|
|
56
68
|
res.jsonResponse(result);
|
|
@@ -62,8 +74,12 @@ router.get('/:version/address', (req, res) => {
|
|
|
62
74
|
// Parse a User-Agent string
|
|
63
75
|
router.get('/:version/agent', (req, res) => {
|
|
64
76
|
const ua = req.query.ua ?? req.headers['user-agent'] ?? '';
|
|
77
|
+
const agentFn = req.module.agent;
|
|
78
|
+
if (!agentFn) {
|
|
79
|
+
error(res, 404, `Endpoint not available in ${req.version}.`, `${req.latest}/agent`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
65
82
|
try {
|
|
66
|
-
const agentFn = req.module.agent;
|
|
67
83
|
const result = agentFn(ua);
|
|
68
84
|
res.jsonResponse(result);
|
|
69
85
|
}
|
|
@@ -89,8 +105,27 @@ router.get('/:version/algorithms', (req, res) => {
|
|
|
89
105
|
}
|
|
90
106
|
});
|
|
91
107
|
// GET asymmetric error
|
|
92
|
-
router.get('/:version/asymmetric', (
|
|
93
|
-
|
|
108
|
+
router.get('/:version/asymmetric', postOnly('asymmetric'));
|
|
109
|
+
// Convert text to a different case format
|
|
110
|
+
router.get('/:version/case', (req, res) => {
|
|
111
|
+
const { text, to } = req.query;
|
|
112
|
+
const { version } = req.params;
|
|
113
|
+
const caseConvertFn = req.module.caseConvert;
|
|
114
|
+
if (!caseConvertFn) {
|
|
115
|
+
error(res, 404, `Endpoint not available in ${version}.`, `${req.latest}/case`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (!text || typeof text !== 'string') {
|
|
119
|
+
error(res, 400, 'Please provide a text (?text={text})', `${version}/case`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const result = caseConvertFn(text, to);
|
|
124
|
+
res.jsonResponse(result);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
error(res, 400, err.message, `${req.version}/case`);
|
|
128
|
+
}
|
|
94
129
|
});
|
|
95
130
|
// Generate an identicon or pixel-art avatar from a seed
|
|
96
131
|
router.get('/:version/avatar', (req, res) => {
|
|
@@ -100,10 +135,15 @@ router.get('/:version/avatar', (req, res) => {
|
|
|
100
135
|
return;
|
|
101
136
|
}
|
|
102
137
|
const { seed, size, type, bg, format } = req.query;
|
|
138
|
+
const parsedSize = size !== undefined ? parseInt(size, 10) : undefined;
|
|
139
|
+
if (parsedSize !== undefined && isNaN(parsedSize)) {
|
|
140
|
+
error(res, 400, 'Please provide a valid size (&size={50-2000})', `${req.version}/avatar`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
103
143
|
try {
|
|
104
144
|
const { contentType, body } = avatarFn({
|
|
105
145
|
seed: seed,
|
|
106
|
-
size:
|
|
146
|
+
size: parsedSize,
|
|
107
147
|
type: type,
|
|
108
148
|
bg: bg,
|
|
109
149
|
format: format,
|
|
@@ -126,12 +166,18 @@ router.get('/:version/barcode', (req, res) => {
|
|
|
126
166
|
error(res, 400, 'Please provide data to encode (?data={string})', `${req.version}/barcode`);
|
|
127
167
|
return;
|
|
128
168
|
}
|
|
169
|
+
const parsedWidth = width !== undefined ? parseInt(width, 10) : undefined;
|
|
170
|
+
const parsedHeight = height !== undefined ? parseInt(height, 10) : undefined;
|
|
171
|
+
if ((parsedWidth !== undefined && isNaN(parsedWidth)) || (parsedHeight !== undefined && isNaN(parsedHeight))) {
|
|
172
|
+
error(res, 400, 'Please provide valid dimensions (&width={px}&height={px})', `${req.version}/barcode`);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
129
175
|
try {
|
|
130
176
|
const { contentType, body } = barcodeFn({
|
|
131
177
|
data: data,
|
|
132
178
|
type: type,
|
|
133
|
-
width:
|
|
134
|
-
height:
|
|
179
|
+
width: parsedWidth,
|
|
180
|
+
height: parsedHeight,
|
|
135
181
|
format: format,
|
|
136
182
|
color: color,
|
|
137
183
|
bg: bg,
|
|
@@ -174,14 +220,12 @@ router.get('/:version/captcha', (req, res) => {
|
|
|
174
220
|
}
|
|
175
221
|
});
|
|
176
222
|
// GET chart error
|
|
177
|
-
router.get('/:version/chart', (
|
|
178
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
179
|
-
});
|
|
223
|
+
router.get('/:version/chart', postOnly('chart'));
|
|
180
224
|
// Display stored data
|
|
181
225
|
router.get('/:version/chat', (req, res) => {
|
|
182
226
|
try {
|
|
183
227
|
const messages = req.module.chat('fetch', {
|
|
184
|
-
username: '
|
|
228
|
+
username: `reader:${req.ip ?? 'unknown'}`,
|
|
185
229
|
storage: chatStorage,
|
|
186
230
|
});
|
|
187
231
|
res.jsonResponse(messages);
|
|
@@ -191,9 +235,7 @@ router.get('/:version/chat', (req, res) => {
|
|
|
191
235
|
}
|
|
192
236
|
});
|
|
193
237
|
// GET private chat error
|
|
194
|
-
router.get('/:version/chat/private', (
|
|
195
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
196
|
-
});
|
|
238
|
+
router.get('/:version/chat/private', postOnly('chat'));
|
|
197
239
|
// Generate color
|
|
198
240
|
router.get('/:version/color', (req, res) => {
|
|
199
241
|
try {
|
|
@@ -272,8 +314,13 @@ router.get('/:version/cron', (req, res) => {
|
|
|
272
314
|
error(res, 400, 'Please provide a cron expression (?expr=* * * * *)', `${version}/cron`);
|
|
273
315
|
return;
|
|
274
316
|
}
|
|
317
|
+
const parsedCount = count !== undefined ? parseInt(count, 10) : 5;
|
|
318
|
+
if (isNaN(parsedCount)) {
|
|
319
|
+
error(res, 400, 'Please provide a valid count (&count={n})', `${version}/cron`);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
275
322
|
try {
|
|
276
|
-
const result = cronFn(expr,
|
|
323
|
+
const result = cronFn(expr, parsedCount, from, timezone ?? 'UTC');
|
|
277
324
|
res.jsonResponse(result);
|
|
278
325
|
}
|
|
279
326
|
catch (err) {
|
|
@@ -375,9 +422,7 @@ router.get('/:version/geo', (req, res) => {
|
|
|
375
422
|
}
|
|
376
423
|
});
|
|
377
424
|
// GET hash error
|
|
378
|
-
router.get('/:version/hash', (
|
|
379
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
380
|
-
});
|
|
425
|
+
router.get('/:version/hash', postOnly('hash'));
|
|
381
426
|
// Echo request headers
|
|
382
427
|
router.get('/:version/headers', (req, res) => {
|
|
383
428
|
const redacted = new Set(['authorization', 'cookie', 'set-cookie', 'proxy-authorization']);
|
|
@@ -385,7 +430,8 @@ router.get('/:version/headers', (req, res) => {
|
|
|
385
430
|
for (const [k, v] of Object.entries(req.headers)) {
|
|
386
431
|
headers[k] = redacted.has(k) ? '[redacted]' : v;
|
|
387
432
|
}
|
|
388
|
-
const
|
|
433
|
+
const filterParam = req.query.filter;
|
|
434
|
+
const filter = Array.isArray(filterParam) ? filterParam.join(',') : filterParam;
|
|
389
435
|
if (filter) {
|
|
390
436
|
const keys = new Set(filter.split(',').map((k) => k.trim().toLowerCase()));
|
|
391
437
|
headers = Object.fromEntries(Object.entries(headers).filter(([k]) => keys.has(k)));
|
|
@@ -399,9 +445,7 @@ router.get('/:version/headers', (req, res) => {
|
|
|
399
445
|
});
|
|
400
446
|
});
|
|
401
447
|
// GET planning error
|
|
402
|
-
router.get('/:version/hyperplanning', (
|
|
403
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
404
|
-
});
|
|
448
|
+
router.get('/:version/hyperplanning', postOnly('hyperplanning'));
|
|
405
449
|
// Display API informations
|
|
406
450
|
router.get('/:version/infos', (req, res) => {
|
|
407
451
|
const endpoints = Object.values(versions[req.version].endpoints).flat();
|
|
@@ -417,8 +461,12 @@ router.get('/:version/infos', (req, res) => {
|
|
|
417
461
|
// Analyze an IP address
|
|
418
462
|
router.get('/:version/ip', (req, res) => {
|
|
419
463
|
const address = req.query.address ?? req.ip ?? '';
|
|
464
|
+
const ipFn = req.module.ip;
|
|
465
|
+
if (!ipFn) {
|
|
466
|
+
error(res, 404, `Endpoint not available in ${req.version}.`, `${req.latest}/ip`);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
420
469
|
try {
|
|
421
|
-
const ipFn = req.module.ip;
|
|
422
470
|
const result = ipFn(address);
|
|
423
471
|
res.jsonResponse(result);
|
|
424
472
|
}
|
|
@@ -426,6 +474,8 @@ router.get('/:version/ip', (req, res) => {
|
|
|
426
474
|
error(res, 400, err.message, `${req.version}/ip`);
|
|
427
475
|
}
|
|
428
476
|
});
|
|
477
|
+
// GET jwt error
|
|
478
|
+
router.get('/:version/jwt', postOnly('jwt'));
|
|
429
479
|
// Calculate Levenshtein distance
|
|
430
480
|
router.get('/:version/levenshtein', (req, res) => {
|
|
431
481
|
const { str1, str2 } = req.query;
|
|
@@ -446,13 +496,9 @@ router.get('/:version/levenshtein', (req, res) => {
|
|
|
446
496
|
}
|
|
447
497
|
});
|
|
448
498
|
// GET matrix error
|
|
449
|
-
router.get('/:version/matrix', (
|
|
450
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
451
|
-
});
|
|
499
|
+
router.get('/:version/matrix', postOnly('matrix'));
|
|
452
500
|
// GET otp error
|
|
453
|
-
router.get('/:version/otp', (
|
|
454
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
455
|
-
});
|
|
501
|
+
router.get('/:version/otp', postOnly('otp'));
|
|
456
502
|
// Generate a color palette from a base color
|
|
457
503
|
router.get('/:version/palette', (req, res) => {
|
|
458
504
|
const { color, type } = req.query;
|
|
@@ -617,9 +663,7 @@ router.get('/:version/statistics', (req, res) => {
|
|
|
617
663
|
}
|
|
618
664
|
});
|
|
619
665
|
// GET symmetric error
|
|
620
|
-
router.get('/:version/symmetric', (
|
|
621
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
622
|
-
});
|
|
666
|
+
router.get('/:version/symmetric', postOnly('symmetric'));
|
|
623
667
|
// Text utilities (slug, stats, lorem, number)
|
|
624
668
|
router.get('/:version/text', (req, res) => {
|
|
625
669
|
const { method, value, type, count, lang, text } = req.query;
|
|
@@ -656,15 +700,9 @@ router.get('/:version/text', (req, res) => {
|
|
|
656
700
|
}
|
|
657
701
|
});
|
|
658
702
|
// GET tic-tac-toe errors
|
|
659
|
-
router.get('/:version/tic-tac-toe', (
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
router.get('/:version/tic-tac-toe/fetch', (_req, res) => {
|
|
663
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
664
|
-
});
|
|
665
|
-
router.get('/:version/tic-tac-toe/list', (_req, res) => {
|
|
666
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
667
|
-
});
|
|
703
|
+
router.get('/:version/tic-tac-toe', postOnly('tic_tac_toe'));
|
|
704
|
+
router.get('/:version/tic-tac-toe/fetch', postOnly('tic_tac_toe'));
|
|
705
|
+
router.get('/:version/tic-tac-toe/list', postOnly('tic_tac_toe'));
|
|
668
706
|
// Display or generate time informations, or compute a countdown
|
|
669
707
|
router.get('/:version/time', (req, res) => {
|
|
670
708
|
const { type = 'live', start, end, format, timezone, target } = req.query;
|
|
@@ -678,9 +716,7 @@ router.get('/:version/time', (req, res) => {
|
|
|
678
716
|
}
|
|
679
717
|
});
|
|
680
718
|
// GET token error
|
|
681
|
-
router.get('/:version/token', (
|
|
682
|
-
error(res, 405, 'This endpoint only supports POST requests.');
|
|
683
|
-
});
|
|
719
|
+
router.get('/:version/token', postOnly('token'));
|
|
684
720
|
// Generate username
|
|
685
721
|
router.get('/:version/username', (req, res) => {
|
|
686
722
|
try {
|
|
@@ -818,7 +854,12 @@ router.get('/:version/website', async (req, res) => {
|
|
|
818
854
|
tag: env.TAG,
|
|
819
855
|
active: env.ACTIVE,
|
|
820
856
|
};
|
|
821
|
-
const
|
|
857
|
+
const keyParam = req.query.key;
|
|
858
|
+
if (Array.isArray(keyParam)) {
|
|
859
|
+
error(res, 400, 'Invalid key.');
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
const key = keyParam;
|
|
822
863
|
if (key) {
|
|
823
864
|
if (['__proto__', 'constructor', 'prototype'].some((p) => key.includes(p))) {
|
|
824
865
|
error(res, 400, 'Invalid key.');
|