@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.
- package/.prettierignore +5 -0
- package/LICENSE +28 -0
- package/README.md +277 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.js +55 -0
- package/dist/app.js.map +1 -0
- package/dist/config/env.d.ts +22 -0
- package/dist/config/env.js +36 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/plans.d.ts +26 -0
- package/dist/config/plans.js +44 -0
- package/dist/config/plans.js.map +1 -0
- package/dist/config/versions.d.ts +18 -0
- package/dist/config/versions.js +248 -0
- package/dist/config/versions.js.map +1 -0
- package/dist/constants.d.ts +48 -0
- package/dist/constants.js +75 -0
- package/dist/constants.js.map +1 -0
- package/dist/middleware/cors.d.ts +2 -0
- package/dist/middleware/cors.js +31 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/error.d.ts +4 -0
- package/dist/middleware/error.js +8 -0
- package/dist/middleware/error.js.map +1 -0
- package/dist/middleware/json.d.ts +2 -0
- package/dist/middleware/json.js +8 -0
- package/dist/middleware/json.js.map +1 -0
- package/dist/middleware/logger.d.ts +26 -0
- package/dist/middleware/logger.js +65 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/ratelimit.d.ts +2 -0
- package/dist/middleware/ratelimit.js +83 -0
- package/dist/middleware/ratelimit.js.map +1 -0
- package/dist/middleware/version.d.ts +3 -0
- package/dist/middleware/version.js +30 -0
- package/dist/middleware/version.js.map +1 -0
- package/dist/modules/v4/address.d.ts +20 -0
- package/dist/modules/v4/address.js +381 -0
- package/dist/modules/v4/address.js.map +1 -0
- package/dist/modules/v4/agent.d.ts +30 -0
- package/dist/modules/v4/agent.js +92 -0
- package/dist/modules/v4/agent.js.map +1 -0
- package/dist/modules/v4/algorithms.d.ts +90 -0
- package/dist/modules/v4/algorithms.js +279 -0
- package/dist/modules/v4/algorithms.js.map +1 -0
- package/dist/modules/v4/avatar.d.ts +23 -0
- package/dist/modules/v4/avatar.js +136 -0
- package/dist/modules/v4/avatar.js.map +1 -0
- package/dist/modules/v4/barcode.d.ts +27 -0
- package/dist/modules/v4/barcode.js +440 -0
- package/dist/modules/v4/barcode.js.map +1 -0
- package/dist/modules/v4/captcha.d.ts +22 -0
- package/dist/modules/v4/captcha.js +79 -0
- package/dist/modules/v4/captcha.js.map +1 -0
- package/dist/modules/v4/chat.d.ts +21 -0
- package/dist/modules/v4/chat.js +100 -0
- package/dist/modules/v4/chat.js.map +1 -0
- package/dist/modules/v4/color.d.ts +16 -0
- package/dist/modules/v4/color.js +59 -0
- package/dist/modules/v4/color.js.map +1 -0
- package/dist/modules/v4/convert.d.ts +15 -0
- package/dist/modules/v4/convert.js +116 -0
- package/dist/modules/v4/convert.js.map +1 -0
- package/dist/modules/v4/credit.d.ts +22 -0
- package/dist/modules/v4/credit.js +104 -0
- package/dist/modules/v4/credit.js.map +1 -0
- package/dist/modules/v4/cron.d.ts +17 -0
- package/dist/modules/v4/cron.js +202 -0
- package/dist/modules/v4/cron.js.map +1 -0
- package/dist/modules/v4/dice.d.ts +16 -0
- package/dist/modules/v4/dice.js +37 -0
- package/dist/modules/v4/dice.js.map +1 -0
- package/dist/modules/v4/domain.d.ts +6 -0
- package/dist/modules/v4/domain.js +83 -0
- package/dist/modules/v4/domain.js.map +1 -0
- package/dist/modules/v4/encode.d.ts +81 -0
- package/dist/modules/v4/encode.js +236 -0
- package/dist/modules/v4/encode.js.map +1 -0
- package/dist/modules/v4/geo.d.ts +30 -0
- package/dist/modules/v4/geo.js +51 -0
- package/dist/modules/v4/geo.js.map +1 -0
- package/dist/modules/v4/hash.d.ts +15 -0
- package/dist/modules/v4/hash.js +25 -0
- package/dist/modules/v4/hash.js.map +1 -0
- package/dist/modules/v4/hyperplanning.d.ts +19 -0
- package/dist/modules/v4/hyperplanning.js +80 -0
- package/dist/modules/v4/hyperplanning.js.map +1 -0
- package/dist/modules/v4/ip.d.ts +19 -0
- package/dist/modules/v4/ip.js +132 -0
- package/dist/modules/v4/ip.js.map +1 -0
- package/dist/modules/v4/levenshtein.d.ts +13 -0
- package/dist/modules/v4/levenshtein.js +37 -0
- package/dist/modules/v4/levenshtein.js.map +1 -0
- package/dist/modules/v4/palette.d.ts +19 -0
- package/dist/modules/v4/palette.js +56 -0
- package/dist/modules/v4/palette.js.map +1 -0
- package/dist/modules/v4/password.d.ts +25 -0
- package/dist/modules/v4/password.js +343 -0
- package/dist/modules/v4/password.js.map +1 -0
- package/dist/modules/v4/personal.d.ts +6 -0
- package/dist/modules/v4/personal.js +121 -0
- package/dist/modules/v4/personal.js.map +1 -0
- package/dist/modules/v4/placeholder.d.ts +30 -0
- package/dist/modules/v4/placeholder.js +160 -0
- package/dist/modules/v4/placeholder.js.map +1 -0
- package/dist/modules/v4/qrcode.d.ts +25 -0
- package/dist/modules/v4/qrcode.js +92 -0
- package/dist/modules/v4/qrcode.js.map +1 -0
- package/dist/modules/v4/regex.d.ts +23 -0
- package/dist/modules/v4/regex.js +48 -0
- package/dist/modules/v4/regex.js.map +1 -0
- package/dist/modules/v4/statistics.d.ts +20 -0
- package/dist/modules/v4/statistics.js +48 -0
- package/dist/modules/v4/statistics.js.map +1 -0
- package/dist/modules/v4/text.d.ts +43 -0
- package/dist/modules/v4/text.js +323 -0
- package/dist/modules/v4/text.js.map +1 -0
- package/dist/modules/v4/tic_tac_toe.d.ts +19 -0
- package/dist/modules/v4/tic_tac_toe.js +214 -0
- package/dist/modules/v4/tic_tac_toe.js.map +1 -0
- package/dist/modules/v4/time.d.ts +15 -0
- package/dist/modules/v4/time.js +124 -0
- package/dist/modules/v4/time.js.map +1 -0
- package/dist/modules/v4/token.d.ts +9 -0
- package/dist/modules/v4/token.js +45 -0
- package/dist/modules/v4/token.js.map +1 -0
- package/dist/modules/v4/username.d.ts +6 -0
- package/dist/modules/v4/username.js +92 -0
- package/dist/modules/v4/username.js.map +1 -0
- package/dist/modules/v4/validate.d.ts +34 -0
- package/dist/modules/v4/validate.js +75 -0
- package/dist/modules/v4/validate.js.map +1 -0
- package/dist/modules/v4.d.ts +32 -0
- package/dist/modules/v4.js +33 -0
- package/dist/modules/v4.js.map +1 -0
- package/dist/modules/v5/address.d.ts +5 -0
- package/dist/modules/v5/address.js +20 -0
- package/dist/modules/v5/address.js.map +1 -0
- package/dist/modules/v5/algorithms.d.ts +9 -0
- package/dist/modules/v5/algorithms.js +39 -0
- package/dist/modules/v5/algorithms.js.map +1 -0
- package/dist/modules/v5/asymmetric.d.ts +26 -0
- package/dist/modules/v5/asymmetric.js +74 -0
- package/dist/modules/v5/asymmetric.js.map +1 -0
- package/dist/modules/v5/barcode.d.ts +27 -0
- package/dist/modules/v5/barcode.js +424 -0
- package/dist/modules/v5/barcode.js.map +1 -0
- package/dist/modules/v5/base.d.ts +16 -0
- package/dist/modules/v5/base.js +41 -0
- package/dist/modules/v5/base.js.map +1 -0
- package/dist/modules/v5/captcha.d.ts +27 -0
- package/dist/modules/v5/captcha.js +136 -0
- package/dist/modules/v5/captcha.js.map +1 -0
- package/dist/modules/v5/case.d.ts +10 -0
- package/dist/modules/v5/case.js +57 -0
- package/dist/modules/v5/case.js.map +1 -0
- package/dist/modules/v5/chart.d.ts +53 -0
- package/dist/modules/v5/chart.js +385 -0
- package/dist/modules/v5/chart.js.map +1 -0
- package/dist/modules/v5/chat.d.ts +21 -0
- package/dist/modules/v5/chat.js +107 -0
- package/dist/modules/v5/chat.js.map +1 -0
- package/dist/modules/v5/csv.d.ts +29 -0
- package/dist/modules/v5/csv.js +143 -0
- package/dist/modules/v5/csv.js.map +1 -0
- package/dist/modules/v5/diff.d.ts +20 -0
- package/dist/modules/v5/diff.js +81 -0
- package/dist/modules/v5/diff.js.map +1 -0
- package/dist/modules/v5/evaluate.d.ts +14 -0
- package/dist/modules/v5/evaluate.js +284 -0
- package/dist/modules/v5/evaluate.js.map +1 -0
- package/dist/modules/v5/jwt.d.ts +11 -0
- package/dist/modules/v5/jwt.js +42 -0
- package/dist/modules/v5/jwt.js.map +1 -0
- package/dist/modules/v5/matrix.d.ts +77 -0
- package/dist/modules/v5/matrix.js +239 -0
- package/dist/modules/v5/matrix.js.map +1 -0
- package/dist/modules/v5/otp.d.ts +30 -0
- package/dist/modules/v5/otp.js +117 -0
- package/dist/modules/v5/otp.js.map +1 -0
- package/dist/modules/v5/pow.d.ts +29 -0
- package/dist/modules/v5/pow.js +49 -0
- package/dist/modules/v5/pow.js.map +1 -0
- package/dist/modules/v5/read.d.ts +20 -0
- package/dist/modules/v5/read.js +59 -0
- package/dist/modules/v5/read.js.map +1 -0
- package/dist/modules/v5/semver.d.ts +33 -0
- package/dist/modules/v5/semver.js +99 -0
- package/dist/modules/v5/semver.js.map +1 -0
- package/dist/modules/v5/symmetric.d.ts +15 -0
- package/dist/modules/v5/symmetric.js +88 -0
- package/dist/modules/v5/symmetric.js.map +1 -0
- package/dist/modules/v5/text.d.ts +5 -0
- package/dist/modules/v5/text.js +12 -0
- package/dist/modules/v5/text.js.map +1 -0
- package/dist/modules/v5/tic_tac_toe.d.ts +19 -0
- package/dist/modules/v5/tic_tac_toe.js +226 -0
- package/dist/modules/v5/tic_tac_toe.js.map +1 -0
- package/dist/modules/v5/url.d.ts +18 -0
- package/dist/modules/v5/url.js +51 -0
- package/dist/modules/v5/url.js.map +1 -0
- package/dist/modules/v5/uuid.d.ts +25 -0
- package/dist/modules/v5/uuid.js +40 -0
- package/dist/modules/v5/uuid.js.map +1 -0
- package/dist/modules/v5.d.ts +24 -0
- package/dist/modules/v5.js +25 -0
- package/dist/modules/v5.js.map +1 -0
- package/dist/modules/v6.d.ts +1 -0
- package/dist/modules/v6.js +2 -0
- package/dist/modules/v6.js.map +1 -0
- package/dist/routes/delete.d.ts +2 -0
- package/dist/routes/delete.js +73 -0
- package/dist/routes/delete.js.map +1 -0
- package/dist/routes/get.d.ts +2 -0
- package/dist/routes/get.js +857 -0
- package/dist/routes/get.js.map +1 -0
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.js +95 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/patch.d.ts +2 -0
- package/dist/routes/patch.js +45 -0
- package/dist/routes/patch.js.map +1 -0
- package/dist/routes/post.d.ts +2 -0
- package/dist/routes/post.js +604 -0
- package/dist/routes/post.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +14 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types/storage.d.ts +52 -0
- package/dist/types/storage.js +2 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/utils/challenge.d.ts +40 -0
- package/dist/utils/challenge.js +75 -0
- package/dist/utils/challenge.js.map +1 -0
- package/dist/utils/colors.d.ts +44 -0
- package/dist/utils/colors.js +93 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/helpers.d.ts +55 -0
- package/dist/utils/helpers.js +82 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/response.d.ts +9 -0
- package/dist/utils/response.js +24 -0
- package/dist/utils/response.js.map +1 -0
- package/package.json +90 -0
- package/robots.txt +74 -0
- package/src/favicon.ico +0 -0
package/.prettierignore
ADDED
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
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
|
package/dist/app.js.map
ADDED
|
@@ -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>;
|