@20syldev/api 3.5.0 → 4.1.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 (213) hide show
  1. package/.prettierrc +7 -0
  2. package/README.md +32 -33
  3. package/dist/app.js +36 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/config/env.js +73 -0
  6. package/dist/config/env.js.map +1 -0
  7. package/dist/config/versions.js +72 -0
  8. package/dist/config/versions.js.map +1 -0
  9. package/dist/constants.js +42 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/middleware/cors.js +15 -0
  12. package/dist/middleware/cors.js.map +1 -0
  13. package/dist/middleware/error.js +6 -0
  14. package/dist/middleware/error.js.map +1 -0
  15. package/dist/middleware/json.js +8 -0
  16. package/dist/middleware/json.js.map +1 -0
  17. package/dist/middleware/logger.js +26 -0
  18. package/dist/middleware/logger.js.map +1 -0
  19. package/dist/middleware/ratelimit.js +58 -0
  20. package/dist/middleware/ratelimit.js.map +1 -0
  21. package/dist/middleware/version.js +30 -0
  22. package/dist/middleware/version.js.map +1 -0
  23. package/dist/modules/v3/algorithms.js +221 -0
  24. package/dist/modules/v3/algorithms.js.map +1 -0
  25. package/{modules → dist/modules}/v3/captcha.js +4 -13
  26. package/dist/modules/v3/captcha.js.map +1 -0
  27. package/dist/modules/v3/chat.js +103 -0
  28. package/dist/modules/v3/chat.js.map +1 -0
  29. package/{modules → dist/modules}/v3/color.js +12 -13
  30. package/dist/modules/v3/color.js.map +1 -0
  31. package/dist/modules/v3/convert.js +41 -0
  32. package/dist/modules/v3/convert.js.map +1 -0
  33. package/dist/modules/v3/domain.js +83 -0
  34. package/dist/modules/v3/domain.js.map +1 -0
  35. package/dist/modules/v3/hash.js +16 -0
  36. package/dist/modules/v3/hash.js.map +1 -0
  37. package/dist/modules/v3/hyperplanning.js +50 -0
  38. package/dist/modules/v3/hyperplanning.js.map +1 -0
  39. package/dist/modules/v3/levenshtein.js +38 -0
  40. package/dist/modules/v3/levenshtein.js.map +1 -0
  41. package/dist/modules/v3/personal.js +129 -0
  42. package/dist/modules/v3/personal.js.map +1 -0
  43. package/dist/modules/v3/qrcode.js +21 -0
  44. package/dist/modules/v3/qrcode.js.map +1 -0
  45. package/dist/modules/v3/tic_tac_toe.js +221 -0
  46. package/dist/modules/v3/tic_tac_toe.js.map +1 -0
  47. package/dist/modules/v3/time.js +88 -0
  48. package/dist/modules/v3/time.js.map +1 -0
  49. package/{modules → dist/modules}/v3/token.js +10 -11
  50. package/dist/modules/v3/token.js.map +1 -0
  51. package/dist/modules/v3/username.js +92 -0
  52. package/dist/modules/v3/username.js.map +1 -0
  53. package/dist/modules/v3/utils.js +70 -0
  54. package/dist/modules/v3/utils.js.map +1 -0
  55. package/dist/modules/v3.js +16 -0
  56. package/dist/modules/v3.js.map +1 -0
  57. package/dist/modules/v4/algorithms.js +200 -0
  58. package/dist/modules/v4/algorithms.js.map +1 -0
  59. package/dist/modules/v4/captcha.js +35 -0
  60. package/dist/modules/v4/captcha.js.map +1 -0
  61. package/dist/modules/v4/chat.js +92 -0
  62. package/dist/modules/v4/chat.js.map +1 -0
  63. package/dist/modules/v4/color.js +43 -0
  64. package/dist/modules/v4/color.js.map +1 -0
  65. package/dist/modules/v4/convert.js +33 -0
  66. package/dist/modules/v4/convert.js.map +1 -0
  67. package/dist/modules/v4/dice.js +30 -0
  68. package/dist/modules/v4/dice.js.map +1 -0
  69. package/dist/modules/v4/domain.js +78 -0
  70. package/dist/modules/v4/domain.js.map +1 -0
  71. package/dist/modules/v4/encode.js +165 -0
  72. package/dist/modules/v4/encode.js.map +1 -0
  73. package/dist/modules/v4/geo.js +41 -0
  74. package/dist/modules/v4/geo.js.map +1 -0
  75. package/dist/modules/v4/hash.js +9 -0
  76. package/dist/modules/v4/hash.js.map +1 -0
  77. package/dist/modules/v4/hyperplanning.js +42 -0
  78. package/dist/modules/v4/hyperplanning.js.map +1 -0
  79. package/dist/modules/v4/levenshtein.js +29 -0
  80. package/dist/modules/v4/levenshtein.js.map +1 -0
  81. package/dist/modules/v4/palette.js +89 -0
  82. package/dist/modules/v4/palette.js.map +1 -0
  83. package/dist/modules/v4/personal.js +125 -0
  84. package/dist/modules/v4/personal.js.map +1 -0
  85. package/dist/modules/v4/placeholder.js +96 -0
  86. package/dist/modules/v4/placeholder.js.map +1 -0
  87. package/dist/modules/v4/qrcode.js +12 -0
  88. package/dist/modules/v4/qrcode.js.map +1 -0
  89. package/dist/modules/v4/statistics.js +41 -0
  90. package/dist/modules/v4/statistics.js.map +1 -0
  91. package/dist/modules/v4/text.js +293 -0
  92. package/dist/modules/v4/text.js.map +1 -0
  93. package/dist/modules/v4/tic_tac_toe.js +206 -0
  94. package/dist/modules/v4/tic_tac_toe.js.map +1 -0
  95. package/dist/modules/v4/time.js +73 -0
  96. package/dist/modules/v4/time.js.map +1 -0
  97. package/dist/modules/v4/token.js +36 -0
  98. package/dist/modules/v4/token.js.map +1 -0
  99. package/dist/modules/v4/username.js +87 -0
  100. package/dist/modules/v4/username.js.map +1 -0
  101. package/dist/modules/v4/utils.js +26 -0
  102. package/dist/modules/v4/utils.js.map +1 -0
  103. package/dist/modules/v4/validate.js +54 -0
  104. package/dist/modules/v4/validate.js.map +1 -0
  105. package/dist/modules/v4.js +18 -0
  106. package/dist/modules/v4.js.map +1 -0
  107. package/dist/routes/delete.js +65 -0
  108. package/dist/routes/delete.js.map +1 -0
  109. package/dist/routes/get.js +441 -0
  110. package/dist/routes/get.js.map +1 -0
  111. package/dist/routes/index.js +50 -0
  112. package/dist/routes/index.js.map +1 -0
  113. package/dist/routes/patch.js +41 -0
  114. package/dist/routes/patch.js.map +1 -0
  115. package/dist/routes/post.js +185 -0
  116. package/dist/routes/post.js.map +1 -0
  117. package/dist/storage/index.js +13 -0
  118. package/dist/storage/index.js.map +1 -0
  119. package/dist/types/storage.js +2 -0
  120. package/dist/types/storage.js.map +1 -0
  121. package/dist/utils/response.js +10 -0
  122. package/dist/utils/response.js.map +1 -0
  123. package/dist/utils/version.js +3 -0
  124. package/dist/utils/version.js.map +1 -0
  125. package/docs/changelog.md +333 -0
  126. package/eslint.config.js +20 -0
  127. package/package.json +31 -15
  128. package/src/app.ts +48 -0
  129. package/src/config/env.ts +81 -0
  130. package/src/config/versions.ts +92 -0
  131. package/src/constants.ts +47 -0
  132. package/src/middleware/cors.ts +17 -0
  133. package/src/middleware/error.ts +7 -0
  134. package/src/middleware/json.ts +9 -0
  135. package/src/middleware/logger.ts +31 -0
  136. package/src/middleware/ratelimit.ts +66 -0
  137. package/src/middleware/version.ts +39 -0
  138. package/{modules → src/modules}/v3/algorithms.js +1 -1
  139. package/src/modules/v3/captcha.js +60 -0
  140. package/{modules → src/modules}/v3/chat.js +6 -4
  141. package/src/modules/v3/color.js +60 -0
  142. package/{modules → src/modules}/v3/convert.js +5 -5
  143. package/{modules → src/modules}/v3/domain.js +51 -4
  144. package/{modules → src/modules}/v3/hash.js +1 -1
  145. package/{modules → src/modules}/v3/hyperplanning.js +11 -10
  146. package/{modules → src/modules}/v3/levenshtein.js +3 -3
  147. package/{modules → src/modules}/v3/personal.js +20 -8
  148. package/{modules → src/modules}/v3/qrcode.js +1 -1
  149. package/{modules → src/modules}/v3/tic_tac_toe.js +24 -18
  150. package/{modules → src/modules}/v3/time.js +22 -11
  151. package/src/modules/v3/token.js +54 -0
  152. package/src/modules/v3/username.js +94 -0
  153. package/{modules → src/modules}/v3/utils.js +2 -2
  154. package/{modules → src/modules}/v3.js +1 -1
  155. package/src/modules/v4/algorithms.ts +197 -0
  156. package/src/modules/v4/captcha.ts +49 -0
  157. package/src/modules/v4/chat.ts +122 -0
  158. package/src/modules/v4/color.ts +64 -0
  159. package/src/modules/v4/convert.ts +38 -0
  160. package/src/modules/v4/dice.ts +39 -0
  161. package/src/modules/v4/domain.ts +81 -0
  162. package/src/modules/v4/encode.ts +170 -0
  163. package/src/modules/v4/geo.ts +53 -0
  164. package/src/modules/v4/hash.ts +9 -0
  165. package/src/modules/v4/hyperplanning.ts +58 -0
  166. package/src/modules/v4/levenshtein.ts +38 -0
  167. package/src/modules/v4/palette.ts +103 -0
  168. package/src/modules/v4/personal.ts +147 -0
  169. package/src/modules/v4/placeholder.ts +122 -0
  170. package/src/modules/v4/qrcode.ts +11 -0
  171. package/src/modules/v4/statistics.ts +55 -0
  172. package/src/modules/v4/text.ts +300 -0
  173. package/src/modules/v4/tic_tac_toe.ts +255 -0
  174. package/src/modules/v4/time.ts +92 -0
  175. package/src/modules/v4/token.ts +43 -0
  176. package/src/modules/v4/username.ts +89 -0
  177. package/src/modules/v4/utils.ts +38 -0
  178. package/src/modules/v4/validate.ts +55 -0
  179. package/src/modules/v4.ts +17 -0
  180. package/src/routes/delete.ts +72 -0
  181. package/src/routes/get.ts +508 -0
  182. package/src/routes/index.ts +58 -0
  183. package/src/routes/patch.ts +45 -0
  184. package/src/routes/post.ts +200 -0
  185. package/src/storage/index.ts +16 -0
  186. package/src/types/express.d.ts +17 -0
  187. package/src/types/storage.ts +48 -0
  188. package/src/utils/response.ts +11 -0
  189. package/src/utils/version.ts +5 -0
  190. package/tests/integration/api.test.ts +395 -0
  191. package/tests/tsconfig.json +3 -0
  192. package/tests/unit/algorithms.test.ts +120 -0
  193. package/tests/unit/color.test.ts +33 -0
  194. package/tests/unit/convert.test.ts +42 -0
  195. package/tests/unit/dice.test.ts +57 -0
  196. package/tests/unit/domain.test.ts +47 -0
  197. package/tests/unit/encode.test.ts +108 -0
  198. package/tests/unit/geo.test.ts +45 -0
  199. package/tests/unit/hash.test.ts +37 -0
  200. package/tests/unit/hyperplanning.test.ts +77 -0
  201. package/tests/unit/levenshtein.test.ts +34 -0
  202. package/tests/unit/palette.test.ts +53 -0
  203. package/tests/unit/personal.test.ts +65 -0
  204. package/tests/unit/statistics.test.ts +57 -0
  205. package/tests/unit/text.test.ts +107 -0
  206. package/tests/unit/time.test.ts +67 -0
  207. package/tests/unit/token.test.ts +61 -0
  208. package/tests/unit/username.test.ts +34 -0
  209. package/tests/unit/validate.test.ts +71 -0
  210. package/tsconfig.json +17 -0
  211. package/tsconfig.test.json +9 -0
  212. package/app.js +0 -865
  213. package/modules/v3/username.js +0 -32
