@moxon/api 6.0.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.
Files changed (246) hide show
  1. package/.prettierignore +5 -0
  2. package/LICENSE +28 -0
  3. package/README.md +277 -0
  4. package/dist/app.d.ts +2 -0
  5. package/dist/app.js +55 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/config/env.d.ts +22 -0
  8. package/dist/config/env.js +36 -0
  9. package/dist/config/env.js.map +1 -0
  10. package/dist/config/plans.d.ts +26 -0
  11. package/dist/config/plans.js +44 -0
  12. package/dist/config/plans.js.map +1 -0
  13. package/dist/config/versions.d.ts +18 -0
  14. package/dist/config/versions.js +248 -0
  15. package/dist/config/versions.js.map +1 -0
  16. package/dist/constants.d.ts +48 -0
  17. package/dist/constants.js +75 -0
  18. package/dist/constants.js.map +1 -0
  19. package/dist/middleware/cors.d.ts +2 -0
  20. package/dist/middleware/cors.js +31 -0
  21. package/dist/middleware/cors.js.map +1 -0
  22. package/dist/middleware/error.d.ts +4 -0
  23. package/dist/middleware/error.js +8 -0
  24. package/dist/middleware/error.js.map +1 -0
  25. package/dist/middleware/json.d.ts +2 -0
  26. package/dist/middleware/json.js +8 -0
  27. package/dist/middleware/json.js.map +1 -0
  28. package/dist/middleware/logger.d.ts +26 -0
  29. package/dist/middleware/logger.js +65 -0
  30. package/dist/middleware/logger.js.map +1 -0
  31. package/dist/middleware/ratelimit.d.ts +2 -0
  32. package/dist/middleware/ratelimit.js +83 -0
  33. package/dist/middleware/ratelimit.js.map +1 -0
  34. package/dist/middleware/version.d.ts +3 -0
  35. package/dist/middleware/version.js +30 -0
  36. package/dist/middleware/version.js.map +1 -0
  37. package/dist/modules/v4/address.d.ts +20 -0
  38. package/dist/modules/v4/address.js +381 -0
  39. package/dist/modules/v4/address.js.map +1 -0
  40. package/dist/modules/v4/agent.d.ts +30 -0
  41. package/dist/modules/v4/agent.js +92 -0
  42. package/dist/modules/v4/agent.js.map +1 -0
  43. package/dist/modules/v4/algorithms.d.ts +90 -0
  44. package/dist/modules/v4/algorithms.js +279 -0
  45. package/dist/modules/v4/algorithms.js.map +1 -0
  46. package/dist/modules/v4/avatar.d.ts +23 -0
  47. package/dist/modules/v4/avatar.js +136 -0
  48. package/dist/modules/v4/avatar.js.map +1 -0
  49. package/dist/modules/v4/barcode.d.ts +27 -0
  50. package/dist/modules/v4/barcode.js +440 -0
  51. package/dist/modules/v4/barcode.js.map +1 -0
  52. package/dist/modules/v4/captcha.d.ts +22 -0
  53. package/dist/modules/v4/captcha.js +79 -0
  54. package/dist/modules/v4/captcha.js.map +1 -0
  55. package/dist/modules/v4/chat.d.ts +21 -0
  56. package/dist/modules/v4/chat.js +100 -0
  57. package/dist/modules/v4/chat.js.map +1 -0
  58. package/dist/modules/v4/color.d.ts +16 -0
  59. package/dist/modules/v4/color.js +59 -0
  60. package/dist/modules/v4/color.js.map +1 -0
  61. package/dist/modules/v4/convert.d.ts +15 -0
  62. package/dist/modules/v4/convert.js +116 -0
  63. package/dist/modules/v4/convert.js.map +1 -0
  64. package/dist/modules/v4/credit.d.ts +22 -0
  65. package/dist/modules/v4/credit.js +104 -0
  66. package/dist/modules/v4/credit.js.map +1 -0
  67. package/dist/modules/v4/cron.d.ts +17 -0
  68. package/dist/modules/v4/cron.js +202 -0
  69. package/dist/modules/v4/cron.js.map +1 -0
  70. package/dist/modules/v4/dice.d.ts +16 -0
  71. package/dist/modules/v4/dice.js +37 -0
  72. package/dist/modules/v4/dice.js.map +1 -0
  73. package/dist/modules/v4/domain.d.ts +6 -0
  74. package/dist/modules/v4/domain.js +83 -0
  75. package/dist/modules/v4/domain.js.map +1 -0
  76. package/dist/modules/v4/encode.d.ts +81 -0
  77. package/dist/modules/v4/encode.js +236 -0
  78. package/dist/modules/v4/encode.js.map +1 -0
  79. package/dist/modules/v4/geo.d.ts +30 -0
  80. package/dist/modules/v4/geo.js +51 -0
  81. package/dist/modules/v4/geo.js.map +1 -0
  82. package/dist/modules/v4/hash.d.ts +15 -0
  83. package/dist/modules/v4/hash.js +25 -0
  84. package/dist/modules/v4/hash.js.map +1 -0
  85. package/dist/modules/v4/hyperplanning.d.ts +19 -0
  86. package/dist/modules/v4/hyperplanning.js +80 -0
  87. package/dist/modules/v4/hyperplanning.js.map +1 -0
  88. package/dist/modules/v4/ip.d.ts +19 -0
  89. package/dist/modules/v4/ip.js +132 -0
  90. package/dist/modules/v4/ip.js.map +1 -0
  91. package/dist/modules/v4/levenshtein.d.ts +13 -0
  92. package/dist/modules/v4/levenshtein.js +37 -0
  93. package/dist/modules/v4/levenshtein.js.map +1 -0
  94. package/dist/modules/v4/palette.d.ts +19 -0
  95. package/dist/modules/v4/palette.js +56 -0
  96. package/dist/modules/v4/palette.js.map +1 -0
  97. package/dist/modules/v4/password.d.ts +25 -0
  98. package/dist/modules/v4/password.js +343 -0
  99. package/dist/modules/v4/password.js.map +1 -0
  100. package/dist/modules/v4/personal.d.ts +6 -0
  101. package/dist/modules/v4/personal.js +121 -0
  102. package/dist/modules/v4/personal.js.map +1 -0
  103. package/dist/modules/v4/placeholder.d.ts +30 -0
  104. package/dist/modules/v4/placeholder.js +160 -0
  105. package/dist/modules/v4/placeholder.js.map +1 -0
  106. package/dist/modules/v4/qrcode.d.ts +25 -0
  107. package/dist/modules/v4/qrcode.js +92 -0
  108. package/dist/modules/v4/qrcode.js.map +1 -0
  109. package/dist/modules/v4/regex.d.ts +23 -0
  110. package/dist/modules/v4/regex.js +48 -0
  111. package/dist/modules/v4/regex.js.map +1 -0
  112. package/dist/modules/v4/statistics.d.ts +20 -0
  113. package/dist/modules/v4/statistics.js +48 -0
  114. package/dist/modules/v4/statistics.js.map +1 -0
  115. package/dist/modules/v4/text.d.ts +43 -0
  116. package/dist/modules/v4/text.js +323 -0
  117. package/dist/modules/v4/text.js.map +1 -0
  118. package/dist/modules/v4/tic_tac_toe.d.ts +19 -0
  119. package/dist/modules/v4/tic_tac_toe.js +214 -0
  120. package/dist/modules/v4/tic_tac_toe.js.map +1 -0
  121. package/dist/modules/v4/time.d.ts +15 -0
  122. package/dist/modules/v4/time.js +124 -0
  123. package/dist/modules/v4/time.js.map +1 -0
  124. package/dist/modules/v4/token.d.ts +9 -0
  125. package/dist/modules/v4/token.js +45 -0
  126. package/dist/modules/v4/token.js.map +1 -0
  127. package/dist/modules/v4/username.d.ts +6 -0
  128. package/dist/modules/v4/username.js +92 -0
  129. package/dist/modules/v4/username.js.map +1 -0
  130. package/dist/modules/v4/validate.d.ts +34 -0
  131. package/dist/modules/v4/validate.js +75 -0
  132. package/dist/modules/v4/validate.js.map +1 -0
  133. package/dist/modules/v4.d.ts +32 -0
  134. package/dist/modules/v4.js +33 -0
  135. package/dist/modules/v4.js.map +1 -0
  136. package/dist/modules/v5/address.d.ts +5 -0
  137. package/dist/modules/v5/address.js +20 -0
  138. package/dist/modules/v5/address.js.map +1 -0
  139. package/dist/modules/v5/algorithms.d.ts +9 -0
  140. package/dist/modules/v5/algorithms.js +39 -0
  141. package/dist/modules/v5/algorithms.js.map +1 -0
  142. package/dist/modules/v5/asymmetric.d.ts +26 -0
  143. package/dist/modules/v5/asymmetric.js +74 -0
  144. package/dist/modules/v5/asymmetric.js.map +1 -0
  145. package/dist/modules/v5/barcode.d.ts +27 -0
  146. package/dist/modules/v5/barcode.js +424 -0
  147. package/dist/modules/v5/barcode.js.map +1 -0
  148. package/dist/modules/v5/base.d.ts +16 -0
  149. package/dist/modules/v5/base.js +41 -0
  150. package/dist/modules/v5/base.js.map +1 -0
  151. package/dist/modules/v5/captcha.d.ts +27 -0
  152. package/dist/modules/v5/captcha.js +136 -0
  153. package/dist/modules/v5/captcha.js.map +1 -0
  154. package/dist/modules/v5/case.d.ts +10 -0
  155. package/dist/modules/v5/case.js +57 -0
  156. package/dist/modules/v5/case.js.map +1 -0
  157. package/dist/modules/v5/chart.d.ts +53 -0
  158. package/dist/modules/v5/chart.js +385 -0
  159. package/dist/modules/v5/chart.js.map +1 -0
  160. package/dist/modules/v5/chat.d.ts +21 -0
  161. package/dist/modules/v5/chat.js +107 -0
  162. package/dist/modules/v5/chat.js.map +1 -0
  163. package/dist/modules/v5/csv.d.ts +29 -0
  164. package/dist/modules/v5/csv.js +143 -0
  165. package/dist/modules/v5/csv.js.map +1 -0
  166. package/dist/modules/v5/diff.d.ts +20 -0
  167. package/dist/modules/v5/diff.js +81 -0
  168. package/dist/modules/v5/diff.js.map +1 -0
  169. package/dist/modules/v5/evaluate.d.ts +14 -0
  170. package/dist/modules/v5/evaluate.js +284 -0
  171. package/dist/modules/v5/evaluate.js.map +1 -0
  172. package/dist/modules/v5/jwt.d.ts +11 -0
  173. package/dist/modules/v5/jwt.js +42 -0
  174. package/dist/modules/v5/jwt.js.map +1 -0
  175. package/dist/modules/v5/matrix.d.ts +77 -0
  176. package/dist/modules/v5/matrix.js +239 -0
  177. package/dist/modules/v5/matrix.js.map +1 -0
  178. package/dist/modules/v5/otp.d.ts +30 -0
  179. package/dist/modules/v5/otp.js +117 -0
  180. package/dist/modules/v5/otp.js.map +1 -0
  181. package/dist/modules/v5/pow.d.ts +29 -0
  182. package/dist/modules/v5/pow.js +49 -0
  183. package/dist/modules/v5/pow.js.map +1 -0
  184. package/dist/modules/v5/read.d.ts +20 -0
  185. package/dist/modules/v5/read.js +59 -0
  186. package/dist/modules/v5/read.js.map +1 -0
  187. package/dist/modules/v5/semver.d.ts +33 -0
  188. package/dist/modules/v5/semver.js +99 -0
  189. package/dist/modules/v5/semver.js.map +1 -0
  190. package/dist/modules/v5/symmetric.d.ts +15 -0
  191. package/dist/modules/v5/symmetric.js +88 -0
  192. package/dist/modules/v5/symmetric.js.map +1 -0
  193. package/dist/modules/v5/text.d.ts +5 -0
  194. package/dist/modules/v5/text.js +12 -0
  195. package/dist/modules/v5/text.js.map +1 -0
  196. package/dist/modules/v5/tic_tac_toe.d.ts +19 -0
  197. package/dist/modules/v5/tic_tac_toe.js +226 -0
  198. package/dist/modules/v5/tic_tac_toe.js.map +1 -0
  199. package/dist/modules/v5/url.d.ts +18 -0
  200. package/dist/modules/v5/url.js +51 -0
  201. package/dist/modules/v5/url.js.map +1 -0
  202. package/dist/modules/v5/uuid.d.ts +25 -0
  203. package/dist/modules/v5/uuid.js +40 -0
  204. package/dist/modules/v5/uuid.js.map +1 -0
  205. package/dist/modules/v5.d.ts +24 -0
  206. package/dist/modules/v5.js +25 -0
  207. package/dist/modules/v5.js.map +1 -0
  208. package/dist/modules/v6.d.ts +1 -0
  209. package/dist/modules/v6.js +2 -0
  210. package/dist/modules/v6.js.map +1 -0
  211. package/dist/routes/delete.d.ts +2 -0
  212. package/dist/routes/delete.js +73 -0
  213. package/dist/routes/delete.js.map +1 -0
  214. package/dist/routes/get.d.ts +2 -0
  215. package/dist/routes/get.js +857 -0
  216. package/dist/routes/get.js.map +1 -0
  217. package/dist/routes/index.d.ts +2 -0
  218. package/dist/routes/index.js +95 -0
  219. package/dist/routes/index.js.map +1 -0
  220. package/dist/routes/patch.d.ts +2 -0
  221. package/dist/routes/patch.js +45 -0
  222. package/dist/routes/patch.js.map +1 -0
  223. package/dist/routes/post.d.ts +2 -0
  224. package/dist/routes/post.js +604 -0
  225. package/dist/routes/post.js.map +1 -0
  226. package/dist/storage/index.d.ts +5 -0
  227. package/dist/storage/index.js +14 -0
  228. package/dist/storage/index.js.map +1 -0
  229. package/dist/types/storage.d.ts +52 -0
  230. package/dist/types/storage.js +2 -0
  231. package/dist/types/storage.js.map +1 -0
  232. package/dist/utils/challenge.d.ts +40 -0
  233. package/dist/utils/challenge.js +75 -0
  234. package/dist/utils/challenge.js.map +1 -0
  235. package/dist/utils/colors.d.ts +44 -0
  236. package/dist/utils/colors.js +93 -0
  237. package/dist/utils/colors.js.map +1 -0
  238. package/dist/utils/helpers.d.ts +55 -0
  239. package/dist/utils/helpers.js +82 -0
  240. package/dist/utils/helpers.js.map +1 -0
  241. package/dist/utils/response.d.ts +9 -0
  242. package/dist/utils/response.js +24 -0
  243. package/dist/utils/response.js.map +1 -0
  244. package/package.json +90 -0
  245. package/robots.txt +74 -0
  246. package/src/favicon.ico +0 -0
