@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,5 @@
1
+ .github/
2
+ dist/
3
+ node_modules/
4
+ package-lock.json
5
+ package.json
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Sylvain L.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,277 @@
1
+ # @moxon/api
2
+
3
+ ## About
4
+
5
+ `@moxon/api` bundles 40+ self-contained utilities: encryption, matrix math, SVG charts, CSV, JWT, TOTP, barcodes, fake data generation, text processing, validation and more. Install it and import — no configuration, no setup step, types included.
6
+
7
+ It works two ways:
8
+
9
+ - **As a library** — import any module directly into your code.
10
+ - **As a server** — a single import boots an Express app that exposes every module over HTTP.
11
+
12
+ The HTTP surface is versioned from `v4` to `v6`, and every version stays mounted side by side, so a new release never changes the behaviour of the one you already target. The full endpoint reference lives on [docs.sylvain.sh](https://docs.sylvain.sh).
13
+
14
+ ## Migrating from `@20syldev/api`
15
+
16
+ `@moxon/api` is the new name of `@20syldev/api`. This release is the code of `@20syldev/api@6.0.0` under its new name: same exports, same `/v6` HTTP API. Nothing else changed.
17
+
18
+ ```bash
19
+ npm uninstall @20syldev/api
20
+ npm install @moxon/api
21
+ ```
22
+
23
+ Then replace the package name in your imports. The subpaths are the same.
24
+
25
+ ```diff
26
+ - import { evaluate } from '@20syldev/api/v6';
27
+ + import { evaluate } from '@moxon/api/v6';
28
+ ```
29
+
30
+ ## Requirements
31
+
32
+ **Node.js >= 22.12.0.** The package ships as ESM, but that does not lock out CommonJS: Node has been able to `require()` an ESM module since 22.12, which is why that is the floor. The library entry works from both module systems.
33
+
34
+ ```js
35
+ import { evaluate } from '@moxon/api'; // ESM
36
+ const { evaluate } = require('@moxon/api'); // CommonJS
37
+ ```
38
+
39
+ The server entry loads its plugins asynchronously, so it must be imported rather than required:
40
+
41
+ ```js
42
+ await import('@moxon/api/server'); // from CommonJS
43
+ ```
44
+
45
+ ## Installation
46
+
47
+ ```console
48
+ $ npm install @moxon/api
49
+ ```
50
+
51
+ ## Quick start
52
+
53
+ The root import always resolves to the latest version. Use a subpath (`/v4` to `/v6`) to pin a specific one.
54
+
55
+ ```js
56
+ // Latest version, equivalent to '@moxon/api/v6'
57
+ import { color, evaluate, username } from '@moxon/api';
58
+
59
+ // Or a specific version
60
+ import { color as colorV4 } from '@moxon/api/v4';
61
+
62
+ // Evaluate a math expression
63
+ const expr = evaluate('sin(pi / 2) + sqrt(4)', 5);
64
+ console.log(expr.result); // 3
65
+ console.log(expr.expression); // 'sin(pi / 2) + sqrt(4)'
66
+
67
+ // Generate a random color, converted to every common notation
68
+ const c = color();
69
+ console.log(c.hex, c.rgb, c.hsl, c.hsv, c.hwb, c.cmyk);
70
+
71
+ // Generate a random username
72
+ const user = username();
73
+ console.log(user.username);
74
+ ```
75
+
76
+ ## What's inside
77
+
78
+ | Domain | Exports |
79
+ | ------------------ | ------------------------------------------------------------------------------------- |
80
+ | **Crypto** | `asymmetric` `symmetric` `hash` `jwt` `otp` `token` `password` `captcha` |
81
+ | **Math & data** | **`matrix`** **`algorithms`** `evaluate` `statistics` `convert` `csv` |
82
+ | **Text** | **`text`** **`encode`** **`validate`** `caseConvert` `levenshtein` `regex` `parseUrl` |
83
+ | **Graphics** | **`chart`** `barcode` `qrcode` `avatar` `placeholder` `color` `palette` |
84
+ | **Fake data** | `personal` `address` `credit` `username` `dice` `domain` `agent` |
85
+ | **Network & time** | `ip` `geo` `time` `cron` `hyperplanning` |
86
+ | **Stateful** | `chat` `tic_tac_toe` |
87
+
88
+ The six names in **bold** are namespaces — they group related functions, called as `namespace.method()`:
89
+
90
+ | Namespace | Functions |
91
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
92
+ | **`algorithms`** | `factorial` `fibonacci` `gcd` `isprime` `primefactors` `primelist` `roman` `anagram` `palindrome` `reverse` `bubblesort` |
93
+ | **`chart`** | `bar` `line` `pie` `donut` |
94
+ | **`encode`** | `base64encode` `base64decode` `urlencode` `urldecode` `binary` `unbinary` `morse` `unmorse` `caesar` `rot13` |
95
+ | **`matrix`** | `add` `subtract` `multiply` `scalar` `transpose` `determinant` `inverse` `identity` |
96
+ | **`text`** | `lorem` `slug` `stats` `number` |
97
+ | **`validate`** | `email` `iban` `luhn` |
98
+
99
+ Everything else is a plain function, called directly.
100
+
101
+ Two names differ from their HTTP endpoint, because `case` is a reserved word and `url` is a global identifier:
102
+
103
+ | Endpoint | Import |
104
+ | -------- | ------------- |
105
+ | `/case` | `caseConvert` |
106
+ | `/url` | `parseUrl` |
107
+
108
+ > _`personal` generates **fake** profiles (names, emails, jobs, addresses) for seeding and testing — it holds no real data._
109
+
110
+ ## Examples
111
+
112
+ ```js
113
+ import {
114
+ asymmetric,
115
+ caseConvert,
116
+ chart,
117
+ csv,
118
+ evaluate,
119
+ jwt,
120
+ matrix,
121
+ otp,
122
+ parseUrl,
123
+ symmetric,
124
+ validate,
125
+ } from '@moxon/api/v5';
126
+
127
+ // RSA key generation, encryption and decryption
128
+ const { publicKey, privateKey } = asymmetric('keygen', {});
129
+ const { result: encrypted } = asymmetric('encrypt', { text: 'secret message', publicKey });
130
+ const { result: decrypted } = asymmetric('decrypt', { text: encrypted, privateKey });
131
+ console.log(decrypted); // 'secret message'
132
+
133
+ // AES-256-GCM symmetric encryption, key derived with scrypt
134
+ const { result: blob } = symmetric('encrypt', 'secret message', 'a-strong-key');
135
+ const { result: plain } = symmetric('decrypt', blob, 'a-strong-key');
136
+ console.log(plain); // 'secret message'
137
+
138
+ // TOTP secret, code generation and verification
139
+ const { secret, uri } = otp('secret', { label: 'alice', issuer: 'MyApp' });
140
+ const { code } = otp('generate', { secret });
141
+ const { valid } = otp('verify', { secret, code });
142
+ console.log(valid); // true
143
+
144
+ // Decode a JWT without verifying its signature (inspection only)
145
+ const { header, payload } = jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.qfhpVR4l');
146
+ console.log(header.alg, payload.sub); // 'HS256' '1234567890'
147
+
148
+ // Evaluate a math expression, with a precision
149
+ const { result } = evaluate('log2(8) * (3 + pi)', 4);
150
+ console.log(result); // 18.4248
151
+
152
+ // Matrix product
153
+ const { result: product } = matrix.multiply(
154
+ [
155
+ [1, 2],
156
+ [3, 4],
157
+ ],
158
+ [
159
+ [5, 6],
160
+ [7, 8],
161
+ ],
162
+ );
163
+ console.log(product); // [[19, 22], [43, 50]]
164
+
165
+ // Render an SVG chart in memory
166
+ const { body: svg } = chart.bar(
167
+ { labels: ['Jan', 'Feb', 'Mar'], datasets: [{ label: 'Sales', values: [120, 85, 200] }] },
168
+ { width: 600, height: 300 },
169
+ );
170
+ // body holds a ready-to-serve SVG string
171
+
172
+ // Parse CSV into rows, or format rows back into CSV
173
+ const { rows } = csv('parse', { csv: 'name,age\nAlice,30\nBob,25' });
174
+ console.log(rows); // [{ name: 'Alice', age: '30' }, { name: 'Bob', age: '25' }]
175
+
176
+ // Convert between case styles
177
+ console.log(caseConvert('hello world', 'pascal').result); // 'HelloWorld'
178
+
179
+ // Split a URL into its components
180
+ const parsed = parseUrl('https://example.com/a/b?tag=x&tag=y#top');
181
+ console.log(parsed.host, parsed.port, parsed.params, parsed.fragment);
182
+
183
+ // Validate an email, an IBAN or a card number
184
+ console.log(validate.email('alice@example.com').valid); // true
185
+ ```
186
+
187
+ ## Running the server
188
+
189
+ From the installed package, one import mounts every version:
190
+
191
+ ```js
192
+ import '@moxon/api/server';
193
+ ```
194
+
195
+ From a clone of the repository:
196
+
197
+ ```console
198
+ $ npm run build && npm start
199
+ ```
200
+
201
+ ```console
202
+ > @moxon/api@6.0.0-pre build
203
+ > tsc
204
+
205
+ > @moxon/api@6.0.0-pre start
206
+ > node dist/app.js
207
+
208
+ API is running on
209
+ - http://127.0.0.1:3000
210
+ - http://localhost:3000
211
+ ```
212
+
213
+ For development with automatic reloading:
214
+
215
+ ```console
216
+ $ npm run dev
217
+ ```
218
+
219
+ Endpoints follow the `/:version/:endpoint` pattern — `GET /v5/color`, `GET /v5/evaluate?expr=2%2B2`, `POST /v5/matrix`. `GET /` lists the available versions, and `GET /:version` lists that version's endpoints with their parameters.
220
+
221
+ ### Configuration
222
+
223
+ Every setting is optional and read from the environment; a `.env` file at the project root is loaded automatically. The server runs with none of them set.
224
+
225
+ | Variable | Default | Purpose |
226
+ | ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
227
+ | `PORT` | `3000` | Port the server listens on |
228
+ | `DOCS_URL` | — | Documentation base URL reported by `/`, `/:version` and `/:version/infos` |
229
+ | `REPO_URL` | — | Source repository reported by `/:version/infos` |
230
+ | `INSTANCE_CREATED` | — | Launch date reported by `/:version/infos` |
231
+ | `LOGS_TOKEN` | — | Value required in the `X-Logs-Token` header to read `/logs`; the route answers 404 while unset |
232
+ | `CHALLENGE_SECRET` | random | Key signing the captcha and proof-of-work tokens; a random one is generated at startup while unset |
233
+ | `TRUSTED_PROXIES` | one hop | CIDR blocks separated by spaces or commas, or the `loopback` / `linklocal` / `uniquelocal` shorthands, for deployments behind a CDN or platform router |
234
+ | `GLOBAL_LIMIT` | `50000` | Requests per hour accepted across the whole instance |
235
+ | `DEFAULT_LIMIT` | `2000` | Per-client requests per hour |
236
+ | `DEFAULT_BURST` | `50` | Per-client requests per 10-second window |
237
+
238
+ The three metadata variables are omitted from responses when unset, so an instance never advertises somebody else's documentation or repository.
239
+
240
+ Higher quotas can be granted per client: `ADVANCED_`, `PRO_` and `BUSINESS_` variants of `_LIMIT` and `_BURST` define the tiers, and the matching `*_TOKEN_LIST` variables hold the space-separated bearer tokens that map to them. A client's tier and quota are reported by `GET /auth`.
241
+
242
+ > _Rate-limit counters live in process memory, so each instance of a multi-instance deployment counts separately._
243
+
244
+ > _Captcha and proof-of-work tokens are signed with `CHALLENGE_SECRET`. While it is unset each process invents its own key, so tokens stop verifying after a restart and are rejected by sibling instances — set it explicitly for any deployment running more than one process, with a full-entropy value such as `openssl rand -hex 32`._
245
+
246
+ ## Versioning
247
+
248
+ | Version | What it changes |
249
+ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
250
+ | `v4` | The first fully typed version, and the one that introduced the PATCH and DELETE routes |
251
+ | `v5` | Adds `base`, `case`, `csv`, `diff`, `evaluate`, `pow`, `read`, `semver`, `url`, `uuid`, asymmetric and symmetric crypto, charts, JWT, matrices and OTP |
252
+ | `v6` | The captcha answers with a signed token by default, `levenshtein` moves to POST, chat and tic-tac-toe carry their identifiers in the body, `hyperplanning` is deprecated |
253
+
254
+ Every version is fully typed. The package root always tracks the latest one.
255
+
256
+ > _`v1`, `v2` and `v3` were removed in `6.0.0`, along with the untyped JavaScript they shared. Install `@20syldev/api@5.9.0` if you still need them._
257
+
258
+ > _`hyperplanning` is deprecated: it still works on every version, but `v6` no longer lists it among its endpoints, and it will be removed entirely in `7.0.0`._
259
+
260
+ ## Scripts
261
+
262
+ | Command | Description |
263
+ | ---------------- | ------------------------------------------------------- |
264
+ | `npm run dev` | Development server with automatic reloading (tsx watch) |
265
+ | `npm run build` | Compile TypeScript to `dist/` |
266
+ | `npm start` | Start the production server (`node dist/app.js`) |
267
+ | `npm test` | Run unit and integration tests |
268
+ | `npm run format` | Format with Prettier and auto-fix with ESLint |
269
+ | `npm run check` | TypeScript and ESLint verification |
270
+
271
+ ## Hosted instance
272
+
273
+ A public instance runs at [api.sylvain.sh](https://api.sylvain.sh), with the complete endpoint reference, request examples and usage guides on [docs.sylvain.sh](https://docs.sylvain.sh).
274
+
275
+ ## License
276
+
277
+ BSD 3-Clause. See [LICENSE](LICENSE).
package/dist/app.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ declare const app: import("express-serve-static-core").Express;
2
+ export default app;
package/dist/app.js ADDED
@@ -0,0 +1,55 @@
1
+ import express from 'express';
2
+ import { env } from './config/env.js';
3
+ import { setupCors } from './middleware/cors.js';
4
+ import { errorHandler } from './middleware/error.js';
5
+ import { jsonResponseMiddleware } from './middleware/json.js';
6
+ import { loggerMiddleware } from './middleware/logger.js';
7
+ import { rateLimitMiddleware } from './middleware/ratelimit.js';
8
+ import { endpointCheckMiddleware, versionCheckMiddleware } from './middleware/version.js';
9
+ import deleteRoutes from './routes/delete.js';
10
+ import getRoutes from './routes/get.js';
11
+ import indexRoutes from './routes/index.js';
12
+ import patchRoutes from './routes/patch.js';
13
+ import postRoutes from './routes/post.js';
14
+ import { error } from './utils/response.js';
15
+ const app = express();
16
+ // Setup CORS, body parsing, static files
17
+ setupCors(app);
18
+ // Custom JSON response
19
+ app.use(jsonResponseMiddleware);
20
+ // Rate limiting
21
+ app.use(rateLimitMiddleware);
22
+ // Request logging
23
+ app.use(loggerMiddleware);
24
+ // Root routes (before version check)
25
+ app.use(indexRoutes);
26
+ // Version & endpoint validation
27
+ app.use('/:version', versionCheckMiddleware);
28
+ app.use('/:version/:endpoint', endpointCheckMiddleware);
29
+ // Load plugins if available
30
+ const entry = './plugins/index.js';
31
+ try {
32
+ const { default: plugins } = (await import(entry));
33
+ for (const plugin of plugins)
34
+ app.use(plugin);
35
+ }
36
+ catch {
37
+ // No plugins bundled in this build
38
+ }
39
+ // Versioned routes
40
+ app.use(getRoutes);
41
+ app.use(postRoutes);
42
+ app.use(patchRoutes);
43
+ app.use(deleteRoutes);
44
+ // JSON 404 fallback
45
+ app.use((req, res) => {
46
+ error(res, 404, `Endpoint '${req.path}' does not exist.`);
47
+ });
48
+ // Error handling (after routes)
49
+ app.use(errorHandler);
50
+ // Start server
51
+ if (process.env.NODE_ENV !== 'test') {
52
+ app.listen(env.PORT, () => console.log(`API is running on\n - http://127.0.0.1:${env.PORT}\n - http://localhost:${env.PORT}`));
53
+ }
54
+ export default app;
55
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,OAAqD,MAAM,SAAS,CAAC;AAE5E,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,yCAAyC;AACzC,SAAS,CAAC,GAAG,CAAC,CAAC;AAEf,uBAAuB;AACvB,GAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAEhC,gBAAgB;AAChB,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAE7B,kBAAkB;AAClB,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAE1B,qCAAqC;AACrC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAErB,gCAAgC;AAChC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;AAC7C,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,uBAAuB,CAAC,CAAC;AAExD,4BAA4B;AAC5B,MAAM,KAAK,GAAG,oBAAoB,CAAC;AACnC,IAAI,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAA0B,CAAC;IAC5E,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC;AAAC,MAAM,CAAC;IACL,mCAAmC;AACvC,CAAC;AAED,mBAAmB;AACnB,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACnB,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AACpB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACrB,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAEtB,oBAAoB;AACpB,GAAG,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IACpC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,GAAG,CAAC,IAAI,mBAAmB,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AAEH,gCAAgC;AAChC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAEtB,eAAe;AACf,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;IAClC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,CACtB,OAAO,CAAC,GAAG,CAAC,6CAA6C,GAAG,CAAC,IAAI,4BAA4B,GAAG,CAAC,IAAI,EAAE,CAAC,CAC3G,CAAC;AACN,CAAC;AAED,eAAe,GAAG,CAAC"}
@@ -0,0 +1,22 @@
1
+ export declare function envList(key: string): string[] | null;
2
+ export declare const env: {
3
+ PORT: number;
4
+ TRUSTED_PROXIES: string[] | null;
5
+ DOCS_URL: string;
6
+ REPO_URL: string;
7
+ INSTANCE_CREATED: string;
8
+ LOGS_TOKEN: string;
9
+ CHALLENGE_SECRET: string;
10
+ DEFAULT_LIMIT: number;
11
+ ADVANCED_LIMIT: number;
12
+ PRO_LIMIT: number;
13
+ BUSINESS_LIMIT: number;
14
+ GLOBAL_LIMIT: number;
15
+ DEFAULT_BURST: number;
16
+ ADVANCED_BURST: number;
17
+ PRO_BURST: number;
18
+ BUSINESS_BURST: number;
19
+ BUSINESS_TOKEN_LIST: string[];
20
+ PRO_TOKEN_LIST: string[];
21
+ ADVANCED_TOKEN_LIST: string[];
22
+ };
@@ -0,0 +1,36 @@
1
+ import dotenv from 'dotenv';
2
+ import { DEFAULT_PORT } from '../constants.js';
3
+ dotenv.config();
4
+ export function envList(key) {
5
+ const v = process.env[key];
6
+ if (!v || v === 'undefined')
7
+ return null;
8
+ const items = v.split(/[\s,]+/).filter(Boolean);
9
+ return items.length ? items : null;
10
+ }
11
+ function envNumber(key, fallback) {
12
+ const v = parseInt(process.env[key] ?? '', 10);
13
+ return isNaN(v) ? fallback : v;
14
+ }
15
+ export const env = {
16
+ PORT: envNumber('PORT', DEFAULT_PORT),
17
+ TRUSTED_PROXIES: envList('TRUSTED_PROXIES'),
18
+ DOCS_URL: (process.env.DOCS_URL ?? '').replace(/\/+$/, ''),
19
+ REPO_URL: process.env.REPO_URL ?? '',
20
+ INSTANCE_CREATED: process.env.INSTANCE_CREATED ?? '',
21
+ LOGS_TOKEN: process.env.LOGS_TOKEN ?? '',
22
+ CHALLENGE_SECRET: process.env.CHALLENGE_SECRET ?? '',
23
+ DEFAULT_LIMIT: envNumber('DEFAULT_LIMIT', 2000),
24
+ ADVANCED_LIMIT: envNumber('ADVANCED_LIMIT', 3500),
25
+ PRO_LIMIT: envNumber('PRO_LIMIT', 6000),
26
+ BUSINESS_LIMIT: envNumber('BUSINESS_LIMIT', 10000),
27
+ GLOBAL_LIMIT: envNumber('GLOBAL_LIMIT', 50000),
28
+ DEFAULT_BURST: envNumber('DEFAULT_BURST', 50),
29
+ ADVANCED_BURST: envNumber('ADVANCED_BURST', 80),
30
+ PRO_BURST: envNumber('PRO_BURST', 120),
31
+ BUSINESS_BURST: envNumber('BUSINESS_BURST', 200),
32
+ BUSINESS_TOKEN_LIST: envList('BUSINESS_TOKEN_LIST') ?? [],
33
+ PRO_TOKEN_LIST: envList('PRO_TOKEN_LIST') ?? [],
34
+ ADVANCED_TOKEN_LIST: envList('ADVANCED_TOKEN_LIST') ?? [],
35
+ };
36
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,UAAU,OAAO,CAAC,GAAW;IAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED,SAAS,SAAS,CAAC,GAAW,EAAE,QAAgB;IAC5C,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACf,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC;IACrC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAE3C,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAC1D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE;IACpC,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;IAEpD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE;IACxC,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;IAEpD,aAAa,EAAE,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC;IAC/C,cAAc,EAAE,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC;IACjD,SAAS,EAAE,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC;IACvC,cAAc,EAAE,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC;IAClD,YAAY,EAAE,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC;IAE9C,aAAa,EAAE,SAAS,CAAC,eAAe,EAAE,EAAE,CAAC;IAC7C,cAAc,EAAE,SAAS,CAAC,gBAAgB,EAAE,EAAE,CAAC;IAC/C,SAAS,EAAE,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC;IACtC,cAAc,EAAE,SAAS,CAAC,gBAAgB,EAAE,GAAG,CAAC;IAEhD,mBAAmB,EAAE,OAAO,CAAC,qBAAqB,CAAC,IAAI,EAAE;IACzD,cAAc,EAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE;IAC/C,mBAAmB,EAAE,OAAO,CAAC,qBAAqB,CAAC,IAAI,EAAE;CAC5D,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Rate limit plans configuration.
3
+ *
4
+ * hourly — max requests per hour (matches pricing page)
5
+ * burst — max requests per 10-second window
6
+ * tokens — list of bearer tokens for this tier
7
+ *
8
+ * To adjust limits, edit the values below or override via .env:
9
+ * DEFAULT_LIMIT, ADVANCED_LIMIT, PRO_LIMIT, BUSINESS_LIMIT
10
+ * DEFAULT_BURST, ADVANCED_BURST, PRO_BURST, BUSINESS_BURST
11
+ */
12
+ export interface Plan {
13
+ hourly: number;
14
+ burst: number;
15
+ tokens: string[];
16
+ }
17
+ export declare const plans: Record<string, Plan>;
18
+ export declare const globalLimit: number;
19
+ /**
20
+ * Returns the plan matching a bearer token, or 'default'.
21
+ * Returns null if the token is provided but invalid.
22
+ */
23
+ export declare function getPlan(token: string): {
24
+ name: string;
25
+ plan: Plan;
26
+ } | null;
@@ -0,0 +1,44 @@
1
+ import { env } from './env.js';
2
+ export const plans = {
3
+ business: {
4
+ hourly: env.BUSINESS_LIMIT,
5
+ burst: env.BUSINESS_BURST,
6
+ tokens: env.BUSINESS_TOKEN_LIST,
7
+ },
8
+ pro: {
9
+ hourly: env.PRO_LIMIT,
10
+ burst: env.PRO_BURST,
11
+ tokens: env.PRO_TOKEN_LIST,
12
+ },
13
+ advanced: {
14
+ hourly: env.ADVANCED_LIMIT,
15
+ burst: env.ADVANCED_BURST,
16
+ tokens: env.ADVANCED_TOKEN_LIST,
17
+ },
18
+ default: {
19
+ hourly: env.DEFAULT_LIMIT,
20
+ burst: env.DEFAULT_BURST,
21
+ tokens: [],
22
+ },
23
+ };
24
+ export const globalLimit = env.GLOBAL_LIMIT; // 50 000/h
25
+ /**
26
+ * Returns the plan matching a bearer token, or 'default'.
27
+ * Returns null if the token is provided but invalid.
28
+ */
29
+ export function getPlan(token) {
30
+ if (!token)
31
+ return { name: 'default', plan: plans.default };
32
+ if (token === 'undefined')
33
+ return null;
34
+ for (const [name, plan] of Object.entries(plans)) {
35
+ if (name === 'default')
36
+ continue;
37
+ if (plan.tokens.includes('undefined'))
38
+ continue;
39
+ if (plan.tokens.includes(token))
40
+ return { name, plan };
41
+ }
42
+ return null;
43
+ }
44
+ //# sourceMappingURL=plans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans.js","sourceRoot":"","sources":["../../src/config/plans.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAoB/B,MAAM,CAAC,MAAM,KAAK,GAAyB;IACvC,QAAQ,EAAE;QACN,MAAM,EAAE,GAAG,CAAC,cAAc;QAC1B,KAAK,EAAE,GAAG,CAAC,cAAc;QACzB,MAAM,EAAE,GAAG,CAAC,mBAAmB;KAClC;IACD,GAAG,EAAE;QACD,MAAM,EAAE,GAAG,CAAC,SAAS;QACrB,KAAK,EAAE,GAAG,CAAC,SAAS;QACpB,MAAM,EAAE,GAAG,CAAC,cAAc;KAC7B;IACD,QAAQ,EAAE;QACN,MAAM,EAAE,GAAG,CAAC,cAAc;QAC1B,KAAK,EAAE,GAAG,CAAC,cAAc;QACzB,MAAM,EAAE,GAAG,CAAC,mBAAmB;KAClC;IACD,OAAO,EAAE;QACL,MAAM,EAAE,GAAG,CAAC,aAAa;QACzB,KAAK,EAAE,GAAG,CAAC,aAAa;QACxB,MAAM,EAAE,EAAE;KACb;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,WAAW;AAExD;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACjC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,OAAQ,EAAE,CAAC;IAC7D,IAAI,KAAK,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAEvC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAS;QAChD,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3D,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import * as apiv4 from '../modules/v4.js';
2
+ import * as apiv5 from '../modules/v5.js';
3
+ import * as apiv6 from '../modules/v6.js';
4
+ export interface Endpoint {
5
+ name: string;
6
+ path?: string;
7
+ children?: Record<string, string>;
8
+ }
9
+ export interface VersionConfig {
10
+ endpoints: {
11
+ get: Endpoint[];
12
+ post: Endpoint[];
13
+ patch?: Endpoint[];
14
+ delete?: Endpoint[];
15
+ };
16
+ modules: typeof apiv4 | typeof apiv5 | typeof apiv6;
17
+ }
18
+ export declare const versions: Record<string, VersionConfig>;