@@ -0,0 +1,185 @@
1
+ import { Router } from 'express';
2
+ import { chatStorage, ticTacToeStorage } from '../storage/index.js';
3
+ import { MIN_TOKEN_LENGTH, MAX_TOKEN_LENGTH } from '../constants.js';
4
+ import { error } from '../utils/response.js';
5
+ const router = Router();
6
+ // Store chat messages
7
+ router.post('/:version/chat', (req, res) => {
8
+ const { username, message, timestamp, session, token } = req.body || {};
9
+ if (!username) {
10
+ error(res, 400, 'Please provide a username (?username={username})');
11
+ return;
12
+ }
13
+ if (!message) {
14
+ error(res, 400, 'Please provide a message (&message={message})');
15
+ return;
16
+ }
17
+ if (!session) {
18
+ error(res, 400, 'Please provide a valid session ID (&session={ID})');
19
+ return;
20
+ }
21
+ try {
22
+ const result = req.module.chat('message', {
23
+ username,
24
+ message,
25
+ timestamp,
26
+ session,
27
+ token,
28
+ storage: chatStorage,
29
+ });
30
+ res.jsonResponse(result);
31
+ }
32
+ catch (err) {
33
+ error(res, 400, err.message);
34
+ }
35
+ });
36
+ // Display a private chat with a token
37
+ router.post('/:version/chat/private', (req, res) => {
38
+ const { username, token } = req.body || {};
39
+ if (!username) {
40
+ error(res, 400, 'Please provide a username (?username={username})');
41
+ return;
42
+ }
43
+ if (!token) {
44
+ error(res, 400, 'Please provide a valid token (&token={key}).');
45
+ return;
46
+ }
47
+ try {
48
+ const messages = req.module.chat('private', {
49
+ username,
50
+ token,
51
+ storage: chatStorage,
52
+ });
53
+ res.jsonResponse(messages);
54
+ }
55
+ catch (err) {
56
+ error(res, 400, err.message);
57
+ }
58
+ });
59
+ // Generate hash
60
+ router.post('/:version/hash', (req, res) => {
61
+ const { text, method } = req.body || {};
62
+ if (!text) {
63
+ error(res, 400, 'Please provide a text (?text={text})', `${req.version}/hash`);
64
+ return;
65
+ }
66
+ if (!method) {
67
+ error(res, 400, 'Please provide a valid hash algorithm (&method={algorithm})', `${req.version}/hash`);
68
+ return;
69
+ }
70
+ try {
71
+ const result = req.module.hash(text, method);
72
+ res.jsonResponse(result);
73
+ }
74
+ catch (err) {
75
+ error(res, 400, err.message, `${req.version}/hash`);
76
+ }
77
+ });
78
+ // Display a planning from an ICS file
79
+ router.post('/:version/hyperplanning', async (req, res) => {
80
+ const { url, detail } = req.body || {};
81
+ if (!url) {
82
+ error(res, 400, 'Please provide a valid ICS file URL (?url={URL})', `${req.version}/hyperplanning`);
83
+ return;
84
+ }
85
+ try {
86
+ const hyperplanning = await req.module.hyperplanning(url, detail);
87
+ res.jsonResponse(hyperplanning);
88
+ }
89
+ catch (err) {
90
+ error(res, 400, err.message, `${req.version}/hyperplanning`);
91
+ }
92
+ });
93
+ // Store tic tac toe games
94
+ router.post('/:version/tic-tac-toe', (req, res) => {
95
+ const { username, move, session, game } = req.body || {};
96
+ if (!username) {
97
+ error(res, 400, 'Please provide a username (?username={username})');
98
+ return;
99
+ }
100
+ if (!move) {
101
+ error(res, 400, 'Please provide a valid move (&move={move})');
102
+ return;
103
+ }
104
+ if (!session) {
105
+ error(res, 400, 'Please provide a valid session ID (&session={ID})');
106
+ return;
107
+ }
108
+ if (!game) {
109
+ error(res, 400, 'Please provide a valid game ID (&game={ID})');
110
+ return;
111
+ }
112
+ try {
113
+ const result = req.module.tic_tac_toe('play', {
114
+ username,
115
+ move,
116
+ session,
117
+ game,
118
+ storage: ticTacToeStorage,
119
+ });
120
+ res.jsonResponse(result);
121
+ }
122
+ catch (err) {
123
+ error(res, 400, err.message);
124
+ }
125
+ });
126
+ // Display a tic tac toe game with a token
127
+ router.post('/:version/tic-tac-toe/fetch', (req, res) => {
128
+ const { username, game } = req.body || {};
129
+ const privateGame = (req.body || {}).private;
130
+ if (!username) {
131
+ error(res, 400, 'Please provide a username (?username={username})');
132
+ return;
133
+ }
134
+ try {
135
+ const result = req.module.tic_tac_toe('fetch', {
136
+ username,
137
+ game,
138
+ private: privateGame,
139
+ storage: ticTacToeStorage,
140
+ });
141
+ res.jsonResponse(result);
142
+ }
143
+ catch (err) {
144
+ error(res, 400, err.message);
145
+ }
146
+ });
147
+ // List public tic tac toe games
148
+ router.post('/:version/tic-tac-toe/list', (req, res) => {
149
+ try {
150
+ const result = req.module.tic_tac_toe('list', {
151
+ storage: ticTacToeStorage,
152
+ });
153
+ res.jsonResponse(result);
154
+ }
155
+ catch (err) {
156
+ error(res, 400, err.message);
157
+ }
158
+ });
159
+ // Generate Token
160
+ router.post('/:version/token', (req, res) => {
161
+ const body = req.body || {};
162
+ const len = parseInt(String(body.len || 24), 10);
163
+ const type = body.type ? String(body.type).toLowerCase() : 'alpha';
164
+ if (isNaN(len) || len < 0) {
165
+ error(res, 400, 'Invalid number.', `${req.version}/token`);
166
+ return;
167
+ }
168
+ if (len > MAX_TOKEN_LENGTH) {
169
+ error(res, 400, 'Length cannot exceed 4096.', `${req.version}/token`);
170
+ return;
171
+ }
172
+ if (len < MIN_TOKEN_LENGTH) {
173
+ error(res, 400, 'Length cannot be less than 12.', `${req.version}/token`);
174
+ return;
175
+ }
176
+ try {
177
+ const token = req.module.token(len, type);
178
+ res.jsonResponse({ token });
179
+ }
180
+ catch (err) {
181
+ error(res, 400, err.message, `${req.version}/token`);
182
+ }
183
+ });
184
+ export default router;
185
+ //# sourceMappingURL=post.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.js","sourceRoot":"","sources":["../../src/routes/post.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export const ipLimits = {};
2
+ export const chatStorage = {
3
+ messages: [],
4
+ privateChats: {},
5
+ sessions: {},
6
+ rateLimits: {},
7
+ };
8
+ export const ticTacToeStorage = {
9
+ games: {},
10
+ sessions: {},
11
+ rateLimits: {},
12
+ };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAa,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,WAAW,GAAgB;IACpC,QAAQ,EAAE,EAAE;IACZ,YAAY,EAAE,EAAE;IAChB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAqB;IAC9C,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;CACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/types/storage.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { DOCS_URL, STATUS_MESSAGES } from '../constants.js';
2
+ export function error(res, status, message, docPath) {
3
+ res.status(status).jsonResponse({
4
+ message: STATUS_MESSAGES[status] ?? 'Error',
5
+ error: message,
6
+ documentation: docPath ? `${DOCS_URL}/${docPath}` : DOCS_URL,
7
+ status: String(status),
8
+ });
9
+ }
10
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE5D,MAAM,UAAU,KAAK,CAAC,GAAa,EAAE,MAAc,EAAE,OAAe,EAAE,OAAgB;IAClF,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC;QAC5B,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,OAAO;QAC3C,KAAK,EAAE,OAAO;QACd,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ;QAC5D,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;KACzB,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ const REST_VERSIONS = new Set(['v4']);
2
+ export const supportsRest = (req) => REST_VERSIONS.has(req.version);
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAY,EAAW,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC"}
@@ -0,0 +1,333 @@
1
+ # Changelog
2
+
3
+ ## Exemples curl
4
+
5
+ ```bash
6
+ # dice
7
+ curl -X GET "http://127.0.0.1:3000/v4/dice?roll=2d6%2B3"
8
+
9
+ # encode
10
+ curl -X GET "http://127.0.0.1:3000/v4/encode?method=base64encode&text=hello"
11
+ curl -X GET "http://127.0.0.1:3000/v4/encode?method=morse&text=SOS"
12
+ curl -X GET "http://127.0.0.1:3000/v4/encode?method=caesar&text=hello&shift=3"
13
+
14
+ # geo
15
+ curl -X GET "http://127.0.0.1:3000/v4/geo?lat1=48.8566&lon1=2.3522&lat2=43.2965&lon2=5.3698"
16
+
17
+ # palette
18
+ curl -X GET "http://127.0.0.1:3000/v4/palette?color=%23ff6600&type=triadic"
19
+
20
+ # statistics
21
+ curl -X GET "http://127.0.0.1:3000/v4/statistics?values=1,2,3,4,5"
22
+
23
+ # text - stats
24
+ curl -X GET "http://127.0.0.1:3000/v4/text?method=stats&value=Hello+world"
25
+
26
+ # text - slug
27
+ curl -X GET "http://127.0.0.1:3000/v4/text?method=slug&value=Héllo+Wörld%21"
28
+
29
+ # text - lorem
30
+ curl -X GET "http://127.0.0.1:3000/v4/text?method=lorem&type=sentences&count=3"
31
+
32
+ # text - number
33
+ curl -X GET "http://127.0.0.1:3000/v4/text?method=number&value=42&lang=fr"
34
+
35
+ # validate - luhn
36
+ curl -X GET "http://127.0.0.1:3000/v4/validate?type=luhn&value=4532015112830366"
37
+
38
+ # validate - iban
39
+ curl -X GET "http://127.0.0.1:3000/v4/validate?type=iban&value=FR7630006000011234567890189"
40
+
41
+ # validate - email
42
+ curl -X GET "http://127.0.0.1:3000/v4/validate?type=email&value=user%40example.com"
43
+
44
+ # algorithms - roman
45
+ curl -X GET "http://127.0.0.1:3000/v4/algorithms?method=roman&value=42"
46
+ curl -X GET "http://127.0.0.1:3000/v4/algorithms?method=roman&value=XLII"
47
+
48
+ # REST v4.2 - jouer un coup (PATCH)
49
+ curl -X PATCH "http://127.0.0.1:3000/v4/tic-tac-toe/{gameId}" \
50
+ -H "Content-Type: application/json" \
51
+ -d '{"username":"alice","move":"A1","session":"abc123"}'
52
+
53
+ # REST v4.2 - forfait (DELETE tic-tac-toe)
54
+ curl -X DELETE "http://127.0.0.1:3000/v4/tic-tac-toe/{gameId}" \
55
+ -H "Content-Type: application/json" \
56
+ -d '{"username":"alice","session":"abc123"}'
57
+
58
+ # REST v4.2 - vider un chat (DELETE chat)
59
+ curl -X DELETE "http://127.0.0.1:3000/v4/chat/{token}" \
60
+ -H "Content-Type: application/json" \
61
+ -d '{"username":"alice","session":"abc123"}'
62
+ ```
63
+
64
+
65
+
66
+ ## v4.2.0
67
+
68
+ ### REST endpoints pour tic-tac-toe et chat
69
+
70
+ Les endpoints existants ont été étendus avec des méthodes HTTP REST. Uniquement disponible en `v4+`.
71
+
72
+ #### PATCH `/v4/tic-tac-toe/:game`
73
+
74
+ Jouer un coup dans une partie.
75
+
76
+ **Body (JSON) :**
77
+ | Param | Type | Description |
78
+ |-------|------|-------------|
79
+ | `username` | string | Nom du joueur |
80
+ | `move` | string | Case jouée (ex: `A1`) |
81
+ | `session` | string | ID de session |
82
+
83
+ ---
84
+
85
+ #### DELETE `/v4/tic-tac-toe/:game`
86
+
87
+ Abandonner une partie (forfeit).
88
+
89
+ **Body (JSON) :**
90
+ | Param | Type | Description |
91
+ |-------|------|-------------|
92
+ | `username` | string | Nom du joueur |
93
+ | `session` | string | ID de session |
94
+
95
+ ---
96
+
97
+ #### DELETE `/v4/chat/:token`
98
+
99
+ Effacer tous les messages d'un chat privé (clear).
100
+
101
+ **Body (JSON) :**
102
+ | Param | Type | Description |
103
+ |-------|------|-------------|
104
+ | `username` | string | Nom de l'utilisateur |
105
+ | `session` | string | ID de session |
106
+
107
+ ---
108
+
109
+ ### Autres changements v4.2.0
110
+
111
+ - CORS : ajout de `PATCH`, `DELETE`, `OPTIONS` dans les headers autorisés
112
+ - Nouveau helper `supportsRest()` dans `src/utils/version.ts`
113
+
114
+ ---
115
+
116
+ ## v4.1.0
117
+
118
+ ### Nouveaux endpoints
119
+
120
+ #### GET `/v4/dice`
121
+
122
+ Lance des dés en notation RPG.
123
+
124
+ **Query params :**
125
+ | Param | Requis | Description | Exemple |
126
+ |-------|--------|-------------|---------|
127
+ | `roll` | oui | Notation NdX ou NdX+M | `2d6+3` |
128
+
129
+ **Note :** le `+` dans l'URL peut être encodé en espace (`2d6 3`) — les deux sont acceptés.
130
+
131
+ **Réponse :**
132
+ ```json
133
+ {
134
+ "roll": "2d6+3",
135
+ "count": 2,
136
+ "sides": 6,
137
+ "modifier": 3,
138
+ "results": [4, 2],
139
+ "total": 9
140
+ }
141
+ ```
142
+
143
+ Limites : 1–100 dés, 2–1000 faces.
144
+
145
+ ---
146
+
147
+ #### GET `/v4/encode`
148
+
149
+ Encode ou décode du texte dans différents formats.
150
+
151
+ **Query params :**
152
+ | Param | Requis | Description |
153
+ |-------|--------|-------------|
154
+ | `method` | oui | Voir liste ci-dessous |
155
+ | `value` | oui | Texte à traiter |
156
+ | `shift` | non | Décalage pour Caesar (défaut : 13) |
157
+
158
+ **Méthodes disponibles :**
159
+ | `method` | Description |
160
+ |----------|-------------|
161
+ | `base64encode` | Encode en Base64 |
162
+ | `base64decode` | Décode du Base64 |
163
+ | `urlencode` | Encode pour URL |
164
+ | `urldecode` | Décode une URL |
165
+ | `morse` | Texte → Morse |
166
+ | `unmorse` | Morse → Texte |
167
+ | `rot13` | ROT-13 |
168
+ | `caesar` | Chiffre de César (nécessite `shift`) |
169
+ | `binary` | Texte → binaire 8 bits |
170
+ | `unbinary` | Binaire → texte |
171
+
172
+ ---
173
+
174
+ #### GET `/v4/geo`
175
+
176
+ Calcule la distance et le cap entre deux coordonnées GPS (Haversine).
177
+
178
+ **Query params :**
179
+ | Param | Requis | Description |
180
+ |-------|--------|-------------|
181
+ | `lat1` | oui | Latitude point A (-90/+90) |
182
+ | `lon1` | oui | Longitude point A (-180/+180) |
183
+ | `lat2` | oui | Latitude point B |
184
+ | `lon2` | oui | Longitude point B |
185
+
186
+ **Réponse :**
187
+ ```json
188
+ {
189
+ "distance": { "km": 1214.652, "miles": 754.801, "nauticalMiles": 655.879 },
190
+ "bearing": { "degrees": 157.34, "cardinal": "SSE" },
191
+ "from": { "lat": 48.8566, "lon": 2.3522 },
192
+ "to": { "lat": 43.2965, "lon": 5.3698 }
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ #### GET `/v4/palette`
199
+
200
+ Génère une palette de couleurs harmonieuse à partir d'une couleur HEX.
201
+
202
+ **Query params :**
203
+ | Param | Requis | Description |
204
+ |-------|--------|-------------|
205
+ | `color` | oui | Couleur base en HEX (`#RRGGBB`) |
206
+ | `type` | oui | Type de palette |
207
+
208
+ **Types disponibles :**
209
+ | `type` | Couleurs générées |
210
+ |--------|------------------|
211
+ | `complementary` | 2 couleurs (opposées) |
212
+ | `triadic` | 3 couleurs (120°) |
213
+ | `analogous` | 5 couleurs (-60° à +60°) |
214
+ | `tetradic` | 4 couleurs (90°) |
215
+ | `split-complementary` | 3 couleurs |
216
+
217
+ Chaque couleur retournée a `hex`, `rgb`, `hsl`.
218
+
219
+ ---
220
+
221
+ #### GET `/v4/statistics`
222
+
223
+ Calcule des statistiques descriptives sur une liste de nombres.
224
+
225
+ **Query params :**
226
+ | Param | Requis | Description |
227
+ |-------|--------|-------------|
228
+ | `values` | oui | Nombres séparés par des virgules |
229
+
230
+ **Réponse :**
231
+ ```json
232
+ {
233
+ "count": 5,
234
+ "sum": 15,
235
+ "min": 1,
236
+ "max": 5,
237
+ "range": 4,
238
+ "mean": 3,
239
+ "median": 3,
240
+ "mode": [],
241
+ "variance": 2,
242
+ "stddev": 1.414214
243
+ }
244
+ ```
245
+
246
+ ---
247
+
248
+ #### GET `/v4/text`
249
+
250
+ Manipulation et génération de texte.
251
+
252
+ **Query params :**
253
+ | Param | Requis | Description |
254
+ |-------|--------|-------------|
255
+ | `action` | oui | Voir liste ci-dessous |
256
+ | `value` | non | Texte source (selon action) |
257
+ | `type` | non | `words`, `sentences`, `paragraphs` (pour `lorem`) |
258
+ | `count` | non | Nombre d'éléments (pour `lorem`, défaut 5) |
259
+ | `lang` | non | `fr` ou `en` (pour `number`) |
260
+
261
+ **Actions disponibles :**
262
+ | `action` | Description | Params requis |
263
+ |----------|-------------|---------------|
264
+ | `stats` | Statistiques du texte | `value` |
265
+ | `slug` | Convertit en slug URL | `value` |
266
+ | `lorem` | Génère du Lorem Ipsum | `type`, `count` |
267
+ | `number` | Nombre en lettres | `value`, `lang` |
268
+
269
+ **Réponse `stats` :**
270
+ ```json
271
+ {
272
+ "characters": 42,
273
+ "charactersNoSpaces": 35,
274
+ "words": 8,
275
+ "sentences": 2,
276
+ "paragraphs": 1,
277
+ "readingTime": "3s",
278
+ "mostFrequentChar": "e"
279
+ }
280
+ ```
281
+
282
+ ---
283
+
284
+ #### GET `/v4/validate`
285
+
286
+ Valide différents formats de données.
287
+
288
+ **Query params :**
289
+ | Param | Requis | Description |
290
+ |-------|--------|-------------|
291
+ | `type` | oui | `luhn`, `iban`, `email` |
292
+ | `value` | oui | Valeur à valider |
293
+
294
+ **Réponse `luhn` (numéro de carte) :**
295
+ ```json
296
+ { "valid": true, "value": "4532015112830366" }
297
+ ```
298
+
299
+ **Réponse `iban` :**
300
+ ```json
301
+ { "valid": true, "value": "FR7630006000011234567890189", "country": "FR" }
302
+ ```
303
+
304
+ **Réponse `email` :**
305
+ ```json
306
+ { "valid": true, "value": "user@example.com" }
307
+ ```
308
+
309
+ ---
310
+
311
+ ### Ajout à un endpoint existant
312
+
313
+ #### GET `/v4/algorithms` — conversion de chiffres romains
314
+
315
+ Nouvelle action `roman` sur l'endpoint algorithms.
316
+
317
+ **Query params :**
318
+ | Param | Requis | Description |
319
+ |-------|--------|-------------|
320
+ | `method` | oui | `roman` |
321
+ | `value` | oui | Nombre entier (1–3999) ou chiffre romain |
322
+
323
+ Bidirectionnel : `42` → `XLII`, `XLII` → `42`.
324
+
325
+ ---
326
+
327
+ ### Infrastructure v4.1.0
328
+
329
+ - **`src/app.ts`** : `export default app` + guard `NODE_ENV !== 'test'` pour les tests d'intégration
330
+ - **`src/config/versions.ts`** : helper `merge()` pour dédoublonner les endpoints par `name`
331
+ - **`tsconfig.test.json`** : étend le tsconfig principal, inclut `src/` et `tests/`
332
+ - **`tests/tsconfig.json`** : pointe vers `tsconfig.test.json` pour la résolution IDE
333
+ - **`package.json`** : script `npm test` avec `--test-force-exit` (requis car `setTimeout` dans chat/tic-tac-toe)
@@ -0,0 +1,20 @@
1
+ import eslint from '@eslint/js';
2
+ import tseslint from 'typescript-eslint';
3
+ import eslintConfigPrettier from 'eslint-config-prettier';
4
+
5
+ export default tseslint.config(
6
+ eslint.configs.recommended,
7
+ ...tseslint.configs.strict,
8
+ eslintConfigPrettier,
9
+ {
10
+ rules: {
11
+ '@typescript-eslint/no-explicit-any': 'warn',
12
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
13
+ '@typescript-eslint/no-non-null-assertion': 'off',
14
+ '@typescript-eslint/no-dynamic-delete': 'off',
15
+ },
16
+ },
17
+ {
18
+ ignores: ['dist/', 'node_modules/', 'src/modules/v3/'],
19
+ },
20
+ );
package/package.json CHANGED
@@ -1,38 +1,53 @@
1
1
  {
2
- "version": "3.5.0",
2
+ "version": "4.1.0",
3
3
  "name": "@20syldev/api",
4
4
  "description": "Node.js API with multiple features. Check the documentation at https://docs.sylvain.sh",
5
- "main": "app.js",
5
+ "main": "dist/app.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
- "start": "node app.js",
9
- "dev": "nodemon app.js",
10
- "build": "npm install && node app.js",
11
- "lint": "prettier --write .",
8
+ "dev": "tsx watch src/app.ts",
9
+ "start": "node dist/app.js",
10
+ "build": "tsc",
11
+ "check": "tsc --noEmit -p tsconfig.test.json && eslint src/ tests/",
12
+ "format": "prettier --write src/ tests/ && eslint --fix src/ tests/",
13
+ "test": "NODE_ENV=test node --import tsx --test --test-force-exit tests/unit/*.test.ts tests/integration/*.test.ts",
12
14
  "upgrade:minor": "npm upgrade",
13
- "upgrade:major": "npx npm-check-updates -u && npm install",
14
- "upgrade:build": "npm upgrade && npm install && node app.js"
15
+ "upgrade:major": "npx npm-check-updates -u && npm install"
16
+ },
17
+ "engines": {
18
+ "node": ">=22.0.0"
15
19
  },