@@ -0,0 +1,857 @@
1
+ import { Router } from 'express';
2
+ import { env } from '../config/env.js';
3
+ import { versions } from '../config/versions.js';
4
+ import { chatStorage } from '../storage/index.js';
5
+ import { since } from '../utils/helpers.js';
6
+ import { error } from '../utils/response.js';
7
+ const router = Router();
8
+ const postOnly = (name) => (req, res) => {
9
+ const available = versions[req.version]?.endpoints.post.some((e) => e.name === name);
10
+ if (!available) {
11
+ error(res, 404, `Endpoint not available in ${req.version}.`);
12
+ return;
13
+ }
14
+ error(res, 405, 'This endpoint only supports POST requests.');
15
+ };
16
+ // Display version information
17
+ router.get('/:version', (req, res) => {
18
+ const version = req.params.version;
19
+ const versionConfig = versions[version];
20
+ const endpoints = Object.keys(versionConfig.endpoints).reduce((acc, method) => {
21
+ const endpointList = versionConfig.endpoints[method];
22
+ if (!endpointList)
23
+ return acc;
24
+ acc[method] = endpointList
25
+ .sort((a, b) => a.name.localeCompare(b.name))
26
+ .reduce((group, endpoint) => {
27
+ if (endpoint.children) {
28
+ group[endpoint.name] = Object.keys(endpoint.children)
29
+ .sort((a, b) => a.localeCompare(b))
30
+ .reduce((childGroup, childName) => {
31
+ childGroup[childName] = `/${version}${endpoint.children[childName]}`;
32
+ return childGroup;
33
+ }, {});
34
+ }
35
+ else {
36
+ group[endpoint.name] = `/${version}${endpoint.path}`;
37
+ }
38
+ return group;
39
+ }, {});
40
+ return acc;
41
+ }, {});
42
+ res.jsonResponse({
43
+ version,
44
+ ...(env.DOCS_URL ? { documentation: `${env.DOCS_URL}/${version}` } : {}),
45
+ endpoints,
46
+ });
47
+ });
48
+ // Generate a fictional postal address
49
+ router.get('/:version/address', (req, res) => {
50
+ const { country, count } = req.query;
51
+ const { version } = req.params;
52
+ const addressFn = req.module.address;
53
+ if (!addressFn) {
54
+ error(res, 404, `Endpoint not available in ${version}.`);
55
+ return;
56
+ }
57
+ const parsedCount = count !== undefined ? parseInt(count, 10) : 1;
58
+ if (isNaN(parsedCount)) {
59
+ error(res, 400, 'Please provide a valid count (&count={n})');
60
+ return;
61
+ }
62
+ try {
63
+ const result = addressFn(country, parsedCount);
64
+ res.jsonResponse(result);
65
+ }
66
+ catch (err) {
67
+ error(res, 400, err.message);
68
+ }
69
+ });
70
+ // Parse a User-Agent string
71
+ router.get('/:version/agent', (req, res) => {
72
+ const ua = req.query.ua ?? req.headers['user-agent'] ?? '';
73
+ const agentFn = req.module.agent;
74
+ if (!agentFn) {
75
+ error(res, 404, `Endpoint not available in ${req.version}.`);
76
+ return;
77
+ }
78
+ try {
79
+ const result = agentFn(ua);
80
+ res.jsonResponse(result);
81
+ }
82
+ catch (err) {
83
+ error(res, 400, err.message);
84
+ }
85
+ });
86
+ // Algorithms
87
+ router.get('/:version/algorithms', (req, res) => {
88
+ const { method, value, value2 } = req.query;
89
+ const algorithms = req.module.algorithms;
90
+ if (!algorithms || !method || !Object.hasOwn(algorithms, method)) {
91
+ error(res, 400, 'Please provide a valid algorithm (?method={algorithm})');
92
+ return;
93
+ }
94
+ try {
95
+ const answer = algorithms[method](value, value2);
96
+ res.jsonResponse({ answer });
97
+ }
98
+ catch (err) {
99
+ error(res, 400, err.message);
100
+ }
101
+ });
102
+ // GET asymmetric error
103
+ router.get('/:version/asymmetric', postOnly('asymmetric'));
104
+ // Generate an identicon or pixel-art avatar from a seed
105
+ router.get('/:version/avatar', (req, res) => {
106
+ const avatarFn = req.module.avatar;
107
+ if (!avatarFn) {
108
+ error(res, 404, `Endpoint not available in ${req.version}.`);
109
+ return;
110
+ }
111
+ const { seed, size, type, bg, format } = req.query;
112
+ const parsedSize = size !== undefined ? parseInt(size, 10) : undefined;
113
+ if (parsedSize !== undefined && isNaN(parsedSize)) {
114
+ error(res, 400, 'Please provide a valid size (&size={50-2000})');
115
+ return;
116
+ }
117
+ try {
118
+ const { contentType, body } = avatarFn({
119
+ seed: seed,
120
+ size: parsedSize,
121
+ type: type,
122
+ bg: bg,
123
+ format: format,
124
+ });
125
+ res.type(contentType).send(body);
126
+ }
127
+ catch (err) {
128
+ error(res, 400, err.message);
129
+ }
130
+ });
131
+ // Generate a barcode image
132
+ router.get('/:version/barcode', (req, res) => {
133
+ const barcodeFn = req.module.barcode;
134
+ if (!barcodeFn) {
135
+ error(res, 404, `Endpoint not available in ${req.version}.`);
136
+ return;
137
+ }
138
+ const { data, type, width, height, format, color, bg } = req.query;
139
+ if (!data) {
140
+ error(res, 400, 'Please provide data to encode (?data={string})');
141
+ return;
142
+ }
143
+ const parsedWidth = width !== undefined ? parseInt(width, 10) : undefined;
144
+ const parsedHeight = height !== undefined ? parseInt(height, 10) : undefined;
145
+ if ((parsedWidth !== undefined && isNaN(parsedWidth)) || (parsedHeight !== undefined && isNaN(parsedHeight))) {
146
+ error(res, 400, 'Please provide valid dimensions (&width={px}&height={px})');
147
+ return;
148
+ }
149
+ try {
150
+ const { contentType, body } = barcodeFn({
151
+ data: data,
152
+ type: type,
153
+ width: parsedWidth,
154
+ height: parsedHeight,
155
+ format: format,
156
+ color: color,
157
+ bg: bg,
158
+ });
159
+ res.type(contentType).send(body);
160
+ }
161
+ catch (err) {
162
+ error(res, 400, err.message);
163
+ }
164
+ });
165
+ // Convert a number between bases
166
+ router.get('/:version/base', (req, res) => {
167
+ const { value, from, to } = req.query;
168
+ const { version } = req.params;
169
+ const baseFn = req.module.base;
170
+ if (!baseFn) {
171
+ error(res, 404, `Endpoint not available in ${version}.`);
172
+ return;
173
+ }
174
+ if (!value || typeof value !== 'string') {
175
+ error(res, 400, 'Please provide a value (?value={value})');
176
+ return;
177
+ }
178
+ try {
179
+ const result = baseFn(value, from !== undefined ? Number(from) : undefined, to !== undefined ? Number(to) : undefined);
180
+ res.jsonResponse(result);
181
+ }
182
+ catch (err) {
183
+ error(res, 400, err.message);
184
+ }
185
+ });
186
+ // Generate captcha
187
+ router.get('/:version/captcha', (req, res) => {
188
+ try {
189
+ const mode = req.query.mode ?? (since(req.version, 6) ? 'challenge' : 'image');
190
+ if (mode !== 'image' && mode !== 'challenge') {
191
+ error(res, 400, 'Mode must be one of: image, challenge');
192
+ return;
193
+ }
194
+ const challenge = mode === 'challenge';
195
+ if (challenge && !since(req.version, 5)) {
196
+ error(res, 404, `Challenge mode not available in ${req.version}.`);
197
+ return;
198
+ }
199
+ if (challenge && req.query.text) {
200
+ error(res, 400, 'A custom text cannot be used in challenge mode');
201
+ return;
202
+ }
203
+ const options = {
204
+ text: req.query.text,
205
+ length: req.query.length ? Number(req.query.length) : undefined,
206
+ width: req.query.width ? Number(req.query.width) : undefined,
207
+ height: req.query.height ? Number(req.query.height) : undefined,
208
+ noise: req.query.noise,
209
+ bg: req.query.bg,
210
+ color: req.query.color,
211
+ };
212
+ if (challenge) {
213
+ const challengeFn = req.module
214
+ .captchaChallenge;
215
+ const result = challengeFn(options);
216
+ res.set('X-Captcha-Token', result.token);
217
+ res.type('png').send(result.body);
218
+ return;
219
+ }
220
+ const captchaFn = req.module.captcha;
221
+ const result = captchaFn(options);
222
+ res.set('X-Captcha-Text', result.text);
223
+ res.type('png').send(result.body);
224
+ }
225
+ catch (err) {
226
+ error(res, 400, err.message);
227
+ }
228
+ });
229
+ // Convert text to a different case format
230
+ router.get('/:version/case', (req, res) => {
231
+ const { text, to } = req.query;
232
+ const { version } = req.params;
233
+ const caseConvertFn = req.module.caseConvert;
234
+ if (!caseConvertFn) {
235
+ error(res, 404, `Endpoint not available in ${version}.`);
236
+ return;
237
+ }
238
+ if (!text || typeof text !== 'string') {
239
+ error(res, 400, 'Please provide a text (?text={text})');
240
+ return;
241
+ }
242
+ try {
243
+ const result = caseConvertFn(text, to);
244
+ res.jsonResponse(result);
245
+ }
246
+ catch (err) {
247
+ error(res, 400, err.message);
248
+ }
249
+ });
250
+ // GET chart error
251
+ router.get('/:version/chart', postOnly('chart'));
252
+ // Display stored data
253
+ router.get('/:version/chat', (req, res) => {
254
+ try {
255
+ const messages = req.module.chat('fetch', {
256
+ username: `reader:${req.ip ?? 'unknown'}`,
257
+ storage: chatStorage,
258
+ });
259
+ res.jsonResponse(messages);
260
+ }
261
+ catch (err) {
262
+ error(res, 400, err.message);
263
+ }
264
+ });
265
+ // GET private chat error
266
+ router.get('/:version/chat/private', postOnly('chat'));
267
+ // Generate color
268
+ router.get('/:version/color', (req, res) => {
269
+ try {
270
+ const colorFn = req.module.color;
271
+ const hex = req.query.hex;
272
+ const result = colorFn(hex || undefined);
273
+ res.jsonResponse(result);
274
+ }
275
+ catch (err) {
276
+ error(res, 400, err.message);
277
+ }
278
+ });
279
+ // Convert units
280
+ router.get('/:version/convert', (req, res) => {
281
+ const { value, from, to } = req.query;
282
+ if (!value || isNaN(Number(value))) {
283
+ error(res, 400, 'Please provide a valid value (?value={value})');
284
+ return;
285
+ }
286
+ if (!from) {
287
+ error(res, 400, 'Please provide a valid source unit (&from={unit})');
288
+ return;
289
+ }
290
+ if (!to) {
291
+ error(res, 400, 'Please provide a valid target unit (&to={unit})');
292
+ return;
293
+ }
294
+ try {
295
+ const convertFn = req.module.convert;
296
+ const result = convertFn(Number(value), from, to);
297
+ res.jsonResponse(result);
298
+ }
299
+ catch (err) {
300
+ error(res, 400, err.message);
301
+ }
302
+ });
303
+ // Generate fictitious credit card numbers
304
+ router.get('/:version/credit', (req, res) => {
305
+ const creditFn = req.module
306
+ .credit;
307
+ if (!creditFn) {
308
+ error(res, 404, `Endpoint not available in ${req.version}.`);
309
+ return;
310
+ }
311
+ const { brand, count, format } = req.query;
312
+ try {
313
+ const result = creditFn(brand, count !== undefined ? parseInt(count, 10) : 1, format);
314
+ res.jsonResponse(result);
315
+ }
316
+ catch (err) {
317
+ error(res, 400, err.message);
318
+ }
319
+ });
320
+ // Parse a cron expression and compute next execution dates
321
+ router.get('/:version/cron', (req, res) => {
322
+ const { expr, count, from, timezone } = req.query;
323
+ const { version } = req.params;
324
+ const cronFn = req.module.cron;
325
+ if (!cronFn) {
326
+ error(res, 404, `Endpoint not available in ${version}.`);
327
+ return;
328
+ }
329
+ if (!expr) {
330
+ error(res, 400, 'Please provide a cron expression (?expr=* * * * *)');
331
+ return;
332
+ }
333
+ const parsedCount = count !== undefined ? parseInt(count, 10) : 5;
334
+ if (isNaN(parsedCount)) {
335
+ error(res, 400, 'Please provide a valid count (&count={n})');
336
+ return;
337
+ }
338
+ try {
339
+ const result = cronFn(expr, parsedCount, from, timezone ?? 'UTC');
340
+ res.jsonResponse(result);
341
+ }
342
+ catch (err) {
343
+ error(res, 400, err.message);
344
+ }
345
+ });
346
+ // GET csv error
347
+ router.get('/:version/csv', postOnly('csv'));
348
+ // RPG Dice roller
349
+ router.get('/:version/dice', (req, res) => {
350
+ const { roll } = req.query;
351
+ const { version } = req.params;
352
+ const dice = req.module.dice;
353
+ if (!dice) {
354
+ error(res, 404, `Endpoint not available in ${version}.`);
355
+ return;
356
+ }
357
+ if (!roll) {
358
+ error(res, 400, 'Please provide a roll notation (?roll=2d6+3)');
359
+ return;
360
+ }
361
+ try {
362
+ const result = dice(roll);
363
+ res.jsonResponse(result);
364
+ }
365
+ catch (err) {
366
+ error(res, 400, err.message);
367
+ }
368
+ });
369
+ // GET diff error
370
+ router.get('/:version/diff', postOnly('diff'));
371
+ // Generate domain informations
372
+ router.get('/:version/domain', (req, res) => {
373
+ try {
374
+ const result = req.module.domain();
375
+ res.jsonResponse(result);
376
+ }
377
+ catch (err) {
378
+ error(res, 400, err.message);
379
+ }
380
+ });
381
+ // Encode / decode text
382
+ router.get('/:version/encode', (req, res) => {
383
+ const { method, text, shift } = req.query;
384
+ const { version } = req.params;
385
+ const encode = req.module.encode;
386
+ if (!encode) {
387
+ error(res, 404, `Endpoint not available in ${version}.`);
388
+ return;
389
+ }
390
+ if (!method || !Object.hasOwn(encode, method)) {
391
+ error(res, 400, 'Please provide a valid method (?method={method})');
392
+ return;
393
+ }
394
+ try {
395
+ const result = encode[method](text, shift);
396
+ res.jsonResponse({ method, result });
397
+ }
398
+ catch (err) {
399
+ error(res, 400, err.message);
400
+ }
401
+ });
402
+ // Evaluate a math expression
403
+ router.get('/:version/evaluate', (req, res) => {
404
+ const { expr, precision } = req.query;
405
+ const { version } = req.params;
406
+ const evaluateFn = req.module.evaluate;
407
+ if (!evaluateFn) {
408
+ error(res, 404, `Endpoint not available in ${version}.`);
409
+ return;
410
+ }
411
+ if (!expr || typeof expr !== 'string') {
412
+ error(res, 400, 'Please provide a math expression (?expr={expression})');
413
+ return;
414
+ }
415
+ try {
416
+ const result = evaluateFn(expr, precision !== undefined ? parseInt(precision, 10) : undefined);
417
+ res.jsonResponse(result);
418
+ }
419
+ catch (err) {
420
+ error(res, 400, err.message);
421
+ }
422
+ });
423
+ // Geographic distance and bearing between two coordinates
424
+ router.get('/:version/geo', (req, res) => {
425
+ const { lat1, lon1, lat2, lon2 } = req.query;
426
+ const { version } = req.params;
427
+ const geo = req.module.geo;
428
+ if (!geo) {
429
+ error(res, 404, `Endpoint not available in ${version}.`);
430
+ return;
431
+ }
432
+ if (lat1 === undefined || lon1 === undefined || lat2 === undefined || lon2 === undefined) {
433
+ error(res, 400, 'Please provide lat1, lon1, lat2 and lon2');
434
+ return;
435
+ }
436
+ try {
437
+ const result = geo(lat1, lon1, lat2, lon2);
438
+ res.jsonResponse(result);
439
+ }
440
+ catch (err) {
441
+ error(res, 400, err.message);
442
+ }
443
+ });
444
+ // GET hash error
445
+ router.get('/:version/hash', postOnly('hash'));
446
+ // Echo request headers
447
+ router.get('/:version/headers', (req, res) => {
448
+ const redacted = new Set(['authorization', 'cookie', 'set-cookie', 'proxy-authorization']);
449
+ let headers = {};
450
+ for (const [k, v] of Object.entries(req.headers)) {
451
+ headers[k] = redacted.has(k) ? '[redacted]' : v;
452
+ }
453
+ const filterParam = req.query.filter;
454
+ const filter = Array.isArray(filterParam) ? filterParam.join(',') : filterParam;
455
+ if (filter) {
456
+ const keys = new Set(filter.split(',').map((k) => k.trim().toLowerCase()));
457
+ headers = Object.fromEntries(Object.entries(headers).filter(([k]) => keys.has(k)));
458
+ }
459
+ res.jsonResponse({
460
+ count: Object.keys(headers).length,
461
+ headers,
462
+ ip: req.ip,
463
+ method: req.method,
464
+ url: req.originalUrl,
465
+ });
466
+ });
467
+ // GET planning error
468
+ router.get('/:version/hyperplanning', postOnly('hyperplanning'));
469
+ // Display API informations
470
+ router.get('/:version/infos', (req, res) => {
471
+ const endpoints = Object.values(versions[req.version].endpoints).flat();
472
+ const paths = endpoints.flatMap((e) => (e.children ? Object.values(e.children) : e.path ? [e.path] : []));
473
+ res.jsonResponse({
474
+ endpoints: new Set(paths).size,
475
+ last_version: Object.keys(versions).pop(),
476
+ ...(env.DOCS_URL ? { documentation: env.DOCS_URL } : {}),
477
+ ...(env.REPO_URL ? { github: env.REPO_URL } : {}),
478
+ ...(env.INSTANCE_CREATED ? { creation: env.INSTANCE_CREATED } : {}),
479
+ });
480
+ });
481
+ // Analyze an IP address
482
+ router.get('/:version/ip', (req, res) => {
483
+ const address = req.query.address ?? req.ip ?? '';
484
+ const ipFn = req.module.ip;
485
+ if (!ipFn) {
486
+ error(res, 404, `Endpoint not available in ${req.version}.`);
487
+ return;
488
+ }
489
+ try {
490
+ const result = ipFn(address);
491
+ res.jsonResponse(result);
492
+ }
493
+ catch (err) {
494
+ error(res, 400, err.message);
495
+ }
496
+ });
497
+ // GET jwt error
498
+ router.get('/:version/jwt', postOnly('jwt'));
499
+ // Calculate Levenshtein distance
500
+ router.get('/:version/levenshtein', (req, res) => {
501
+ if (since(req.version, 6)) {
502
+ error(res, 405, 'This endpoint only supports POST requests.');
503
+ return;
504
+ }
505
+ const { str1, str2 } = req.query;
506
+ if (!str1 || typeof str1 !== 'string') {
507
+ error(res, 400, 'Please provide a first string (?str1={string})');
508
+ return;
509
+ }
510
+ if (!str2 || typeof str2 !== 'string') {
511
+ error(res, 400, 'Please provide a second string (&str2={string})');
512
+ return;
513
+ }
514
+ try {
515
+ const result = req.module.levenshtein(str1, str2);
516
+ res.jsonResponse(result);
517
+ }
518
+ catch (err) {
519
+ error(res, 400, err.message);
520
+ }
521
+ });
522
+ // GET matrix error
523
+ router.get('/:version/matrix', postOnly('matrix'));
524
+ // GET otp error
525
+ router.get('/:version/otp', postOnly('otp'));
526
+ // Generate a color palette from a base color
527
+ router.get('/:version/palette', (req, res) => {
528
+ const { color, type } = req.query;
529
+ const { version } = req.params;
530
+ const palette = req.module.palette;
531
+ if (!palette) {
532
+ error(res, 404, `Endpoint not available in ${version}.`);
533
+ return;
534
+ }
535
+ if (!color) {
536
+ error(res, 400, 'Please provide a base color (?color=#ff6600)');
537
+ return;
538
+ }
539
+ if (!type) {
540
+ error(res, 400, 'Please provide a palette type (&type=complementary)');
541
+ return;
542
+ }
543
+ try {
544
+ const result = palette(color, type);
545
+ res.jsonResponse(result);
546
+ }
547
+ catch (err) {
548
+ error(res, 400, err.message);
549
+ }
550
+ });
551
+ // Generate a password or passphrase
552
+ router.get('/:version/password', (req, res) => {
553
+ const { type, length, uppercase, lowercase, digits, symbols, exclude, count, separator } = req.query;
554
+ const { version } = req.params;
555
+ const passwordFn = req.module.password;
556
+ if (!passwordFn) {
557
+ error(res, 404, `Endpoint not available in ${version}.`);
558
+ return;
559
+ }
560
+ const parseBool = (v, def) => (v === undefined ? def : v !== 'false');
561
+ try {
562
+ const result = passwordFn(type ?? 'random', length !== undefined ? parseInt(length, 10) : 16, {
563
+ uppercase: parseBool(uppercase, true),
564
+ lowercase: parseBool(lowercase, true),
565
+ digits: parseBool(digits, true),
566
+ symbols: parseBool(symbols, false),
567
+ exclude: exclude ?? '',
568
+ count: count !== undefined ? parseInt(count, 10) : 1,
569
+ separator: separator ?? '-',
570
+ });
571
+ res.jsonResponse(result);
572
+ }
573
+ catch (err) {
574
+ error(res, 400, err.message);
575
+ }
576
+ });
577
+ // Generate personal data
578
+ router.get('/:version/personal', (req, res) => {
579
+ try {
580
+ const result = req.module.personal();
581
+ res.jsonResponse(result);
582
+ }
583
+ catch (err) {
584
+ error(res, 400, err.message);
585
+ }
586
+ });
587
+ // Generate a placeholder image or skeleton
588
+ router.get('/:version/placeholder', (req, res) => {
589
+ const { type = 'image' } = req.query;
590
+ const { version } = req.params;
591
+ const placeholder = req.module.placeholder;
592
+ if (!placeholder) {
593
+ error(res, 404, `Endpoint not available in ${version}.`);
594
+ return;
595
+ }
596
+ try {
597
+ const result = placeholder(type, req.query);
598
+ res.type(result.contentType).send(result.body);
599
+ }
600
+ catch (err) {
601
+ error(res, 400, err.message);
602
+ }
603
+ });
604
+ // Issue a proof-of-work challenge
605
+ router.get('/:version/pow', (req, res) => {
606
+ const { difficulty } = req.query;
607
+ const { version } = req.params;
608
+ const powFn = req.module.pow;
609
+ if (!powFn) {
610
+ error(res, 404, `Endpoint not available in ${version}.`);
611
+ return;
612
+ }
613
+ try {
614
+ const result = powFn(difficulty !== undefined ? Number(difficulty) : undefined);
615
+ res.jsonResponse(result);
616
+ }
617
+ catch (err) {
618
+ error(res, 400, err.message);
619
+ }
620
+ });
621
+ // Generate QR Code
622
+ router.get('/:version/qrcode', async (req, res) => {
623
+ const { url } = req.query;
624
+ if (!url) {
625
+ error(res, 400, 'Please provide a valid url (?url={URL})');
626
+ return;
627
+ }
628
+ try {
629
+ const qrcodeFn = req.module.qrcode;
630
+ const result = await qrcodeFn({
631
+ url: url,
632
+ size: req.query.size ? Number(req.query.size) : undefined,
633
+ margin: req.query.margin ? Number(req.query.margin) : undefined,
634
+ correction: req.query.correction,
635
+ dark: req.query.dark,
636
+ light: req.query.light,
637
+ icon: req.query.icon,
638
+ iconSize: req.query.iconSize ? Number(req.query.iconSize) : undefined,
639
+ iconPadding: req.query.iconPadding ? Number(req.query.iconPadding) : undefined,
640
+ iconRadius: req.query.iconRadius ? Number(req.query.iconRadius) : undefined,
641
+ format: req.query.format,
642
+ });
643
+ if (result.contentType === 'application/json') {
644
+ res.jsonResponse(result.body);
645
+ }
646
+ else {
647
+ res.type(result.contentType).send(result.body);
648
+ }
649
+ }
650
+ catch (err) {
651
+ error(res, 400, err.message);
652
+ }
653
+ });
654
+ // GET read error
655
+ router.get('/:version/read', postOnly('read'));
656
+ // Test a regex pattern against a text
657
+ router.get('/:version/regex', (req, res) => {
658
+ const { pattern, text, flags } = req.query;
659
+ const { version } = req.params;
660
+ const regexFn = req.module.regex;
661
+ if (!regexFn) {
662
+ error(res, 404, `Endpoint not available in ${version}.`);
663
+ return;
664
+ }
665
+ if (!pattern) {
666
+ error(res, 400, 'Please provide a pattern (?pattern={regex})');
667
+ return;
668
+ }
669
+ if (!text) {
670
+ error(res, 400, 'Please provide a text (&text={string})');
671
+ return;
672
+ }
673
+ try {
674
+ const result = regexFn(pattern, text, flags);
675
+ res.jsonResponse(result);
676
+ }
677
+ catch (err) {
678
+ error(res, 400, err.message);
679
+ }
680
+ });
681
+ // Parse, bump or compare semantic versions
682
+ router.get('/:version/semver', (req, res) => {
683
+ const { version: input, action, part, other } = req.query;
684
+ const { version } = req.params;
685
+ const semverFn = req.module.semver;
686
+ if (!semverFn) {
687
+ error(res, 404, `Endpoint not available in ${version}.`);
688
+ return;
689
+ }
690
+ if (!input || typeof input !== 'string') {
691
+ error(res, 400, 'Please provide a version (?version={version})');
692
+ return;
693
+ }
694
+ const restorePlus = (v) => v.replace(/ /g, '+');
695
+ try {
696
+ const result = semverFn(restorePlus(input), action, part, typeof other === 'string' ? restorePlus(other) : undefined);
697
+ res.jsonResponse(result);
698
+ }
699
+ catch (err) {
700
+ error(res, 400, err.message);
701
+ }
702
+ });
703
+ // Statistics on a list of numbers
704
+ router.get('/:version/statistics', (req, res) => {
705
+ const { values } = req.query;
706
+ const { version } = req.params;
707
+ const statistics = req.module.statistics;
708
+ if (!statistics) {
709
+ error(res, 404, `Endpoint not available in ${version}.`);
710
+ return;
711
+ }
712
+ if (!values) {
713
+ error(res, 400, 'Please provide a list of values (?values=1,2,3)');
714
+ return;
715
+ }
716
+ try {
717
+ const result = statistics(values);
718
+ res.jsonResponse(result);
719
+ }
720
+ catch (err) {
721
+ error(res, 400, err.message);
722
+ }
723
+ });
724
+ // GET symmetric error
725
+ router.get('/:version/symmetric', postOnly('symmetric'));
726
+ // Text utilities (slug, stats, lorem, number)
727
+ router.get('/:version/text', (req, res) => {
728
+ const { method, value, type, count, lang, text } = req.query;
729
+ const { version } = req.params;
730
+ const textMod = req.module.text;
731
+ if (!textMod) {
732
+ error(res, 404, `Endpoint not available in ${version}.`);
733
+ return;
734
+ }
735
+ if (!method || !Object.hasOwn(textMod, method)) {
736
+ error(res, 400, 'Please provide a valid method (?method={slug|stats|lorem|number})');
737
+ return;
738
+ }
739
+ try {
740
+ let result;
741
+ switch (method) {
742
+ case 'slug':
743
+ case 'stats':
744
+ result = textMod[method]((value ?? text));
745
+ break;
746
+ case 'lorem':
747
+ result = textMod.lorem(type || 'words', count || '5');
748
+ break;
749
+ case 'number':
750
+ result = textMod.number(value, lang || 'en');
751
+ break;
752
+ default:
753
+ throw new Error('Unknown method');
754
+ }
755
+ res.jsonResponse({ method, result });
756
+ }
757
+ catch (err) {
758
+ error(res, 400, err.message);
759
+ }
760
+ });
761
+ // GET tic-tac-toe errors
762
+ router.get('/:version/tic-tac-toe', postOnly('tic_tac_toe'));
763
+ router.get('/:version/tic-tac-toe/fetch', postOnly('tic_tac_toe'));
764
+ router.get('/:version/tic-tac-toe/list', postOnly('tic_tac_toe'));
765
+ // Display or generate time informations, or compute a countdown
766
+ router.get('/:version/time', (req, res) => {
767
+ const { type = 'live', start, end, format, timezone, target } = req.query;
768
+ try {
769
+ const timeFn = req.module.time;
770
+ const time = timeFn(type, start, end, format, timezone, target);
771
+ res.jsonResponse(time);
772
+ }
773
+ catch (err) {
774
+ error(res, 400, err.message);
775
+ }
776
+ });
777
+ // GET token error
778
+ router.get('/:version/token', postOnly('token'));
779
+ // Parse a URL into its components
780
+ router.get('/:version/url', (req, res) => {
781
+ const { url } = req.query;
782
+ const { version } = req.params;
783
+ const parseUrlFn = req.module.parseUrl;
784
+ if (!parseUrlFn) {
785
+ error(res, 404, `Endpoint not available in ${version}.`);
786
+ return;
787
+ }
788
+ if (!url || typeof url !== 'string') {
789
+ error(res, 400, 'Please provide a URL (?url={URL})');
790
+ return;
791
+ }
792
+ try {
793
+ const result = parseUrlFn(url);
794
+ res.jsonResponse(result);
795
+ }
796
+ catch (err) {
797
+ error(res, 400, err.message);
798
+ }
799
+ });
800
+ // Generate username
801
+ router.get('/:version/username', (req, res) => {
802
+ try {
803
+ const result = req.module.username();
804
+ res.jsonResponse(result);
805
+ }
806
+ catch (err) {
807
+ error(res, 400, err.message);
808
+ }
809
+ });
810
+ // Generate or parse a UUID
811
+ router.get('/:version/uuid', (req, res) => {
812
+ const { uuid: input, count } = req.query;
813
+ const { version } = req.params;
814
+ const uuidFn = req.module.uuid;
815
+ if (!uuidFn) {
816
+ error(res, 404, `Endpoint not available in ${version}.`);
817
+ return;
818
+ }
819
+ if (input !== undefined && typeof input !== 'string') {
820
+ error(res, 400, 'Please provide a valid UUID (?uuid={uuid})');
821
+ return;
822
+ }
823
+ try {
824
+ const result = uuidFn(input, count !== undefined ? Number(count) : undefined);
825
+ res.jsonResponse(result);
826
+ }
827
+ catch (err) {
828
+ error(res, 400, err.message);
829
+ }
830
+ });
831
+ // Validate data (luhn, iban, email)
832
+ router.get('/:version/validate', (req, res) => {
833
+ const { type, value } = req.query;
834
+ const { version } = req.params;
835
+ const validate = req.module.validate;
836
+ if (!validate) {
837
+ error(res, 404, `Endpoint not available in ${version}.`);
838
+ return;
839
+ }
840
+ if (!type || !Object.hasOwn(validate, type)) {
841
+ error(res, 400, 'Please provide a valid type (?type={luhn|iban|email})');
842
+ return;
843
+ }
844
+ if (!value) {
845
+ error(res, 400, 'Please provide a value (&value={value})');
846
+ return;
847
+ }
848
+ try {
849
+ const result = validate[type](value);
850
+ res.jsonResponse(result);
851
+ }
852
+ catch (err) {
853
+ error(res, 400, err.message);
854
+ }
855
+ });
856
+ export default router;
857
+ //# sourceMappingURL=get.js.map