16
20
  "exports": {
17
- "./v1": "./modules/v1.js",
18
- "./v2": "./modules/v2.js",
19
- "./v3": "./modules/v3.js"
21
+ "./v1": "./dist/modules/v1.js",
22
+ "./v2": "./dist/modules/v2.js",
23
+ "./v3": "./dist/modules/v3.js",
24
+ "./v4": "./dist/modules/v4.js"
20
25
  },
21
26
  "dependencies": {
27
+ "@20syldev/logger.ts": "^1.0.1",
22
28
  "canvas": "^3.1.0",
23
29
  "cors": "^2.8.5",
24
30
  "dotenv": "^16.4.7",
25
31
  "express": "^5.1.0",
26
32
  "ical.js": "^2.1.0",
27
- "node-fetch": "^3.3.2",
28
33
  "qrcode": "^1.5.4",
29
34
  "random": "^5.3.0",
30
35
  "uuid": "^11.1.0"
31
36
  },
32
37
  "devDependencies": {
33
- "nodemon": "^3.1.10",
38
+ "@eslint/js": "^9.24.0",
39
+ "@types/cors": "^2.8.17",
40
+ "@types/express": "^5.0.0",
41
+ "@types/node": "^22.19.17",
42
+ "@types/qrcode": "^1.5.6",
43
+ "@types/uuid": "^10.0.0",
44
+ "eslint": "^9.24.0",
45
+ "eslint-config-prettier": "^10.1.1",
34
46
  "npm-check-updates": "^18.0.1",
35
- "prettier": "^3.5.3"
47
+ "prettier": "^3.5.3",
48
+ "tsx": "^4.19.0",
49
+ "typescript": "^5.7.0",
50
+ "typescript-eslint": "^8.29.0"
36
51
  },
37
52
  "publishConfig": {
38
53
  "access": "public"
@@ -45,7 +60,8 @@
45
60
  "api",
46
61
  "express",
47
62
  "utility",
48
- "math"
63
+ "math",
64
+ "typescript"
49
65
  ],
50
66
  "author": "Sylvain L.",
51
67
  "license": "BSD 3-Clause",