mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 12:36:08 +00:00
the ultimate framework
This commit is contained in:
parent
37e4125a20
commit
d0915ba882
@ -5,9 +5,9 @@ charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
quote_type = single
|
||||
|
||||
[Makefile]
|
||||
indent_style = space
|
||||
indent_style = tab
|
||||
|
62
.gitignore
vendored
62
.gitignore
vendored
@ -1,63 +1,5 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
package-lock.json
|
||||
|
||||
# Eater asked for this dunno why
|
||||
bot/
|
||||
apps/
|
||||
|
||||
# Enviorment
|
||||
.env
|
||||
|
||||
# bun
|
||||
bun-test.js
|
||||
|
||||
# NPM
|
||||
npm/
|
||||
|
||||
# DOCS
|
||||
docs.json
|
||||
packages/core/docs.json
|
||||
|
||||
# dependencies
|
||||
pnpm-lock.yaml
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
.vscode
|
||||
|
||||
# testing
|
||||
coverage
|
||||
|
||||
# node
|
||||
out/
|
||||
lib/
|
||||
dist/
|
||||
build
|
||||
package-lock.json
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
*.vs
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env
|
||||
|
||||
# turbo
|
||||
.turbo
|
||||
|
||||
# tests
|
||||
__tests__
|
||||
__test__
|
||||
|
||||
# changeset
|
||||
.changeset
|
||||
|
4
.husky/pre-commit
Normal file
4
.husky/pre-commit
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
30
.swcrc
Normal file
30
.swcrc
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"sourceMaps": false,
|
||||
"module": {
|
||||
"type": "commonjs",
|
||||
"strictMode": true,
|
||||
"noInterop": false
|
||||
},
|
||||
"jsc": {
|
||||
"externalHelpers": false,
|
||||
"target": "esnext",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"decorators": true,
|
||||
"dynamicImport": true
|
||||
},
|
||||
"transform": {
|
||||
"legacyDecorator": true,
|
||||
"decoratorMetadata": true,
|
||||
"react": {
|
||||
"throwIfNamespace": false,
|
||||
"useBuiltins": false,
|
||||
"pragma": "React.createElement",
|
||||
"pragmaFrag": "React.Fragment",
|
||||
"importSource": "react"
|
||||
}
|
||||
},
|
||||
"keepClassNames": true
|
||||
}
|
||||
}
|
8
.vscode/extensions.json
vendored
Normal file
8
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"biomejs.biome",
|
||||
"orta.vscode-twoslash-queries",
|
||||
"eamodio.gitlens",
|
||||
"yoavbls.pretty-ts-errors"
|
||||
]
|
||||
}
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||
}
|
99
README.md
99
README.md
@ -1,68 +1,57 @@
|
||||
# biscuit
|
||||
<div align='center'>
|
||||
|
||||
## A brand new bleeding edge non bloated Discord library
|
||||
# **Seyfert**
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/oasisjs/biscuit/main/assets/icon.svg" alt="biscuit"/>
|
||||
<img src="./assets/icon.png" alt="seyfert" width="200px" />
|
||||
|
||||
## Install (for [node18](https://nodejs.org/en/download/))
|
||||
**A brand new bleeding edge non bloated Discord framework**
|
||||
|
||||
```sh-session
|
||||
npm install @biscuitland/core
|
||||
yarn add @biscuitland/core
|
||||
[](https://github.com/tiramisulabs/biscuit/blob/main/LICENSE)
|
||||
[](https://www.npmjs.com/package/seyfert)
|
||||
[](https://discord.com/invite/XNw2RZFzaP)
|
||||
|
||||
</div>
|
||||
|
||||
> [!WARNING]
|
||||
> This readme is work in progress!
|
||||
|
||||
# FAQ
|
||||
## So, what is `seyfert`?
|
||||
Seyfert is the ultimate Discord framework! With its highly efficient interaction with the Discord API, you can achieve anything you set your mind to.
|
||||
|
||||
## Why I should use it?
|
||||
Seyfert has a good scalability, strict types, smooth developing experience...
|
||||
|
||||
> more questions soon...
|
||||
|
||||
# User guide
|
||||
## Installation
|
||||
> [!NOTE]
|
||||
> You **NEED** Node.js 18>= for this to work, also we recomended Node.js 20 LTS and Bun latest
|
||||
```sh
|
||||
pnpm add seyfert
|
||||
```
|
||||
|
||||
for further reading join our [Discord](https://discord.com/invite/XNw2RZFzaP)
|
||||
> You may use your preferred package manager, for this example I am using PNPM since is more efficient.
|
||||
|
||||
## Most importantly, biscuit:
|
||||
Stands apart from other libraries like Discord.js or Eris as it takes a conscious and dedicated approach, adhering strictly to [simplicity](https://en.wikipedia.org/wiki/Unix_philosophy). We have examined the features and functionalities that contribute to [bloat](https://en.wikipedia.org/wiki/Code_bloat) in libraries, intentionally removing unnecessary complexities we deliver a [minimalistic](https://en.wikipedia.org/wiki/Minimalism_(computing)) and efficient solution that includes only essential components for Discord API interaction, reducing the library's footprint and enabling scalability.
|
||||
|
||||
High RAM usage in other libraries often arises due to unnecessary features and functionalities and suboptimal caching mechanisms tied to the core library.
|
||||
|
||||
### Leveraging the power of meta programming
|
||||
The Proxy object enables dynamic, flexible and efficient calls to the API, it is typesafe due to TypeScript wizardry, meta programming is not for the weak minded.
|
||||
|
||||
## Why biscuit?:
|
||||
- Remarkably minimal memory footprint
|
||||
- Scalable
|
||||
- Non feature-rich!
|
||||
|
||||
## Example bot (TS/JS)
|
||||
## Basic bot example
|
||||
|
||||
```ts
|
||||
import { Session } from '@biscuitland/core';
|
||||
import { GatewayIntentBits, InteractionType, InteractionResponseType } from '@biscuitland/common';
|
||||
import { Client } from 'seyfert';
|
||||
|
||||
const session = new Session({
|
||||
intents: GatewayIntentBits.Guilds,
|
||||
token: 'your token goes here'
|
||||
});
|
||||
const client = new Client();
|
||||
|
||||
const commands = [
|
||||
{
|
||||
name: 'ping',
|
||||
description: 'Replies with pong!'
|
||||
}
|
||||
];
|
||||
|
||||
session.once('READY', (payload) => {
|
||||
const username = payload.user.username;
|
||||
console.log('Logged in as: %s', username);
|
||||
session.managers.applications.bulkCommands(session.applicationId, commands);
|
||||
});
|
||||
|
||||
session.on('INTERACTION_CREATE', (interaction) => {
|
||||
if (interaction.type !== InteractionType.ApplicationCommand) return;
|
||||
session.managers.interactions.reply(interaction.id, interaction.token, {
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: { content: 'pong!' }
|
||||
});
|
||||
});
|
||||
|
||||
session.start();
|
||||
(async () => {
|
||||
await client.start();
|
||||
await client.uploadCommands().catch(e => {
|
||||
console.error(JSON.stringify(e, null, 2))
|
||||
process.exit(1)
|
||||
})
|
||||
})();
|
||||
```
|
||||
|
||||
## Links
|
||||
* [Website](https://biscuitjs.com/)
|
||||
* [Documentation](https://docs.biscuitjs.com/)
|
||||
* [Discord](https://discord.gg/XNw2RZFzaP)
|
||||
* [core](https://www.npmjs.com/package/@biscuitland/core) | [rest](https://www.npmjs.com/package/@biscuitland/rest) | [ws](https://www.npmjs.com/package/@biscuitland/ws) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)
|
||||
# Useful links
|
||||
|
||||
- [GitHub Repository](https://github.com/tiramisulabs/biscuit)
|
||||
- [Discord server](https://discord.com/invite/XNw2RZFzaP)
|
||||
- [npm - core](https://www.npmjs.com/package/seyfert)
|
||||
|
BIN
assets/icon.png
BIN
assets/icon.png
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 301 KiB |
414
assets/icon.svg
414
assets/icon.svg
@ -1,75 +1,345 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="52.382698mm"
|
||||
height="39.664326mm"
|
||||
viewBox="0 0 52.382698 39.664326"
|
||||
version="1.1"
|
||||
id="svg72859"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||
sodipodi:docname="fabicon opt web.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview72861"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#999999"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="1.300746"
|
||||
inkscape:cx="124.92831"
|
||||
inkscape:cy="106.47736"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs72856" />
|
||||
<g
|
||||
inkscape:label="Capa 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-60.052883,-81.833223)">
|
||||
<g
|
||||
id="g73848">
|
||||
<path
|
||||
style="fill:#898f8c;fill-opacity:1;stroke:none;stroke-width:0.105"
|
||||
d="m 77.78561,100.07756 c -0.74854,4.03168 1.36028,8.44105 3.63048,11.65499 0.76576,1.08413 1.84117,2.84277 3.29951,3.00626 1.21202,0.13597 2.90472,-1.40217 3.78,-2.10966 0.36992,-0.29894 0.94248,-1.05997 1.4699,-0.74277 1.43304,0.86194 2.32774,2.80129 3.5701,3.92332 1.66257,1.5017 3.68371,2.52273 5.66999,3.50888 1.98073,0.98333 4.16976,2.00235 6.405,2.17897 0.70487,-3.40589 3.62743,-6.96381 6.82499,-8.295 -0.4306,-0.9156 -1.47378,-1.2769 -2.41499,-1.4239 -2.01464,-0.31469 -4.11285,0.29998 -6.09,-0.33443 -2.51485,-0.80692 -4.43918,-3.00121 -6.40541,-4.66189 -0.7287,-0.61551 -1.51735,-1.42274 -2.41458,-1.76977 0.65614,-2.27871 1.40143,-4.42774 1.56555,-6.825003 0.26701,-3.89896 -1.44606,-7.99889 -4.50555,-10.44602 -1.9152,-1.53188 -3.91534,-2.34289 -6.08999,-3.37596 -1.8647,-0.88584 -3.39591,-2.5916 -5.67,-2.53077 -1.90155,0.0509 -2.78806,1.64193 -4.30499,2.42091 -1.05063,0.53948 -2.27945,0.76416 -3.36001,1.25927 -3.0367,1.39139 -6.05884,3.24012 -8.39844,5.63758 -3.22838,3.30823 -4.88029,7.579 -4.10489,12.179993 0.30441,1.80631 1.18473,4.37293 3.36834,4.49295 1.66435,0.0916 3.38325,-1.33078 4.725,-2.13581 1.03421,-0.62055 2.28039,-0.99603 3.255,-1.68902 1.11478,-0.79265 1.97988,-1.94239 3.14999,-2.66374 0.92884,-0.57257 2.08898,-0.68975 3.045,-1.25938"
|
||||
id="path369864-82-2-3-8" />
|
||||
<path
|
||||
style="fill:#dfe5e9;fill-opacity:1;stroke:none;stroke-width:0.105"
|
||||
d="m 111.17555,112.88755 v 0.21 c -2.51905,1.54203 -5.4896,4.28201 -6.29999,7.245 -1.45141,-0.0624 -2.77315,-0.60574 -4.09499,-1.15374 -2.42645,-1.00612 -4.93101,-2.22852 -6.82457,-4.09784 -1.68956,-1.66781 -2.82136,-3.81895 -4.83043,-5.16977 -1.14964,-0.77301 -2.40533,-0.90867 -3.675,-1.33864 0.45918,-1.38432 2.01643,-2.19367 3.25501,-2.76245 0.84157,-0.3864 1.92244,-1.31344 2.835,-1.40458 1.56039,-0.15582 3.40031,1.09914 4.51499,2.03815 2.09286,1.76305 4.28158,4.30574 6.82499,5.39721 1.95751,0.8401 3.96973,0.16978 5.985,0.31111 0.85323,0.0597 1.54214,0.39637 2.30999,0.72555"
|
||||
id="path369892-7-5-7-7" />
|
||||
<path
|
||||
style="fill:#dfe5e9;fill-opacity:1;stroke:none;stroke-width:0.105"
|
||||
d="m 94.22389,103.73414 -1.48416,-0.23959 c 0.30365,-1.30028 1.14312,-2.45552 1.50182,-3.756513 0.90558,-3.28374 0.20088,-7.06295 -2.20123,-9.56013 -0.84365,-0.87716 -1.81642,-1.68063 -2.8345,-2.34807 -1.22443,-0.80262 -2.06794,-0.98378 -2.85121,-2.30286 1.36529,0.13372 2.74412,0.99706 3.87308,1.72549 0.98991,0.6387 1.97247,1.3684 2.76379,2.24602 3.8927,4.31727 2.99331,9.23033 1.23241,14.235653"
|
||||
id="path369888-0-6-7-5" />
|
||||
<path
|
||||
style="fill:#dfe5e9;fill-opacity:1;stroke:none;stroke-width:0.105"
|
||||
d="m 80.75018,82.790847 c -2.11775,0.18734 -3.9062,1.55745 -5.15095,3.20737 -0.40659,0.5113 -0.78493,1.04448 -1.13922,1.59322 0.65257,-1.00756 1.26966,-2.0373 1.89173,-3.06394 -4.01184,1.66344 -8.1914,3.44725 -11.13277,6.76942 -1.39959,1.63616 -2.60521,3.56159 -2.99814,5.70588 -0.34405,2.13885 1.00799,3.987553 1.90515,5.799463 0.46885,0.89423 1.25596,2.17452 0.68408,3.93482 2.20474,-0.89478 4.3388,-2.77361 6.59683,-3.52479 1.04818,-0.8651 2.01495,-1.864 3.11758,-2.64166 1.10122,-0.45261 2.20409,-0.901233 3.30424,-1.356433 0.20037,-1.27862 0.37559,-2.56351 0.90032,-3.75875 0.4672,-1.33123 0.93463,-2.66237 1.40079,-3.99396 -0.58425,0.4536 -1.20063,0.86705 -1.7637,1.34712 0.91888,-1.69492 1.50387,-3.54856 1.85387,-5.43898 0.1353,-0.33711 0.23307,-0.98421 0.68889,-0.9576 0.77324,0.67141 0.80137,1.83022 0.90376,2.78295 0.0789,1.16285 -0.15754,2.35952 -0.90376,3.28181 -1.69376,2.671 -2.90145,5.78765 -2.66715,8.998863 0.15268,3.11908 1.42078,6.09773 3.30568,8.56103 0.38376,0.53726 0.7038,1.35766 1.05848,1.91457 0.62542,0.14036 0.93737,-0.1044 0.92316,-0.75105 0.29772,-1.84544 1.2544,-3.97094 2.96731,-4.87644 1.67168,-0.93946 3.86842,-1.21585 4.96711,-2.96308 2.79949,-3.740853 2.80945,-9.439513 -0.34583,-12.977013 -1.02738,-1.12859 -2.18025,-2.23377 -3.68496,-2.66939 -0.46715,0.0679 -0.41173,-0.35487 -0.76668,-0.86609 -1.08342,-1.91083 -2.74785,-3.87495 -5.09009,-4.05881 -0.27552,-0.0284 -0.54994,-0.0142 -0.82573,0.002 z"
|
||||
id="path369886-3-4-4-8"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="path369890-4-0-3-4"
|
||||
style="fill:#c4c6c8;fill-opacity:1;stroke:none;stroke-width:0.105"
|
||||
d="m 61.06212,100.63424 c -0.57591,1.50298 -0.22809,3.21694 0.37144,4.65774 0.39627,0.76014 1.22937,1.75582 2.18374,1.35269 0.86909,-0.5462 0.39563,-1.72342 0.0955,-2.47142 -0.62453,-1.55489 -1.44739,-3.01794 -2.26254,-4.478823 -0.12939,0.313263 -0.25877,0.626543 -0.38816,0.939813 z" />
|
||||
<path
|
||||
id="path369896-9-4-8-7"
|
||||
style="fill:#c4c6c8;fill-opacity:1;stroke:none;stroke-width:0.105"
|
||||
d="m 84.26313,110.37997 c -0.23248,1.19921 -0.23853,2.47677 0.27591,3.60857 1.58701,-0.38357 3.44289,-0.94231 4.12827,-2.59514 0.24236,-0.49078 -0.86862,-0.50777 -1.20861,-0.79342 -0.98076,-0.44184 -2.04839,-0.66629 -3.12524,-0.64741 -0.0235,0.14247 -0.0469,0.28494 -0.0704,0.4274 z" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 4000 4000" style="enable-background:new 0 0 4000 4000;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:url(#SVGID_1_);}
|
||||
.st1{fill:none;stroke:#1D1D19;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;}
|
||||
.st2{fill:url(#SVGID_00000111161471117857181650000008874287497415348138_);}
|
||||
.st3{fill:#00AAE6;}
|
||||
.st4{fill:url(#SVGID_00000154415358219097987360000000950432104712010413_);}
|
||||
.st5{fill:url(#SVGID_00000080187546048067913100000007428919299044684716_);}
|
||||
.st6{fill:url(#SVGID_00000080915494984279035640000011859275636825242557_);}
|
||||
.st7{fill:#001630;}
|
||||
.st8{fill:#000C28;}
|
||||
.st9{fill:url(#SVGID_00000012474585635025126550000006984666226631448704_);}
|
||||
.st10{fill:url(#SVGID_00000135652297518986943980000011147478890175969213_);}
|
||||
.st11{fill:url(#SVGID_00000101071206471393636430000006601806650292057749_);}
|
||||
.st12{fill:url(#SVGID_00000071521284048130989020000012508463264477232052_);}
|
||||
.st13{fill:url(#SVGID_00000090297060644371771830000010583929609890356107_);}
|
||||
.st14{fill:#00081C;}
|
||||
.st15{fill:url(#SVGID_00000150795815764103649730000009982554383684358784_);}
|
||||
.st16{fill:#001335;}
|
||||
.st17{fill:#002441;}
|
||||
.st18{fill:#00B4CE;}
|
||||
.st19{fill:url(#SVGID_00000048461043874345920890000002145403735974172056_);}
|
||||
.st20{fill:#001A48;}
|
||||
.st21{fill:#001636;}
|
||||
.st22{fill:#00123E;}
|
||||
.st23{fill:#001C4B;}
|
||||
.st24{fill:#001226;}
|
||||
</style>
|
||||
<g id="XMLID_00000052095757296515447230000000036625776780304020_">
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="1128.1837" y1="3302.6326" x2="1712.0858" y2="3302.6326">
|
||||
<stop offset="0" style="stop-color:#0058B0"/>
|
||||
<stop offset="1" style="stop-color:#00A1CC"/>
|
||||
</linearGradient>
|
||||
<path class="st0" d="M1712.09,3183.04c-33.41,10.17-67.38,18.35-100.69,28.86c-56.22,17.72-110.44,42.1-160.28,73.66
|
||||
c-24.88,15.75-48.7,33.18-71.2,52.19c-23.3,19.68-44.11,41.67-65.74,63.14c-7.2,7.16-14.49,14.22-21.71,21.33
|
||||
c-55.02-24.66-111.27-53.13-164.29-85.55c8.1-11.3,26.8-18.93,38.6-25.92c15.96-9.44,32.25-18.3,48.83-26.59
|
||||
c73.41-36.68,150.16-54.45,230.04-71.23c44.39-9.32,87.76-13.6,132.85-18.32C1622.94,3189.97,1667.5,3186.1,1712.09,3183.04z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st1" d="M1333.24,3184.07c-0.7,0-1.71,0.65-2.75,1.34c3.34-0.85,6.68-1.69,10.02-2.51c2.73-0.68,5.48-1.35,8.24-2
|
||||
c0.49-0.12,0.98-0.24,1.48-0.36c0.1-0.02,0.21-0.04,0.31-0.07c0.91-0.22,1.83-0.45,2.73-0.68
|
||||
C1346.63,3181.19,1339.95,3182.61,1333.24,3184.07z M1537.11,3146.51c31.27-4.66,62.63-8.85,93.79-14.04
|
||||
c0.71-0.12,1.44-0.24,2.15-0.36C1600.47,3136.83,1568.65,3141.55,1537.11,3146.51z M1858.04,2932.61
|
||||
c10.83-7.7,21.52-15.65,32.12-23.68c11.52-8.73,22.92-17.61,34.34-26.47c0.83-0.64,1.96-1.63,3.32-2.87L1858.04,2932.61z
|
||||
M1796.05,2972.48l-100.56,49C1729.85,3007.22,1763.87,2990.9,1796.05,2972.48z M1630.9,3132.47c0.71-0.12,1.44-0.24,2.15-0.36
|
||||
c-32.58,4.72-64.4,9.44-95.94,14.4C1568.38,3141.85,1599.75,3137.66,1630.9,3132.47z M1330.5,3185.4c3.34-0.85,6.68-1.69,10.02-2.51
|
||||
c2.75-0.68,5.49-1.35,8.24-2c0.49-0.12,0.98-0.24,1.48-0.36c0.1-0.02,0.21-0.04,0.31-0.07c0.91-0.22,1.83-0.45,2.73-0.68
|
||||
c-6.65,1.41-13.33,2.84-20.04,4.29C1332.54,3184.07,1331.53,3184.72,1330.5,3185.4z M1537.11,3146.51
|
||||
c-15.41,2.42-30.74,4.9-46.07,7.45c26.63-4.16,53.31-8.05,79.94-12.07c14.17-2.14,28.33-4.32,42.48-6.58
|
||||
c5.82-0.94,11.64-1.89,17.44-2.85c0.71-0.12,1.44-0.24,2.15-0.36C1600.47,3136.83,1568.65,3141.55,1537.11,3146.51z
|
||||
M1353.28,3179.78c-6.65,1.41-13.33,2.84-20.04,4.29c-0.7,0-1.71,0.65-2.75,1.34c3.34-0.85,6.68-1.69,10.02-2.51
|
||||
c2.73-0.68,5.48-1.35,8.24-2c0.49-0.12,0.98-0.24,1.48-0.36c0.1-0.02,0.21-0.04,0.31-0.07c1.42-0.34,2.86-0.67,4.3-1.01
|
||||
C1354.33,3179.55,1353.8,3179.67,1353.28,3179.78z M1121.99,3243.19c-0.04,0.03-0.07,0.04-0.12,0.06c-0.21,0.1-0.4,0.22-0.61,0.33
|
||||
c-0.43,0.24-0.86,0.48-1.29,0.7c-3.25,1.71-8.52,4.54-16.45,8.91c-0.58,0.33-1.17,0.64-1.75,0.95
|
||||
C1105.19,3253.12,1131.89,3238.04,1121.99,3243.19z M2569.38,951.05c-5.58-0.46-11.13-1.08-16.67-1.8
|
||||
c-6.87-0.88-13.73-1.89-20.6-2.84c3.19,0.86,6.52,2,9.28,2c26.72,2.97,51.95,4.45,77.18,7.42c34,3.01,67.67,4.99,101.21,6
|
||||
C2669.44,960.12,2619.57,955.13,2569.38,951.05z M2460.28,937.51c4.05,0.58,8.12,1.13,12.19,1.68
|
||||
C2470.69,938.93,2461.39,936.51,2460.28,937.51z"/>
|
||||
<linearGradient id="SVGID_00000157290804937867201410000002913548497684341399_" gradientUnits="userSpaceOnUse" x1="2065.2195" y1="2160.8179" x2="2065.2195" y2="3165.0955">
|
||||
<stop offset="0" style="stop-color:#002A58"/>
|
||||
<stop offset="0.9948" style="stop-color:#0067B0"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000157290804937867201410000002913548497684341399_);" d="M2626.74,2642.4
|
||||
c-5.49,35.48-15.01,70.32-28.41,103.65c-5.14,12.78-9.5,25.89-15.01,38.54c-5.52,12.66-12.01,24.98-18.66,37.1
|
||||
c-9.17,16.71-19.15,33.01-29.86,48.78c-21.37,31.43-45.76,60.76-72.67,87.57c-27.24,27.12-57.05,51.63-88.8,73.29
|
||||
c-12.94,8.83-26.21,17.19-39.75,25.07l-4.45,4.45c-34.14,19.3-68.27,35.63-103.89,51.96c-26.72,10.39-54.92,19.3-83.12,28.21
|
||||
c-96.47,26.72-191.46,29.69-289.42,16.33c-67.28-8.21-132.3-20.5-197.04-33.37c-52.38-10.39-104.59-21.17-157.68-30.46
|
||||
c13.89-4.97,27.8-9.95,41.69-14.92c37.27-13.35,74.54-26.66,111.79-40.01l0.85-0.31l32.82-11.74l10.36-5.05
|
||||
c34.36-14.27,68.38-30.58,100.56-49l26.48-12.9l35.52-26.97c10.83-7.7,21.52-15.65,32.12-23.68c11.52-8.73,22.92-17.61,34.34-26.47
|
||||
c0.83-0.64,1.96-1.63,3.32-2.87l28.39-21.57c39.69,2.97,79.57,2.42,118.62-2.94c14.81-2.03,29.49-4.77,44.01-8.27
|
||||
c59.67-10.21,114.73-24.51,165.65-58.88c33.32-22.49,62.66-50.84,86.35-83.32c26.15-35.87,35.95-73.13,35.8-117.38
|
||||
c-0.18-55.8-13.52-108.44-49.9-151.61c-33.6-39.86-76.82-71.63-125.03-91.49c-0.04-0.22-0.1-0.45-0.16-0.67
|
||||
c-4.66-17.95-11.4-35.38-19.61-52c-24.79-50.15-62.11-93.29-103.45-130.59c113.04-1.69,235.44,32.09,328.72,96.88
|
||||
c65.99,45.83,119.95,106.2,174.02,165c0.92,3.06,1.8,6.12,2.64,9.19c9.39,34.11,15.35,69.19,17.57,104.52
|
||||
C2633.69,2571.82,2632.16,2607.4,2626.74,2642.4z"/>
|
||||
<path class="st3" d="M1956.02,2858.01c-5.45,0-20.44,14.59-28.19,21.58c-1.37,1.23-2.49,2.23-3.32,2.87
|
||||
c-11.43,8.86-22.83,17.74-34.34,26.47c-10.6,8.03-21.28,15.97-32.12,23.68c-12.62,9-25.45,17.7-38.6,25.9
|
||||
c-7.67,4.78-15.48,9.44-23.39,13.97c-32.18,18.42-66.2,34.74-100.56,49c-12.32,5.11-24.7,9.96-37.03,14.55
|
||||
c-2.05,0.76-4.1,1.5-6.14,2.24l-0.85,0.31l-111.79,40.01c-13.89,4.97-27.8,9.95-41.69,14.92c-0.49-0.01-0.98-0.03-1.47-0.06
|
||||
c-46.8-1.77-93.8-9.55-140.69-13.41c-50.17-4.14-100.51-6.46-150.84-5.64c-52.79,0.86-105.6,5.2-157.64,14.39
|
||||
c-49.54,8.74-97.93,23.2-145.93,37.47c-47.55-80.65-62.32-173.79-21.74-280.2c48.92-128.32,186.34-196.95,313.02-224.44
|
||||
c47.79-10.38,68.29,22.5,109.91,46.39c91.72,52.65,196.57,76.08,297.32,104.91c93.37,26.71,185.54,58.77,281.18,75.59
|
||||
C1905.8,2852.86,1930.87,2856.16,1956.02,2858.01z"/>
|
||||
<linearGradient id="SVGID_00000151537649501067446000000011787695674670850743_" gradientUnits="userSpaceOnUse" x1="1897.1814" y1="2064.208" x2="1897.1814" y2="3336.6721">
|
||||
<stop offset="0" style="stop-color:#00606A"/>
|
||||
<stop offset="0.4665" style="stop-color:#000B33"/>
|
||||
<stop offset="1" style="stop-color:#000D2C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000151537649501067446000000011787695674670850743_);" d="M2892.94,2626.65v0.01
|
||||
c-4.97,26.23-11.87,52.22-20.57,77.91c-28.2,80.16-66.79,151.42-123.19,218.22c-72.73,86.1-158.81,146.96-259.74,190.02
|
||||
c-2.97,1.48-4.45,0-7.42,1.48c-31.17,14.84-65.3,23.75-97.96,35.63c-13.36,4.45-26.72,5.94-40.07,8.91
|
||||
c-35.62,10.39-71.24,13.36-106.86,16.33c-48.98,4.45-97.96,4.45-146.94,1.48c-75.69-2.97-149.9-1.48-225.6-1.48
|
||||
c-50.46,1.48-102.41,4.45-152.5,7.88c-44.59,3.06-89.14,6.93-133.58,11.58c-45.09,4.72-88.46,9-132.85,18.32
|
||||
c-79.88,16.77-156.63,34.54-230.04,71.23c-16.58,8.28-32.88,17.15-48.83,26.59c-11.8,6.99-30.5,14.62-38.6,25.92
|
||||
c-93.86-57.39-177.62-127.18-226.64-210.2c-0.04-0.07-0.07-0.13-0.12-0.21c48-14.27,96.38-28.73,145.93-37.47
|
||||
c52.04-9.19,104.84-13.52,157.64-14.39c50.33-0.82,100.67,1.5,150.84,5.64c46.89,3.86,93.89,11.64,140.69,13.41
|
||||
c0.49,0.03,0.98,0.04,1.47,0.06c-71.24,20.78-142.48,40.08-210.76,68.29c-31.17,13.36-60.85,26.72-90.54,41.57
|
||||
c-25.59,12.8-50.26,26.5-74.7,39.83c-0.04,0.03-0.07,0.04-0.12,0.06c-0.21,0.1-0.4,0.22-0.61,0.33c-0.43,0.24-0.86,0.48-1.29,0.7
|
||||
c-3.25,1.71-8.52,4.54-16.45,8.91c-0.58,0.33-1.17,0.64-1.75,0.95c54.35-14.09,106.45-33.39,160.65-49.75
|
||||
c4.84-1.44,9.68-2.86,14.53-4.29c23.11-6.78,46.47-12.6,69.77-18.66c1.17-0.3,2.33-0.59,3.5-0.91c0.1-0.02,0.21-0.04,0.31-0.07
|
||||
c0.91-0.22,1.83-0.45,2.73-0.68c16.33-4.02,32.82-7.45,49.39-10.55c0.45-0.09,0.89-0.18,1.34-0.25c28.14-5.24,56.49-9.6,84.54-14.61
|
||||
c0.09-0.01,0.16-0.03,0.25-0.04c16.04-2.86,32.18-5.39,48.31-7.81c31.27-4.66,62.63-8.85,93.79-14.04c0.71-0.12,1.44-0.24,2.15-0.36
|
||||
c8.34-1.4,15.38-5.39,22.62-8.14c64.74,12.87,129.76,25.16,197.04,33.37c97.96,13.36,192.95,10.39,289.42-16.33
|
||||
c28.2-8.91,56.4-17.81,83.12-28.21c35.62-16.33,69.76-32.66,103.89-51.96l4.45-4.45c13.54-7.88,26.8-16.24,39.75-25.07
|
||||
c31.75-21.66,61.56-46.17,88.8-73.29c26.91-26.81,51.29-56.14,72.67-87.57c10.72-15.77,20.69-32.07,29.86-48.78
|
||||
c6.65-12.11,13.14-24.44,18.66-37.1c5.51-12.65,9.87-25.76,15.01-38.54c13.4-33.33,22.92-68.17,28.41-103.65
|
||||
c5.42-35,6.95-70.59,4.72-105.93c-2.23-35.33-8.18-70.41-17.57-104.52c-0.85-3.07-1.72-6.13-2.64-9.19
|
||||
c-9.38-31.69-21.91-62.13-36.68-91.73c-1.07-2.14-2.15-4.28-3.25-6.4c-0.49-0.95-0.99-1.9-1.5-2.85c-0.83-1.6-1.68-3.19-2.54-4.78
|
||||
c-0.12-0.25-0.25-0.49-0.39-0.71c-0.92-1.71-1.84-3.41-2.79-5.11c-0.62-1.13-1.26-2.26-1.9-3.37c-0.67-1.22-1.37-2.42-2.06-3.61
|
||||
c-0.49-0.89-1.01-1.77-1.53-2.63c-0.65-1.16-1.34-2.3-2.02-3.43c-0.61-1.04-1.23-2.08-1.86-3.1c-0.74-1.23-1.5-2.46-2.26-3.68
|
||||
c-0.59-0.99-1.2-1.97-1.83-2.94c-3.59-5.76-7.32-11.43-11.15-17.01c-0.74-1.1-1.5-2.18-2.26-3.28c-0.31-0.46-0.64-0.91-0.96-1.37
|
||||
c-0.77-1.11-1.56-2.23-2.36-3.34c-2.2-3.09-4.44-6.16-6.71-9.19c-0.8-1.05-1.59-2.11-2.39-3.15c-0.85-1.13-1.72-2.27-2.6-3.38
|
||||
c-1.4-1.81-2.82-3.62-4.24-5.4c-0.04-0.06-0.09-0.12-0.13-0.16c-1.42-1.78-2.85-3.56-4.3-5.33c0,0-0.01,0-0.01-0.01
|
||||
c-78.99-96.25-192.19-160.04-319.46-172.04c-1.93-0.18-3.87-0.37-5.8-0.55c39.94,0.55,80.01,5,121.57,7.97
|
||||
c4.45,0,10.39,2.97,14.84,2.97c114.28,10.39,222.63,40.08,325.04,90.55c2.97,1.48,5.94,5.94,10.39,7.42
|
||||
c68.27,35.63,121.71,84.62,163.26,151.42c14.84,25.24,26.72,48.99,37.11,75.71c7.42,22.27,13.36,43.05,17.81,65.32
|
||||
c8.91,53.44,10.39,105.4,14.49,159L2892.94,2626.65z"/>
|
||||
<linearGradient id="SVGID_00000048474317101889883790000018157094566315166863_" gradientUnits="userSpaceOnUse" x1="1607.6506" y1="998.0541" x2="1607.6506" y2="2052.2134">
|
||||
<stop offset="0" style="stop-color:#004F58"/>
|
||||
<stop offset="1" style="stop-color:#00091E"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000048474317101889883790000018157094566315166863_);" d="M2062.67,2017.46l-3.1,34.75
|
||||
c-40.3-3.83-80.4-7.84-120.43-12.31c-116.2-12.96-231.91-29.88-350.61-58.28c-84.38-18.87-163.44-47.7-232.75-93.58
|
||||
c-34.33-22.73-66.25-49.63-95.26-81.59c-1.48-1.48-1.48-4.45-2.97-5.94c-17.81-19.3-32.65-40.08-44.53-62.35l-4.45-4.45
|
||||
c-53.22-99.28-61.83-209.71-52.85-319.14l2.92-12.31c11.95-42.75,25.78-85.11,44.23-125.54c18.37-40.3,41.5-78.34,69.4-112.78
|
||||
c27.41-33.85,59.58-64.01,96.81-86.83c40.1-24.57,84.73-43.99,129.42-58.52c22.31-7.26,45.15-13.03,68.38-16.51
|
||||
c22.14-3.33,45.8-5.48,68.16-2.91l6.47,1.04c-16.95,12.94-33.1,26.97-48.71,41.54c-30.38,28.34-58.91,58.86-82.77,92.87
|
||||
c-34.06,48.5-58.08,103.26-79.98,158.32c-15.39,38.69-15.01,72.65-15.01,113.43c-7.36,62.7-0.22,127.18,17.65,189.27
|
||||
c34.14,114.31,103.89,207.83,200.37,282.05c7.42,5.94,14.84,10.39,22.26,14.84c68.27,47.5,135.06,77.19,213.73,95.01
|
||||
c1.48,0,4.45,2.97,5.94,2.97c62.34,14.84,123.19,22.27,185.53,26.72C2061.23,2017.33,2061.94,2017.39,2062.67,2017.46z"/>
|
||||
<linearGradient id="SVGID_00000017515604425283082870000013321954441328810411_" gradientUnits="userSpaceOnUse" x1="1943.6947" y1="899.934" x2="1943.6947" y2="2065.7371">
|
||||
<stop offset="0" style="stop-color:#00B0A1"/>
|
||||
<stop offset="0.1598" style="stop-color:#008891"/>
|
||||
<stop offset="0.5026" style="stop-color:#00B8AB"/>
|
||||
<stop offset="0.7938" style="stop-color:#006A83"/>
|
||||
<stop offset="1" style="stop-color:#00798D"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000017515604425283082870000013321954441328810411_);" d="M2475.22,2065.74
|
||||
c-134.26-30.08-273.73-35-412.55-48.28c-0.73-0.07-1.44-0.13-2.17-0.21c-62.34-4.45-123.19-11.88-185.53-26.72
|
||||
c-1.48,0-4.45-2.97-5.94-2.97c-78.66-17.81-145.45-47.5-213.73-95.01c-7.42-4.45-14.84-8.91-22.26-14.84
|
||||
c-96.47-74.22-166.23-167.75-200.37-282.05c-17.87-62.1-25.01-126.57-17.65-189.27c4.26-36.24,13.36-71.89,28.04-106.14
|
||||
c1.48-2.97,0-4.45,1.48-7.42c38.71-93.32,98.66-172.02,173.18-237.91l2.57-1.17c47.6-20.71,91.46-49.17,140.32-68.32
|
||||
c51.62-20.22,105.01-35.82,159.14-47.77c102.57-22.64,207.6-32.27,312.5-37.39l9.5-0.33c0.68,0.1,1.37,0.21,2.05,0.33
|
||||
c4.2,0.7,8.4,1.41,12.62,2.14c69.64,12.35,135.88,25.56,203.86,35.11c-45.95,41.33-93.88,80.47-143.54,117.26
|
||||
c-48.98,36.28-102.57,66.65-154.74,98.12c-19.77,11.92-39.48,23.93-58.97,36.31c-36.39-5.89-72.34-9.56-109-7.47
|
||||
c-0.71,0.04-1.44,0.09-2.15,0.12c-25.84,1.56-51.61,2.45-77.33,6.15c-14.35,2.06-28.63,4.68-42.77,7.85
|
||||
c-7.39,1.65-14.74,3.44-22.04,5.4c-3.25,0.86-6.69,2.12-10.17,3.24c-0.73,0.15-1.45,0.3-2.18,0.45c-0.88,0.18-1.74,0.37-2.6,0.56
|
||||
c-0.85,0.18-1.71,0.37-2.55,0.58c-0.91,0.21-1.8,0.43-2.67,0.64c-0.19,0.06-0.39,0.1-0.58,0.16c-0.01,0-0.01,0-0.03,0
|
||||
c-0.01,0-0.01,0-0.03,0c-0.61,0.16-1.23,0.31-1.84,0.49c-0.68,0.18-1.37,0.36-2.05,0.56c-1.87,0.5-3.73,1.05-5.58,1.63
|
||||
c-129.62,40.44-198.28,193.18-161.65,319.24c28.17,96.91,100.17,183.11,172.47,251.13c167.33,157.42,391.27,223.77,610.19,275.88
|
||||
L2475.22,2065.74z"/>
|
||||
<path class="st7" d="M3011.76,821.82c-43.92,28.34-87.05,55.91-134.44,78.32c-47.36,22.4-96.22,41.45-144.78,61.04l-2.69,0.95
|
||||
c-3.35-0.09-6.72-0.19-10.08-0.3c-50.33-1.72-100.2-6.71-150.39-10.79c-5.58-0.46-11.13-1.08-16.67-1.8l4.63-1.54
|
||||
c24.39-8.92,48.56-18.35,72.43-28.56c42.34-18.11,83.71-38.69,122.88-62.96c27.55-17.07,54.77-35.67,79.48-56.97
|
||||
c16.18-13.92,31.27-29.01,44.69-45.56c4.53-5.58,9.07-11.18,13.6-16.76c0.92,0.61,1.83,1.22,2.75,1.84
|
||||
C2932.92,765.54,2972.21,793.45,3011.76,821.82z"/>
|
||||
<path class="st8" d="M3132.04,919.35l-17.07,6.12c-18.52,5.31-37.28,9.75-56.21,13.43c-46.05,8.97-93.79,14.99-140.39,18.42
|
||||
c-63.52,4.68-125.88,6.4-188.52,4.81l2.69-0.95c48.56-19.6,97.42-38.64,144.78-61.04c47.39-22.42,90.52-49.98,134.44-78.32
|
||||
c14.72,10.55,29.49,21.18,44.35,31.84C3084.9,874.33,3111.14,894.93,3132.04,919.35z"/>
|
||||
<linearGradient id="SVGID_00000182504939189219026290000001687771729988917677_" gradientUnits="userSpaceOnUse" x1="1833.2477" y1="464.5893" x2="1833.2477" y2="2382.7954">
|
||||
<stop offset="2.577320e-03" style="stop-color:#9DD32F"/>
|
||||
<stop offset="0.3376" style="stop-color:#1BC3C5"/>
|
||||
<stop offset="1" style="stop-color:#008CD8"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000182504939189219026290000001687771729988917677_);" d="M2890.41,736.89
|
||||
c-2.05,1.17-4.11,2.35-6.17,3.52c-50.82,29.02-107.34,48.31-163.49,64.55c-59.62,17.25-120.59,29.66-182.07,38.17
|
||||
c-61.56,8.54-123.66,13.15-185.79,14.74c-127.64,2.97-256.77,0-384.41,1.48c-114.28,2.97-225.6,4.45-339.88,31.17
|
||||
c-68.27,16.33-126.16,41.57-187.01,75.71l-4.45,4.45c-16.33,7.42-29.68,17.81-46.01,29.69c-40.07,29.69-74.21,57.9-106.86,95.01
|
||||
c-1.48,1.48-1.48,4.45-2.97,5.94c-17.81,19.3-34.14,38.6-46.01,62.35l-4.45,4.45c-43.04,74.22-65.31,152.9-74.21,236.03
|
||||
c-0.33,3.47-0.62,6.95-0.91,10.42c-8.98,109.42-0.37,219.85,52.85,319.14l4.45,4.45c11.87,22.27,26.72,43.05,44.53,62.35
|
||||
c1.48,1.48,1.48,4.45,2.97,5.94c29,31.96,60.93,58.86,95.26,81.59c25.83,58.04,77.83,99.36,132.97,127.59
|
||||
c57.08,29.23,117.22,52.86,176.49,77.24c60.23,24.78,120.65,49.06,180.91,73.78c59.71,24.49,119.24,49.42,178.19,75.66
|
||||
c43.44,19.34,86.56,39.41,129.17,60.54c26.36,13.08,52.39,26.23,78.05,40.62c0.06,0.22,0.12,0.45,0.16,0.67
|
||||
c3.27,12.74,5.08,25.59,6.52,38.66c-32.15-14.3-68.48-21.35-106.8-19.03c-120.15,7.29-241.3,4.99-361.64,5.42
|
||||
c-141.13,0.49-284.37-5.46-420-48.11c-87.36-27.48-169.41-70.97-242.22-126.43C735.7,1911.38,672.81,1358.57,938.64,980.53
|
||||
c90.54-128.74,212.15-234.03,347.1-314.99c246.27-147.8,538.56-215.3,825.28-198.4c176.04,10.38,349.84,52.22,512.36,120.42
|
||||
C2719.6,628.45,2806.14,680.2,2890.41,736.89z"/>
|
||||
<linearGradient id="SVGID_00000041294334513375484540000007751390379576468904_" gradientUnits="userSpaceOnUse" x1="1336.1295" y1="3465.8823" x2="2961.1921" y2="1840.8196">
|
||||
<stop offset="0" style="stop-color:#00155F"/>
|
||||
<stop offset="0.5077" style="stop-color:#0068C0"/>
|
||||
<stop offset="1" style="stop-color:#10BAD0"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000041294334513375484540000007751390379576468904_);" d="M3244.96,2757.96
|
||||
c-112.55,421.08-512.84,753.71-941.31,811.77c-48.46,6.56-97.48,7.84-146.37,8.86c-231.71,4.9-452.39-5.97-673.07-81.45
|
||||
c-56.25-19.24-123.04-44.1-191.73-74.91c7.23-7.11,14.52-14.18,21.71-21.33c21.62-21.47,42.43-43.45,65.74-63.14
|
||||
c22.5-19.02,46.32-36.44,71.2-52.19c49.84-31.56,104.06-55.94,160.28-73.66c33.31-10.51,67.28-18.69,100.69-28.86
|
||||
c50.09-3.43,102.04-6.4,152.5-7.88c75.69,0,149.9-1.48,225.6,1.48c48.98,2.97,97.96,2.97,146.94-1.48
|
||||
c35.62-2.97,71.24-5.94,106.86-16.33c13.36-2.97,26.72-4.45,40.07-8.91c32.65-11.88,66.79-20.78,97.96-35.63
|
||||
c2.97-1.48,4.45,0,7.42-1.48c100.93-43.05,187.01-103.91,259.74-190.02c56.4-66.8,94.99-138.06,123.19-218.22
|
||||
c8.7-25.68,15.6-51.68,20.57-77.91v-0.01c13.71-72.31,12.78-146.39-5.73-220.46c-5.94-22.27-11.87-43.05-20.78-63.83
|
||||
c-8.91-17.81-14.84-37.11-25.23-54.93l-4.45-4.45c-20.93-42.69-51.77-77.83-88.25-105.96c-0.01,0-0.01-0.01-0.01-0.01
|
||||
c-41.2-50.38-92.32-79.11-149.89-106.75c-62.2-29.87-125.03-58.39-187.97-86.62c-125.91-56.46-252.42-111.74-375.5-174.21
|
||||
c-47.55-24.14-94.56-49.36-140.6-76.29c-45.18-26.44-94.63-52.77-133.1-88.61c57.5,34.38,135.36,30.31,199.48,32.41
|
||||
c105.87,3.47,211.74-2.89,317.61-2.49c100.32,0.37,200.86,0.7,300.8,10.3c81.54,7.82,156.38,37.45,230.05,73.48
|
||||
c138.11,67.53,260.14,168.22,341.6,299.63C3277.57,2262.08,3306.51,2527.64,3244.96,2757.96z"/>
|
||||
<linearGradient id="SVGID_00000116218201835915488090000007698577740652986507_" gradientUnits="userSpaceOnUse" x1="2670.0232" y1="1333.7509" x2="3138.8401" y2="1333.7509">
|
||||
<stop offset="0" style="stop-color:#006D88"/>
|
||||
<stop offset="1" style="stop-color:#001325"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000116218201835915488090000007698577740652986507_);" d="M3138.84,1246.53
|
||||
c-4.05,7.21-8.39,14.3-13.02,21.21c-62.44,93.39-170.24,149.34-281.64,153.16c-55.52,1.92-92.85-38.69-137.04-64.66
|
||||
c-11.78-6.93-24.25-13.03-37.12-18.59c9.28,0.07,19.16,6.29,27.68,9.8c10.34,4.28,20.69,8.55,31.03,12.81
|
||||
c28.42,11.73,57.39,27.24,87.98,32.11c30.28,4.81,61.36,0.27,90.66-7.84c39.58-10.96,79.27-27.46,114.66-48.2
|
||||
C3063.65,1311.94,3106.02,1282.22,3138.84,1246.53z"/>
|
||||
<linearGradient id="SVGID_00000107554274915499741620000017142357276473639840_" gradientUnits="userSpaceOnUse" x1="2103.0261" y1="1156.8447" x2="3182.2144" y2="1156.8447">
|
||||
<stop offset="0" style="stop-color:#33C391"/>
|
||||
<stop offset="1" style="stop-color:#61C961"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000107554274915499741620000017142357276473639840_);" d="M3138.84,1246.53
|
||||
c-32.82,35.69-75.19,65.41-116.81,89.8c-35.38,20.74-75.07,37.25-114.66,48.2c-29.3,8.11-60.38,12.65-90.66,7.84
|
||||
c-30.59-4.87-59.56-20.38-87.98-32.11c-10.34-4.26-20.69-8.54-31.03-12.81c-8.52-3.5-18.4-9.72-27.68-9.8
|
||||
c-35.78-15.45-74.73-26.57-111.18-38.82c-113.9-38.26-230.57-68.23-348.8-89.62c-36.75-6.65-72.09-14.35-107.01-20.01
|
||||
c19.49-12.38,39.2-24.39,58.97-36.31c52.17-31.47,105.76-61.84,154.74-98.12c49.66-36.79,97.59-75.93,143.54-117.26
|
||||
c1.11-0.99,10.42,1.43,12.19,1.68h0.01c1.72,0.22,3.44,0.46,5.17,0.68c2.12,0.28,4.24,0.55,6.37,0.82c0.86,0.12,1.74,0.22,2.6,0.33
|
||||
c9.47,1.19,18.97,2.29,28.47,3.28c5.7,0.59,11.37,1.34,17.04,2.12c6.87,0.95,13.73,1.96,20.6,2.84c5.54,0.71,11.09,1.34,16.67,1.8
|
||||
c50.2,4.08,100.07,9.07,150.39,10.79c3.35,0.1,6.72,0.21,10.08,0.3c62.65,1.59,125-0.13,188.52-4.81
|
||||
c46.6-3.43,94.34-9.46,140.39-18.42c18.92-3.68,37.68-8.12,56.21-13.43l17.07-6.12c22.44,26.23,38.69,56.89,45.24,96.76
|
||||
C3190.21,1094.74,3177.84,1177.04,3138.84,1246.53z"/>
|
||||
<linearGradient id="SVGID_00000020390254334245868170000018312103307704318869_" gradientUnits="userSpaceOnUse" x1="2243.8032" y1="874.23" x2="2832.1287" y2="874.23">
|
||||
<stop offset="0" style="stop-color:#000C2C"/>
|
||||
<stop offset="1" style="stop-color:#004857"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000020390254334245868170000018312103307704318869_);" d="M2832.13,799.21
|
||||
c-24.71,21.3-51.93,39.9-79.48,56.97c-39.17,24.27-80.53,44.85-122.88,62.96c-23.87,10.21-48.04,19.64-72.43,28.56l-4.63,1.54
|
||||
c-6.87-0.88-13.73-1.89-20.6-2.84c-1.96-0.53-3.87-0.96-5.57-0.96c-3.83-0.37-7.66-0.76-11.47-1.16c-9.5-0.99-19-2.09-28.47-3.28
|
||||
c-0.86-0.1-1.74-0.21-2.6-0.33c-2.12-0.27-4.24-0.53-6.37-0.82c-1.72-0.22-3.44-0.46-5.17-0.68h-0.01
|
||||
c-1.77-0.25-11.07-2.67-12.19-1.68c-67.98-9.55-134.22-22.76-203.86-35.11c-4.22-0.73-8.42-1.44-12.62-2.14h7.35
|
||||
c27.67-1.29,55.23-3.1,83.03-4.07c89.66-3.12,179.59-8.21,268.08-23.74C2683.57,858.19,2756.97,831.87,2832.13,799.21z"/>
|
||||
<path class="st14" d="M2890.41,736.89c-4.53,5.58-9.07,11.18-13.6,16.76c-13.42,16.55-28.51,31.63-44.69,45.56
|
||||
c-75.16,32.66-148.55,58.98-229.87,73.24c-88.49,15.53-178.42,20.62-268.08,23.74c-27.8,0.96-55.36,2.78-83.03,4.07h-7.35
|
||||
c-0.68-0.12-1.37-0.22-2.05-0.33c-3.09-0.5-6.16-0.99-9.23-1.47c-2.78-0.43-5.55-0.85-8.34-1.25c-2.05-0.31-4.1-0.61-6.14-0.89
|
||||
c-5.27-0.76-10.55-1.47-15.85-2.14c-2.18-0.3-4.38-0.56-6.56-0.82c-0.79-0.1-1.57-0.21-2.36-0.3c-2.31-0.28-4.63-0.55-6.95-0.8
|
||||
c-5.31-0.61-10.61-1.17-15.91-1.69c-2.43-0.24-4.85-0.48-7.27-0.68c-0.37-0.03-0.73-0.07-1.1-0.09c-2.52-0.25-5.05-0.46-7.55-0.65
|
||||
c-2.57-0.22-5.14-0.43-7.7-0.62c-5.61-0.42-11.24-0.79-16.86-1.1c-2.3-0.15-4.6-0.28-6.9-0.37c-0.28-0.03-0.56-0.04-0.85-0.04
|
||||
c-2.52-0.15-5.03-0.25-7.55-0.36c-0.01,0-0.01,0-0.03,0h-0.1c-3.13-0.15-6.26-0.25-9.38-0.34c-2.88-0.1-5.77-0.18-8.65-0.24
|
||||
c-40.06-0.89-79.97,0.82-120.06,5.49c-0.5-0.04-1.02-0.09-1.53-0.13c-155.5-14.25-315.63,18.3-459.26,78.11
|
||||
c-83.99,34.96-157.96,83.25-234.31,131.76c1.48-1.48,1.48-4.45,2.97-5.94c32.65-37.11,66.79-65.32,106.86-95.01
|
||||
c16.33-11.88,29.68-22.27,46.01-29.69l4.45-4.45c60.85-34.14,118.74-59.38,187.01-75.71c114.28-26.72,225.6-28.21,339.88-31.17
|
||||
c127.64-1.48,256.77,1.48,384.41-1.48c62.13-1.59,124.23-6.21,185.79-14.74c61.48-8.51,122.45-20.92,182.07-38.17
|
||||
c56.15-16.24,112.67-35.52,163.49-64.55C2886.3,739.24,2888.36,738.06,2890.41,736.89z"/>
|
||||
<linearGradient id="SVGID_00000125600022378541841150000017409231584131792266_" gradientUnits="userSpaceOnUse" x1="2198.241" y1="1201.1409" x2="2198.241" y2="2177">
|
||||
<stop offset="0.2577" style="stop-color:#001737"/>
|
||||
<stop offset="0.5954" style="stop-color:#009BAA"/>
|
||||
<stop offset="0.8479" style="stop-color:#006E95"/>
|
||||
<stop offset="1" style="stop-color:#000A2D"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000125600022378541841150000017409231584131792266_);" d="M2748.48,2177
|
||||
c-28.21-21.72-59.8-39.26-92.81-52.86c-2.97-1.48-4.45,0-7.42-1.48c-56.34-25.7-114.18-43.72-173.03-56.92l-34.76-9.92
|
||||
c-218.92-52.11-442.86-118.46-610.19-275.88c-72.3-68.02-144.29-154.22-172.47-251.13c-36.63-126.06,32.03-278.8,161.65-319.24
|
||||
c1.86-0.58,3.71-1.13,5.58-1.63c0.68-0.21,1.37-0.39,2.05-0.56c0.61-0.18,1.23-0.33,1.84-0.49c0.01,0,0.01,0,0.03,0
|
||||
c0.01,0,0.01,0,0.03,0c0.19-0.06,0.39-0.1,0.58-0.16c0.88-0.21,1.77-0.43,2.67-0.64c0.85-0.21,1.71-0.4,2.55-0.58
|
||||
c0.86-0.19,1.72-0.39,2.6-0.56c0.67-0.13,1.34-0.27,2-0.39c0.01,0,0.03-0.01,0.04-0.01c0.62-0.12,1.25-0.25,1.87-0.36
|
||||
c1.28-0.24,2.55-0.46,3.84-0.67c0.73-0.12,1.45-0.24,2.17-0.34c2.92-0.45,5.86-0.82,8.8-1.1c0.64-0.07,1.26-0.13,1.9-0.19
|
||||
c0.95-0.09,1.9-0.16,2.85-0.24c11.68-0.86,23.44-0.62,35.12,0.79c-2.29,0.85-4.57,1.71-6.84,2.58
|
||||
c-78.34,30.31-151.52,85.34-188.18,161.84c-36.26,75.68-30.06,190.74,30.01,253.51c9.25,9.66,19.47,17.62,30.43,24.17h0.01
|
||||
c38.47,35.84,87.92,62.17,133.1,88.61c46.04,26.93,93.05,52.15,140.6,76.29c123.09,62.47,249.6,117.75,375.5,174.21
|
||||
c62.95,28.24,125.77,56.75,187.97,86.62C2656.16,2097.89,2707.28,2126.62,2748.48,2177z"/>
|
||||
<path class="st16" d="M1976.39,891.58c-21.46,2.49-42.98,5.85-64.61,10.09c-0.09,0.01-0.16,0.03-0.25,0.06
|
||||
c-10.18,2-20.39,4.2-30.62,6.61c-0.67,0-1.65,0.61-2.64,1.26c-1.22,0.82-2.48,1.71-3.29,1.71c-3.34,0.52-6.59,1.16-9.77,1.91h-0.01
|
||||
c-3.53,0.83-6.99,1.8-10.39,2.84c-0.01,0-0.01,0-0.03,0c-66.4,5.82-130.94,28.71-186.7,65.3c-9.1,5.95-17.93,12.28-26.57,18.87
|
||||
l-6.47-1.04c-22.35-2.57-46.01-0.42-68.16,2.91c-23.23,3.47-46.07,9.25-68.38,16.51c-44.69,14.53-89.32,33.95-129.42,58.52
|
||||
c-37.24,22.82-69.4,52.98-96.81,86.83c-27.9,34.44-51.03,72.47-69.4,112.78c-18.45,40.44-32.28,82.79-44.23,125.54l-2.92,12.31
|
||||
c0.28-3.47,0.58-6.95,0.91-10.42c8.91-83.13,31.17-161.81,74.21-236.03l4.45-4.45c11.87-23.75,28.2-43.05,46.01-62.35
|
||||
c76.35-48.51,150.32-96.8,234.31-131.76c121.08-50.41,253.89-81.47,385.76-81.44c4.94,0,9.9,0.04,14.84,0.15
|
||||
c1.14,0,2.29,0.03,3.43,0.06c3.07,0.06,6.14,0.15,9.22,0.25c1.42,0.04,2.85,0.1,4.27,0.16c1.91,0.06,3.83,0.15,5.74,0.24
|
||||
c2.8,0.12,5.61,0.27,8.42,0.43c2.91,0.16,5.82,0.34,8.73,0.53c0.19,0.01,0.37,0.01,0.56,0.03c2.76,0.19,5.54,0.4,8.3,0.62
|
||||
c0.31,0.01,0.62,0.04,0.93,0.07c2.95,0.24,5.91,0.49,8.85,0.76c0.07,0,0.13,0,0.21,0.01
|
||||
C1975.37,891.49,1975.89,891.53,1976.39,891.58z"/>
|
||||
<path class="st17" d="M1655.67,3123.97c-7.24,2.75-14.28,6.74-22.62,8.14c-0.71,0.12-1.44,0.24-2.15,0.36
|
||||
c-5.8,0.97-11.62,1.92-17.44,2.85c-14.14,2.27-28.3,4.44-42.48,6.58c-26.63,4.02-53.31,7.91-79.94,12.07
|
||||
c-0.22,0.03-0.46,0.07-0.71,0.12c-0.5,0.07-1.02,0.16-1.53,0.24c-0.09,0.01-0.16,0.03-0.25,0.04c-28.26,4.41-56.47,9.13-84.54,14.61
|
||||
c-0.45,0.07-0.89,0.16-1.34,0.25c-15.12,2.95-30.19,6.15-45.21,9.62c-0.85,0.19-1.68,0.39-2.52,0.59c-0.03,0-0.06,0-0.09,0.02
|
||||
c-1.44,0.34-2.88,0.67-4.3,1.01c-0.1,0.03-0.21,0.06-0.31,0.07c-0.5,0.12-0.99,0.24-1.48,0.36c-2.75,0.65-5.49,1.32-8.24,2
|
||||
c-3.34,0.82-6.68,1.66-10.02,2.51c0,0-0.01,0-0.01,0.01c-17.93,4.56-35.75,9.5-53.52,14.68c-4.85,1.41-9.69,2.85-14.53,4.29
|
||||
c-53.71,16.05-106.95,33.89-160.65,49.75c3.41-1.01,30.11-16.09,20.21-10.94c24.45-13.33,49.11-27.03,74.7-39.83
|
||||
c29.68-14.84,59.37-28.21,90.54-41.57c68.27-28.21,139.52-47.5,210.76-68.29C1551.08,3102.8,1603.29,3113.58,1655.67,3123.97z"/>
|
||||
<path class="st18" d="M2231.56,2343.47c-25.66-14.38-51.7-27.54-78.05-40.62c-42.61-21.12-85.73-41.19-129.17-60.54
|
||||
c-58.95-26.25-118.48-51.17-178.19-75.66c-60.26-24.72-120.68-49-180.91-73.78c-59.26-24.38-119.4-48.01-176.49-77.24
|
||||
c-55.14-28.23-107.14-69.55-132.97-127.59c69.31,45.89,148.38,74.71,232.75,93.58c118.71,28.4,234.42,45.32,350.61,58.28
|
||||
c18.36,11.91,37.25,23.01,55.48,35.11c16.98,11.28,33.8,22.76,50.26,34.72h0.01c20.7,15.05,40.85,30.85,60.04,47.93
|
||||
c1.2,1.07,2.39,2.14,3.58,3.21c41.34,37.31,78.66,80.44,103.45,130.59C2220.16,2308.1,2226.9,2325.52,2231.56,2343.47z"/>
|
||||
<path class="st1" d="M1121.27,3243.58c-6.5,3.56-13,7.08-19.49,10.55"/>
|
||||
<linearGradient id="SVGID_00000043453862302291417740000006473128975406365587_" gradientUnits="userSpaceOnUse" x1="1658.1101" y1="1124.8477" x2="2193.2344" y2="815.8935">
|
||||
<stop offset="0" style="stop-color:#001636"/>
|
||||
<stop offset="0.9948" style="stop-color:#00547A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000043453862302291417740000006473128975406365587_);" d="M2241.76,899.93l-9.5,0.33
|
||||
c-104.9,5.12-209.93,14.76-312.5,37.39c-54.13,11.95-107.52,27.55-159.14,47.77c-48.86,19.15-92.72,47.61-140.32,68.32l-2.57,1.17
|
||||
c8.28-3.79,16.74-14.3,23.96-20.32c0.18-0.16,0.34-0.3,0.5-0.43c0.59-0.49,1.19-0.96,1.8-1.45c1.2-0.96,2.4-1.93,3.61-2.89
|
||||
c0.89-0.71,1.8-1.44,2.7-2.15c1.68-1.32,3.35-2.64,5.05-3.96c11.24-8.77,22.74-17.29,34.51-25.56c1.4-0.98,2.81-1.97,4.23-2.95
|
||||
c0.98-0.68,1.96-1.37,2.95-2.05c1.83-1.25,3.67-2.51,5.51-3.74c0.46-0.33,0.93-0.64,1.4-0.94c1.84-1.26,3.68-2.49,5.52-3.71
|
||||
c0.5-0.34,1.01-0.68,1.51-0.99c2-1.34,4.01-2.66,6.01-3.95c2.08-1.37,4.16-2.72,6.25-4.04c0.45-0.3,0.89-0.58,1.34-0.86
|
||||
c1.14-0.73,2.29-1.44,3.43-2.17c0.21-0.13,0.4-0.27,0.61-0.37c29.02-18.04,60.04-32.57,92.12-44.48c6.29-2.35,12.62-4.57,18.98-6.71
|
||||
c0.73-0.25,1.45-0.5,2.18-0.74c7.72-2.57,15.48-4.97,23.3-7.21c4.35-1.26,8.7-2.46,13.08-3.62c11.09-2.94,22.26-5.58,33.51-7.93
|
||||
c20.84-4.36,41.9-7.73,63.08-10.23c40.34-4.75,81.13-6.32,121.59-5.36c2.88,0.06,5.77,0.13,8.65,0.24c3.13,0.09,6.26,0.21,9.38,0.34
|
||||
h0.1c0.01,0,0.01,0,0.03,0c2.52,0.1,5.05,0.22,7.55,0.36c0.28,0,0.56,0.01,0.85,0.04c2.3,0.1,4.6,0.22,6.9,0.37
|
||||
c5.62,0.31,11.25,0.68,16.86,1.1c2.57,0.21,5.14,0.4,7.7,0.62c2.52,0.21,5.03,0.42,7.55,0.65c0.37,0.01,0.73,0.06,1.1,0.09
|
||||
c2.42,0.22,4.85,0.45,7.27,0.68c5.31,0.52,10.61,1.08,15.91,1.69c2.32,0.25,4.63,0.52,6.95,0.8c0.79,0.09,1.57,0.19,2.36,0.3
|
||||
c2.2,0.25,4.38,0.53,6.56,0.82c5.3,0.67,10.58,1.38,15.85,2.14c2.05,0.28,4.1,0.58,6.14,0.89c2.79,0.4,5.57,0.82,8.34,1.25
|
||||
C2235.6,898.94,2238.67,899.43,2241.76,899.93z"/>
|
||||
<path class="st20" d="M2406.65,2587.24c0.15,44.25-9.65,81.51-35.8,117.38c-23.69,32.48-53.03,60.83-86.35,83.32
|
||||
c-50.92,34.37-105.99,48.66-165.65,58.88c16.79-4.04,33.32-9.1,49.54-15.31c90.71-34.68,169.63-109.27,191.92-203.81
|
||||
c25.34-107.36-31.79-204.74-122.08-244.91c-1.44-13.06-3.25-25.92-6.52-38.66c48.21,19.86,91.43,51.63,125.03,91.49
|
||||
C2393.13,2478.8,2406.47,2531.44,2406.65,2587.24z"/>
|
||||
<path class="st21" d="M1854.78,916.06c-5.09,1.56-10.08,3.31-15.06,5.12c-6,2.17-11.99,4.39-18.17,6.46
|
||||
c-0.27,0.09-0.55,0.16-0.82,0.25c-29.33,8.91-54.37,22.16-82.3,38.34c-3.29,2.02-6.56,4.05-9.83,6.13c-0.21,0.1-0.4,0.24-0.61,0.37
|
||||
c-1.59,0.99-3.18,2-4.76,3.03c-2.09,1.32-4.17,2.67-6.25,4.04c-2,1.29-4.01,2.6-6.01,3.95c-0.5,0.31-1.01,0.65-1.51,0.99
|
||||
c-1.84,1.22-3.68,2.45-5.52,3.71c-0.46,0.3-0.94,0.61-1.4,0.94c-1.84,1.23-3.68,2.48-5.51,3.74c-0.99,0.68-1.97,1.37-2.95,2.05
|
||||
c-1.41,0.98-2.82,1.97-4.23,2.95c-11.77,8.27-23.27,16.79-34.51,25.56c-1.69,1.31-3.37,2.63-5.05,3.96
|
||||
c-0.91,0.71-1.81,1.44-2.7,2.15c-1.2,0.96-2.4,1.93-3.61,2.89c-0.77,0.62-1.54,1.25-2.3,1.89c-8.15,6.62-16.13,13.4-23.96,20.32
|
||||
c-74.52,65.88-134.47,144.59-173.18,237.91c-1.48,2.97,0,4.45-1.48,7.42c-14.68,34.25-23.78,69.9-28.04,106.14
|
||||
c0-40.78-0.39-74.74,15.01-113.43c21.91-55.06,45.92-109.82,79.98-158.32c23.87-34.01,52.39-64.53,82.77-92.87
|
||||
c15.61-14.56,31.76-28.59,48.71-41.54c8.64-6.59,17.47-12.92,26.57-18.87C1723.84,944.77,1788.37,921.87,1854.78,916.06z"/>
|
||||
<path class="st21" d="M1991.87,1181.85c-25.96,1.65-52.29,6.19-79.38,14.89c-5.51,1.77-11.01,3.67-16.5,5.69h-0.01
|
||||
c-11.68-1.41-23.44-1.65-35.12-0.79c-0.95,0.07-1.9,0.15-2.85,0.24c-0.64,0.06-1.26,0.12-1.9,0.19c-2.94,0.28-5.88,0.65-8.8,1.1
|
||||
c-0.71,0.1-1.44,0.22-2.17,0.34c-1.29,0.21-2.57,0.43-3.84,0.67c-0.58,0.09-1.16,0.21-1.74,0.31c3.47-1.11,6.92-2.38,10.17-3.24
|
||||
c7.3-1.96,14.65-3.76,22.04-5.4c14.14-3.18,28.42-5.79,42.77-7.85C1940.27,1184.3,1966.03,1183.41,1991.87,1181.85z"/>
|
||||
<path class="st22" d="M2513.54,2236.8c-33.31-20.11-65.53-42.96-100.3-60.48c-34.18-17.22-70.54-29.9-107.62-39.29
|
||||
c-43.43-11.01-87.84-17.61-132.32-22.56c-42.89-4.78-85.22-4.72-128.41-4.72h-0.01c-16.46-11.97-33.28-23.44-50.26-34.72
|
||||
c-18.23-12.1-37.12-23.2-55.48-35.11c40.03,4.47,80.13,8.48,120.43,12.31c42.63,4.05,85.48,7.93,128.71,11.99
|
||||
c1.93,0.18,3.87,0.37,5.8,0.55C2321.35,2076.75,2434.55,2140.54,2513.54,2236.8z"/>
|
||||
<path class="st23" d="M2611.25,2422.76c-54.07-58.8-108.04-119.18-174.02-165c-93.28-64.78-215.69-98.57-328.72-96.88
|
||||
c-1.19-1.07-2.37-2.14-3.58-3.21c-19.19-17.09-39.33-32.88-60.04-47.93c43.19,0,85.52-0.06,128.41,4.72
|
||||
c44.48,4.96,88.89,11.55,132.32,22.56c37.08,9.4,73.44,22.07,107.62,39.29c34.78,17.52,67,40.36,100.3,60.48
|
||||
c0,0.01,0.01,0.01,0.01,0.01c1.44,1.77,2.88,3.53,4.3,5.33c0.04,0.04,0.09,0.1,0.13,0.16c1.42,1.78,2.85,3.59,4.24,5.4
|
||||
c0.88,1.11,1.75,2.26,2.6,3.38c0.8,1.04,1.59,2.09,2.39,3.15c2.27,3.03,4.51,6.1,6.71,9.19c0.8,1.11,1.59,2.23,2.36,3.34
|
||||
c0.33,0.46,0.65,0.91,0.96,1.37c0.76,1.1,1.51,2.18,2.26,3.28c3.83,5.58,7.55,11.25,11.15,17.01c0.62,0.98,1.23,1.96,1.83,2.94
|
||||
c0.76,1.22,1.51,2.45,2.26,3.68c0.62,1.02,1.25,2.06,1.86,3.1c0.68,1.13,1.37,2.27,2.02,3.43c0.52,0.88,1.02,1.75,1.53,2.63
|
||||
c0.7,1.19,1.4,2.39,2.06,3.61c0.64,1.11,1.28,2.24,1.9,3.37c0.95,1.69,1.87,3.4,2.79,5.11c0.13,0.22,0.27,0.46,0.39,0.71
|
||||
c0.86,1.59,1.71,3.18,2.54,4.78c0.5,0.95,1.01,1.9,1.5,2.85c1.1,2.12,2.18,4.26,3.25,6.4
|
||||
C2589.34,2360.63,2601.87,2391.06,2611.25,2422.76z"/>
|
||||
<path class="st24" d="M2892.94,2626.65l-0.15-2.08c-4.1-53.6-5.58-105.56-14.49-159c-4.45-22.27-10.39-43.05-17.81-65.32
|
||||
c-10.39-26.72-22.26-50.47-37.11-75.71c-41.56-66.8-94.99-115.79-163.26-151.42c-4.45-1.48-7.42-5.94-10.39-7.42
|
||||
c-102.41-50.47-210.76-80.16-325.04-90.55c-4.45,0-10.39-2.97-14.84-2.97c-41.56-2.97-81.63-7.42-121.57-7.97
|
||||
c-43.24-4.07-86.08-7.94-128.71-11.99l3.1-34.75c138.82,13.27,278.29,18.2,412.55,48.28c58.85,13.2,116.69,31.22,173.03,56.92
|
||||
c2.97,1.48,4.45,0,7.42,1.48c33.01,13.6,64.59,31.14,92.81,52.86c0,0,0,0.01,0.01,0.01c36.48,28.13,67.32,63.27,88.25,105.96
|
||||
l4.45,4.45c10.39,17.81,16.33,37.11,25.23,54.93c8.91,20.78,14.84,41.57,20.78,63.83
|
||||
C2905.72,2480.27,2906.65,2554.34,2892.94,2626.65z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 32 KiB |
70
biome.json
70
biome.json
@ -1,35 +1,75 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.5.0/schema.json",
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"all": true,
|
||||
"style": {
|
||||
"useWhile": "off",
|
||||
"noNonNullAssertion": "off"
|
||||
},
|
||||
"suspicious": {
|
||||
"noExplicitAny": "off",
|
||||
"noAssignInExpressions": "off"
|
||||
"noAssignInExpressions": "off",
|
||||
"noUnsafeDeclarationMerging": "off",
|
||||
"noRedeclare": "off",
|
||||
"noEmptyInterface": "off",
|
||||
"noConfusingVoidType": "off",
|
||||
"noImplicitAnyLet": "off"
|
||||
},
|
||||
"style": {
|
||||
"noNonNullAssertion": "off",
|
||||
"noParameterAssign": "off"
|
||||
},
|
||||
"correctness": {
|
||||
"noUnusedVariables": "off"
|
||||
},
|
||||
"nursery": {
|
||||
"useExportType": "error",
|
||||
"useImportType": "error",
|
||||
"useNodejsImportProtocol": "error",
|
||||
"noUselessLoneBlockStatements": "warn",
|
||||
"noUselessTernary": "error",
|
||||
"noEmptyBlockStatements": "off"
|
||||
},
|
||||
"complexity": {
|
||||
"noBannedTypes": "off",
|
||||
"noForEach": "off",
|
||||
"noUselessConstructor": "off",
|
||||
"noThisInStatic": "off"
|
||||
},
|
||||
"a11y": {
|
||||
"all": false
|
||||
},
|
||||
"performance": {
|
||||
"noDelete": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"json": {
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 80
|
||||
}
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentWidth": 2,
|
||||
"indentStyle": "space",
|
||||
"lineWidth": 140,
|
||||
"indentStyle": "tab",
|
||||
"lineWidth": 120,
|
||||
"lineEnding": "crlf",
|
||||
"formatWithErrors": true
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "single",
|
||||
"arrowParentheses": "asNeeded",
|
||||
"bracketSameLine": true,
|
||||
"semicolons": "always"
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"ignore": [
|
||||
"node_modules/",
|
||||
"build",
|
||||
"dist",
|
||||
"tsup.config.ts",
|
||||
"__test__"
|
||||
]
|
||||
"ignoreUnknown": true,
|
||||
"ignore": ["node_modules/", "build", "lib", "__test__"]
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
|
2688
package-lock.json
generated
Normal file
2688
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
100
package.json
100
package.json
@ -1,30 +1,59 @@
|
||||
{
|
||||
"name": "@biscuitland/core",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
"name": "seyfert",
|
||||
"version": "0.1.0",
|
||||
"main": "./lib/index.js",
|
||||
"module": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"files": [
|
||||
"lib/**"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"clean": "turbo run clean",
|
||||
"check": "biome check ./packages/",
|
||||
"check:apply": "biome check --apply --max-diagnostics 200 --quote-style single --trailing-comma none ./packages/",
|
||||
"lint": "biome format --write --quote-style single --trailing-comma none ./packages/",
|
||||
"dev": "turbo run dev --parallel"
|
||||
"build": "tsc --outDir ./lib",
|
||||
"dev": "swc src -d lib -w",
|
||||
"prepublishOnly": "npm run build",
|
||||
"prepare": "npm run build && husky install",
|
||||
"lint": "biome lint --apply ./src",
|
||||
"format": "biome format --write ./src",
|
||||
"check-h": "biome check --apply ./src",
|
||||
"check": "biome check --apply --changed --no-errors-on-unmatched ./src"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=7.0.0",
|
||||
"node": ">=16.0.0"
|
||||
"author": "MARCROCK22",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.5.3",
|
||||
"discord-api-types": "^0.37.71",
|
||||
"magic-bytes.js": "^1.7.0",
|
||||
"ts-mixer": "^6.0.3",
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"biome check --apply",
|
||||
"biome format --write"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.3.3",
|
||||
"@changesets/cli": "^2.24.1",
|
||||
"@types/node": "^20.0.0",
|
||||
"turbo": "^1.4.2",
|
||||
"typescript": "^5.0.4"
|
||||
"lint-staged": "^15.2.2",
|
||||
"@biomejs/biome": "1.5.0",
|
||||
"@swc/cli": "^0.1.63",
|
||||
"@swc/core": "^1.3.102",
|
||||
"@types/node": "^20.10.7",
|
||||
"@types/ws": "^8.5.10",
|
||||
"husky": "^8.0.3",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"ioredis": "^5.3.2",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.39.0"
|
||||
},
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/tiramisulabs/biscuit.git"
|
||||
},
|
||||
"packageManager": "npm@8.19.4",
|
||||
"bugs": {
|
||||
"url": "https://github.com/oasisjs/biscuit"
|
||||
"url": "https://github.com/tiramisulabs/biscuit"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
@ -33,38 +62,13 @@
|
||||
"typescript",
|
||||
"botdev"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"author": "Yuzuru <yuzuru@programmer.net>",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Yuzuru",
|
||||
"url": "https://github.com/yuzudev",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "miia",
|
||||
"url": "https://github.com/dragurimu"
|
||||
},
|
||||
{
|
||||
"name": "n128",
|
||||
"url": "https://github.com/nicolito128"
|
||||
},
|
||||
{
|
||||
"name": "socram03",
|
||||
"url": "https://github.com/socram03"
|
||||
},
|
||||
{
|
||||
"name": "Drylozu",
|
||||
"url": "https://github.com/Drylozu"
|
||||
},
|
||||
{
|
||||
"name": "FreeAoi",
|
||||
"url": "https://github.com/FreeAoi"
|
||||
}
|
||||
],
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/oasisjs/biscuit.git"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
# @biscuitland/common
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- idk
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix the silly logger and other silly things affected by this bug
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- I meessed up
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix: logger on every module
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- first 3.0.\* without bugs
|
@ -1,20 +0,0 @@
|
||||
# @biscuitland/common
|
||||
## Most importantly, biscuit's common is:
|
||||
Custom types, functions and utility classes, a feature-rich package for sharing in the biscuit libraries
|
||||
|
||||
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
|
||||
[<img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white">](https://discord.gg/XNw2RZFzaP)
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/oasisjs/biscuit/main/assets/icon.svg" alt="biscuit"/>
|
||||
|
||||
## Install (for [node18](https://nodejs.org/en/download/))
|
||||
|
||||
```sh-session
|
||||
npm install @biscuitland/common
|
||||
yarn add @biscuitland/common
|
||||
```
|
||||
## Links
|
||||
* [Website](https://biscuitjs.com/)
|
||||
* [Documentation](https://docs.biscuitjs.com/)
|
||||
* [Discord](https://discord.gg/XNw2RZFzaP)
|
||||
* [core](https://www.npmjs.com/package/@biscuitland/core) | [rest](https://www.npmjs.com/package/@biscuitland/rest) | [ws](https://www.npmjs.com/package/@biscuitland/ws) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)
|
@ -1,75 +0,0 @@
|
||||
{
|
||||
"name": "@biscuitland/common",
|
||||
"version": "0.0.10",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"clean": "rm -rf dist && rm -rf .turbo",
|
||||
"dev": "tsup --watch"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsup": "^7.0.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": "Yuzuru <yuzuru@programmer.net>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Yuzuru",
|
||||
"url": "https://github.com/yuzudev"
|
||||
},
|
||||
{
|
||||
"name": "miia",
|
||||
"url": "https://github.com/dragurimu"
|
||||
},
|
||||
{
|
||||
"name": "n128",
|
||||
"url": "https://github.com/nicolito128"
|
||||
},
|
||||
{
|
||||
"name": "socram03",
|
||||
"url": "https://github.com/socram03",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Drylozu",
|
||||
"url": "https://github.com/Drylozu"
|
||||
}
|
||||
],
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/oasisjs/biscuit.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/oasisjs/biscuit"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
"discord",
|
||||
"bots",
|
||||
"typescript",
|
||||
"botdev"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.37.39"
|
||||
}
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
// https://github.com/discordeno/discordeno/blob/main/packages/utils/src/Collection.ts
|
||||
export class Collection<K, V> extends Map<K, V> {
|
||||
/**
|
||||
* The maximum amount of items allowed in this collection. To disable cache, set it 0, set to undefined to make it infinite.
|
||||
* @default undefined
|
||||
*/
|
||||
maxSize: number | undefined;
|
||||
/** Handler to remove items from the collection every so often. */
|
||||
sweeper: (CollectionSweeper<K, V> & { intervalId?: NodeJS.Timeout }) | undefined;
|
||||
|
||||
constructor(entries?: (ReadonlyArray<readonly [K, V]> | null) | Map<K, V>, options?: CollectionOptions<K, V>) {
|
||||
super(entries ?? []);
|
||||
|
||||
this.maxSize = options?.maxSize;
|
||||
|
||||
if (!options?.sweeper) return;
|
||||
|
||||
this.startSweeper(options.sweeper);
|
||||
}
|
||||
|
||||
startSweeper(options: CollectionSweeper<K, V>): NodeJS.Timer {
|
||||
if (this.sweeper?.intervalId) clearInterval(this.sweeper.intervalId);
|
||||
|
||||
this.sweeper = options;
|
||||
this.sweeper.intervalId = setInterval(() => {
|
||||
// biome-ignore lint/complexity/noForEach: <explanation>
|
||||
this.forEach((value, key) => {
|
||||
if (!this.sweeper?.filter(value, key)) return;
|
||||
|
||||
this.delete(key);
|
||||
return key;
|
||||
});
|
||||
}, options.interval);
|
||||
|
||||
return this.sweeper.intervalId;
|
||||
}
|
||||
|
||||
stopSweeper(): void {
|
||||
clearInterval(this.sweeper?.intervalId);
|
||||
}
|
||||
|
||||
changeSweeperInterval(newInterval: number): void {
|
||||
if (this.sweeper == null) return;
|
||||
|
||||
this.startSweeper({ filter: this.sweeper.filter, interval: newInterval });
|
||||
}
|
||||
|
||||
changeSweeperFilter(newFilter: (value: V, key: K) => boolean): void {
|
||||
if (this.sweeper == null) return;
|
||||
|
||||
this.startSweeper({ filter: newFilter, interval: this.sweeper.interval });
|
||||
}
|
||||
|
||||
/** Add an item to the collection. Makes sure not to go above the maxSize. */
|
||||
set(key: K, value: V): this {
|
||||
// When this collection is maxSized make sure we can add first
|
||||
if ((this.maxSize !== undefined || this.maxSize === 0) && this.size >= this.maxSize) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return super.set(key, value);
|
||||
}
|
||||
|
||||
/** Add an item to the collection, no matter what the maxSize is. */
|
||||
forceSet(key: K, value: V): this {
|
||||
return super.set(key, value);
|
||||
}
|
||||
|
||||
/** Convert the collection to an array. */
|
||||
array(): V[] {
|
||||
return [...this.values()];
|
||||
}
|
||||
|
||||
/** Retrieve the value of the first element in this collection. */
|
||||
first(): V | undefined {
|
||||
return this.values().next().value;
|
||||
}
|
||||
|
||||
/** Retrieve the value of the last element in this collection. */
|
||||
last(): V | undefined {
|
||||
return [...this.values()][this.size - 1];
|
||||
}
|
||||
|
||||
/** Retrieve the value of a random element in this collection. */
|
||||
random(): V | undefined {
|
||||
const array = [...this.values()];
|
||||
return array[Math.floor(Math.random() * array.length)];
|
||||
}
|
||||
|
||||
/** Find a specific element in this collection. */
|
||||
find(callback: (value: V, key: K) => boolean): NonNullable<V> | undefined {
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key)!;
|
||||
if (callback(value, key)) return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Find all elements in this collection that match the given pattern. */
|
||||
filter(callback: (value: V, key: K) => boolean): Collection<K, V> {
|
||||
const relevant = new Collection<K, V>();
|
||||
// biome-ignore lint/complexity/noForEach: <explanation>
|
||||
this.forEach((value, key) => {
|
||||
if (callback(value, key)) relevant.set(key, value);
|
||||
});
|
||||
|
||||
return relevant;
|
||||
}
|
||||
|
||||
/** Converts the collection into an array by running a callback on all items in the collection. */
|
||||
map<T>(callback: (value: V, key: K) => T): T[] {
|
||||
const results = [];
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key)!;
|
||||
results.push(callback(value, key));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Check if one of the items in the collection matches the pattern. */
|
||||
some(callback: (value: V, key: K) => boolean): boolean {
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key)!;
|
||||
if (callback(value, key)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check if all of the items in the collection matches the pattern. */
|
||||
every(callback: (value: V, key: K) => boolean): boolean {
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key)!;
|
||||
if (!callback(value, key)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Runs a callback on all items in the collection, merging them into a single value. */
|
||||
reduce<T>(callback: (accumulator: T, value: V, key: K) => T, initialValue?: T): T {
|
||||
let accumulator: T = initialValue!;
|
||||
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key)!;
|
||||
accumulator = callback(accumulator, value, key);
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}
|
||||
}
|
||||
|
||||
export interface CollectionOptions<K, V> {
|
||||
/** Handler to clean out the items in the collection every so often. */
|
||||
sweeper?: CollectionSweeper<K, V>;
|
||||
/** The maximum number of items allowed in the collection. */
|
||||
maxSize?: number;
|
||||
}
|
||||
|
||||
export interface CollectionSweeper<K, V> {
|
||||
/** The filter to determine whether an element should be deleted or not */
|
||||
filter: (value: V, key: K, ...args: any[]) => boolean;
|
||||
/** The interval in which the sweeper should run */
|
||||
interval: number;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
export const DiscordEpoch = 14200704e5;
|
||||
|
||||
export const API_VERSION = '10';
|
||||
|
||||
export const BASE_URL = `/api/v${API_VERSION}`;
|
||||
export const BASE_HOST = 'https://discord.com';
|
||||
|
||||
export const CDN_URL = 'https://cdn.discordapp.com';
|
||||
|
||||
export const GATEWAY_BASE_URL = 'wss://gateway.discord.gg/?v=10&encoding=json';
|
||||
|
||||
export const OK_STATUS_CODES = [200, 201, 204, 304];
|
||||
|
||||
export enum HTTPMethods {
|
||||
Delete = 'DELETE',
|
||||
Get = 'GET',
|
||||
Patch = 'PATCH',
|
||||
Post = 'POST',
|
||||
Put = 'PUT'
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
import { Options, bgBrightWhite, black, bold, cyan, gray, italic, red, yellow } from './Util';
|
||||
|
||||
export enum LogLevels {
|
||||
Debug = 0,
|
||||
Info = 1,
|
||||
Warn = 2,
|
||||
Error = 3,
|
||||
Fatal = 4
|
||||
}
|
||||
|
||||
export enum LogDepth {
|
||||
Minimal = 0,
|
||||
Full = 1
|
||||
}
|
||||
|
||||
export type LoggerOptions = {
|
||||
logLevel?: LogLevels;
|
||||
name?: string;
|
||||
active?: boolean;
|
||||
};
|
||||
|
||||
export class Logger {
|
||||
readonly options: Required<LoggerOptions>;
|
||||
|
||||
constructor(options: LoggerOptions) {
|
||||
this.options = Options(Logger.DEFAULT_OPTIONS, options);
|
||||
}
|
||||
|
||||
set level(level: LogLevels) {
|
||||
this.options.logLevel = level;
|
||||
}
|
||||
|
||||
get level(): LogLevels {
|
||||
return this.options.logLevel;
|
||||
}
|
||||
|
||||
set active(active: boolean) {
|
||||
this.options.active = active;
|
||||
}
|
||||
|
||||
get active(): boolean {
|
||||
return this.options.active;
|
||||
}
|
||||
|
||||
set name(name: string) {
|
||||
this.options.name = name;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this.options.name;
|
||||
}
|
||||
|
||||
rawLog(level: LogLevels, ...args: unknown[]) {
|
||||
if (!this.active) return;
|
||||
if (level < this.level) return;
|
||||
|
||||
const color = Logger.colorFunctions.get(level) ?? Logger.noColor;
|
||||
|
||||
const date = new Date();
|
||||
const log = [
|
||||
bgBrightWhite(black(`[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`)),
|
||||
color(Logger.prefixes.get(level) ?? 'DEBUG'),
|
||||
this.name ? `${this.name} >` : '>',
|
||||
...args
|
||||
];
|
||||
|
||||
switch (level) {
|
||||
case LogLevels.Debug:
|
||||
return console.debug(...log);
|
||||
case LogLevels.Info:
|
||||
return console.info(...log);
|
||||
case LogLevels.Warn:
|
||||
return console.warn(...log);
|
||||
case LogLevels.Error:
|
||||
return console.error(...log);
|
||||
case LogLevels.Fatal:
|
||||
return console.error(...log);
|
||||
default:
|
||||
return console.log(...log);
|
||||
}
|
||||
}
|
||||
|
||||
debug(...args: any[]) {
|
||||
this.rawLog(LogLevels.Debug, ...args);
|
||||
}
|
||||
|
||||
info(...args: any[]) {
|
||||
this.rawLog(LogLevels.Info, ...args);
|
||||
}
|
||||
|
||||
warn(...args: any[]) {
|
||||
this.rawLog(LogLevels.Warn, ...args);
|
||||
}
|
||||
|
||||
error(...args: any[]) {
|
||||
this.rawLog(LogLevels.Error, ...args);
|
||||
}
|
||||
|
||||
fatal(...args: any[]) {
|
||||
this.rawLog(LogLevels.Fatal, ...args);
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS: Required<LoggerOptions> = {
|
||||
logLevel: LogLevels.Info,
|
||||
name: 'BISCUIT',
|
||||
active: true
|
||||
};
|
||||
|
||||
static noColor(msg: string) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
static colorFunctions = new Map<LogLevels, (str: string) => string>([
|
||||
[LogLevels.Debug, gray],
|
||||
[LogLevels.Info, cyan],
|
||||
[LogLevels.Warn, yellow],
|
||||
[LogLevels.Error, (str: string) => red(str)],
|
||||
[LogLevels.Fatal, (str: string) => red(bold(italic(str)))]
|
||||
]);
|
||||
|
||||
static prefixes = new Map<LogLevels, string>([
|
||||
[LogLevels.Debug, 'DEBUG'],
|
||||
[LogLevels.Info, 'INFO'],
|
||||
[LogLevels.Warn, 'WARN'],
|
||||
[LogLevels.Error, 'ERROR'],
|
||||
[LogLevels.Fatal, 'FATAL']
|
||||
]);
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
export type Tail<A> = A extends [unknown, ...infer rest] ? rest : A extends [unknown] ? [] : A extends (infer first)[] ? first[] : never;
|
||||
|
||||
export type ValueOf<T> = T[keyof T];
|
||||
|
||||
export type ArrayFirsElement<A> = A extends [...infer arr] ? arr[0] : never;
|
||||
|
||||
export type RestToKeys<T extends unknown[]> = T extends [infer V, ...infer Keys] ? { [K in Extract<Keys[number], string>]: V } : never;
|
||||
|
||||
export type Identify<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;
|
||||
|
||||
export type TypeArray<T> = T | T[];
|
||||
|
||||
export type When<T extends boolean, A, B = never> = T extends true ? A : B;
|
||||
|
||||
export type PickPartial<T, K extends keyof T> = {
|
||||
[P in keyof T]?: T[P] | undefined;
|
||||
} & {
|
||||
[P in K]: T[P];
|
||||
};
|
||||
|
||||
export type MakeRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
||||
|
||||
export type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}`
|
||||
? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}`
|
||||
: Lowercase<S>;
|
||||
|
||||
export type SnakeCase<S extends string> = S extends `${infer A}${infer Rest}`
|
||||
? A extends Uppercase<A>
|
||||
? `_${Lowercase<A>}${SnakeCase<Rest>}`
|
||||
: `${A}${SnakeCase<Rest>}`
|
||||
: Lowercase<S>;
|
||||
|
||||
export type ObjectToLower<T> = Identify<{
|
||||
[K in keyof T as CamelCase<Exclude<K, symbol | number>>]: T[K] extends unknown[]
|
||||
? Identify<ObjectToLower<T[K][0]>[]>
|
||||
: T[K] extends object
|
||||
? Identify<ObjectToLower<T[K]>>
|
||||
: T[K];
|
||||
}>;
|
||||
export type ObjectToSnake<T> = Identify<{
|
||||
[K in keyof T as SnakeCase<Exclude<K, symbol | number>>]: T[K] extends unknown[]
|
||||
? Identify<ObjectToSnake<T[K][0]>[]>
|
||||
: T[K] extends object
|
||||
? Identify<ObjectToSnake<T[K]>>
|
||||
: T[K];
|
||||
}>;
|
@ -1,6 +0,0 @@
|
||||
export * from './Constants';
|
||||
export * from './Util';
|
||||
export * from './Types';
|
||||
export * from 'discord-api-types/v10';
|
||||
export * from './Collection';
|
||||
export * from './Logger';
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
export default defineConfig({
|
||||
clean: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
format: ['cjs', 'esm'],
|
||||
minify: isProduction,
|
||||
sourcemap: false
|
||||
});
|
@ -1,171 +0,0 @@
|
||||
# @biscuitland/core
|
||||
|
||||
## 3.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- new changes
|
||||
- new changes
|
||||
- Updated dependencies
|
||||
- Updated dependencies
|
||||
- @biscuitland/ws@3.0.12
|
||||
|
||||
## 3.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.8
|
||||
- @biscuitland/ws@3.0.8
|
||||
|
||||
## 3.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.7
|
||||
- @biscuitland/ws@3.0.7
|
||||
|
||||
## 3.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- I meessed up
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.6
|
||||
- @biscuitland/rest@3.0.6
|
||||
- @biscuitland/ws@3.0.6
|
||||
|
||||
## 3.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix: logger on every module
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.5
|
||||
- @biscuitland/rest@3.0.5
|
||||
- @biscuitland/ws@3.0.5
|
||||
|
||||
## 3.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- first 3.0.\* without bugs
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.4
|
||||
- @biscuitland/rest@3.0.4
|
||||
- @biscuitland/ws@3.0.4
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- fix TODO
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.3.0
|
||||
- @biscuitland/rest@2.3.0
|
||||
- @biscuitland/ws@2.3.0
|
||||
|
||||
## 2.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- bug fixes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.3
|
||||
- @biscuitland/rest@2.2.3
|
||||
- @biscuitland/ws@2.2.3
|
||||
|
||||
## 2.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- rename guildLocales to guildLocale in interactions
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.2
|
||||
- @biscuitland/rest@2.2.2
|
||||
- @biscuitland/ws@2.2.2
|
||||
|
||||
## 2.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- select menu options now can be empty since the latest Discord API update
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.1
|
||||
- @biscuitland/rest@2.2.1
|
||||
- @biscuitland/ws@2.2.1
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Functionality to delete ephemeral messages added, select menus were updated
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.0
|
||||
- @biscuitland/rest@2.2.0
|
||||
- @biscuitland/ws@2.2.0
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- minor changes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.2
|
||||
- @biscuitland/rest@2.1.2
|
||||
- @biscuitland/ws@2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- dumb hotfix that LH asked for (blame Yuzu)
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.1
|
||||
- @biscuitland/rest@2.1.1
|
||||
- @biscuitland/ws@2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Changes to cache and forum channels ✨
|
||||
- Forum channels and updates to @biscuitland/cache ✨
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.0
|
||||
- @biscuitland/rest@2.1.0
|
||||
- @biscuitland/ws@2.1.0
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Minor fixes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.0.6
|
||||
- @biscuitland/rest@2.0.6
|
||||
- @biscuitland/ws@2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Major Changes
|
||||
|
||||
- publish
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.0.5
|
||||
- @biscuitland/rest@2.0.5
|
||||
- @biscuitland/ws@2.0.5
|
@ -1,46 +0,0 @@
|
||||
# @biscuitland/core
|
||||
Core contains the essentials to launch you to develop your own customized and scalable bot.
|
||||
|
||||
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
|
||||
[<img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white">](https://discord.gg/XNw2RZFzaP)
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Install (for [node18](https://nodejs.org/en/download/))
|
||||
|
||||
```sh-session
|
||||
npm install @biscuitland/core
|
||||
yarn add @biscuitland/core
|
||||
```
|
||||
|
||||
### Example bot
|
||||
`project/index.js`:
|
||||
```ts
|
||||
import { Session } from '@biscuitland/core';
|
||||
import { GatewayIntentBits } from '@biscuitland/common';
|
||||
|
||||
const session = new Session({ token: 'your token', intents: GatewayIntentBits.Guilds });
|
||||
|
||||
session.on('READY', (payload, shardId) => {
|
||||
console.log('Logged in as: %s in shard #%s', payload.user.username, shardId);
|
||||
});
|
||||
|
||||
session.start();
|
||||
```
|
||||
|
||||
### Execute
|
||||
For node 18.+:
|
||||
```
|
||||
B:\project> node index.js
|
||||
```
|
||||
|
||||
For node 16.+:
|
||||
```
|
||||
B:\project> node --experimental-fetch index.js
|
||||
```
|
||||
|
||||
## Links
|
||||
* [Website](https://biscuitjs.com/)
|
||||
* [Documentation](https://docs.biscuitjs.com/)
|
||||
* [Discord](https://discord.gg/XNw2RZFzaP)
|
||||
* [rest](https://www.npmjs.com/package/@biscuitland/rest) | [ws](https://www.npmjs.com/package/@biscuitland/ws) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)
|
@ -1,78 +0,0 @@
|
||||
{
|
||||
"name": "@biscuitland/core",
|
||||
"version": "3.0.12",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"clean": "rm -rf dist && rm -rf .turbo",
|
||||
"dev": "tsup --watch"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@biscuitland/common": "^0.0.10",
|
||||
"@biscuitland/rest": "^3.0.7",
|
||||
"@biscuitland/ws": "^3.0.12",
|
||||
"eventemitter2": "^6.4.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"tsup": "^7.0.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": "Yuzuru <yuzuru@programmer.net>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Yuzuru",
|
||||
"url": "https://github.com/yuzudev"
|
||||
},
|
||||
{
|
||||
"name": "miia",
|
||||
"url": "https://github.com/dragurimu"
|
||||
},
|
||||
{
|
||||
"name": "n128",
|
||||
"url": "https://github.com/nicolito128"
|
||||
},
|
||||
{
|
||||
"name": "socram03",
|
||||
"url": "https://github.com/socram03",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Drylozu",
|
||||
"url": "https://github.com/Drylozu"
|
||||
}
|
||||
],
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/oasisjs/biscuit.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/oasisjs/biscuit"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
"discord",
|
||||
"bots",
|
||||
"typescript",
|
||||
"botdev"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import type { GatewayEvents } from '@biscuitland/ws';
|
||||
import type { Session } from '../index';
|
||||
|
||||
export function actionHandler([session, payload, shardId]: Parameters<ActionHandler>) {
|
||||
// @ts-expect-error At this point, typescript sucks
|
||||
session.emit(payload.t, payload.d, shardId);
|
||||
// @ts-expect-error At this point, typescript sucks
|
||||
session.emit('RAW', payload.d, shardId);
|
||||
}
|
||||
|
||||
export type ActionHandler<G extends keyof GatewayEvents = keyof GatewayEvents,> = (
|
||||
...args: [Session<true>, { t: G; d: GatewayEvents[G] }, number]
|
||||
) => unknown;
|
||||
|
||||
export type Handler = {
|
||||
[K in keyof GatewayEvents]: (...args: [GatewayEvents[K], number]) => unknown;
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
export * from './utils/types';
|
||||
export * from './utils/utils';
|
||||
export * from './session';
|
||||
export { Session as Biscuit } from './session';
|
||||
export * from './managers/MainManager';
|
||||
export * from './events/handler';
|
@ -1,121 +0,0 @@
|
||||
import {
|
||||
APIApplicationCommand,
|
||||
Identify,
|
||||
MakeRequired,
|
||||
RESTGetAPIApplicationCommandsQuery,
|
||||
RESTGetAPIApplicationGuildCommandsQuery,
|
||||
RESTPatchAPIApplicationCommandJSONBody,
|
||||
RESTPatchAPIApplicationGuildCommandJSONBody,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
RESTPostAPIApplicationGuildCommandsJSONBody,
|
||||
RESTPutAPIApplicationCommandPermissionsJSONBody,
|
||||
RESTPutAPIApplicationCommandsJSONBody,
|
||||
RESTPutAPIApplicationGuildCommandsJSONBody,
|
||||
RESTPutAPIApplicationRoleConnectionMetadataJSONBody
|
||||
} from '@biscuitland/common';
|
||||
import { Session } from '..';
|
||||
|
||||
export class ApplicationManager {
|
||||
readonly session!: Session;
|
||||
constructor(session: Session) {
|
||||
Object.defineProperty(this, 'session', {
|
||||
value: session,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
|
||||
getBotGateway() {
|
||||
return this.session.api.gateway.bot.get();
|
||||
}
|
||||
|
||||
getGateway() {
|
||||
return this.session.api.gateway.get();
|
||||
}
|
||||
|
||||
getNitroStickerPacks() {
|
||||
return this.session.api['sticker-packs'].get();
|
||||
}
|
||||
|
||||
getRoleConnectionMetadata(applicationId: string) {
|
||||
return this.session.api.applications(applicationId)['role-connections'].metadata.get();
|
||||
}
|
||||
|
||||
editRoleConnectionMetadata(applicationId: string, body: RESTPutAPIApplicationRoleConnectionMetadataJSONBody) {
|
||||
return this.session.api.applications(applicationId)['role-connections'].metadata.put({ body });
|
||||
}
|
||||
|
||||
getCommands(
|
||||
applicationId: string,
|
||||
query: RESTGetAPIApplicationCommandsQuery
|
||||
): Promise<RESTGetAPIApplicationCommandsWithLocalizationsResult>;
|
||||
getCommands(applicationId: string, query?: RESTGetAPIApplicationCommandsQuery) {
|
||||
return this.session.api.applications(applicationId).commands.get({ query });
|
||||
}
|
||||
|
||||
createCommand(applicationId: string, body: RESTPostAPIApplicationCommandsJSONBody) {
|
||||
return this.session.api.applications(applicationId).commands.post({ body });
|
||||
}
|
||||
|
||||
getCommand(applicationId: string, commandId: string) {
|
||||
return this.session.api.applications(applicationId).commands(commandId).get();
|
||||
}
|
||||
|
||||
editCommand(applicationId: string, commandId: string, body: RESTPatchAPIApplicationCommandJSONBody) {
|
||||
return this.session.api.applications(applicationId).commands(commandId).patch({ body });
|
||||
}
|
||||
|
||||
deleteCommand(applicationId: string, commandId: string) {
|
||||
return this.session.api.applications(applicationId).commands(commandId).delete();
|
||||
}
|
||||
|
||||
bulkCommands(applicationId: string, body: RESTPutAPIApplicationCommandsJSONBody) {
|
||||
return this.session.api.applications(applicationId).commands.put({ body });
|
||||
}
|
||||
|
||||
getCommandPermissions(applicationId: string, guildId: string, commandId: string) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands(commandId).permissions.get();
|
||||
}
|
||||
|
||||
editCommandPermissions(applicationId: string, guildId: string, commandId: string, body: RESTPutAPIApplicationCommandPermissionsJSONBody) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands(commandId).permissions.put({ body });
|
||||
}
|
||||
|
||||
getGuildCommands(
|
||||
applicationId: string,
|
||||
guildId: string,
|
||||
query: RESTGetAPIApplicationGuildCommandsQuery
|
||||
): Promise<RESTGetAPIApplicationGuildCommandsWithLocalizationsResult>;
|
||||
getGuildCommands(applicationId: string, guildId: string, query?: RESTGetAPIApplicationGuildCommandsQuery) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands.get({ query });
|
||||
}
|
||||
|
||||
createGuildCommand(applicationId: string, guildId: string, body: RESTPostAPIApplicationGuildCommandsJSONBody) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands.post({ body });
|
||||
}
|
||||
|
||||
getGuildCommand(applicationId: string, guildId: string, commandId: string) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands(commandId).get();
|
||||
}
|
||||
|
||||
editGuildCommand(applicationId: string, guildId: string, commandId: string, body: RESTPatchAPIApplicationGuildCommandJSONBody) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands(commandId).patch({ body });
|
||||
}
|
||||
|
||||
deleteGuildCommand(applicationId: string, guildId: string, commandId: string) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands(commandId).delete();
|
||||
}
|
||||
|
||||
bulkGuildCommands(applicationId: string, guildId: string, body: RESTPutAPIApplicationGuildCommandsJSONBody) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands.put({ body });
|
||||
}
|
||||
|
||||
getGuildCommandPermissions(applicationId: string, guildId: string) {
|
||||
return this.session.api.applications(applicationId).guilds(guildId).commands.permissions.get();
|
||||
}
|
||||
}
|
||||
|
||||
export type RESTGetAPIApplicationCommandsWithLocalizationsResult = Identify<
|
||||
MakeRequired<APIApplicationCommand, 'name_localizations' | 'description_localizations'>
|
||||
>[];
|
||||
|
||||
export type RESTGetAPIApplicationGuildCommandsWithLocalizationsResult = RESTGetAPIApplicationCommandsWithLocalizationsResult;
|
@ -1,214 +0,0 @@
|
||||
import type {
|
||||
APIChannel,
|
||||
RESTGetAPIChannelMessageReactionUsersQuery,
|
||||
RESTGetAPIChannelThreadMemberQuery,
|
||||
RESTGetAPIChannelThreadMembersQuery,
|
||||
RESTGetAPIChannelThreadsArchivedQuery,
|
||||
RESTPatchAPIChannelJSONBody,
|
||||
RESTPatchAPIChannelMessageJSONBody,
|
||||
RESTPatchAPIStageInstanceJSONBody,
|
||||
RESTPostAPIChannelFollowersJSONBody,
|
||||
RESTPostAPIChannelInviteJSONBody,
|
||||
RESTPostAPIChannelMessageJSONBody,
|
||||
RESTPostAPIChannelMessagesBulkDeleteJSONBody,
|
||||
RESTPostAPIChannelMessagesThreadsJSONBody,
|
||||
RESTPostAPIChannelThreadsJSONBody,
|
||||
RESTPostAPIChannelThreadsResult,
|
||||
RESTPostAPIChannelWebhookJSONBody,
|
||||
RESTPostAPIGuildForumThreadsJSONBody,
|
||||
RESTPutAPIChannelPermissionJSONBody,
|
||||
RESTPutAPIChannelRecipientJSONBody
|
||||
} from '@biscuitland/common';
|
||||
import type { RawFile } from '@biscuitland/rest';
|
||||
|
||||
import type { Session } from '../session';
|
||||
|
||||
export class ChannelManager {
|
||||
readonly session!: Session;
|
||||
constructor(session: Session) {
|
||||
Object.defineProperty(this, 'session', {
|
||||
value: session,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
|
||||
get<T extends APIChannel = APIChannel>(id: string) {
|
||||
return this.session.api.channels(id).get() as Promise<T>;
|
||||
}
|
||||
|
||||
getWebhooks(channelId: string) {
|
||||
return this.session.api.channels(channelId).webhooks.get();
|
||||
}
|
||||
|
||||
createWebhook(channelId: string, body: RESTPostAPIChannelWebhookJSONBody) {
|
||||
return this.session.api.channels(channelId).webhooks.post({ body });
|
||||
}
|
||||
|
||||
edit(id: string, data: RESTPatchAPIChannelJSONBody) {
|
||||
return this.session.api.channels(id).patch({ body: data });
|
||||
}
|
||||
|
||||
delete(id: string) {
|
||||
return this.session.api.channels(id).delete();
|
||||
}
|
||||
|
||||
getMessages(id: string, limit = 50) {
|
||||
return this.session.api.channels(id).messages.get({
|
||||
query: { limit }
|
||||
});
|
||||
}
|
||||
|
||||
getMessage(id: string, messageId: string) {
|
||||
return this.session.api.channels(id).messages(messageId).get();
|
||||
}
|
||||
|
||||
createMessage(id: string, data: RESTPostAPIChannelMessageJSONBody) {
|
||||
return this.session.api.channels(id).messages.post({ body: data });
|
||||
}
|
||||
|
||||
sendTyping(id: string) {
|
||||
return this.session.api.channels(id).typing.post();
|
||||
}
|
||||
|
||||
getArchivedThreads(channelId: string, options: RESTGetAPIChannelThreadsArchivedOptions) {
|
||||
const { type, ...query } = options;
|
||||
if (type === 'private') {
|
||||
return this.session.api.channels(channelId).threads.archived.private.get({ query });
|
||||
}
|
||||
|
||||
return this.session.api.channels(channelId).threads.archived.public.get({ query });
|
||||
}
|
||||
|
||||
crosspostMessage(channelId: string, messageId: string) {
|
||||
return this.session.api.channels(channelId).messages(messageId).crosspost.post({});
|
||||
}
|
||||
|
||||
createReaction(channelId: string, messageId: string, emoji: string) {
|
||||
return this.session.api.channels(channelId).messages(messageId).reactions(emoji)('@me').put({});
|
||||
}
|
||||
|
||||
deleteReaction(channelId: string, messageId: string, emoji: string, user = '@me') {
|
||||
return this.session.api.channels(channelId).messages(messageId).reactions(emoji)(user).delete();
|
||||
}
|
||||
|
||||
getReactions(channelId: string, messageId: string, emoji: string, query?: RESTGetAPIChannelMessageReactionUsersQuery) {
|
||||
return this.session.api.channels(channelId).messages(messageId).reactions(emoji).get({ query });
|
||||
}
|
||||
|
||||
deleteAllReactions(channelId: string, messageId: string, emoji?: string) {
|
||||
if (emoji?.length) return this.session.api.channels(channelId).messages(messageId).reactions(emoji).delete();
|
||||
return this.session.api.channels(channelId).messages(messageId).reactions.delete();
|
||||
}
|
||||
|
||||
editMessage(channelId: string, messageId: string, body: RESTPatchAPIChannelMessageJSONBody, files?: RawFile[]) {
|
||||
return this.session.api.channels(channelId).messages(messageId).patch({
|
||||
body,
|
||||
files
|
||||
});
|
||||
}
|
||||
|
||||
deleteMessage(channelId: string, messageId: string, reason?: string) {
|
||||
return this.session.api.channels(channelId).messages(messageId).delete({ reason });
|
||||
}
|
||||
|
||||
bulkMessages(channelId: string, body: RESTPostAPIChannelMessagesBulkDeleteJSONBody, reason?: string) {
|
||||
return this.session.api.channels(channelId).messages['bulk-delete'].post({ body, reason });
|
||||
}
|
||||
|
||||
editPermissions(channelId: string, overwriteId: string, body: RESTPutAPIChannelPermissionJSONBody, reason?: string) {
|
||||
return this.session.api.channels(channelId).permissions(overwriteId).put({ body, reason });
|
||||
}
|
||||
|
||||
deletePermission(channelId: string, overwriteId: string, reason?: string) {
|
||||
return this.session.api.channels(channelId).permissions(overwriteId).delete({ reason });
|
||||
}
|
||||
|
||||
getInvites(channelId: string) {
|
||||
return this.session.api.channels(channelId).invites.get();
|
||||
}
|
||||
|
||||
createInvite(channelId: string, body: RESTPostAPIChannelInviteJSONBody) {
|
||||
return this.session.api.channels(channelId).invites.post({ body });
|
||||
}
|
||||
|
||||
followAnnoucement(channelId: string, body: RESTPostAPIChannelFollowersJSONBody) {
|
||||
return this.session.api.channels(channelId).followers.post({ body });
|
||||
}
|
||||
|
||||
getPinnedMessages(channelId: string) {
|
||||
return this.session.api.channels(channelId).pins.get();
|
||||
}
|
||||
|
||||
pinMessage(channelId: string, messageId: string, reason?: string) {
|
||||
return this.session.api.channels(channelId).pins(messageId).put({ reason });
|
||||
}
|
||||
|
||||
unpinMessage(channelId: string, messageId: string, reason?: string) {
|
||||
return this.session.api.channels(channelId).pins(messageId).delete({ reason });
|
||||
}
|
||||
|
||||
groupDMAddRecipient(channelId: string, userId: string, body: RESTPutAPIChannelRecipientJSONBody) {
|
||||
return this.session.api.channels(channelId).recipients(userId).put({ body });
|
||||
}
|
||||
|
||||
groupDMRemoveRecipient(channelId: string, userId: string) {
|
||||
return this.session.api.channels(channelId).recipients(userId).delete();
|
||||
}
|
||||
|
||||
startThreadFromMessage(channelId: string, messageId: string, body: RESTPostAPIChannelMessagesThreadsJSONBody, reason?: string) {
|
||||
return this.session.api.channels(channelId).messages(messageId).threads.post({ body, reason });
|
||||
}
|
||||
|
||||
startThread(channelId: string, body: RESTPostAPIChannelThreadsJSONBody, reason?: string): Promise<RESTPostAPIChannelThreadsResult>;
|
||||
startThread(channelId: string, body: RESTPostAPIGuildForumThreadsJSONBody, reason?: string) {
|
||||
return this.session.api.channels(channelId).threads.post({ body, reason });
|
||||
}
|
||||
|
||||
getListJoinedPrivateArchivedThreads(channelId: string, query?: RESTGetAPIChannelThreadsArchivedQuery) {
|
||||
return this.session.api.channels(channelId).users('@me').threads.archived.private.get({ query });
|
||||
}
|
||||
|
||||
getThreadMembers(channelId: string, query?: RESTGetAPIChannelThreadMembersQuery) {
|
||||
return this.session.api.channels(channelId)['thread-members'].get({ query });
|
||||
}
|
||||
|
||||
getThreadMember(channelId: string, userId: string, query?: RESTGetAPIChannelThreadMemberQuery) {
|
||||
return this.session.api.channels(channelId)['thread-members'](userId).get({ query });
|
||||
}
|
||||
|
||||
addThreadMember(channelId: string, userId: string) {
|
||||
return this.session.api.channels(channelId)['thread-members'](userId).put({});
|
||||
}
|
||||
|
||||
removeThreadMember(channelId: string, userId: string) {
|
||||
return this.session.api.channels(channelId)['thread-members'](userId).delete();
|
||||
}
|
||||
|
||||
leaveThread(channelId: string) {
|
||||
return this.session.api.channels(channelId)['thread-members']('@me').delete();
|
||||
}
|
||||
|
||||
joinThread(channelId: string) {
|
||||
return this.session.api.channels(channelId)['thread-members']('@me').put({});
|
||||
}
|
||||
|
||||
getVoiceRegions() {
|
||||
return this.session.api.voice.region.get();
|
||||
}
|
||||
|
||||
getStageInstance(channelId: string) {
|
||||
return this.session.api['stage-instances'](channelId).get();
|
||||
}
|
||||
|
||||
editStageInstance(channelId: string, body: RESTPatchAPIStageInstanceJSONBody, reason?: string) {
|
||||
return this.session.api['stage-instances'](channelId).patch({ body, reason });
|
||||
}
|
||||
|
||||
deleteStageInstance(channelId: string, reason?: string) {
|
||||
return this.session.api['stage-instances'](channelId).delete({ reason });
|
||||
}
|
||||
}
|
||||
|
||||
export type RESTGetAPIChannelThreadsArchivedOptions = {
|
||||
type: 'private' | 'public';
|
||||
} & RESTGetAPIChannelThreadsArchivedQuery;
|
@ -1,348 +0,0 @@
|
||||
import type {
|
||||
APIGuildChannel,
|
||||
GuildChannelType,
|
||||
GuildMFALevel,
|
||||
RESTGetAPIAuditLogQuery,
|
||||
RESTGetAPIGuildBansQuery,
|
||||
RESTGetAPIGuildMembersQuery,
|
||||
RESTGetAPIGuildMembersSearchQuery,
|
||||
RESTGetAPIGuildPruneCountQuery,
|
||||
RESTGetAPIGuildScheduledEventQuery,
|
||||
RESTGetAPIGuildScheduledEventUsersQuery,
|
||||
RESTGetAPIGuildScheduledEventsQuery,
|
||||
RESTGetAPIGuildWidgetImageQuery,
|
||||
RESTPatchAPIAutoModerationRuleJSONBody,
|
||||
RESTPatchAPICurrentGuildMemberJSONBody,
|
||||
RESTPatchAPIGuildChannelPositionsJSONBody,
|
||||
RESTPatchAPIGuildEmojiJSONBody,
|
||||
RESTPatchAPIGuildJSONBody,
|
||||
RESTPatchAPIGuildMemberJSONBody,
|
||||
RESTPatchAPIGuildRoleJSONBody,
|
||||
RESTPatchAPIGuildRolePositionsJSONBody,
|
||||
RESTPatchAPIGuildScheduledEventJSONBody,
|
||||
RESTPatchAPIGuildStickerJSONBody,
|
||||
RESTPatchAPIGuildTemplateJSONBody,
|
||||
RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody,
|
||||
RESTPatchAPIGuildVoiceStateUserJSONBody,
|
||||
RESTPatchAPIGuildWelcomeScreenJSONBody,
|
||||
RESTPatchAPIGuildWidgetSettingsJSONBody,
|
||||
RESTPostAPIAutoModerationRuleJSONBody,
|
||||
RESTPostAPIGuildChannelJSONBody,
|
||||
RESTPostAPIGuildEmojiJSONBody,
|
||||
RESTPostAPIGuildPruneJSONBody,
|
||||
RESTPostAPIGuildRoleJSONBody,
|
||||
RESTPostAPIGuildScheduledEventJSONBody,
|
||||
RESTPostAPIGuildStickerFormDataBody,
|
||||
RESTPostAPIGuildTemplatesJSONBody,
|
||||
RESTPostAPIGuildsJSONBody,
|
||||
RESTPostAPITemplateCreateGuildJSONBody,
|
||||
RESTPutAPIGuildBanJSONBody,
|
||||
RESTPutAPIGuildMemberJSONBody
|
||||
} from '@biscuitland/common';
|
||||
import type { Session } from '../session';
|
||||
|
||||
export class GuildManager {
|
||||
readonly session!: Session;
|
||||
constructor(session: Session) {
|
||||
Object.defineProperty(this, 'session', {
|
||||
value: session,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
|
||||
get(guildId: string) {
|
||||
return this.session.api.guilds(guildId).get();
|
||||
}
|
||||
|
||||
create(options: RESTPostAPIGuildsJSONBody) {
|
||||
return this.session.api.guilds.post({ body: options });
|
||||
}
|
||||
|
||||
delete(guildId: string) {
|
||||
return this.session.api.guilds(guildId).delete();
|
||||
}
|
||||
|
||||
edit(guildId: string, options: RESTPatchAPIGuildJSONBody) {
|
||||
return this.session.api.guilds(guildId).patch({ body: options });
|
||||
}
|
||||
|
||||
getChannels(guildId: string) {
|
||||
return this.session.api.guilds(guildId).channels.get();
|
||||
}
|
||||
|
||||
createChannel<T extends APIGuildChannel<GuildChannelType>>(guildId: string, body: RESTPostAPIGuildChannelJSONBody) {
|
||||
return this.session.api.guilds(guildId).channels.post({ body }) as Promise<T>;
|
||||
}
|
||||
|
||||
editChannelPositions(guildId: string, body: RESTPatchAPIGuildChannelPositionsJSONBody): Promise<void> {
|
||||
return this.session.api.guilds(guildId).channels.patch({ body });
|
||||
}
|
||||
|
||||
getThreads(guildId: string) {
|
||||
return this.session.api.guilds(guildId).threads.active.get();
|
||||
}
|
||||
|
||||
getBans(guildId: string, query: RESTGetAPIGuildBansQuery = {}) {
|
||||
return this.session.api.guilds(guildId).bans.get({
|
||||
query
|
||||
});
|
||||
}
|
||||
|
||||
getBan(guildId: string, userId: string) {
|
||||
return this.session.api.guilds(guildId).bans(userId).get();
|
||||
}
|
||||
|
||||
createBan(guildId: string, userId: string, body: RESTPutAPIGuildBanJSONBody) {
|
||||
return this.session.api.guilds(guildId).bans(userId).put({ body });
|
||||
}
|
||||
|
||||
removeBan(guildId: string, userId: string) {
|
||||
return this.session.api.guilds(guildId).bans(userId).delete();
|
||||
}
|
||||
|
||||
getRoles(guildId: string) {
|
||||
return this.session.api.guilds(guildId).roles.get();
|
||||
}
|
||||
|
||||
createRole(guildId: string, options: RESTPostAPIGuildRoleJSONBody) {
|
||||
return this.session.api.guilds(guildId).roles.post({ body: options });
|
||||
}
|
||||
|
||||
editRolePositions(guildId: string, options: RESTPatchAPIGuildRolePositionsJSONBody) {
|
||||
return this.session.api.guilds(guildId).roles.patch({ body: options });
|
||||
}
|
||||
|
||||
editRole(guildId: string, roleId: string, options: RESTPatchAPIGuildRoleJSONBody) {
|
||||
return this.session.api.guilds(guildId).roles(roleId).patch({ body: options });
|
||||
}
|
||||
|
||||
deleteRole(guildId: string, roleId: string) {
|
||||
return this.session.api.guilds(guildId).roles(roleId).delete();
|
||||
}
|
||||
|
||||
editGuildMFALevel(guildId: string, level: GuildMFALevel) {
|
||||
return this.session.api.guilds(guildId).mfa.post({ body: { level } });
|
||||
}
|
||||
|
||||
getPruneCount(guildId: string, query: RESTGetAPIGuildPruneCountQuery) {
|
||||
return this.session.api.guilds(guildId).prune.get({
|
||||
query
|
||||
});
|
||||
}
|
||||
|
||||
beginGuildPrune(guildId: string, options: RESTPostAPIGuildPruneJSONBody) {
|
||||
return this.session.api.guilds(guildId).prune.post({ body: options });
|
||||
}
|
||||
|
||||
getVoiceRegions(guildId: string) {
|
||||
return this.session.api.guilds(guildId).regions.get();
|
||||
}
|
||||
|
||||
getInvites(guildId: string) {
|
||||
return this.session.api.guilds(guildId).invites.get();
|
||||
}
|
||||
|
||||
getIntegrations(guildId: string) {
|
||||
return this.session.api.guilds(guildId).integrations.get();
|
||||
}
|
||||
|
||||
deleteIntegration(guildId: string, integrationId: string) {
|
||||
return this.session.api.guilds(guildId).integrations(integrationId).delete();
|
||||
}
|
||||
|
||||
getWidget(guildId: string) {
|
||||
return this.session.api.guilds(guildId).widget.get();
|
||||
}
|
||||
|
||||
editWidget(guildId: string, options: RESTPatchAPIGuildWidgetSettingsJSONBody) {
|
||||
return this.session.api.guilds(guildId).widget.patch({ body: options });
|
||||
}
|
||||
|
||||
getVanityUrl(guildId: string) {
|
||||
return this.session.api.guilds(guildId)['vanity-url'].get();
|
||||
}
|
||||
|
||||
getWelcomeScreen(guildId: string) {
|
||||
return this.session.api.guilds(guildId)['welcome-screen'].get();
|
||||
}
|
||||
|
||||
editWelcomeScreen(guildId: string, options: RESTPatchAPIGuildWelcomeScreenJSONBody) {
|
||||
return this.session.api.guilds(guildId)['welcome-screen'].patch({ body: options });
|
||||
}
|
||||
|
||||
getAuditLog(guildId: string, query?: RESTGetAPIAuditLogQuery) {
|
||||
return this.session.api.guilds(guildId)['audit-logs'].get({ query });
|
||||
}
|
||||
|
||||
getAutoModerationRules(guildId: string) {
|
||||
return this.session.api.guilds(guildId)['auto-moderation'].rules.get();
|
||||
}
|
||||
|
||||
getAutoModerationRule(guildId: string, ruleId: string) {
|
||||
return this.session.api.guilds(guildId)['auto-moderation'].rules(ruleId).get();
|
||||
}
|
||||
|
||||
createAutoModerationRule(guildId: string, body: RESTPostAPIAutoModerationRuleJSONBody, reason?: string) {
|
||||
return this.session.api.guilds(guildId)['auto-moderation'].rules.post({ body, reason });
|
||||
}
|
||||
|
||||
editAutoModerationRule(guildId: string, ruleId: string, body: RESTPatchAPIAutoModerationRuleJSONBody, reason?: string) {
|
||||
return this.session.api.guilds(guildId)['auto-moderation'].rules(ruleId).patch({ body, reason });
|
||||
}
|
||||
|
||||
deleteAutoModerationRule(guildId: string, ruleId: string, reason?: string) {
|
||||
return this.session.api.guilds(guildId)['auto-moderation'].rules(ruleId).delete({ reason });
|
||||
}
|
||||
|
||||
getTemplate(code: string) {
|
||||
return this.session.api.guilds.templates(code).get();
|
||||
}
|
||||
|
||||
createTemplate(code: string, body: RESTPostAPITemplateCreateGuildJSONBody) {
|
||||
return this.session.api.guilds.templates(code).post({ body });
|
||||
}
|
||||
|
||||
getWebhooks(guildId: string) {
|
||||
return this.session.api.guilds(guildId).webhooks.get();
|
||||
}
|
||||
|
||||
getPreview(guildId: string) {
|
||||
return this.session.api.guilds(guildId).preview.get();
|
||||
}
|
||||
|
||||
getMembers(guildId: string, query?: RESTGetAPIGuildMembersQuery) {
|
||||
return this.session.api.guilds(guildId).members.get({ query });
|
||||
}
|
||||
|
||||
searchMembers(guildId: string, query?: RESTGetAPIGuildMembersSearchQuery) {
|
||||
return this.session.api.guilds(guildId).members.search.get({ query });
|
||||
}
|
||||
|
||||
editCurrentMember(guildId: string, body: RESTPatchAPICurrentGuildMemberJSONBody) {
|
||||
return this.session.api.guilds(guildId).members['@me'].patch({ body });
|
||||
}
|
||||
|
||||
getMember(guildId: string, memberId: string) {
|
||||
return this.session.api.guilds(guildId).members(memberId).get();
|
||||
}
|
||||
|
||||
addMember(guildId: string, memberId: string, body: RESTPutAPIGuildMemberJSONBody) {
|
||||
return this.session.api.guilds(guildId).members(memberId).put({ body });
|
||||
}
|
||||
|
||||
editMember(guildId: string, memberId: string, body: RESTPatchAPIGuildMemberJSONBody) {
|
||||
return this.session.api.guilds(guildId).members(memberId).patch({ body });
|
||||
}
|
||||
|
||||
removeMember(guildId: string, memberId: string) {
|
||||
return this.session.api.guilds(guildId).members(memberId).delete();
|
||||
}
|
||||
|
||||
addRoleMember(guildId: string, memberId: string, roleId: string) {
|
||||
return this.session.api.guilds(guildId).members(memberId).roles(roleId).put({});
|
||||
}
|
||||
|
||||
removeRoleMember(guildId: string, memberId: string, roleId: string) {
|
||||
return this.session.api.guilds(guildId).members(memberId).roles(roleId).delete({});
|
||||
}
|
||||
|
||||
getWidgetJson(guildId: string) {
|
||||
return this.session.api.guilds(guildId)['widget.json'].get();
|
||||
}
|
||||
|
||||
getWidgetPng(guildId: string, query?: RESTGetAPIGuildWidgetImageQuery) {
|
||||
return this.session.api.guilds(guildId)['widget.png'].get({ query });
|
||||
}
|
||||
|
||||
getEmojis(guildId: string) {
|
||||
return this.session.api.guilds(guildId).emojis.get();
|
||||
}
|
||||
|
||||
createEmoji(guildId: string, body: RESTPostAPIGuildEmojiJSONBody) {
|
||||
return this.session.api.guilds(guildId).emojis.post({ body });
|
||||
}
|
||||
|
||||
getEmoji(guildId: string, emojiId: string) {
|
||||
return this.session.api.guilds(guildId).emojis(emojiId).get();
|
||||
}
|
||||
|
||||
editEmoji(guildId: string, emojiId: string, body: RESTPatchAPIGuildEmojiJSONBody) {
|
||||
return this.session.api.guilds(guildId).emojis(emojiId).patch({ body });
|
||||
}
|
||||
|
||||
deleteEmoji(guildId: string, emojiId: string) {
|
||||
return this.session.api.guilds(guildId).emojis(emojiId).delete();
|
||||
}
|
||||
|
||||
editCurrentVoiceState(guildId: string, body: RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody) {
|
||||
return this.session.api.guilds(guildId)['voice-states']['@me'].patch({ body });
|
||||
}
|
||||
|
||||
editMemberVoiceState(guildId: string, memberId: string, body: RESTPatchAPIGuildVoiceStateUserJSONBody) {
|
||||
return this.session.api.guilds(guildId)['voice-states'](memberId).patch({ body });
|
||||
}
|
||||
|
||||
getStickers(guildId: string) {
|
||||
return this.session.api.guilds(guildId).stickers.get();
|
||||
}
|
||||
|
||||
createSticker(guildId: string, body: RESTPostAPIGuildStickerFormDataBody) {
|
||||
return this.session.api.guilds(guildId).stickers.post({ body });
|
||||
}
|
||||
|
||||
getSticker(guildId: string, stickerId: string) {
|
||||
return this.session.api.guilds(guildId).stickers(stickerId).get();
|
||||
}
|
||||
|
||||
editSticker(guildId: string, stickerId: string, body: RESTPatchAPIGuildStickerJSONBody) {
|
||||
return this.session.api.guilds(guildId).stickers(stickerId).patch({ body });
|
||||
}
|
||||
|
||||
deleteSticker(guildId: string, stickerId: string) {
|
||||
return this.session.api.guilds(guildId).stickers(stickerId).delete();
|
||||
}
|
||||
|
||||
getScheduledEvents(guildId: string, query?: RESTGetAPIGuildScheduledEventsQuery) {
|
||||
return this.session.api.guilds(guildId)['scheduled-events'].get({ query });
|
||||
}
|
||||
|
||||
createScheduledEvent(guildId: string, body: RESTPostAPIGuildScheduledEventJSONBody) {
|
||||
return this.session.api.guilds(guildId)['scheduled-events'].post({ body });
|
||||
}
|
||||
|
||||
getScheduledEvent(guildId: string, scheduledEvent: string, query?: RESTGetAPIGuildScheduledEventQuery) {
|
||||
return this.session.api.guilds(guildId)['scheduled-events'](scheduledEvent).get({ query });
|
||||
}
|
||||
|
||||
editScheduledEvent(guildId: string, scheduledEvent: string, body: RESTPatchAPIGuildScheduledEventJSONBody) {
|
||||
return this.session.api.guilds(guildId)['scheduled-events'](scheduledEvent).patch({ body });
|
||||
}
|
||||
|
||||
deleteScheduledEvent(guildId: string, scheduledEvent: string) {
|
||||
return this.session.api.guilds(guildId)['scheduled-events'](scheduledEvent).delete();
|
||||
}
|
||||
|
||||
getUsersScheduledEvent(guildId: string, scheduledEvent: string, query: RESTGetAPIGuildScheduledEventUsersQuery) {
|
||||
return this.session.api.guilds(guildId)['scheduled-events'](scheduledEvent).users.get({ query });
|
||||
}
|
||||
|
||||
getGuildTemplates(guildId: string) {
|
||||
return this.session.api.guilds(guildId).templates.get();
|
||||
}
|
||||
|
||||
createGuildTemplate(guildId: string, body: RESTPostAPIGuildTemplatesJSONBody) {
|
||||
return this.session.api.guilds(guildId).templates.post({ body });
|
||||
}
|
||||
|
||||
syncGuildTemplate(guildId: string, code: string) {
|
||||
return this.session.api.guilds(guildId).templates(code).put({});
|
||||
}
|
||||
|
||||
modifyGuildTemaplte(guildId: string, code: string, body: RESTPatchAPIGuildTemplateJSONBody) {
|
||||
return this.session.api.guilds(guildId).templates(code).patch({ body });
|
||||
}
|
||||
|
||||
deleteCodeTemplate(guildId: string, code: string) {
|
||||
return this.session.api.guilds(guildId).templates(code).delete();
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
import type {
|
||||
RESTPatchAPIWebhookWithTokenMessageJSONBody,
|
||||
RESTPostAPIInteractionCallbackJSONBody,
|
||||
RESTPostAPIInteractionFollowupJSONBody
|
||||
} from '@biscuitland/common';
|
||||
import type { RawFile } from '@biscuitland/rest';
|
||||
import type { Session } from '..';
|
||||
|
||||
export class InteractionManager {
|
||||
readonly session!: Session;
|
||||
constructor(session: Session) {
|
||||
Object.defineProperty(this, 'session', {
|
||||
value: session,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
|
||||
reply<T extends RESTPostAPIInteractionCallbackJSONBody = RESTPostAPIInteractionCallbackJSONBody>(
|
||||
interactionId: string,
|
||||
token: string,
|
||||
body: T,
|
||||
files?: RawFile[]
|
||||
) {
|
||||
return this.session.api.interactions(interactionId)(token).callback.post({
|
||||
body,
|
||||
files
|
||||
});
|
||||
}
|
||||
|
||||
getResponse(applicationId: string, token: string, messageId = '@original') {
|
||||
return this.session.api.webhooks(applicationId)(token).messages(messageId).get();
|
||||
}
|
||||
|
||||
editResponse(
|
||||
applicationId: string,
|
||||
token: string,
|
||||
messageId: string,
|
||||
body: RESTPatchAPIWebhookWithTokenMessageJSONBody,
|
||||
files?: RawFile[]
|
||||
) {
|
||||
return this.session.api.webhooks(applicationId)(token).messages(messageId).patch({
|
||||
body,
|
||||
files
|
||||
});
|
||||
}
|
||||
|
||||
deleteResponse(applicationId: string, token: string, messageId = '@original') {
|
||||
return this.session.api.webhooks(applicationId)(token).messages(messageId).delete();
|
||||
}
|
||||
|
||||
followUp(applicationId: string, token: string, body: RESTPostAPIInteractionFollowupJSONBody, files?: RawFile[]) {
|
||||
return this.session.api.webhooks(applicationId)(token).post({
|
||||
body,
|
||||
files
|
||||
});
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import type { Session } from '../session';
|
||||
import { ApplicationManager } from './ApplicationManager';
|
||||
import { ChannelManager } from './ChannelManager';
|
||||
import { GuildManager } from './GuildManager';
|
||||
import { InteractionManager } from './InteractionManager';
|
||||
import { MemberManager } from './MemberManager';
|
||||
import { UserManager } from './UserManager';
|
||||
import { WebhookManager } from './WebhookManager';
|
||||
|
||||
export class MainManager {
|
||||
constructor(private readonly session: Session) {
|
||||
this.users = new UserManager(this.session);
|
||||
this.guilds = new GuildManager(this.session);
|
||||
this.members = new MemberManager(this.session);
|
||||
this.channels = new ChannelManager(this.session);
|
||||
this.applications = new ApplicationManager(this.session);
|
||||
this.interactions = new InteractionManager(this.session);
|
||||
this.webhooks = new WebhookManager(this.session);
|
||||
}
|
||||
|
||||
users: UserManager;
|
||||
guilds: GuildManager;
|
||||
members: MemberManager;
|
||||
channels: ChannelManager;
|
||||
applications: ApplicationManager;
|
||||
interactions: InteractionManager;
|
||||
webhooks: WebhookManager;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import type { APIGuildMember, MakeRequired } from '@biscuitland/common';
|
||||
import type { ImageOptions, Session } from '../index';
|
||||
import { formatImageURL } from '../index';
|
||||
|
||||
export class MemberManager {
|
||||
constructor(private readonly session: Session) {}
|
||||
|
||||
dynamicAvatarURL({ avatar, guild_id, user }: DynamicMember, { size, format }: ImageOptions = {}): string {
|
||||
if (avatar?.length) {
|
||||
return formatImageURL(this.session.cdn.guilds(guild_id).users(user.id).avatars(avatar).get(), size, format);
|
||||
}
|
||||
|
||||
return this.session.managers.users.avatarURL(user, { size, format });
|
||||
}
|
||||
}
|
||||
|
||||
export type DynamicMember = MakeRequired<APIGuildMember, 'user'> & {
|
||||
guild_id: string;
|
||||
};
|
@ -1,64 +0,0 @@
|
||||
import type {
|
||||
APIUser,
|
||||
RESTGetAPICurrentUserGuildsQuery,
|
||||
RESTPatchAPICurrentUserJSONBody,
|
||||
RESTPutAPICurrentUserApplicationRoleConnectionJSONBody
|
||||
} from '@biscuitland/common';
|
||||
import type { ImageOptions, Session } from '../index';
|
||||
import { formatImageURL } from '../index';
|
||||
|
||||
export class UserManager {
|
||||
readonly session!: Session;
|
||||
constructor(session: Session) {
|
||||
Object.defineProperty(this, 'session', {
|
||||
value: session,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
|
||||
get(userId = '@me') {
|
||||
return this.session.api.users(userId).get();
|
||||
}
|
||||
|
||||
avatarURL(user: APIUser, { size, format }: ImageOptions = {}) {
|
||||
if (user.avatar?.length) {
|
||||
return formatImageURL(this.session.cdn.avatars(user.id).get(user.avatar), size, format);
|
||||
}
|
||||
|
||||
return formatImageURL(this.session.cdn.embed.avatars.get(Number(user.discriminator) % 5));
|
||||
}
|
||||
|
||||
createDM(userId: string) {
|
||||
return this.session.api.users('@me').channels.post({ body: { recipient_id: userId } });
|
||||
}
|
||||
|
||||
editCurrent(body: RESTPatchAPICurrentUserJSONBody) {
|
||||
return this.session.api.users('@me').patch({
|
||||
body
|
||||
});
|
||||
}
|
||||
|
||||
getGuilds(query?: RESTGetAPICurrentUserGuildsQuery) {
|
||||
return this.session.api.users('@me').guilds.get({ query });
|
||||
}
|
||||
|
||||
getGuildMember(guildId: string) {
|
||||
return this.session.api.users('@me').guilds(guildId).member.get();
|
||||
}
|
||||
|
||||
leaveGuild(guildId: string) {
|
||||
return this.session.api.users('@me').guilds(guildId).delete();
|
||||
}
|
||||
|
||||
getConnections() {
|
||||
return this.session.api.users('@me').connections.get();
|
||||
}
|
||||
|
||||
getRoleConnections(applicationId: string) {
|
||||
return this.session.api.users('@me').applications(applicationId)['role-connection'].get();
|
||||
}
|
||||
|
||||
updateRoleConnection(applicationId: string, body: RESTPutAPICurrentUserApplicationRoleConnectionJSONBody) {
|
||||
return this.session.api.users('@me').applications(applicationId)['role-connection'].put({ body });
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
import {
|
||||
Identify,
|
||||
RESTPatchAPIWebhookJSONBody,
|
||||
RESTPatchAPIWebhookResult,
|
||||
RESTPatchAPIWebhookWithTokenJSONBody,
|
||||
RESTPatchAPIWebhookWithTokenMessageJSONBody,
|
||||
RESTPatchAPIWebhookWithTokenResult,
|
||||
RESTPostAPIChannelWebhookJSONBody,
|
||||
RESTPostAPIWebhookWithTokenGitHubQuery,
|
||||
RESTPostAPIWebhookWithTokenGitHubWaitResult,
|
||||
RESTPostAPIWebhookWithTokenJSONBody,
|
||||
RESTPostAPIWebhookWithTokenQuery,
|
||||
RESTPostAPIWebhookWithTokenSlackQuery,
|
||||
RESTPostAPIWebhookWithTokenSlackWaitResult,
|
||||
RESTPostAPIWebhookWithTokenWaitResult
|
||||
} from '@biscuitland/common';
|
||||
import type { Session } from '..';
|
||||
|
||||
export class WebhookManager {
|
||||
readonly session!: Session;
|
||||
constructor(session: Session) {
|
||||
Object.defineProperty(this, 'session', {
|
||||
value: session,
|
||||
writable: false
|
||||
});
|
||||
}
|
||||
|
||||
create(channelId: string, body: RESTPostAPIChannelWebhookJSONBody) {
|
||||
return this.session.api.channels(channelId).webhooks.post({ body });
|
||||
}
|
||||
|
||||
getChannelWebhooks(channelId: string) {
|
||||
return this.session.api.channels(channelId).webhooks.get();
|
||||
}
|
||||
|
||||
getGuildWebhooks(guildId: string) {
|
||||
return this.session.api.guilds(guildId).webhooks.get();
|
||||
}
|
||||
|
||||
get(webhookdId: string, token?: string) {
|
||||
if (!token?.length) return this.session.api.webhooks(webhookdId).get();
|
||||
return this.session.api.webhooks(webhookdId)(token).get();
|
||||
}
|
||||
|
||||
edit(webhookId: string, body: RESTPatchAPIWebhookJSONBody): Promise<RESTPatchAPIWebhookResult>;
|
||||
edit(webhookId: string, body: RESTPatchAPIWebhookWithTokenJSONBody, token: string): Promise<RESTPatchAPIWebhookWithTokenResult>;
|
||||
edit(webhookId: string, body: RESTPatchAPIWebhookJSONBody, token?: string) {
|
||||
if (!token?.length) {
|
||||
return this.session.api.webhooks(webhookId).patch({ body });
|
||||
}
|
||||
return this.session.api.webhooks(webhookId)(token).patch({ body });
|
||||
}
|
||||
|
||||
delete(webhookdId: string, token?: string) {
|
||||
if (!token?.length) return this.session.api.webhooks(webhookdId).delete();
|
||||
return this.session.api.webhooks(webhookdId)(token).delete();
|
||||
}
|
||||
|
||||
execute(
|
||||
webhookId: string,
|
||||
token: string,
|
||||
body: RESTPostAPIWebhookWithTokenJSONBody,
|
||||
query: RESTPostAPIWebhookWithTokenWaitQuery
|
||||
): Promise<RESTPostAPIWebhookWithTokenWaitResult>;
|
||||
execute(webhookId: string, token: string, body: RESTPostAPIWebhookWithTokenJSONBody, query?: RESTPostAPIWebhookWithTokenQuery) {
|
||||
return this.session.api.webhooks(webhookId)(token).post({
|
||||
body,
|
||||
query
|
||||
});
|
||||
}
|
||||
|
||||
executeGithub(
|
||||
webhookId: string,
|
||||
token: string,
|
||||
body: RESTPostAPIWebhookWithTokenJSONBody,
|
||||
query: Identify<RESTPostAPIWebhookWithTokenGitHubQuery & { wait: true }>
|
||||
): Promise<RESTPostAPIWebhookWithTokenGitHubWaitResult>;
|
||||
executeGithub(
|
||||
webhookId: string,
|
||||
token: string,
|
||||
body: RESTPostAPIWebhookWithTokenJSONBody,
|
||||
query?: RESTPostAPIWebhookWithTokenGitHubQuery
|
||||
) {
|
||||
return this.session.api.webhooks(webhookId)(token).github.post({
|
||||
body,
|
||||
query
|
||||
});
|
||||
}
|
||||
|
||||
executeSlack(
|
||||
webhookId: string,
|
||||
token: string,
|
||||
body: RESTPostAPIWebhookWithTokenJSONBody,
|
||||
query: Identify<RESTPostAPIWebhookWithTokenSlackQuery & { wait: true }>
|
||||
): Promise<RESTPostAPIWebhookWithTokenSlackWaitResult>;
|
||||
executeSlack(webhookId: string, token: string, body: RESTPostAPIWebhookWithTokenJSONBody, query?: RESTPostAPIWebhookWithTokenSlackQuery) {
|
||||
return this.session.api.webhooks(webhookId)(token).slack.post({
|
||||
body,
|
||||
query
|
||||
});
|
||||
}
|
||||
|
||||
getMessage(webhookId: string, token: string, messageId: string, query?: { thread_id?: string }) {
|
||||
return this.session.api.webhooks(webhookId)(token).messages(messageId).get({
|
||||
query
|
||||
});
|
||||
}
|
||||
|
||||
editMessage(
|
||||
webhookId: string,
|
||||
token: string,
|
||||
messageId: string,
|
||||
body: RESTPatchAPIWebhookWithTokenMessageJSONBody,
|
||||
query?: { thread_id?: string }
|
||||
) {
|
||||
return this.session.api.webhooks(webhookId)(token).messages(messageId).patch({ query, body });
|
||||
}
|
||||
|
||||
deleteMessage(webhookId: string, token: string, messageId: string, query?: { thread_id?: string }) {
|
||||
return this.session.api.webhooks(webhookId)(token).messages(messageId).delete({ query });
|
||||
}
|
||||
}
|
||||
|
||||
export type RESTPostAPIWebhookWithTokenWaitQuery = Identify<RESTPostAPIWebhookWithTokenQuery & { wait: true }>;
|
@ -1,121 +0,0 @@
|
||||
import { GatewayIntentBits, Identify, When } from '@biscuitland/common';
|
||||
import type { BiscuitRESTOptions, CDNRoutes, Routes } from '@biscuitland/rest';
|
||||
import { BiscuitREST, CDN, Router } from '@biscuitland/rest';
|
||||
import { GatewayEvents, ShardManager, ShardManagerOptions } from '@biscuitland/ws';
|
||||
import EventEmitter2 from 'eventemitter2';
|
||||
import { MainManager, getBotIdFromToken } from '.';
|
||||
import { Handler, actionHandler } from './events/handler';
|
||||
|
||||
export class Session<On extends boolean = boolean> extends EventEmitter2 {
|
||||
constructor(public options: BiscuitOptions) {
|
||||
super();
|
||||
this.rest = this.createRest(this.options.rest);
|
||||
this.api = new Router(this.rest).createProxy();
|
||||
this.cdn = CDN.createProxy();
|
||||
this.managers = new MainManager(this);
|
||||
}
|
||||
rest: BiscuitREST;
|
||||
api: Routes;
|
||||
cdn: CDNRoutes;
|
||||
managers: MainManager;
|
||||
gateway!: When<On, ShardManager>;
|
||||
private _applicationId?: string;
|
||||
private _botId?: string;
|
||||
|
||||
override on<K extends keyof GatewayEvents>(event: `${K}`, func: Handler[K]): this;
|
||||
override on<K extends string>(event: `${K}`, func: (...args: unknown[]) => unknown): this {
|
||||
const ev = super.on(event, func);
|
||||
|
||||
// @ts-expect-error Eventemitter can sometimes return a listener
|
||||
return ev.emitter ? ev.emitter : ev;
|
||||
}
|
||||
override off<K extends keyof GatewayEvents>(event: `${K}`, func: Handler[K]): this;
|
||||
override off<K extends keyof GatewayEvents>(event: `${K}`, func: (...args: unknown[]) => unknown): this {
|
||||
return super.off(event, func);
|
||||
}
|
||||
|
||||
override once<K extends keyof GatewayEvents>(event: `${K}`, func: Handler[K]): this;
|
||||
override once<K extends string>(event: `${K}`, func: (...args: unknown[]) => unknown): this {
|
||||
const ev = super.on(event, func);
|
||||
|
||||
// @ts-expect-error Eventemitter can sometimes return a listener
|
||||
return ev.emitter ? ev.emitter : ev;
|
||||
}
|
||||
|
||||
override emit<K extends keyof GatewayEvents>(event: `${K}`, ...params: Parameters<Handler[K]>): boolean;
|
||||
override emit<K extends string>(event: `${K}`, ...params: unknown[]): boolean {
|
||||
return super.emit(event, ...params);
|
||||
}
|
||||
|
||||
set botId(id: string) {
|
||||
this._botId = id;
|
||||
}
|
||||
|
||||
set applicationId(id: string) {
|
||||
this._applicationId = id;
|
||||
}
|
||||
|
||||
get botId() {
|
||||
return this._botId ?? getBotIdFromToken(this.options.token);
|
||||
}
|
||||
|
||||
get applicationId() {
|
||||
return this._applicationId ?? this.botId;
|
||||
}
|
||||
|
||||
private createRest(rest: any) {
|
||||
if (!rest) {
|
||||
return new BiscuitREST({
|
||||
token: this.options.token,
|
||||
...this.options.defaultRestOptions
|
||||
});
|
||||
}
|
||||
|
||||
if (rest instanceof BiscuitREST || rest.cRest) {
|
||||
return rest;
|
||||
}
|
||||
|
||||
throw new Error('[CORE] REST not found');
|
||||
}
|
||||
|
||||
async start() {
|
||||
// alias fixed `this` on handlePayload
|
||||
const ctx = this as Session<true>;
|
||||
|
||||
ctx.gateway = new ShardManager({
|
||||
token: this.options.token,
|
||||
intents: this.options.intents ?? 0,
|
||||
info: this.options.defaultGatewayOptions?.info ?? (await this.api.gateway.bot.get()),
|
||||
async handlePayload(shard, data) {
|
||||
const { t, d } = data;
|
||||
if (!(t && d)) return;
|
||||
// @ts-expect-error
|
||||
actionHandler([ctx, { t, d }, shard]);
|
||||
},
|
||||
...this.options.defaultGatewayOptions
|
||||
});
|
||||
|
||||
ctx.once('READY', (payload) => {
|
||||
const { user, application } = payload;
|
||||
this.botId = user.id;
|
||||
this.applicationId = application.id;
|
||||
});
|
||||
|
||||
await ctx.gateway.spawnShards();
|
||||
}
|
||||
|
||||
async stop() {
|
||||
this.removeAllListeners();
|
||||
await this.gateway.disconnectAll();
|
||||
}
|
||||
}
|
||||
|
||||
export type HandlePayload = Pick<ShardManagerOptions, 'handlePayload'>['handlePayload'];
|
||||
|
||||
export interface BiscuitOptions {
|
||||
token: string;
|
||||
intents: number | GatewayIntentBits;
|
||||
rest?: BiscuitREST;
|
||||
defaultRestOptions?: Partial<BiscuitRESTOptions>;
|
||||
defaultGatewayOptions?: Identify<Partial<Omit<ShardManagerOptions, 'token' | 'intents'>>>;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import type { ImageFormat } from '@biscuitland/common';
|
||||
|
||||
export type EditNickname = { nick?: string; reason?: string };
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/reference#image-formatting
|
||||
*/
|
||||
export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;
|
||||
export type ImageOptions = {
|
||||
format?: ImageFormat;
|
||||
size?: ImageSize;
|
||||
};
|
||||
|
||||
export enum ThreadTypes {
|
||||
AnnouncementThread = 10,
|
||||
PublicThread = 11,
|
||||
PrivateThread = 12
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
import { ReplaceRegex } from '@biscuitland/common';
|
||||
import { DiscordEpoch } from '@biscuitland/common';
|
||||
import { ImageFormat } from '@biscuitland/common';
|
||||
import type { ImageSize } from './types';
|
||||
|
||||
/**
|
||||
* Convert a timestamp to a snowflake.
|
||||
* @param timestamp The timestamp to convert.
|
||||
* @returns The snowflake.
|
||||
*/
|
||||
export function snowflakeToTimestamp(id: string): number {
|
||||
return (Number(id) >> 22) + DiscordEpoch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an image URL.
|
||||
* @param url The URL to format.
|
||||
* @param size The size of the image.
|
||||
* @param format The format of the image.
|
||||
* @returns The formatted URL.
|
||||
*/
|
||||
export function formatImageURL(url: string, size: ImageSize = 128, format?: ImageFormat): string {
|
||||
return `${url}.${format ?? (url.includes('/a_') ? 'gif' : 'jpg')}?size=${size}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bot ID from a token.
|
||||
* @param token The token to get the bot ID from.
|
||||
* @returns The bot ID.
|
||||
* @warning Discord staff has mentioned this may not be stable forever xd.
|
||||
*/
|
||||
export function getBotIdFromToken(token: string): string {
|
||||
return Buffer.from(token.split('.')[0], 'base64').toString('ascii');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object to a URLSearchParams object.
|
||||
* @param obj The object to convert.
|
||||
* @returns The URLSearchParams object.
|
||||
*/
|
||||
export function objectToParams(obj: object): URLSearchParams {
|
||||
const query = new URLSearchParams();
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (!value) continue;
|
||||
query.append(ReplaceRegex.snake(key), String(value));
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channel link from a channel ID and guild ID.
|
||||
*
|
||||
* @param channelId The channel ID.
|
||||
* @param guildId The guild ID.
|
||||
* @returns The channel link.
|
||||
*/
|
||||
export function channelLink(channelId: string, guildId?: string) {
|
||||
return `https://discord.com/channels/${guildId ?? '@me'}/${channelId}`;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
export default defineConfig({
|
||||
clean: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
format: ['cjs', 'esm'],
|
||||
minify: isProduction,
|
||||
sourcemap: false
|
||||
});
|
@ -1,52 +0,0 @@
|
||||
# @biscuitland/helpers
|
||||
|
||||
## 3.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- new changes
|
||||
- new changes
|
||||
|
||||
## 3.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.8
|
||||
|
||||
## 3.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.7
|
||||
|
||||
## 3.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- I meessed up
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.6
|
||||
|
||||
## 3.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix: logger on every module
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.5
|
||||
|
||||
## 3.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix mixer
|
||||
|
||||
## 3.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- first 3.0.\* without bugs
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.4
|
@ -1,21 +0,0 @@
|
||||
# @biscuitland/helpers
|
||||
## Most importantly, helpers is:
|
||||
A collection of builders to make your life easier, not built into the core library due to performance concerns.
|
||||
|
||||
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
|
||||
[<img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white">](https://discord.gg/XNw2RZFzaP)
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/oasisjs/biscuit/main/assets/icon.svg" alt="biscuit"/>
|
||||
|
||||
## Install (for [node18](https://nodejs.org/en/download/))
|
||||
|
||||
```sh-session
|
||||
npm install @biscuitland/helpers
|
||||
yarn add @biscuitland/helpers
|
||||
```
|
||||
|
||||
## Links
|
||||
* [Website](https://biscuitjs.com/)
|
||||
* [Documentation](https://docs.biscuitjs.com/)
|
||||
* [Discord](https://discord.gg/XNw2RZFzaP)
|
||||
* [core](https://www.npmjs.com/package/@biscuitland/core) | [rest](https://www.npmjs.com/package/@biscuitland/rest) | [ws](https://www.npmjs.com/package/@biscuitland/ws)
|
@ -1,76 +0,0 @@
|
||||
{
|
||||
"name": "@biscuitland/helpers",
|
||||
"version": "3.0.14",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"clean": "rm -rf dist && rm -rf .turbo",
|
||||
"dev": "tsup --watch"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@biscuitland/common": "^0.0.10",
|
||||
"ts-mixer": "^6.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"tsup": "^7.0.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": "Yuzuru <yuzuru@programmer.net>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Yuzuru",
|
||||
"url": "https://github.com/yuzudev",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "miia",
|
||||
"url": "https://github.com/dragurimu"
|
||||
},
|
||||
{
|
||||
"name": "n128",
|
||||
"url": "https://github.com/nicolito128"
|
||||
},
|
||||
{
|
||||
"name": "socram03",
|
||||
"url": "https://github.com/socram03"
|
||||
},
|
||||
{
|
||||
"name": "Drylozu",
|
||||
"url": "https://github.com/Drylozu"
|
||||
}
|
||||
],
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/oasisjs/biscuit.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/oasisjs/biscuit"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
"discord",
|
||||
"bots",
|
||||
"typescript",
|
||||
"botdev"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { MakeRequired, Options } from '@biscuitland/common';
|
||||
import { Handler, type Session } from '@biscuitland/core';
|
||||
import { GatewayEvents } from '@biscuitland/ws';
|
||||
|
||||
interface CollectorOptions<E extends keyof GatewayEvents> {
|
||||
event: `${E}`;
|
||||
filter?: (...args: Parameters<Handler[E]>) => unknown;
|
||||
max?: number;
|
||||
time?: number;
|
||||
idle?: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_OPTIONS = {
|
||||
filter: () => true,
|
||||
max: -1
|
||||
};
|
||||
|
||||
export enum CollectorStatus {
|
||||
Idle = 0,
|
||||
Started = 1,
|
||||
Ended = 2
|
||||
}
|
||||
|
||||
export class EventCollector<E extends keyof GatewayEvents> extends EventEmitter {
|
||||
collected = new Set<Parameters<Handler[E]>[0]>();
|
||||
status: CollectorStatus = CollectorStatus.Idle;
|
||||
options: MakeRequired<CollectorOptions<E>, 'filter' | 'max'>;
|
||||
private timeout: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor(readonly session: Session, rawOptions: CollectorOptions<E>) {
|
||||
super();
|
||||
this.options = Options(DEFAULT_OPTIONS, rawOptions);
|
||||
}
|
||||
|
||||
start() {
|
||||
this.session.setMaxListeners(this.session.getMaxListeners() + 1);
|
||||
this.session.on(this.options.event, (...args: unknown[]) => this.collect(...(args as Parameters<Handler[E]>)));
|
||||
this.timeout = setTimeout(() => this.stop('time'), this.options.idle ?? this.options.time);
|
||||
}
|
||||
|
||||
private collect(...args: Parameters<Handler[E]>) {
|
||||
if (this.options.filter?.(...args)) {
|
||||
this.collected.add(args[0]);
|
||||
this.emit('collect', ...args);
|
||||
}
|
||||
|
||||
if (this.options.idle) {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => this.stop('time'), this.options.idle);
|
||||
}
|
||||
|
||||
if (this.collected.size >= this.options.max!) this.stop('max');
|
||||
}
|
||||
|
||||
stop(reason = 'User stopped') {
|
||||
if (this.status === CollectorStatus.Ended) return;
|
||||
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
|
||||
this.session.removeListener(this.options.event, (...args: unknown[]) => this.collect(...(args as Parameters<Handler[E]>)));
|
||||
this.session.setMaxListeners(this.session.getMaxListeners() - 1);
|
||||
|
||||
this.status = CollectorStatus.Ended;
|
||||
this.emit('end', reason, this.collected);
|
||||
}
|
||||
|
||||
on(event: 'collect', listener: (...args: Parameters<Handler[E]>) => unknown): this;
|
||||
on(event: 'end', listener: (reason: string | null | undefined, collected: Set<Parameters<Handler[E]>[0]>) => void): this;
|
||||
on(event: string, listener: unknown): this {
|
||||
return super.on(event, listener as () => unknown);
|
||||
}
|
||||
|
||||
once(event: 'collect', listener: (...args: Parameters<Handler[E]>) => unknown): this;
|
||||
once(event: 'end', listener: (reason: string | null | undefined, collected: Set<Parameters<Handler[E]>[0]>) => void): this;
|
||||
once(event: string, listener: unknown): this {
|
||||
return super.once(event, listener as () => unknown);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
import { APIEmbed, APIEmbedAuthor, APIEmbedField, APIEmbedFooter, ObjectToLower, TypeArray, toSnakeCase } from '@biscuitland/common';
|
||||
|
||||
export class MessageEmbed {
|
||||
constructor(public data: Partial<APIEmbed> = {}) {
|
||||
if (!data.fields) this.data.fields = [];
|
||||
}
|
||||
|
||||
setAuthor(author: ObjectToLower<APIEmbedAuthor>): this {
|
||||
this.data.author = toSnakeCase(author);
|
||||
return this;
|
||||
}
|
||||
|
||||
// TODO: Color resolve
|
||||
setColor(color: number): this {
|
||||
this.data.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDescription(desc: string): this {
|
||||
this.data.description = desc;
|
||||
return this;
|
||||
}
|
||||
|
||||
addFields(field: TypeArray<APIEmbedField>): this {
|
||||
this.data.fields = this.data.fields!.concat(field);
|
||||
return this;
|
||||
}
|
||||
|
||||
setFields(fields: APIEmbedField[]): this {
|
||||
this.data.fields = fields;
|
||||
return this;
|
||||
}
|
||||
|
||||
setFooter(footer: ObjectToLower<APIEmbedFooter>): this {
|
||||
this.data.footer = toSnakeCase(footer);
|
||||
return this;
|
||||
}
|
||||
|
||||
setImage(url: string): this {
|
||||
this.data.image = { url };
|
||||
return this;
|
||||
}
|
||||
|
||||
setTimestamp(time: string | number | Date = Date.now()): this {
|
||||
this.data.timestamp = new Date(time).toISOString();
|
||||
return this;
|
||||
}
|
||||
|
||||
setTitle(title: string): this {
|
||||
this.data.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
setURL(url: string): this {
|
||||
this.data.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON(): APIEmbed {
|
||||
return { ...this.data };
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
import { PermissionFlagsBits } from '@biscuitland/common';
|
||||
|
||||
export type PermissionsStrings = keyof typeof PermissionFlagsBits;
|
||||
export type PermissionResolvable = bigint | PermissionsStrings | PermissionsStrings[] | PermissionsStrings | PermissionsStrings[];
|
||||
|
||||
export class Permissions {
|
||||
/** Stores a reference to BitwisePermissionFlags */
|
||||
static Flags = PermissionFlagsBits;
|
||||
|
||||
/** Falsy; Stores the lack of permissions*/
|
||||
static None = 0n;
|
||||
|
||||
/** Stores all entity permissions */
|
||||
bitfield: bigint;
|
||||
|
||||
/**
|
||||
* Wheter to grant all other permissions to the administrator
|
||||
* **Not to get confused with Permissions#admin**
|
||||
*/
|
||||
__admin__ = true;
|
||||
|
||||
constructor(bitfield: PermissionResolvable) {
|
||||
this.bitfield = Permissions.resolve(bitfield);
|
||||
}
|
||||
|
||||
/** Wheter the bitfield has the administrator flag */
|
||||
get admin(): boolean {
|
||||
return this.has(Permissions.Flags.Administrator);
|
||||
}
|
||||
|
||||
get array(): PermissionsStrings[] {
|
||||
// unsafe cast, do not edit
|
||||
const permissions = Object.keys(Permissions.Flags) as PermissionsStrings[];
|
||||
return permissions.filter((bit) => this.has(bit));
|
||||
}
|
||||
|
||||
add(...bits: PermissionResolvable[]): this {
|
||||
let reduced = 0n;
|
||||
for (const bit of bits) {
|
||||
reduced |= Permissions.resolve(bit);
|
||||
}
|
||||
this.bitfield |= reduced;
|
||||
return this;
|
||||
}
|
||||
|
||||
remove(...bits: PermissionResolvable[]): this {
|
||||
let reduced = 0n;
|
||||
for (const bit of bits) {
|
||||
reduced |= Permissions.resolve(bit);
|
||||
}
|
||||
this.bitfield &= ~reduced;
|
||||
return this;
|
||||
}
|
||||
|
||||
has(bit: PermissionResolvable): boolean {
|
||||
const bbit = Permissions.resolve(bit);
|
||||
|
||||
if (this.__admin__ && this.bitfield & BigInt(Permissions.Flags.Administrator)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (this.bitfield & bbit) === bbit;
|
||||
}
|
||||
|
||||
any(bit: PermissionResolvable): boolean {
|
||||
const bbit = Permissions.resolve(bit);
|
||||
|
||||
if (this.__admin__ && this.bitfield & BigInt(Permissions.Flags.Administrator)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (this.bitfield & bbit) !== Permissions.None;
|
||||
}
|
||||
|
||||
equals(bit: PermissionResolvable): boolean {
|
||||
return !!(this.bitfield & Permissions.resolve(bit));
|
||||
}
|
||||
|
||||
/** Gets all permissions */
|
||||
static get All(): bigint {
|
||||
let reduced = 0n;
|
||||
for (const key in PermissionFlagsBits) {
|
||||
const perm = PermissionFlagsBits[key];
|
||||
|
||||
reduced = reduced | perm;
|
||||
}
|
||||
return reduced;
|
||||
}
|
||||
|
||||
static resolve(bit: PermissionResolvable): bigint {
|
||||
switch (typeof bit) {
|
||||
case 'bigint':
|
||||
return bit;
|
||||
case 'number':
|
||||
return BigInt(bit);
|
||||
case 'string':
|
||||
return BigInt(Permissions.Flags[bit]);
|
||||
case 'object':
|
||||
return Permissions.resolve(
|
||||
bit
|
||||
.map((p) => (typeof p === 'string' ? BigInt(Permissions.Flags[p]) : BigInt(p)))
|
||||
.reduce((acc, cur) => acc | cur, Permissions.None)
|
||||
);
|
||||
default:
|
||||
throw new TypeError(`Cannot resolve permission: ${bit}`);
|
||||
}
|
||||
}
|
||||
|
||||
static sum(permissions: (bigint | number)[]) {
|
||||
return permissions.reduce((y, x) => BigInt(y) | BigInt(x), Permissions.None);
|
||||
}
|
||||
|
||||
static reduce(permissions: PermissionResolvable[]): Permissions {
|
||||
const solved = permissions.map(Permissions.resolve);
|
||||
|
||||
return new Permissions(solved.reduce((y, x) => y | x, Permissions.None));
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
yield* this.array;
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.bitfield;
|
||||
}
|
||||
|
||||
toJSON(): { fields: string[] } {
|
||||
const fields = Object.keys(Permissions.Flags).filter((bit) => typeof bit === 'number' && this.has(bit));
|
||||
|
||||
return { fields };
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
import { APIMessageActionRowComponent, APIModalActionRowComponent, ComponentType } from '@biscuitland/common';
|
||||
import {
|
||||
ChannelSelectMenu,
|
||||
MentionableSelectMenu,
|
||||
MessageButton,
|
||||
ModalTextInput,
|
||||
RoleSelectMenu,
|
||||
StringSelectMenu,
|
||||
UserSelectMenu
|
||||
} from './components';
|
||||
import { BaseComponent } from './components/BaseComponent';
|
||||
|
||||
export function createComponent(data: APIMessageActionRowComponent): HelperComponents;
|
||||
export function createComponent(data: APIModalActionRowComponent): HelperComponents;
|
||||
export function createComponent(data: HelperComponents): HelperComponents;
|
||||
export function createComponent(data: HelperComponents | APIMessageActionRowComponent | APIModalActionRowComponent): HelperComponents {
|
||||
if (data instanceof BaseComponent) {
|
||||
return data;
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
case ComponentType.Button:
|
||||
return new MessageButton(data);
|
||||
case ComponentType.StringSelect:
|
||||
return new StringSelectMenu(data);
|
||||
case ComponentType.TextInput:
|
||||
return new ModalTextInput(data);
|
||||
case ComponentType.UserSelect:
|
||||
return new UserSelectMenu(data);
|
||||
case ComponentType.RoleSelect:
|
||||
return new RoleSelectMenu(data);
|
||||
case ComponentType.MentionableSelect:
|
||||
return new MentionableSelectMenu(data);
|
||||
case ComponentType.ChannelSelect:
|
||||
return new ChannelSelectMenu(data);
|
||||
}
|
||||
}
|
||||
|
||||
export type OptionValuesLength = { max: number; min: number };
|
||||
export type MessageSelectMenus = RoleSelectMenu | UserSelectMenu | StringSelectMenu | ChannelSelectMenu | MentionableSelectMenu;
|
||||
export type MessageComponents = MessageButton | MessageSelectMenus;
|
||||
export type HelperComponents = MessageComponents | ModalTextInput;
|
@ -1,43 +0,0 @@
|
||||
import { ApplicationCommandType, LocalizationMap, RESTPostAPIContextMenuApplicationCommandsJSONBody } from '@biscuitland/common';
|
||||
import { PermissionResolvable, Permissions } from '../../Permissions';
|
||||
|
||||
export type ContextCommandType = ApplicationCommandType.Message | ApplicationCommandType.User;
|
||||
|
||||
export class ContextCommand {
|
||||
name: string = undefined!;
|
||||
name_localizations?: LocalizationMap;
|
||||
type: ContextCommandType = undefined!;
|
||||
default_permission: boolean | undefined = undefined;
|
||||
default_member_permissions: string | undefined = undefined;
|
||||
dm_permission: boolean | undefined = undefined;
|
||||
|
||||
setName(name: string): this {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
setType(type: ContextCommandType) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
addNameLocalizations(locals: LocalizationMap): this {
|
||||
this.name_localizations = locals;
|
||||
Reflect;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDMPermission(value = true): this {
|
||||
this.dm_permission = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDefautlMemberPermissions(permissions: PermissionResolvable[]): this {
|
||||
this.default_member_permissions = Permissions.reduce(permissions).bitfield.toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON(): RESTPostAPIContextMenuApplicationCommandsJSONBody {
|
||||
return { ...this };
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export * from './contextMenu/ContextCommand';
|
||||
export * from './slash/SlashCommand';
|
||||
export * from './slash/SlashCommandOption';
|
@ -1,53 +0,0 @@
|
||||
import { ApplicationCommandType, RESTPostAPIChatInputApplicationCommandsJSONBody } from '@biscuitland/common';
|
||||
import { Mixin } from 'ts-mixer';
|
||||
import { PermissionResolvable, Permissions } from '../../Permissions';
|
||||
import { AllSlashOptions, SlashSubcommandGroupOption, SlashSubcommandOption } from './SlashCommandOption';
|
||||
|
||||
class SlashCommandB {
|
||||
constructor(public data: Partial<RESTPostAPIChatInputApplicationCommandsJSONBody> = {}) {}
|
||||
|
||||
setDMPermission(value = true): this {
|
||||
this.data.dm_permission = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
setNSFW(value = true): this {
|
||||
this.data.nsfw = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDefautlMemberPermissions(permissions: PermissionResolvable[]): this {
|
||||
this.data.default_member_permissions = Permissions.reduce(permissions).bitfield.toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
addSubcommandGroup(fn: (option: SlashSubcommandGroupOption) => SlashSubcommandGroupOption): this {
|
||||
const option = fn(new SlashSubcommandGroupOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addSubcommand(fn: (option: SlashSubcommandOption) => SlashSubcommandOption): this {
|
||||
const option = fn(new SlashSubcommandOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addRawOption(option: ReturnType<AllSlashOptions['toJSON']>) {
|
||||
this.data.options ??= [];
|
||||
// @ts-expect-error discord-api-types bad typing, again
|
||||
this.data.options.push(option);
|
||||
}
|
||||
|
||||
toJSON(): RESTPostAPIChatInputApplicationCommandsJSONBody {
|
||||
return {
|
||||
...this.data,
|
||||
type: ApplicationCommandType.ChatInput
|
||||
} as RESTPostAPIChatInputApplicationCommandsJSONBody & {
|
||||
type: ApplicationCommandType.ChatInput;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const SlashCommand = Mixin(SlashCommandB, SlashSubcommandOption);
|
||||
export type SlashCommand = InstanceType<typeof SlashCommand>;
|
@ -1,340 +0,0 @@
|
||||
import {
|
||||
APIApplicationCommandAttachmentOption,
|
||||
APIApplicationCommandBooleanOption,
|
||||
APIApplicationCommandChannelOption,
|
||||
APIApplicationCommandIntegerOption as AACIO,
|
||||
APIApplicationCommandMentionableOption,
|
||||
APIApplicationCommandNumberOption as AACNO,
|
||||
APIApplicationCommandOption,
|
||||
APIApplicationCommandOptionBase,
|
||||
APIApplicationCommandOptionChoice,
|
||||
APIApplicationCommandRoleOption,
|
||||
APIApplicationCommandStringOption as AACSO,
|
||||
APIApplicationCommandSubcommandGroupOption as AACSGO,
|
||||
APIApplicationCommandSubcommandOption as AACSCO,
|
||||
APIApplicationCommandUserOption,
|
||||
ApplicationCommandOptionType,
|
||||
ChannelType,
|
||||
LocalizationMap,
|
||||
RestToKeys,
|
||||
TypeArray,
|
||||
When
|
||||
} from '@biscuitland/common';
|
||||
import { OptionValuesLength } from '../../';
|
||||
|
||||
export type SlashBaseOptionTypes =
|
||||
| Exclude<APIApplicationCommandOption, AACSO | AACNO | AACIO | AACSCO>
|
||||
| APIApplicationCommandStringOption
|
||||
| APIApplicationCommandNumberOption
|
||||
| APIApplicationCommandIntegerOption
|
||||
| APIApplicationCommandSubcommandOption;
|
||||
|
||||
export type ApplicationCommandBasicOptions =
|
||||
| APIApplicationCommandAttachmentOption
|
||||
| APIApplicationCommandChannelOption
|
||||
| APIApplicationCommandIntegerOption
|
||||
| APIApplicationCommandMentionableOption
|
||||
| APIApplicationCommandNumberOption
|
||||
| APIApplicationCommandStringOption
|
||||
| APIApplicationCommandRoleOption
|
||||
| APIApplicationCommandBooleanOption
|
||||
| APIApplicationCommandUserOption;
|
||||
|
||||
export abstract class SlashBaseOption<DataType extends SlashBaseOptionTypes> {
|
||||
constructor(public data: Partial<DataType> = {}) {}
|
||||
|
||||
setName(name: string): this {
|
||||
this.data.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDesciption(desc: string): this {
|
||||
this.data.description = desc;
|
||||
return this;
|
||||
}
|
||||
|
||||
addLocalizations(locals: RestToKeys<[LocalizationMap, 'name', 'description']>): this {
|
||||
this.data.name_localizations = locals.name;
|
||||
this.data.description_localizations = locals.description;
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON(): DataType {
|
||||
return { ...this.data } as DataType;
|
||||
}
|
||||
}
|
||||
|
||||
export type SlashRequiredOptionTypes = Exclude<SlashBaseOptionTypes, AACSGO | AACSGO>;
|
||||
|
||||
export class SlashRequiredOption<DataType extends SlashRequiredOptionTypes> extends SlashBaseOption<DataType> {
|
||||
setRequired(required = true): this {
|
||||
this.data.required = required;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporal fix type
|
||||
* I didn't find the correct way to set this with discord-api-types
|
||||
* Author: socram03
|
||||
*/
|
||||
export interface APIApplicationCommandStringOption<AC extends boolean = boolean>
|
||||
extends APIApplicationCommandOptionBase<ApplicationCommandOptionType.String> {
|
||||
/**
|
||||
* For option type `STRING`, the minimum allowed length (minimum of `0`, maximum of `6000`).
|
||||
*/
|
||||
min_length?: number;
|
||||
/**
|
||||
* For option type `STRING`, the maximum allowed length (minimum of `1`, maximum of `6000`).
|
||||
*/
|
||||
max_length?: number;
|
||||
|
||||
autocomplete: When<AC, false | undefined, true>;
|
||||
|
||||
choices: When<AC, APIApplicationCommandOptionChoice<string>[], never>;
|
||||
}
|
||||
|
||||
export class SlashStringOption<AC extends boolean = boolean> extends SlashRequiredOption<APIApplicationCommandStringOption<AC>> {
|
||||
constructor(data: Partial<APIApplicationCommandStringOption<AC>> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.String });
|
||||
}
|
||||
|
||||
addChoices(choices: TypeArray<APIApplicationCommandOptionChoice<string>>): SlashStringOption<true> {
|
||||
const ctx = this as SlashStringOption<true>;
|
||||
ctx.data.choices ??= [];
|
||||
ctx.data.choices = ctx.data.choices!.concat(choices);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
setAutocomplete(auto = true): SlashStringOption<typeof auto> {
|
||||
const ctx = this as SlashStringOption<typeof auto>;
|
||||
ctx.data.autocomplete = auto;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
setLength({ min, max }: OptionValuesLength): this {
|
||||
this.data.min_length = min;
|
||||
this.data.max_length = max;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporal fix type
|
||||
* I didn't find the correct way to set this with discord-api-types
|
||||
* Author: socram03
|
||||
*/
|
||||
interface APIApplicationCommandNumberOption<AC extends boolean = boolean>
|
||||
extends APIApplicationCommandOptionBase<ApplicationCommandOptionType.Number> {
|
||||
/**
|
||||
* If the option is an `INTEGER` or `NUMBER` type, the minimum value permitted.
|
||||
*/
|
||||
min_value?: number;
|
||||
/**
|
||||
* If the option is an `INTEGER` or `NUMBER` type, the maximum value permitted.
|
||||
*/
|
||||
max_value?: number;
|
||||
|
||||
autocomplete: When<AC, false | undefined, true>;
|
||||
|
||||
choices: When<AC, APIApplicationCommandOptionChoice<number>[], never>;
|
||||
}
|
||||
|
||||
export class SlashNumberOption<AC extends boolean = boolean> extends SlashRequiredOption<APIApplicationCommandNumberOption<AC>> {
|
||||
constructor(data: Partial<APIApplicationCommandNumberOption<AC>> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Number });
|
||||
}
|
||||
|
||||
addChoices(choices: TypeArray<APIApplicationCommandOptionChoice<number>>): SlashNumberOption<true> {
|
||||
const ctx = this as SlashNumberOption<true>;
|
||||
ctx.data.choices ??= [];
|
||||
ctx.data.choices = ctx.data.choices.concat(choices);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
setValueRange({ min, max }: OptionValuesLength): this {
|
||||
this.data.max_value = max;
|
||||
this.data.min_value = min;
|
||||
return this;
|
||||
}
|
||||
|
||||
setAutocomplete(auto = true): SlashNumberOption<typeof auto> {
|
||||
const ctx = this as SlashNumberOption<typeof auto>;
|
||||
ctx.data.autocomplete = auto;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporal fix type
|
||||
* I didn't find the correct way to set this with discord-api-types
|
||||
* Author: socram03
|
||||
*/
|
||||
interface APIApplicationCommandIntegerOption<AC extends boolean = boolean>
|
||||
extends APIApplicationCommandOptionBase<ApplicationCommandOptionType.Integer> {
|
||||
/**
|
||||
* If the option is an `INTEGER` or `NUMBER` type, the minimum value permitted.
|
||||
*/
|
||||
min_value?: number;
|
||||
/**
|
||||
* If the option is an `INTEGER` or `NUMBER` type, the maximum value permitted.
|
||||
*/
|
||||
max_value?: number;
|
||||
|
||||
autocomplete: When<AC, false | undefined, true>;
|
||||
|
||||
choices: When<AC, APIApplicationCommandOptionChoice<number>[], never>;
|
||||
}
|
||||
|
||||
export class SlashIntegerOption<AC extends boolean = boolean> extends SlashRequiredOption<APIApplicationCommandIntegerOption<AC>> {
|
||||
constructor(data: Partial<APIApplicationCommandIntegerOption<AC>> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Integer });
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashUserOption extends SlashRequiredOption<APIApplicationCommandUserOption> {
|
||||
constructor(data: Partial<APIApplicationCommandUserOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.User });
|
||||
}
|
||||
}
|
||||
|
||||
export type SlashChannelOptionChannelTypes = Exclude<ChannelType, ChannelType.DM | ChannelType.GroupDM>;
|
||||
|
||||
export class SlashChannelOption extends SlashRequiredOption<APIApplicationCommandChannelOption> {
|
||||
constructor(data: Partial<APIApplicationCommandChannelOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Channel });
|
||||
}
|
||||
|
||||
setChannelTypes(types: SlashChannelOptionChannelTypes[]): this {
|
||||
this.data.channel_types = types;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashRoleOption extends SlashRequiredOption<APIApplicationCommandRoleOption> {
|
||||
constructor(data: Partial<APIApplicationCommandRoleOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Role });
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashMentionableOption extends SlashRequiredOption<APIApplicationCommandMentionableOption> {
|
||||
constructor(data: Partial<APIApplicationCommandMentionableOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Mentionable });
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashAttachmentOption extends SlashRequiredOption<APIApplicationCommandAttachmentOption> {
|
||||
constructor(data: Partial<APIApplicationCommandAttachmentOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Attachment });
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashBooleanOption extends SlashRequiredOption<APIApplicationCommandBooleanOption> {
|
||||
constructor(data: Partial<APIApplicationCommandBooleanOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Boolean });
|
||||
}
|
||||
}
|
||||
|
||||
export type BasicSlashOptions =
|
||||
| SlashStringOption
|
||||
| SlashAttachmentOption
|
||||
| SlashChannelOption
|
||||
| SlashIntegerOption
|
||||
| SlashNumberOption
|
||||
| SlashRoleOption
|
||||
| SlashMentionableOption
|
||||
| SlashUserOption
|
||||
| SlashBooleanOption;
|
||||
|
||||
export type APIApplicationCommandSubcommandOption = AACSCO & {
|
||||
options?: ApplicationCommandBasicOptions[];
|
||||
};
|
||||
|
||||
export class SlashSubcommandOption extends SlashBaseOption<APIApplicationCommandSubcommandOption> {
|
||||
constructor(data: Partial<APIApplicationCommandSubcommandOption> = {}) {
|
||||
super({ ...data, type: ApplicationCommandOptionType.Subcommand });
|
||||
}
|
||||
|
||||
addStringOption(fn: (option: SlashStringOption) => SlashStringOption): this {
|
||||
const option = fn(new SlashStringOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addNumberOption(fn: (option: SlashNumberOption) => SlashNumberOption): this {
|
||||
const option = fn(new SlashNumberOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addIntegerOption(fn: (option: SlashIntegerOption) => SlashIntegerOption): this {
|
||||
const option = fn(new SlashIntegerOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addChannelOption(fn: (option: SlashChannelOption) => SlashChannelOption): this {
|
||||
const option = fn(new SlashChannelOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addUserOption(fn: (option: SlashUserOption) => SlashUserOption): this {
|
||||
const option = fn(new SlashUserOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addRoleOption(fn: (option: SlashRoleOption) => SlashRoleOption): this {
|
||||
const option = fn(new SlashRoleOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addMentionableOption(fn: (option: SlashMentionableOption) => SlashMentionableOption): this {
|
||||
const option = fn(new SlashMentionableOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addAttachmentOption(fn: (option: SlashAttachmentOption) => SlashAttachmentOption): this {
|
||||
const option = fn(new SlashAttachmentOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addBooleanOption(fn: (option: SlashBooleanOption) => SlashBooleanOption): this {
|
||||
const option = fn(new SlashBooleanOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addRawOption(option: ApplicationCommandBasicOptions) {
|
||||
this.data.options ??= [];
|
||||
this.data.options.push(option);
|
||||
}
|
||||
}
|
||||
|
||||
export type APIApplicationCommandSubcommandGroupOption = AACSGO & {
|
||||
options?: APIApplicationCommandSubcommandOption[];
|
||||
};
|
||||
|
||||
export type AllSlashOptions = BasicSlashOptions | SlashSubcommandGroupOption | SlashSubcommandOption;
|
||||
|
||||
export class SlashSubcommandGroupOption extends SlashBaseOption<APIApplicationCommandSubcommandGroupOption> {
|
||||
constructor(data: Partial<APIApplicationCommandSubcommandGroupOption> = {}) {
|
||||
if (!data.options) data.options = [];
|
||||
super({ ...data, type: ApplicationCommandOptionType.SubcommandGroup });
|
||||
}
|
||||
|
||||
addSubCommand(fn: (option: SlashSubcommandOption) => SlashSubcommandOption): this {
|
||||
const option = fn(new SlashSubcommandOption());
|
||||
this.addRawOption(option.toJSON());
|
||||
return this;
|
||||
}
|
||||
|
||||
addRawOption(option: ReturnType<SlashSubcommandOption['toJSON']>) {
|
||||
this.data.options ??= [];
|
||||
this.data.options.push(option);
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import { APIActionRowComponent, APIMessageActionRowComponent, ComponentType, TypeArray } from '@biscuitland/common';
|
||||
import { MessageComponents, createComponent } from '../Utils';
|
||||
import { BaseComponent } from './BaseComponent';
|
||||
|
||||
export class MessageActionRow<T extends MessageComponents> extends BaseComponent<APIActionRowComponent<APIMessageActionRowComponent>> {
|
||||
constructor({ components, ...data }: Partial<APIActionRowComponent<APIMessageActionRowComponent>> = {}) {
|
||||
super({ ...data, type: ComponentType.ActionRow });
|
||||
this.components = (components?.map(createComponent) ?? []) as T[];
|
||||
}
|
||||
components: T[];
|
||||
|
||||
addComponents(component: TypeArray<T>): this {
|
||||
this.components = this.components.concat(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
setComponents(component: T[]): this {
|
||||
this.components = [...component];
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON(): APIActionRowComponent<APIMessageActionRowComponent> {
|
||||
return {
|
||||
...this.data,
|
||||
components: this.components.map((c) => c.toJSON())
|
||||
} as APIActionRowComponent<ReturnType<T['toJSON']>>;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import { APIBaseComponent, ComponentType } from '@biscuitland/common';
|
||||
|
||||
export abstract class BaseComponent<TYPE extends Partial<APIBaseComponent<ComponentType>> = APIBaseComponent<ComponentType>,> {
|
||||
constructor(public data: Partial<TYPE>) {}
|
||||
|
||||
toJSON(): TYPE {
|
||||
return { ...this.data } as TYPE;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import { APIButtonComponentBase, APIMessageComponentEmoji, ButtonStyle, ComponentType, When } from '@biscuitland/common';
|
||||
import { BaseComponent } from './BaseComponent';
|
||||
|
||||
export type ButtonStylesForID = Exclude<ButtonStyle, ButtonStyle.Link>;
|
||||
|
||||
export interface APIButtonComponent<WI extends boolean = boolean>
|
||||
extends APIButtonComponentBase<When<WI, ButtonStylesForID, ButtonStyle.Link>> {
|
||||
url: When<WI, never, string>;
|
||||
|
||||
custom_id: When<WI, string, never>;
|
||||
}
|
||||
|
||||
export class MessageButton<WI extends boolean = boolean> extends BaseComponent<APIButtonComponent<WI>> {
|
||||
constructor(data: Partial<APIButtonComponent<WI>> = {}) {
|
||||
super({ ...data, type: ComponentType.Button });
|
||||
}
|
||||
|
||||
setLabel(label: string): this {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
setEmoji(emoji: APIMessageComponentEmoji): this {
|
||||
this.data.emoji = emoji;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDisabled(disabled = true): this {
|
||||
this.data.disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
setURL(url: string): MessageButton<false> {
|
||||
const ctx = this as MessageButton<false>;
|
||||
ctx.data.url = url;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
setStyle(style: When<WI, ButtonStylesForID, ButtonStyle.Link>): this {
|
||||
this.data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
setCustomId(id: string): MessageButton<true> {
|
||||
const ctx = this as MessageButton<true>;
|
||||
ctx.data.custom_id = id;
|
||||
return ctx;
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
import {
|
||||
APIChannelSelectComponent,
|
||||
APIMentionableSelectComponent,
|
||||
APIMessageComponentEmoji,
|
||||
APIRoleSelectComponent,
|
||||
APISelectMenuComponent,
|
||||
APISelectMenuOption,
|
||||
APIStringSelectComponent,
|
||||
APIUserSelectComponent,
|
||||
ChannelType,
|
||||
ComponentType,
|
||||
TypeArray
|
||||
} from '@biscuitland/common';
|
||||
import { OptionValuesLength } from '..';
|
||||
import { BaseComponent } from './BaseComponent';
|
||||
|
||||
class SelectMenu<Select extends APISelectMenuComponent = APISelectMenuComponent,> extends BaseComponent<Select> {
|
||||
setCustomId(id: string): this {
|
||||
this.data.custom_id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
setPlaceholder(placeholder: string): this {
|
||||
this.data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
setValuesLength({ max, min }: Partial<OptionValuesLength>): this {
|
||||
this.data.max_values = max;
|
||||
this.data.min_values = min;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDisabled(disabled = true): this {
|
||||
this.data.disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class UserSelectMenu extends SelectMenu<APIUserSelectComponent> {
|
||||
constructor(data: Partial<APIUserSelectComponent> = {}) {
|
||||
super({ ...data, type: ComponentType.UserSelect });
|
||||
}
|
||||
}
|
||||
|
||||
export class RoleSelectMenu extends SelectMenu<APIRoleSelectComponent> {
|
||||
constructor(data: Partial<APIRoleSelectComponent> = {}) {
|
||||
super({ ...data, type: ComponentType.RoleSelect });
|
||||
}
|
||||
}
|
||||
|
||||
export class MentionableSelectMenu extends SelectMenu<APIMentionableSelectComponent> {
|
||||
constructor(data: Partial<APIMentionableSelectComponent> = {}) {
|
||||
super({ ...data, type: ComponentType.MentionableSelect });
|
||||
}
|
||||
}
|
||||
|
||||
export class ChannelSelectMenu extends SelectMenu<APIChannelSelectComponent> {
|
||||
constructor(data: Partial<APIChannelSelectComponent> = {}) {
|
||||
super({ ...data, type: ComponentType.ChannelSelect });
|
||||
}
|
||||
|
||||
setChannelTypes(types: ChannelType[]): this {
|
||||
this.data.channel_types = types;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class StringSelectMenu extends SelectMenu<APIStringSelectComponent> {
|
||||
constructor(data: Partial<APIStringSelectComponent> = {}) {
|
||||
super({ ...data, type: ComponentType.StringSelect });
|
||||
}
|
||||
|
||||
addOption(option: TypeArray<APISelectMenuOption>): this {
|
||||
this.data.options ??= [];
|
||||
this.data.options = this.data.options.concat(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
setOptions(options: APISelectMenuOption[]): this {
|
||||
this.data.options = options;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class StringSelectOption {
|
||||
// biome-ignore lint/nursery/noEmptyBlockStatements: <explanation>
|
||||
constructor(public data: Partial<APISelectMenuOption> = {}) {}
|
||||
|
||||
setLabel(label: string): this {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
setValue(value: string): this {
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDescription(description: string): this {
|
||||
this.data.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDefault(Default = true): this {
|
||||
this.data.default = Default;
|
||||
return this;
|
||||
}
|
||||
|
||||
setEmoji(emoji: APIMessageComponentEmoji): this {
|
||||
this.data.emoji = emoji;
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON(): APISelectMenuOption {
|
||||
return { ...this.data } as APISelectMenuOption;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import { APITextInputComponent, ComponentType, TextInputStyle } from '@biscuitland/common';
|
||||
import { OptionValuesLength } from '..';
|
||||
import { BaseComponent } from './BaseComponent';
|
||||
|
||||
export class ModalTextInput extends BaseComponent<APITextInputComponent> {
|
||||
constructor(data: Partial<APITextInputComponent> = {}) {
|
||||
super({ ...data, type: ComponentType.TextInput });
|
||||
}
|
||||
|
||||
setStyle(style: TextInputStyle): this {
|
||||
this.data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
setLabel(label: string): this {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
setPlaceholder(placeholder: string): this {
|
||||
this.data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
setLength({ max, min }: Partial<OptionValuesLength>): this {
|
||||
this.data.max_length = max;
|
||||
this.data.min_length = min;
|
||||
return this;
|
||||
}
|
||||
|
||||
setCustomId(id: string): this {
|
||||
this.data.custom_id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
setValue(value: string): this {
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
setRequired(required = true): this {
|
||||
this.data.required = required;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export * from './ActionRow';
|
||||
export * from './BaseComponent';
|
||||
export * from './MessageButton';
|
||||
export * from './SelectMenu';
|
||||
export * from './TextInput';
|
@ -1,5 +0,0 @@
|
||||
export * from './MessageEmbed';
|
||||
export * from './Permissions';
|
||||
export * from './Utils';
|
||||
export * from './commands';
|
||||
export * from './components';
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
export default defineConfig({
|
||||
clean: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
format: ['cjs', 'esm'],
|
||||
minify: isProduction,
|
||||
sourcemap: false
|
||||
});
|
@ -1,113 +0,0 @@
|
||||
# @biscuitland/rest
|
||||
|
||||
## 3.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- I meessed up
|
||||
|
||||
## 3.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix: logger on every module
|
||||
|
||||
## 3.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- first 3.0.\* without bugs
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- fix TODO
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.3.0
|
||||
|
||||
## 2.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- bug fixes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.3
|
||||
|
||||
## 2.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- rename guildLocales to guildLocale in interactions
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.2
|
||||
|
||||
## 2.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- select menu options now can be empty since the latest Discord API update
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.1
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Functionality to delete ephemeral messages added, select menus were updated
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.0
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- minor changes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- dumb hotfix that LH asked for (blame Yuzu)
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Changes to cache and forum channels ✨
|
||||
- Forum channels and updates to @biscuitland/cache ✨
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.0
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Minor fixes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Major Changes
|
||||
|
||||
- publish
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.0.5
|
@ -1,65 +0,0 @@
|
||||
# @biscuitland/rest
|
||||
## Most importantly, biscuit's rest is:
|
||||
A standalone rest library that is yet easy to use and easy to host on a serverless infrastructure, it is meant to be used with biscuit's libraries.
|
||||
|
||||
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
|
||||
[<img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white">](https://discord.gg/XNw2RZFzaP)
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/oasisjs/biscuit/main/assets/icon.svg" alt="biscuit"/>
|
||||
|
||||
## Install (for [node18](https://nodejs.org/en/download/))
|
||||
|
||||
```sh-session
|
||||
npm install @biscuitland/rest
|
||||
yarn add @biscuitland/rest
|
||||
```
|
||||
|
||||
## Example (Standalone rest)
|
||||
```ts
|
||||
import { BiscuitREST } from "@biscuitland/rest";
|
||||
import Fastify from "fastify";
|
||||
|
||||
const manager = new BiscuitREST({
|
||||
api: "http://any.rest.proxy/",
|
||||
version: 10,
|
||||
token: "your token goes here"
|
||||
});
|
||||
|
||||
const app = Fastify({});
|
||||
|
||||
app.all("*", (req, reply) => {
|
||||
let response: unknown;
|
||||
|
||||
switch (req.method) {
|
||||
case "GET":
|
||||
response = await rest.get(req.url, req.body);
|
||||
break;
|
||||
case "POST":
|
||||
response = await rest.post(req.url, req.body);
|
||||
break;
|
||||
case "PUT":
|
||||
response = await rest.put(req.url, req.body);
|
||||
break;
|
||||
case "PATCH":
|
||||
response = await rest.patch(req.url, req.body);
|
||||
break;
|
||||
case "DELETE":
|
||||
response = await rest.delete(req.url, req.body);
|
||||
break;
|
||||
}
|
||||
|
||||
if (response)
|
||||
reply.status(200).send({ status: 200, data: response });
|
||||
|
||||
else
|
||||
reply.status(204).send({ status: 204, data: null });
|
||||
});
|
||||
|
||||
app.listen({ port: "port..." });
|
||||
```
|
||||
|
||||
## Links
|
||||
* [Website](https://biscuitjs.com/)
|
||||
* [Documentation](https://docs.biscuitjs.com/)
|
||||
* [Discord](https://discord.gg/XNw2RZFzaP)
|
||||
* [core](https://www.npmjs.com/package/@biscuitland/core) | [ws](https://www.npmjs.com/package/@biscuitland/ws) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"name": "@biscuitland/rest",
|
||||
"version": "3.0.7",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"clean": "rm -rf dist && rm -rf .turbo",
|
||||
"dev": "tsup --watch"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsup": "^7.0.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": "Yuzuru <yuzuru@programmer.net>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Yuzuru",
|
||||
"url": "https://github.com/yuzudev"
|
||||
},
|
||||
{
|
||||
"name": "miia",
|
||||
"url": "https://github.com/dragurimu"
|
||||
},
|
||||
{
|
||||
"name": "n128",
|
||||
"url": "https://github.com/nicolito128"
|
||||
},
|
||||
{
|
||||
"name": "socram03",
|
||||
"url": "https://github.com/socram03",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Drylozu",
|
||||
"url": "https://github.com/Drylozu"
|
||||
}
|
||||
],
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/oasisjs/biscuit.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/oasisjs/biscuit"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
"discord",
|
||||
"bots",
|
||||
"typescript",
|
||||
"botdev"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordjs/rest": "^2.0.0"
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
export interface CDNRoutes {
|
||||
embed: {
|
||||
avatars: {
|
||||
get(embed: UserAvatarDefault): string;
|
||||
};
|
||||
};
|
||||
avatars(id: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
icons(guildId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
splashes(guildId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
'discovery-splashes'(guidId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
banners(id: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
guilds(id: string): {
|
||||
users(id: string): {
|
||||
avatars(hash: string): {
|
||||
get(): string;
|
||||
};
|
||||
banners(hash: string): {
|
||||
get(): string;
|
||||
};
|
||||
};
|
||||
};
|
||||
emojis(id: string): {
|
||||
get(): string;
|
||||
};
|
||||
appIcons(appId: string): {
|
||||
get(iconOrCover: string): string;
|
||||
};
|
||||
'app-assets'(appId: string): {
|
||||
get(asset: string): string;
|
||||
achievements(id: string): {
|
||||
icons(hash: string): {
|
||||
get(): string;
|
||||
};
|
||||
};
|
||||
};
|
||||
'team-icons'(teamId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
stickers(id: string): {
|
||||
get(): string;
|
||||
};
|
||||
'role-icons'(roleId: string): {
|
||||
get(icon: string): string;
|
||||
};
|
||||
'guild-events'(id: string): {
|
||||
get(cover: string): string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CDNRoutes {
|
||||
'app-assets'(id: '710982414301790216'): {
|
||||
store(packBannerId: string): {
|
||||
get(): string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type UserAvatarDefault = 1 | 2 | 3 | 4 | 5 | number;
|
@ -1,83 +0,0 @@
|
||||
import type { Identify } from '@biscuitland/common';
|
||||
import type { RawFile, RequestData } from '@discordjs/rest';
|
||||
import { REST } from '@discordjs/rest';
|
||||
import type { RequestMethod } from './Router';
|
||||
|
||||
export class BiscuitREST {
|
||||
api: REST;
|
||||
constructor(public options: BiscuitRESTOptions) {
|
||||
const { token, ...restOptions } = this.options;
|
||||
this.api = new REST(restOptions).setToken(token);
|
||||
}
|
||||
|
||||
async get<T>(route: string, options?: RequestObject<RequestMethod.Get>): Promise<T> {
|
||||
const data = await this.api.get(route as `/${string}`, {
|
||||
...options,
|
||||
query: options?.query ? new URLSearchParams(options.query) : undefined
|
||||
});
|
||||
|
||||
return data as T;
|
||||
}
|
||||
|
||||
async post<T>(route: string, body?: RequestObject<RequestMethod.Post>): Promise<T> {
|
||||
const data = await this.api.post(route as `/${string}`, {
|
||||
...body,
|
||||
body: body?.body,
|
||||
query: body?.query ? new URLSearchParams(body.query) : undefined,
|
||||
files: body?.files
|
||||
});
|
||||
|
||||
return data as T;
|
||||
}
|
||||
|
||||
async put<T>(route: string, body?: RequestObject<RequestMethod.Put>): Promise<T> {
|
||||
const data = await this.api.put(route as `/${string}`, {
|
||||
...body,
|
||||
body: body?.body,
|
||||
query: body?.query ? new URLSearchParams(body.query) : undefined,
|
||||
files: body?.files
|
||||
});
|
||||
|
||||
return data as T;
|
||||
}
|
||||
|
||||
async patch<T>(route: string, body?: RequestObject<RequestMethod.Patch>): Promise<T> {
|
||||
const data = await this.api.patch(route as `/${string}`, {
|
||||
...body,
|
||||
body: body?.body,
|
||||
query: body?.query ? new URLSearchParams(body.query) : undefined,
|
||||
files: body?.files
|
||||
});
|
||||
|
||||
return data as T;
|
||||
}
|
||||
|
||||
async delete<T>(route: string, options?: RequestObject<RequestMethod.Delete>): Promise<T> {
|
||||
const data = await this.api.delete(route as `/${string}`, {
|
||||
...options,
|
||||
query: options?.query ? new URLSearchParams(options.query) : undefined
|
||||
});
|
||||
|
||||
return data as T;
|
||||
}
|
||||
}
|
||||
|
||||
export type BiscuitRESTOptions = Identify<ConstructorParameters<typeof REST>[0] & { token: string }>;
|
||||
|
||||
export type RequestOptions = Pick<RequestData, 'passThroughBody' | 'reason' | 'auth'>;
|
||||
|
||||
export type RequestObject<M extends RequestMethod, B = Record<string, any>, Q = Record<string, any>> = {
|
||||
query?: Q;
|
||||
} & RequestOptions &
|
||||
(M extends `${RequestMethod.Get}`
|
||||
? unknown
|
||||
: {
|
||||
body?: B;
|
||||
files?: RawFile[];
|
||||
});
|
||||
|
||||
export type RestArguments<M extends RequestMethod, B = any, Q extends never | Record<string, any> = any> = M extends RequestMethod.Get
|
||||
? Q extends never
|
||||
? RequestObject<M, never, B>
|
||||
: never
|
||||
: RequestObject<M, B, Q>;
|
@ -1,64 +0,0 @@
|
||||
import { CDN_URL } from '@biscuitland/common';
|
||||
import type { CDNRoutes, Routes } from './';
|
||||
import { BiscuitREST } from './REST';
|
||||
|
||||
export enum RequestMethod {
|
||||
Delete = 'delete',
|
||||
Get = 'get',
|
||||
Patch = 'patch',
|
||||
Post = 'post',
|
||||
Put = 'put'
|
||||
}
|
||||
|
||||
const ArrRequestsMethods = Object.values(RequestMethod) as string[];
|
||||
|
||||
export class Router {
|
||||
noop = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
constructor(private rest: BiscuitREST) {}
|
||||
|
||||
createProxy(route = [] as string[]): Routes {
|
||||
return new Proxy(this.noop, {
|
||||
get: (_, key: string) => {
|
||||
if (ArrRequestsMethods.includes(key)) {
|
||||
return (...options: any[]) => this.rest[key](`/${route.join('/')}`, ...options);
|
||||
}
|
||||
return this.createProxy([...route, key]);
|
||||
},
|
||||
apply: (...[, _, args]) => {
|
||||
return this.createProxy([...route, ...args.filter((x) => x != null)]);
|
||||
}
|
||||
}) as unknown as Routes;
|
||||
}
|
||||
}
|
||||
|
||||
export class CDN {
|
||||
static createProxy(route = [] as string[]): CDNRoutes {
|
||||
const noop = () => {
|
||||
return;
|
||||
};
|
||||
return new Proxy(noop, {
|
||||
get: (_, key: string) => {
|
||||
if (key === 'get') {
|
||||
return (value?: string) => {
|
||||
const lastRoute = `${CDN_URL}/${route.join('/')}`;
|
||||
if (value) {
|
||||
if (typeof value !== 'string') {
|
||||
// rome-ignore lint/nursery/noParameterAssign: fix multiples value types
|
||||
value = String(value);
|
||||
}
|
||||
return `${lastRoute}/${value}`;
|
||||
}
|
||||
return lastRoute;
|
||||
};
|
||||
}
|
||||
return this.createProxy([...route, key]);
|
||||
},
|
||||
apply: (...[, _, args]) => {
|
||||
return this.createProxy([...route, ...args.filter((x) => x != null)]);
|
||||
}
|
||||
}) as unknown as CDNRoutes;
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
import {
|
||||
RESTGetAPIApplicationCommandResult,
|
||||
RESTGetAPIApplicationCommandsQuery,
|
||||
RESTGetAPIApplicationCommandsResult,
|
||||
RESTGetAPIApplicationGuildCommandResult,
|
||||
RESTGetAPIApplicationGuildCommandsQuery,
|
||||
RESTGetAPIApplicationGuildCommandsResult,
|
||||
RESTGetAPIApplicationRoleConnectionMetadataResult,
|
||||
RESTGetAPIGuildApplicationCommandsPermissionsResult,
|
||||
RESTPatchAPIApplicationCommandJSONBody,
|
||||
RESTPatchAPIApplicationCommandResult,
|
||||
RESTPatchAPIApplicationGuildCommandJSONBody,
|
||||
RESTPatchAPIApplicationGuildCommandResult,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
RESTPostAPIApplicationCommandsResult,
|
||||
RESTPostAPIApplicationGuildCommandsJSONBody,
|
||||
RESTPostAPIApplicationGuildCommandsResult,
|
||||
RESTPutAPIApplicationCommandPermissionsJSONBody,
|
||||
RESTPutAPIApplicationCommandsJSONBody,
|
||||
RESTPutAPIApplicationCommandsResult,
|
||||
RESTPutAPIApplicationGuildCommandsJSONBody,
|
||||
RESTPutAPIApplicationGuildCommandsResult,
|
||||
RESTPutAPIApplicationRoleConnectionMetadataJSONBody,
|
||||
RESTPutAPIApplicationRoleConnectionMetadataResult,
|
||||
RESTPutAPIGuildApplicationCommandsPermissionsResult
|
||||
} from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface ApplicationRoutes {
|
||||
applications: {
|
||||
(id: string): {
|
||||
guilds: {
|
||||
(id: string): {
|
||||
commands: {
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get, RESTGetAPIApplicationGuildCommandsQuery>
|
||||
): Promise<RESTGetAPIApplicationGuildCommandsResult>;
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIApplicationGuildCommandsJSONBody>
|
||||
): Promise<RESTPostAPIApplicationGuildCommandsResult>;
|
||||
put(
|
||||
args: RestArguments<RequestMethod.Put, RESTPutAPIApplicationGuildCommandsJSONBody>
|
||||
): Promise<RESTPutAPIApplicationGuildCommandsResult>;
|
||||
permissions: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildApplicationCommandsPermissionsResult>;
|
||||
// put(args: RestArguments<RequestMethod.Put, RESTPutAPIGuildApplicationCommandsPermissionsJSONBody>): Promise<RESTPutAPIGuildApplicationCommandsPermissionsResult>
|
||||
};
|
||||
(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIApplicationGuildCommandResult>;
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIApplicationGuildCommandJSONBody>
|
||||
): Promise<RESTPatchAPIApplicationGuildCommandResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<never>;
|
||||
permissions: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildApplicationCommandsPermissionsResult>;
|
||||
put(
|
||||
args: RestArguments<RequestMethod.Put, RESTPutAPIApplicationCommandPermissionsJSONBody>
|
||||
): Promise<RESTPutAPIGuildApplicationCommandsPermissionsResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
commands: {
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIApplicationCommandsQuery>): Promise<RESTGetAPIApplicationCommandsResult>;
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIApplicationCommandsJSONBody>
|
||||
): Promise<RESTPostAPIApplicationCommandsResult>;
|
||||
put(args: RestArguments<RequestMethod.Put, RESTPutAPIApplicationCommandsJSONBody>): Promise<RESTPutAPIApplicationCommandsResult>;
|
||||
(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIApplicationCommandResult>;
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIApplicationCommandJSONBody>
|
||||
): Promise<RESTPatchAPIApplicationCommandResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<never>;
|
||||
};
|
||||
};
|
||||
'role-connections': {
|
||||
metadata: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIApplicationRoleConnectionMetadataResult>;
|
||||
put(
|
||||
args: RestArguments<RequestMethod.Put, RESTPutAPIApplicationRoleConnectionMetadataJSONBody>
|
||||
): Promise<RESTPutAPIApplicationRoleConnectionMetadataResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
import {
|
||||
RESTDeleteAPIChannelAllMessageReactionsResult,
|
||||
RESTDeleteAPIChannelMessageReactionResult,
|
||||
RESTDeleteAPIChannelMessageResult,
|
||||
RESTDeleteAPIChannelPermissionResult,
|
||||
RESTDeleteAPIChannelPinResult,
|
||||
RESTDeleteAPIChannelRecipientResult,
|
||||
RESTDeleteAPIChannelResult,
|
||||
RESTDeleteAPIChannelThreadMembersResult,
|
||||
RESTGetAPIChannelInvitesResult,
|
||||
RESTGetAPIChannelMessageReactionUsersQuery,
|
||||
RESTGetAPIChannelMessageReactionUsersResult,
|
||||
RESTGetAPIChannelMessageResult,
|
||||
RESTGetAPIChannelMessagesQuery,
|
||||
RESTGetAPIChannelMessagesResult,
|
||||
RESTGetAPIChannelPinsResult,
|
||||
RESTGetAPIChannelResult,
|
||||
RESTGetAPIChannelThreadMemberQuery,
|
||||
RESTGetAPIChannelThreadMemberResult,
|
||||
RESTGetAPIChannelThreadMembersQuery,
|
||||
RESTGetAPIChannelThreadMembersResult,
|
||||
RESTGetAPIChannelThreadsArchivedPrivateResult,
|
||||
RESTGetAPIChannelThreadsArchivedPublicResult,
|
||||
RESTGetAPIChannelThreadsArchivedQuery,
|
||||
RESTGetAPIChannelUsersThreadsArchivedResult,
|
||||
RESTGetAPIGuildWebhooksResult,
|
||||
RESTPatchAPIChannelJSONBody,
|
||||
RESTPatchAPIChannelMessageJSONBody,
|
||||
RESTPatchAPIChannelMessageResult,
|
||||
RESTPatchAPIChannelResult,
|
||||
RESTPostAPIChannelFollowersJSONBody,
|
||||
RESTPostAPIChannelFollowersResult,
|
||||
RESTPostAPIChannelInviteJSONBody,
|
||||
RESTPostAPIChannelInviteResult,
|
||||
RESTPostAPIChannelMessageCrosspostResult,
|
||||
RESTPostAPIChannelMessageJSONBody,
|
||||
RESTPostAPIChannelMessageResult,
|
||||
RESTPostAPIChannelMessagesBulkDeleteJSONBody,
|
||||
RESTPostAPIChannelMessagesBulkDeleteResult,
|
||||
RESTPostAPIChannelMessagesThreadsJSONBody,
|
||||
RESTPostAPIChannelMessagesThreadsResult,
|
||||
RESTPostAPIChannelThreadsJSONBody,
|
||||
RESTPostAPIChannelThreadsResult,
|
||||
RESTPostAPIChannelTypingResult,
|
||||
RESTPostAPIChannelWebhookJSONBody,
|
||||
RESTPostAPIChannelWebhookResult,
|
||||
RESTPostAPIGuildForumThreadsJSONBody,
|
||||
RESTPutAPIChannelMessageReactionResult,
|
||||
RESTPutAPIChannelPermissionJSONBody,
|
||||
RESTPutAPIChannelPermissionResult,
|
||||
RESTPutAPIChannelPinResult,
|
||||
RESTPutAPIChannelRecipientJSONBody,
|
||||
RESTPutAPIChannelRecipientResult,
|
||||
RESTPutAPIChannelThreadMembersResult
|
||||
} from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface ChannelRoutes {
|
||||
channels(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIChannelResult>;
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIChannelJSONBody>): Promise<RESTPatchAPIChannelResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelResult>;
|
||||
users: {
|
||||
(id: '@me'): {
|
||||
threads: {
|
||||
archived: {
|
||||
private: {
|
||||
//.
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelThreadsArchivedQuery>
|
||||
): Promise<RESTGetAPIChannelUsersThreadsArchivedResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
'thread-members': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelThreadMembersQuery>): Promise<RESTGetAPIChannelThreadMembersResult>;
|
||||
(id: '@me'): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put>): Promise<RESTPutAPIChannelThreadMembersResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelThreadMembersResult>;
|
||||
};
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelThreadMemberQuery>): Promise<RESTGetAPIChannelThreadMemberResult>;
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put>): Promise<RESTPutAPIChannelThreadMembersResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelThreadMembersResult>;
|
||||
};
|
||||
};
|
||||
threads: {
|
||||
//.
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIChannelThreadsJSONBody | RESTPostAPIGuildForumThreadsJSONBody>
|
||||
): Promise<RESTPostAPIChannelThreadsResult>;
|
||||
archived: {
|
||||
public: {
|
||||
//.
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelThreadsArchivedQuery>
|
||||
): Promise<RESTGetAPIChannelThreadsArchivedPublicResult>;
|
||||
};
|
||||
private: {
|
||||
//.
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelThreadsArchivedQuery>
|
||||
): Promise<RESTGetAPIChannelThreadsArchivedPrivateResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
recipients: {
|
||||
(id: string): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put, RESTPutAPIChannelRecipientJSONBody>): Promise<RESTPutAPIChannelRecipientResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelRecipientResult>;
|
||||
};
|
||||
};
|
||||
pins: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIChannelPinsResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put>): Promise<RESTPutAPIChannelPinResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelPinResult>;
|
||||
};
|
||||
};
|
||||
followers: {
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIChannelFollowersJSONBody>): Promise<RESTPostAPIChannelFollowersResult>;
|
||||
};
|
||||
permissions: {
|
||||
(id: string): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put, RESTPutAPIChannelPermissionJSONBody>): Promise<RESTPutAPIChannelPermissionResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelPermissionResult>;
|
||||
};
|
||||
};
|
||||
invites: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIChannelInvitesResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIChannelInviteJSONBody>): Promise<RESTPostAPIChannelInviteResult>;
|
||||
};
|
||||
messages: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelMessagesQuery>): Promise<RESTGetAPIChannelMessagesResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIChannelMessageJSONBody>): Promise<RESTPostAPIChannelMessageResult>;
|
||||
'bulk-delete': {
|
||||
//.
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIChannelMessagesBulkDeleteJSONBody>
|
||||
): Promise<RESTPostAPIChannelMessagesBulkDeleteResult>;
|
||||
};
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIChannelMessageResult>;
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIChannelMessageJSONBody>): Promise<RESTPatchAPIChannelMessageResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelMessageResult>;
|
||||
threads: {
|
||||
//.
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIChannelMessagesThreadsJSONBody>
|
||||
): Promise<RESTPostAPIChannelMessagesThreadsResult>;
|
||||
};
|
||||
crosspost: {
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post>): Promise<RESTPostAPIChannelMessageCrosspostResult>;
|
||||
};
|
||||
reactions: {
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelAllMessageReactionsResult>;
|
||||
(emoji: string): {
|
||||
//.
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get, RESTGetAPIChannelMessageReactionUsersQuery>
|
||||
): Promise<RESTGetAPIChannelMessageReactionUsersResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelMessageReactionResult>;
|
||||
(id: '@me'): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put>): Promise<RESTPutAPIChannelMessageReactionResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelMessageReactionResult>;
|
||||
};
|
||||
(id: string): {
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIChannelMessageReactionResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
typing: {
|
||||
//.
|
||||
post(args?: RestArguments<RequestMethod.Post>): Promise<RESTPostAPIChannelTypingResult>;
|
||||
};
|
||||
webhooks: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildWebhooksResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIChannelWebhookJSONBody>): Promise<RESTPostAPIChannelWebhookResult>;
|
||||
};
|
||||
};
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { RESTGetAPIGatewayBotResult, RESTGetAPIGatewayResult } from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface GatewayRoutes {
|
||||
gateway: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGatewayResult>;
|
||||
bot: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGatewayBotResult>;
|
||||
};
|
||||
};
|
||||
}
|
@ -1,381 +0,0 @@
|
||||
import {
|
||||
APIThreadChannel,
|
||||
Identify,
|
||||
RESTDeleteAPIAutoModerationRuleResult,
|
||||
RESTDeleteAPIGuildBanResult,
|
||||
RESTDeleteAPIGuildEmojiResult,
|
||||
RESTDeleteAPIGuildIntegrationResult,
|
||||
RESTDeleteAPIGuildMemberResult,
|
||||
RESTDeleteAPIGuildMemberRoleResult,
|
||||
RESTDeleteAPIGuildResult,
|
||||
RESTDeleteAPIGuildRoleResult,
|
||||
RESTDeleteAPIGuildScheduledEventResult,
|
||||
RESTDeleteAPIGuildStickerResult,
|
||||
RESTDeleteAPIGuildTemplateResult,
|
||||
RESTGetAPIAuditLogQuery,
|
||||
RESTGetAPIAuditLogResult,
|
||||
RESTGetAPIAutoModerationRuleResult,
|
||||
RESTGetAPIAutoModerationRulesResult,
|
||||
RESTGetAPIGuildBanResult,
|
||||
RESTGetAPIGuildBansQuery,
|
||||
RESTGetAPIGuildBansResult,
|
||||
RESTGetAPIGuildChannelsResult,
|
||||
RESTGetAPIGuildEmojiResult,
|
||||
RESTGetAPIGuildEmojisResult,
|
||||
RESTGetAPIGuildIntegrationsResult,
|
||||
RESTGetAPIGuildInvitesResult,
|
||||
RESTGetAPIGuildMemberResult,
|
||||
RESTGetAPIGuildMembersQuery,
|
||||
RESTGetAPIGuildMembersResult,
|
||||
RESTGetAPIGuildMembersSearchQuery,
|
||||
RESTGetAPIGuildMembersSearchResult,
|
||||
RESTGetAPIGuildPreviewResult,
|
||||
RESTGetAPIGuildPruneCountQuery,
|
||||
RESTGetAPIGuildPruneCountResult,
|
||||
RESTGetAPIGuildQuery,
|
||||
RESTGetAPIGuildResult,
|
||||
RESTGetAPIGuildRolesResult,
|
||||
RESTGetAPIGuildScheduledEventQuery,
|
||||
RESTGetAPIGuildScheduledEventResult,
|
||||
RESTGetAPIGuildScheduledEventUsersQuery,
|
||||
RESTGetAPIGuildScheduledEventUsersResult,
|
||||
RESTGetAPIGuildScheduledEventsQuery,
|
||||
RESTGetAPIGuildScheduledEventsResult,
|
||||
RESTGetAPIGuildStickerResult,
|
||||
RESTGetAPIGuildStickersResult,
|
||||
RESTGetAPIGuildTemplatesResult,
|
||||
RESTGetAPIGuildThreadsResult,
|
||||
RESTGetAPIGuildVanityUrlResult,
|
||||
RESTGetAPIGuildVoiceRegionsResult,
|
||||
RESTGetAPIGuildWebhooksResult,
|
||||
RESTGetAPIGuildWelcomeScreenResult,
|
||||
RESTGetAPIGuildWidgetImageQuery,
|
||||
RESTGetAPIGuildWidgetImageResult,
|
||||
RESTGetAPIGuildWidgetJSONResult,
|
||||
RESTGetAPIGuildWidgetSettingsResult,
|
||||
RESTGetAPITemplateResult,
|
||||
RESTPatchAPIAutoModerationRuleJSONBody,
|
||||
RESTPatchAPIAutoModerationRuleResult,
|
||||
RESTPatchAPICurrentGuildMemberJSONBody,
|
||||
RESTPatchAPIGuildChannelPositionsJSONBody,
|
||||
RESTPatchAPIGuildChannelPositionsResult,
|
||||
RESTPatchAPIGuildEmojiJSONBody,
|
||||
RESTPatchAPIGuildEmojiResult,
|
||||
RESTPatchAPIGuildJSONBody,
|
||||
RESTPatchAPIGuildMemberJSONBody,
|
||||
RESTPatchAPIGuildMemberResult,
|
||||
RESTPatchAPIGuildResult,
|
||||
RESTPatchAPIGuildRoleJSONBody,
|
||||
RESTPatchAPIGuildRolePositionsJSONBody,
|
||||
RESTPatchAPIGuildRolePositionsResult,
|
||||
RESTPatchAPIGuildRoleResult,
|
||||
RESTPatchAPIGuildScheduledEventJSONBody,
|
||||
RESTPatchAPIGuildScheduledEventResult,
|
||||
RESTPatchAPIGuildStickerJSONBody,
|
||||
RESTPatchAPIGuildStickerResult,
|
||||
RESTPatchAPIGuildTemplateJSONBody,
|
||||
RESTPatchAPIGuildTemplateResult,
|
||||
RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody,
|
||||
RESTPatchAPIGuildVoiceStateCurrentMemberResult,
|
||||
RESTPatchAPIGuildVoiceStateUserJSONBody,
|
||||
RESTPatchAPIGuildVoiceStateUserResult,
|
||||
RESTPatchAPIGuildWelcomeScreenJSONBody,
|
||||
RESTPatchAPIGuildWelcomeScreenResult,
|
||||
RESTPatchAPIGuildWidgetSettingsJSONBody,
|
||||
RESTPatchAPIGuildWidgetSettingsResult,
|
||||
RESTPostAPIAutoModerationRuleJSONBody,
|
||||
RESTPostAPIAutoModerationRuleResult,
|
||||
RESTPostAPIGuildChannelJSONBody,
|
||||
RESTPostAPIGuildChannelResult,
|
||||
RESTPostAPIGuildEmojiJSONBody,
|
||||
RESTPostAPIGuildEmojiResult,
|
||||
RESTPostAPIGuildPruneJSONBody,
|
||||
RESTPostAPIGuildPruneResult,
|
||||
RESTPostAPIGuildRoleJSONBody,
|
||||
RESTPostAPIGuildRoleResult,
|
||||
RESTPostAPIGuildScheduledEventJSONBody,
|
||||
RESTPostAPIGuildScheduledEventResult,
|
||||
RESTPostAPIGuildStickerFormDataBody,
|
||||
RESTPostAPIGuildStickerResult,
|
||||
RESTPostAPIGuildTemplatesJSONBody,
|
||||
RESTPostAPIGuildTemplatesResult,
|
||||
RESTPostAPIGuildsJSONBody,
|
||||
RESTPostAPIGuildsMFAJSONBody,
|
||||
RESTPostAPIGuildsMFAResult,
|
||||
RESTPostAPIGuildsResult,
|
||||
RESTPostAPITemplateCreateGuildJSONBody,
|
||||
RESTPostAPITemplateCreateGuildResult,
|
||||
RESTPutAPIGuildBanJSONBody,
|
||||
RESTPutAPIGuildBanResult,
|
||||
RESTPutAPIGuildMemberJSONBody,
|
||||
RESTPutAPIGuildMemberResult,
|
||||
RESTPutAPIGuildMemberRoleResult,
|
||||
RESTPutAPIGuildTemplateSyncResult
|
||||
} from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface GuildRoutes {
|
||||
guilds: {
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildsJSONBody>): Promise<RESTPostAPIGuildsResult>;
|
||||
templates(code: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPITemplateResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPITemplateCreateGuildJSONBody>): Promise<RESTPostAPITemplateCreateGuildResult>;
|
||||
};
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIGuildQuery>): Promise<RESTGetAPIGuildResult>;
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildJSONBody>): Promise<RESTPatchAPIGuildResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildResult>;
|
||||
webhooks: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildWebhooksResult>;
|
||||
};
|
||||
preview: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildPreviewResult>;
|
||||
};
|
||||
'audit-logs': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIAuditLogQuery>): Promise<RESTGetAPIAuditLogResult>;
|
||||
};
|
||||
'auto-moderation': {
|
||||
rules: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIAutoModerationRulesResult>;
|
||||
//.
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIAutoModerationRuleJSONBody>
|
||||
): Promise<RESTPostAPIAutoModerationRuleResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIAutoModerationRuleResult>;
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Post, RESTPatchAPIAutoModerationRuleJSONBody>
|
||||
): Promise<RESTPatchAPIAutoModerationRuleResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIAutoModerationRuleResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
channels: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildChannelsResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildChannelJSONBody>): Promise<RESTPostAPIGuildChannelResult>;
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildChannelPositionsJSONBody>
|
||||
): Promise<RESTPatchAPIGuildChannelPositionsResult>;
|
||||
};
|
||||
members: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIGuildMembersQuery>): Promise<RESTGetAPIGuildMembersResult>;
|
||||
search: {
|
||||
//.
|
||||
get(args: RestArguments<RequestMethod.Get, RESTGetAPIGuildMembersSearchQuery>): Promise<RESTGetAPIGuildMembersSearchResult>;
|
||||
};
|
||||
'@me': {
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPICurrentGuildMemberJSONBody>): Promise<RESTGetAPIGuildMemberResult>;
|
||||
};
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildMemberResult>;
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put, RESTPutAPIGuildMemberJSONBody>): Promise<RESTPutAPIGuildMemberResult>;
|
||||
//.
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildMemberJSONBody>): Promise<RESTPatchAPIGuildMemberResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildMemberResult>;
|
||||
roles(id: string): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put>): Promise<RESTPutAPIGuildMemberRoleResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildMemberRoleResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
threads: {
|
||||
active: {
|
||||
//.
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get>
|
||||
): Promise<Identify<RESTGetAPIGuildThreadsResult & { threads: Partial<APIThreadChannel> }>>;
|
||||
};
|
||||
};
|
||||
roles: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildRolesResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildRoleJSONBody>): Promise<RESTPostAPIGuildRoleResult>;
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildRolePositionsJSONBody>
|
||||
): Promise<RESTPatchAPIGuildRolePositionsResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildRoleJSONBody>): Promise<RESTPatchAPIGuildRoleResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildRoleResult>;
|
||||
};
|
||||
};
|
||||
bans: {
|
||||
//.
|
||||
get(args: RestArguments<RequestMethod.Get, RESTGetAPIGuildBansQuery>): Promise<RESTGetAPIGuildBansResult>;
|
||||
(userId: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildBanResult>;
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put, RESTPutAPIGuildBanJSONBody>): Promise<RESTPutAPIGuildBanResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildBanResult>;
|
||||
};
|
||||
};
|
||||
mfa: {
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildsMFAJSONBody>): Promise<RESTPostAPIGuildsMFAResult>;
|
||||
};
|
||||
prune: {
|
||||
//.
|
||||
get(args: RestArguments<RequestMethod.Get, RESTGetAPIGuildPruneCountQuery>): Promise<RESTGetAPIGuildPruneCountResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildPruneJSONBody>): Promise<RESTPostAPIGuildPruneResult>;
|
||||
};
|
||||
regions: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildVoiceRegionsResult>;
|
||||
};
|
||||
invites: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildInvitesResult>;
|
||||
};
|
||||
widget: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildWidgetSettingsResult>;
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildWidgetSettingsJSONBody>
|
||||
): Promise<RESTPatchAPIGuildWidgetSettingsResult>;
|
||||
};
|
||||
'widget.json': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildWidgetJSONResult>;
|
||||
};
|
||||
'widget.png': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIGuildWidgetImageQuery>): Promise<RESTGetAPIGuildWidgetImageResult>;
|
||||
};
|
||||
integrations: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildIntegrationsResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildIntegrationResult>;
|
||||
};
|
||||
};
|
||||
'vanity-url': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildVanityUrlResult>;
|
||||
};
|
||||
'welcome-screen': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildWelcomeScreenResult>;
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildWelcomeScreenJSONBody>
|
||||
): Promise<RESTPatchAPIGuildWelcomeScreenResult>;
|
||||
};
|
||||
// onboarding: {
|
||||
// get(args:RestArguments<RequestMethod.Get,boarding>);
|
||||
// }
|
||||
emojis: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildEmojisResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildEmojiJSONBody>): Promise<RESTPostAPIGuildEmojiResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildEmojiResult>;
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildEmojiJSONBody>): Promise<RESTPatchAPIGuildEmojiResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildEmojiResult>;
|
||||
};
|
||||
};
|
||||
'voice-states': {
|
||||
'@me': {
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody>
|
||||
): Promise<RESTPatchAPIGuildVoiceStateCurrentMemberResult>;
|
||||
};
|
||||
(id: string): {
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildVoiceStateUserJSONBody>
|
||||
): Promise<RESTPatchAPIGuildVoiceStateUserResult>;
|
||||
};
|
||||
};
|
||||
stickers: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildStickersResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildStickerFormDataBody>): Promise<RESTPostAPIGuildStickerResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildStickerResult>;
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildStickerJSONBody>): Promise<RESTPatchAPIGuildStickerResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildStickerResult>;
|
||||
};
|
||||
};
|
||||
'scheduled-events': {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIGuildScheduledEventsQuery>): Promise<RESTGetAPIGuildScheduledEventsResult>;
|
||||
//.
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIGuildScheduledEventJSONBody>
|
||||
): Promise<RESTPostAPIGuildScheduledEventResult>;
|
||||
(id: string): {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIGuildScheduledEventQuery>): Promise<RESTGetAPIGuildScheduledEventResult>;
|
||||
//.
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildScheduledEventJSONBody>
|
||||
): Promise<RESTPatchAPIGuildScheduledEventResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildScheduledEventResult>;
|
||||
users: {
|
||||
//.
|
||||
get(
|
||||
args?: RestArguments<RequestMethod.Get, RESTGetAPIGuildScheduledEventUsersQuery>
|
||||
): Promise<RESTGetAPIGuildScheduledEventUsersResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
templates: {
|
||||
//.
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIGuildTemplatesResult>;
|
||||
//.
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIGuildTemplatesJSONBody>): Promise<RESTPostAPIGuildTemplatesResult>;
|
||||
(code: string): {
|
||||
//.
|
||||
put(args: RestArguments<RequestMethod.Put>): Promise<RESTPutAPIGuildTemplateSyncResult>;
|
||||
//.
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIGuildTemplateJSONBody>): Promise<RESTPatchAPIGuildTemplateResult>;
|
||||
//.
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildTemplateResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { ApplicationRoutes } from './applications';
|
||||
import { ChannelRoutes } from './channels';
|
||||
import { GatewayRoutes } from './gateway';
|
||||
import { GuildRoutes } from './guilds';
|
||||
import { InteractionRoutes } from './interactions';
|
||||
import { InviteRoutes } from './invites';
|
||||
import { StageInstanceRoutes } from './stage-instances';
|
||||
import { StickerRoutes } from './stickers';
|
||||
import { UserRoutes } from './users';
|
||||
import { VoiceRoutes } from './voice';
|
||||
import { WebhookRoutes } from './webhooks';
|
||||
|
||||
export type Routes = ApplicationRoutes &
|
||||
ChannelRoutes &
|
||||
GatewayRoutes &
|
||||
GuildRoutes &
|
||||
InteractionRoutes &
|
||||
InviteRoutes &
|
||||
StageInstanceRoutes &
|
||||
StickerRoutes &
|
||||
UserRoutes &
|
||||
VoiceRoutes &
|
||||
WebhookRoutes;
|
@ -1,15 +0,0 @@
|
||||
import { RESTPostAPIInteractionCallbackJSONBody } from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface InteractionRoutes {
|
||||
interactions: {
|
||||
(id: string): {
|
||||
(token: string): {
|
||||
callback: {
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIInteractionCallbackJSONBody>): Promise<never>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
import { RESTDeleteAPIInviteResult, RESTGetAPIInviteQuery, RESTGetAPIInviteResult } from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface InviteRoutes {
|
||||
invites(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPIInviteQuery>): Promise<RESTGetAPIInviteResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIInviteResult>;
|
||||
};
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import {
|
||||
RESTDeleteAPIStageInstanceResult,
|
||||
RESTGetAPIStageInstanceResult,
|
||||
RESTPatchAPIStageInstanceJSONBody,
|
||||
RESTPatchAPIStageInstanceResult,
|
||||
RESTPostAPIStageInstanceJSONBody,
|
||||
RESTPostAPIStageInstanceResult
|
||||
} from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface StageInstanceRoutes {
|
||||
'stage-instances': {
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPIStageInstanceJSONBody>): Promise<RESTPostAPIStageInstanceResult>;
|
||||
(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIStageInstanceResult>;
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIStageInstanceJSONBody>): Promise<RESTPatchAPIStageInstanceResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIStageInstanceResult>;
|
||||
};
|
||||
};
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { RESTGetAPIStickerResult, RESTGetNitroStickerPacksResult } from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface StickerRoutes {
|
||||
stickers(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIStickerResult>;
|
||||
};
|
||||
'sticker-packs': {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetNitroStickerPacksResult>;
|
||||
};
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import {
|
||||
APIDMChannel,
|
||||
RESTDeleteAPIGuildResult,
|
||||
RESTGetAPICurrentUserApplicationRoleConnectionResult,
|
||||
RESTGetAPICurrentUserConnectionsResult,
|
||||
RESTGetAPICurrentUserGuildsQuery,
|
||||
RESTGetAPICurrentUserGuildsResult,
|
||||
RESTGetAPICurrentUserResult,
|
||||
RESTGetAPIUserResult,
|
||||
RESTGetCurrentUserGuildMemberResult,
|
||||
RESTPatchAPICurrentUserJSONBody,
|
||||
RESTPatchAPICurrentUserResult,
|
||||
RESTPostAPICurrentUserCreateDMChannelJSONBody,
|
||||
RESTPutAPICurrentUserApplicationRoleConnectionJSONBody,
|
||||
RESTPutAPICurrentUserApplicationRoleConnectionResult
|
||||
} from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface UserRoutes {
|
||||
users: {
|
||||
(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIUserResult>;
|
||||
};
|
||||
(id: '@me'): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPICurrentUserResult>;
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPICurrentUserJSONBody>): Promise<RESTPatchAPICurrentUserResult>;
|
||||
guilds: {
|
||||
get(args?: RestArguments<RequestMethod.Get, RESTGetAPICurrentUserGuildsQuery>): Promise<RESTGetAPICurrentUserGuildsResult>;
|
||||
(id: string): {
|
||||
member: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetCurrentUserGuildMemberResult>;
|
||||
};
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIGuildResult>;
|
||||
};
|
||||
};
|
||||
channels: {
|
||||
post(args: RestArguments<RequestMethod.Post, RESTPostAPICurrentUserCreateDMChannelJSONBody>): Promise<APIDMChannel>;
|
||||
};
|
||||
connections: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPICurrentUserConnectionsResult>;
|
||||
};
|
||||
applications(applicationId: string): {
|
||||
'role-connection': {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPICurrentUserApplicationRoleConnectionResult>;
|
||||
put(
|
||||
args: RestArguments<RequestMethod.Put, RESTPutAPICurrentUserApplicationRoleConnectionJSONBody>
|
||||
): Promise<RESTPutAPICurrentUserApplicationRoleConnectionResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { RESTGetAPIVoiceRegionsResult } from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface VoiceRoutes {
|
||||
voice: {
|
||||
region: {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIVoiceRegionsResult>;
|
||||
};
|
||||
};
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import {
|
||||
RESTDeleteAPIWebhookResult,
|
||||
RESTDeleteAPIWebhookWithTokenMessageResult,
|
||||
RESTDeleteAPIWebhookWithTokenResult,
|
||||
RESTGetAPIWebhookResult,
|
||||
RESTGetAPIWebhookWithTokenMessageResult,
|
||||
RESTGetAPIWebhookWithTokenResult,
|
||||
RESTPatchAPIWebhookJSONBody,
|
||||
RESTPatchAPIWebhookResult,
|
||||
RESTPatchAPIWebhookWithTokenJSONBody,
|
||||
RESTPatchAPIWebhookWithTokenMessageJSONBody,
|
||||
RESTPatchAPIWebhookWithTokenMessageResult,
|
||||
RESTPatchAPIWebhookWithTokenResult,
|
||||
RESTPostAPIWebhookWithTokenGitHubQuery,
|
||||
RESTPostAPIWebhookWithTokenGitHubResult,
|
||||
RESTPostAPIWebhookWithTokenGitHubWaitResult,
|
||||
RESTPostAPIWebhookWithTokenJSONBody,
|
||||
RESTPostAPIWebhookWithTokenQuery,
|
||||
RESTPostAPIWebhookWithTokenResult,
|
||||
RESTPostAPIWebhookWithTokenSlackQuery,
|
||||
RESTPostAPIWebhookWithTokenSlackResult,
|
||||
RESTPostAPIWebhookWithTokenSlackWaitResult,
|
||||
RESTPostAPIWebhookWithTokenWaitResult
|
||||
} from '@biscuitland/common';
|
||||
import { RestArguments } from '../REST';
|
||||
import { RequestMethod } from '../Router';
|
||||
|
||||
export interface WebhookRoutes {
|
||||
webhooks(id: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIWebhookResult>;
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIWebhookJSONBody>): Promise<RESTPatchAPIWebhookResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIWebhookResult>;
|
||||
(token: string): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIWebhookWithTokenResult>;
|
||||
patch(args: RestArguments<RequestMethod.Patch, RESTPatchAPIWebhookWithTokenJSONBody>): Promise<RESTPatchAPIWebhookWithTokenResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIWebhookWithTokenResult>;
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIWebhookWithTokenJSONBody, RESTPostAPIWebhookWithTokenQuery>
|
||||
): Promise<RESTPostAPIWebhookWithTokenResult | RESTPostAPIWebhookWithTokenWaitResult>;
|
||||
slack: {
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIWebhookWithTokenJSONBody, RESTPostAPIWebhookWithTokenSlackQuery>
|
||||
): Promise<RESTPostAPIWebhookWithTokenSlackResult | RESTPostAPIWebhookWithTokenSlackWaitResult>;
|
||||
};
|
||||
github: {
|
||||
post(
|
||||
args: RestArguments<RequestMethod.Post, RESTPostAPIWebhookWithTokenJSONBody, RESTPostAPIWebhookWithTokenGitHubQuery>
|
||||
): Promise<RESTPostAPIWebhookWithTokenGitHubResult | RESTPostAPIWebhookWithTokenGitHubWaitResult>;
|
||||
};
|
||||
messages: {
|
||||
(id: string | '@original'): {
|
||||
get(args?: RestArguments<RequestMethod.Get>): Promise<RESTGetAPIWebhookWithTokenMessageResult>;
|
||||
patch(
|
||||
args: RestArguments<RequestMethod.Patch, RESTPatchAPIWebhookWithTokenMessageJSONBody>
|
||||
): Promise<RESTPatchAPIWebhookWithTokenMessageResult>;
|
||||
delete(args?: RestArguments<RequestMethod.Delete>): Promise<RESTDeleteAPIWebhookWithTokenMessageResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export { REST, type RawFile } from '@discordjs/rest';
|
||||
export * from './CDN';
|
||||
export * from './REST';
|
||||
export * from './Router';
|
||||
export * from './Routes';
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
export default defineConfig({
|
||||
clean: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
format: ['cjs', 'esm'],
|
||||
minify: isProduction,
|
||||
sourcemap: false
|
||||
});
|
@ -1,149 +0,0 @@
|
||||
# @biscuitland/ws
|
||||
|
||||
## 3.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- new changes
|
||||
- new changes
|
||||
|
||||
## 3.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- silly bug on options
|
||||
|
||||
## 3.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.8
|
||||
|
||||
## 3.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.7
|
||||
|
||||
## 3.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- I meessed up
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.6
|
||||
- @biscuitland/rest@3.0.6
|
||||
|
||||
## 3.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix: logger on every module
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.5
|
||||
- @biscuitland/rest@3.0.5
|
||||
|
||||
## 3.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- first 3.0.\* without bugs
|
||||
- Updated dependencies
|
||||
- @biscuitland/common@0.0.4
|
||||
- @biscuitland/rest@3.0.4
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- fix TODO
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.3.0
|
||||
|
||||
## 2.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- bug fixes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.3
|
||||
|
||||
## 2.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- rename guildLocales to guildLocale in interactions
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.2
|
||||
|
||||
## 2.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- select menu options now can be empty since the latest Discord API update
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.1
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Functionality to delete ephemeral messages added, select menus were updated
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.2.0
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- minor changes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- dumb hotfix that LH asked for (blame Yuzu)
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Changes to cache and forum channels ✨
|
||||
- Forum channels and updates to @biscuitland/cache ✨
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.1.0
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Minor fixes
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Major Changes
|
||||
|
||||
- publish
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @biscuitland/api-types@2.0.5
|
@ -1,56 +0,0 @@
|
||||
# @biscuitland/ws
|
||||
|
||||
## Advice
|
||||
|
||||
This version of @biscuitland/ws is a **fork** of @discordeno/gateway, all credits go to them. However it has been heavily modified for proper use within biscuit.
|
||||
|
||||
## Most importantly, biscuit's ws is:
|
||||
|
||||
A standalone gateway to interface Discord, it is meant to be used with a rest manager to send fetch requests to Discord
|
||||
|
||||
[<img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white">](https://github.com/oasisjs/biscuit)
|
||||
[<img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white">](https://discord.gg/XNw2RZFzaP)
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/oasisjs/biscuit/main/assets/icon.svg" alt="biscuit"/>
|
||||
|
||||
## Install (for [node18](https://nodejs.org/en/download/))
|
||||
|
||||
```sh-session
|
||||
npm install @biscuitland/ws
|
||||
yarn add @biscuitland/ws
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import { ShardManager } from "@biscuitland/ws";
|
||||
import { BiscuitREST, Router } from "@biscuitland/rest";
|
||||
import { GatewayIntentBits } from "@biscuitland/common";
|
||||
|
||||
const intents = GatewayIntentBits.Guilds;
|
||||
const token = "your token goes here";
|
||||
const rest = new BiscuitREST({ token });
|
||||
const api = new Router(rest).createProxy();
|
||||
|
||||
(async () => {
|
||||
const connection = await api.gateway.bot.get();
|
||||
|
||||
// gateway bot code ↓
|
||||
const ws = new ShardManager({
|
||||
token,
|
||||
intents,
|
||||
connection,
|
||||
async handlePayload(shardId, payload) {
|
||||
console.log("Received payload on shard #%s", shardId, payload);
|
||||
},
|
||||
});
|
||||
|
||||
await ws.spawnShards();
|
||||
})();
|
||||
```
|
||||
|
||||
## Links
|
||||
* [Website](https://biscuitjs.com/)
|
||||
* [Documentation](https://docs.biscuitjs.com/)
|
||||
* [Discord](https://discord.gg/XNw2RZFzaP)
|
||||
* [rest](https://www.npmjs.com/package/@biscuitland/rest) | [core](https://www.npmjs.com/package/@biscuitland/core) | [helpers](https://www.npmjs.com/package/@biscuitland/helpers)
|
@ -1,82 +0,0 @@
|
||||
{
|
||||
"name": "@biscuitland/ws",
|
||||
"version": "3.0.12",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"clean": "rm -rf dist && rm -rf .turbo",
|
||||
"dev": "tsup --watch",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@biscuitland/common": "^0.0.10",
|
||||
"@biscuitland/rest": "^3.0.7",
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/ws": "^8.5.4",
|
||||
"tsup": "^7.0.0"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "src"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": "Yuzuru <yuzuru@programmer.net>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Yuzuru",
|
||||
"url": "https://github.com/yuzudev"
|
||||
},
|
||||
{
|
||||
"name": "miia",
|
||||
"url": "https://github.com/dragurimu"
|
||||
},
|
||||
{
|
||||
"name": "n128",
|
||||
"url": "https://github.com/nicolito128"
|
||||
},
|
||||
{
|
||||
"name": "socram03",
|
||||
"url": "https://github.com/socram03",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Drylozu",
|
||||
"url": "https://github.com/Drylozu"
|
||||
}
|
||||
],
|
||||
"homepage": "https://biscuitjs.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/oasisjs/biscuit.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/oasisjs/biscuit"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
"discord",
|
||||
"bots",
|
||||
"typescript",
|
||||
"botdev"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
import type {
|
||||
APIAuditLogEntry,
|
||||
APIAutoModerationRule,
|
||||
APIChannel,
|
||||
APIGuild,
|
||||
APIGuildMember,
|
||||
APIGuildScheduledEvent,
|
||||
APIStageInstance,
|
||||
APIUser,
|
||||
GatewayActivity,
|
||||
GatewayAutoModerationActionExecutionDispatchData,
|
||||
GatewayChannelPinsUpdateDispatchData,
|
||||
GatewayChannelUpdateDispatchData,
|
||||
GatewayDispatchEvents,
|
||||
GatewayGuildBanAddDispatchData,
|
||||
GatewayGuildBanRemoveDispatchData,
|
||||
GatewayGuildCreateDispatchData,
|
||||
GatewayGuildDeleteDispatchData,
|
||||
GatewayGuildEmojisUpdateDispatchData,
|
||||
GatewayGuildIntegrationsUpdateDispatchData,
|
||||
GatewayGuildMemberAddDispatchData,
|
||||
GatewayGuildMemberRemoveDispatchData,
|
||||
GatewayGuildMemberUpdateDispatchData,
|
||||
GatewayGuildMembersChunkDispatchData,
|
||||
GatewayGuildRoleCreateDispatchData,
|
||||
GatewayGuildRoleDeleteDispatchData,
|
||||
GatewayGuildRoleUpdateDispatchData,
|
||||
GatewayGuildScheduledEventUserRemoveDispatchData,
|
||||
GatewayGuildStickersUpdateDispatchData,
|
||||
GatewayIntegrationCreateDispatchData,
|
||||
GatewayIntegrationDeleteDispatchData,
|
||||
GatewayInteractionCreateDispatchData,
|
||||
GatewayInviteCreateDispatchData,
|
||||
GatewayInviteDeleteDispatchData,
|
||||
GatewayMessageCreateDispatchData,
|
||||
GatewayMessageDeleteBulkDispatchData,
|
||||
GatewayMessageDeleteDispatchData,
|
||||
GatewayMessageReactionAddDispatchData,
|
||||
GatewayMessageReactionRemoveAllDispatchData,
|
||||
GatewayMessageReactionRemoveDispatchData,
|
||||
GatewayMessageReactionRemoveEmojiDispatchData,
|
||||
GatewayMessageUpdateDispatchData,
|
||||
GatewayPresenceUpdateData,
|
||||
GatewayPresenceUpdateDispatchData,
|
||||
GatewayReadyDispatchData,
|
||||
GatewayRequestGuildMembersDataWithQuery,
|
||||
GatewayRequestGuildMembersDataWithUserIds,
|
||||
GatewayThreadCreateDispatchData,
|
||||
GatewayThreadDeleteDispatchData,
|
||||
GatewayThreadListSyncDispatchData,
|
||||
GatewayThreadMemberUpdateDispatchData,
|
||||
GatewayThreadMembersUpdateDispatchData,
|
||||
GatewayTypingStartDispatchData,
|
||||
GatewayUserUpdateDispatchData,
|
||||
GatewayVoiceServerUpdateDispatchData,
|
||||
GatewayVoiceStateUpdateData,
|
||||
GatewayWebhooksUpdateDispatchData,
|
||||
PresenceUpdateStatus,
|
||||
RestToKeys
|
||||
} from '@biscuitland/common';
|
||||
|
||||
/** https://discord.com/developers/docs/topics/gateway-events#update-presence */
|
||||
export interface StatusUpdate {
|
||||
/** The user's activities */
|
||||
activities?: Omit<GatewayActivity, 'created_at' | 'id'>[];
|
||||
/** The user's new status */
|
||||
status: PresenceUpdateStatus;
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/topics/gateway#update-voice-state */
|
||||
export interface UpdateVoiceState {
|
||||
/** id of the guild */
|
||||
guild_id: string;
|
||||
/** id of the voice channel client wants to join (null if disconnecting) */
|
||||
channel_id: string | null;
|
||||
/** Is the client muted */
|
||||
self_mute: boolean;
|
||||
/** Is the client deafened */
|
||||
self_deaf: boolean;
|
||||
}
|
||||
|
||||
export type ShardStatusUpdate = Pick<GatewayPresenceUpdateData, 'activities' | 'status'>;
|
||||
|
||||
export interface RequestGuildMembersOptions extends GatewayRequestGuildMembersDataWithQuery, GatewayRequestGuildMembersDataWithUserIds {}
|
||||
|
||||
export interface GatewayMemberRequest {
|
||||
/** The unique nonce for this request. */
|
||||
nonce: string;
|
||||
/** The resolver handler to run when all members arrive. */
|
||||
resolve: (value: APIGuildMember[] | PromiseLike<APIGuildMember[]>) => void;
|
||||
/** The members that have already arrived for this request. */
|
||||
members: APIGuildMember[];
|
||||
}
|
||||
|
||||
export type AtLeastOne<
|
||||
T,
|
||||
U = {
|
||||
[K in keyof T]: Pick<T, K>;
|
||||
}
|
||||
> = Partial<T> & U[keyof U];
|
||||
|
||||
export type ClientUser = { bot: true } & APIUser;
|
||||
|
||||
export interface Events {
|
||||
[GatewayDispatchEvents.Ready]: GatewayReadyDispatchData & {
|
||||
user: ClientUser;
|
||||
};
|
||||
[GatewayDispatchEvents.ChannelUpdate]: GatewayChannelUpdateDispatchData;
|
||||
[GatewayDispatchEvents.AutoModerationActionExecution]: GatewayAutoModerationActionExecutionDispatchData;
|
||||
[GatewayDispatchEvents.ThreadCreate]: GatewayThreadCreateDispatchData;
|
||||
[GatewayDispatchEvents.ThreadDelete]: GatewayThreadDeleteDispatchData;
|
||||
[GatewayDispatchEvents.ThreadUpdate]: GatewayThreadDeleteDispatchData;
|
||||
[GatewayDispatchEvents.ThreadListSync]: GatewayThreadListSyncDispatchData;
|
||||
[GatewayDispatchEvents.ThreadMemberUpdate]: GatewayThreadMemberUpdateDispatchData;
|
||||
[GatewayDispatchEvents.ThreadMembersUpdate]: GatewayThreadMembersUpdateDispatchData;
|
||||
[GatewayDispatchEvents.ChannelPinsUpdate]: GatewayChannelPinsUpdateDispatchData;
|
||||
[GatewayDispatchEvents.GuildCreate]: GatewayGuildCreateDispatchData;
|
||||
[GatewayDispatchEvents.GuildUpdate]: APIGuild;
|
||||
[GatewayDispatchEvents.GuildDelete]: GatewayGuildDeleteDispatchData;
|
||||
[GatewayDispatchEvents.GuildAuditLogEntryCreate]: APIAuditLogEntry;
|
||||
[GatewayDispatchEvents.GuildBanAdd]: GatewayGuildBanAddDispatchData;
|
||||
[GatewayDispatchEvents.GuildBanRemove]: GatewayGuildBanRemoveDispatchData;
|
||||
[GatewayDispatchEvents.GuildEmojisUpdate]: GatewayGuildEmojisUpdateDispatchData;
|
||||
[GatewayDispatchEvents.GuildStickersUpdate]: GatewayGuildStickersUpdateDispatchData;
|
||||
[GatewayDispatchEvents.GuildIntegrationsUpdate]: GatewayGuildIntegrationsUpdateDispatchData;
|
||||
[GatewayDispatchEvents.GuildMemberAdd]: GatewayGuildMemberAddDispatchData;
|
||||
[GatewayDispatchEvents.GuildMemberRemove]: GatewayGuildMemberRemoveDispatchData;
|
||||
[GatewayDispatchEvents.GuildMemberUpdate]: GatewayGuildMemberUpdateDispatchData;
|
||||
[GatewayDispatchEvents.GuildMembersChunk]: GatewayGuildMembersChunkDispatchData;
|
||||
[GatewayDispatchEvents.GuildRoleCreate]: GatewayGuildRoleCreateDispatchData;
|
||||
[GatewayDispatchEvents.GuildRoleUpdate]: GatewayGuildRoleUpdateDispatchData;
|
||||
[GatewayDispatchEvents.GuildRoleDelete]: GatewayGuildRoleDeleteDispatchData;
|
||||
[GatewayDispatchEvents.IntegrationDelete]: GatewayIntegrationDeleteDispatchData;
|
||||
[GatewayDispatchEvents.InviteCreate]: GatewayInviteCreateDispatchData;
|
||||
[GatewayDispatchEvents.InviteDelete]: GatewayInviteDeleteDispatchData;
|
||||
[GatewayDispatchEvents.MessageCreate]: GatewayMessageCreateDispatchData;
|
||||
[GatewayDispatchEvents.MessageUpdate]: GatewayMessageUpdateDispatchData;
|
||||
[GatewayDispatchEvents.MessageDelete]: GatewayMessageDeleteDispatchData;
|
||||
[GatewayDispatchEvents.MessageDeleteBulk]: GatewayMessageDeleteBulkDispatchData;
|
||||
[GatewayDispatchEvents.MessageReactionAdd]: GatewayMessageReactionAddDispatchData;
|
||||
[GatewayDispatchEvents.MessageReactionRemove]: GatewayMessageReactionRemoveDispatchData;
|
||||
[GatewayDispatchEvents.MessageReactionRemoveAll]: GatewayMessageReactionRemoveAllDispatchData;
|
||||
[GatewayDispatchEvents.MessageReactionRemoveEmoji]: GatewayMessageReactionRemoveEmojiDispatchData;
|
||||
[GatewayDispatchEvents.PresenceUpdate]: GatewayPresenceUpdateDispatchData;
|
||||
[GatewayDispatchEvents.TypingStart]: GatewayTypingStartDispatchData;
|
||||
[GatewayDispatchEvents.UserUpdate]: GatewayUserUpdateDispatchData;
|
||||
[GatewayDispatchEvents.VoiceStateUpdate]: GatewayVoiceStateUpdateData;
|
||||
[GatewayDispatchEvents.VoiceServerUpdate]: GatewayVoiceServerUpdateDispatchData;
|
||||
[GatewayDispatchEvents.WebhooksUpdate]: GatewayWebhooksUpdateDispatchData;
|
||||
[GatewayDispatchEvents.InteractionCreate]: GatewayInteractionCreateDispatchData;
|
||||
}
|
||||
|
||||
export type StageSameEvents = RestToKeys<
|
||||
[
|
||||
APIStageInstance,
|
||||
GatewayDispatchEvents.StageInstanceCreate,
|
||||
GatewayDispatchEvents.StageInstanceUpdate,
|
||||
GatewayDispatchEvents.StageInstanceDelete
|
||||
]
|
||||
>;
|
||||
|
||||
export type IntegrationSameEvents = RestToKeys<
|
||||
[GatewayIntegrationCreateDispatchData, GatewayDispatchEvents.IntegrationCreate, GatewayDispatchEvents.IntegrationUpdate]
|
||||
>;
|
||||
|
||||
export type GuildScheduledUserSameEvents = RestToKeys<
|
||||
[
|
||||
GatewayGuildScheduledEventUserRemoveDispatchData,
|
||||
GatewayDispatchEvents.GuildScheduledEventUserRemove,
|
||||
GatewayDispatchEvents.GuildScheduledEventUserAdd
|
||||
]
|
||||
>;
|
||||
|
||||
export type GuildScheduledSameEvents = RestToKeys<
|
||||
[
|
||||
APIGuildScheduledEvent,
|
||||
GatewayDispatchEvents.GuildScheduledEventCreate,
|
||||
GatewayDispatchEvents.GuildScheduledEventDelete,
|
||||
GatewayDispatchEvents.GuildScheduledEventUpdate
|
||||
]
|
||||
>;
|
||||
|
||||
export type ChannelSameEvents = RestToKeys<
|
||||
[APIChannel, GatewayDispatchEvents.ChannelCreate, GatewayDispatchEvents.ChannelDelete, GatewayDispatchEvents.ChannelUpdate]
|
||||
>;
|
||||
|
||||
export type AutoModetaractionRuleEvents = RestToKeys<
|
||||
[
|
||||
APIAutoModerationRule,
|
||||
GatewayDispatchEvents.AutoModerationRuleCreate,
|
||||
GatewayDispatchEvents.AutoModerationRuleDelete,
|
||||
GatewayDispatchEvents.AutoModerationRuleUpdate
|
||||
]
|
||||
>;
|
||||
|
||||
export type NormalizeEvents = Events &
|
||||
AutoModetaractionRuleEvents &
|
||||
ChannelSameEvents &
|
||||
GuildScheduledSameEvents &
|
||||
GuildScheduledUserSameEvents &
|
||||
IntegrationSameEvents &
|
||||
StageSameEvents & { RAW: GatewayDispatchEvents };
|
||||
|
||||
export type GatewayEvents = { [x in keyof NormalizeEvents]: NormalizeEvents[x] };
|
@ -1,40 +0,0 @@
|
||||
import type { GatewayDispatchPayload } from '@biscuitland/common';
|
||||
import { ShardManagerOptions } from '../discord';
|
||||
|
||||
const COMPRESS = false;
|
||||
|
||||
const properties = {
|
||||
os: process.platform,
|
||||
browser: 'Biscuit',
|
||||
device: 'Biscuit'
|
||||
};
|
||||
|
||||
const ShardManagerDefaults: Partial<ShardManagerOptions> = {
|
||||
totalShards: 1,
|
||||
spawnShardDelay: 5300,
|
||||
debug: false,
|
||||
intents: 0,
|
||||
properties: properties,
|
||||
version: 10,
|
||||
handlePayload: (shardId: number, packet: GatewayDispatchPayload): void => {
|
||||
console.info(`Packet ${packet.t} on shard ${shardId}`);
|
||||
}
|
||||
};
|
||||
|
||||
export interface IdentifyProperties {
|
||||
/**
|
||||
* Operating system the shard runs on.
|
||||
* @default "darwin" | "linux" | "windows"
|
||||
*/
|
||||
os: string;
|
||||
/**
|
||||
* The "browser" where this shard is running on.
|
||||
*/
|
||||
browser: string;
|
||||
/**
|
||||
* The device on which the shard is running.
|
||||
*/
|
||||
device: string;
|
||||
}
|
||||
|
||||
export { COMPRESS, ShardManagerDefaults, properties };
|
@ -1,302 +0,0 @@
|
||||
import { inflateSync } from 'node:zlib';
|
||||
import type { GatewayReceivePayload, GatewaySendPayload, Logger } from '@biscuitland/common';
|
||||
import { GatewayCloseCodes, GatewayDispatchEvents, GatewayOpcodes } from '@biscuitland/common';
|
||||
import type WS from 'ws';
|
||||
import { type CloseEvent, WebSocket } from 'ws';
|
||||
import { properties } from '../constants';
|
||||
import { ConnectTimeout, DynamicBucket, PriorityQueue } from '../structures';
|
||||
import type { ShardData, ShardOptions } from './shared';
|
||||
import { ShardSocketCloseCodes } from './shared';
|
||||
|
||||
export class Shard {
|
||||
logger: Logger;
|
||||
data: Partial<ShardData> | ShardData = {
|
||||
resumeSeq: null
|
||||
};
|
||||
|
||||
websocket: WebSocket | null = null;
|
||||
connectTimeout = new ConnectTimeout();
|
||||
heart: {
|
||||
interval: number;
|
||||
nodeInterval?: NodeJS.Timeout;
|
||||
lastAck?: number;
|
||||
lastBeat?: number;
|
||||
ack: boolean;
|
||||
} = {
|
||||
interval: 30e3,
|
||||
ack: true
|
||||
};
|
||||
|
||||
bucket: DynamicBucket;
|
||||
offlineSendQueue = new PriorityQueue<(_?: unknown) => void>();
|
||||
|
||||
constructor(public id: number, protected options: ShardOptions) {
|
||||
this.options.ratelimitOptions ??= {
|
||||
rateLimitResetInterval: 60_000,
|
||||
maxRequestsPerRateLimitTick: 120
|
||||
};
|
||||
this.logger = options.logger;
|
||||
|
||||
const safe = this.calculateSafeRequests();
|
||||
this.bucket = new DynamicBucket({
|
||||
limit: safe,
|
||||
refillAmount: safe,
|
||||
refillInterval: 6e4,
|
||||
logger: this.logger
|
||||
});
|
||||
}
|
||||
|
||||
get latency() {
|
||||
return this.heart.lastAck && this.heart.lastBeat ? this.heart.lastAck - this.heart.lastBeat : Infinity;
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
return this.websocket?.readyState === WebSocket.OPEN;
|
||||
}
|
||||
|
||||
get gatewayURL() {
|
||||
return this.options.info.url;
|
||||
}
|
||||
|
||||
get resumeGatewayURL() {
|
||||
return this.data.resume_gateway_url;
|
||||
}
|
||||
|
||||
get currentGatewayURL() {
|
||||
return this.resumeGatewayURL ?? this.options.info.url;
|
||||
}
|
||||
|
||||
async connect() {
|
||||
await this.connectTimeout.wait();
|
||||
|
||||
this.logger.debug(`[Shard #${this.id}] Connecting to ${this.currentGatewayURL}`);
|
||||
|
||||
this.websocket = new WebSocket(this.currentGatewayURL);
|
||||
|
||||
this.websocket!.onmessage = (event) => this.handleMessage(event);
|
||||
|
||||
this.websocket!.onclose = (event) => this.handleClosed(event);
|
||||
|
||||
this.websocket!.onerror = (event) => this.logger.error(event);
|
||||
|
||||
this.websocket!.onopen = () => {
|
||||
this.heart.ack = true;
|
||||
};
|
||||
}
|
||||
|
||||
async send<T extends GatewaySendPayload = GatewaySendPayload>(priority: number, message: T) {
|
||||
this.logger.info(`[Shard #${this.id}] Sending: ${GatewayOpcodes[message.op]} ${JSON.stringify(message.d, null, 1)}`);
|
||||
await this.checkOffline(priority);
|
||||
await this.bucket.acquire(priority);
|
||||
await this.checkOffline(priority);
|
||||
this.websocket?.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
async identify() {
|
||||
await this.send(0, {
|
||||
op: GatewayOpcodes.Identify,
|
||||
d: {
|
||||
token: `Bot ${this.options.token}`,
|
||||
compress: this.options.compress,
|
||||
properties,
|
||||
shard: [this.id, this.options.info.shards],
|
||||
intents: this.options.intents,
|
||||
presence: this.options.presence
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get resumable() {
|
||||
return !!(this.data.resume_gateway_url && this.data.session_id && this.data.resumeSeq !== null);
|
||||
}
|
||||
|
||||
async resume() {
|
||||
await this.send(0, {
|
||||
op: GatewayOpcodes.Resume,
|
||||
d: {
|
||||
seq: this.data.resumeSeq!,
|
||||
session_id: this.data.session_id!,
|
||||
token: `Bot ${this.options.token}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async heartbeat(requested: boolean) {
|
||||
this.logger.debug(`[Shard #${this.id}] Sending ${requested ? '' : 'un'}requested heartbeat (Ack=${this.heart.ack})`);
|
||||
if (!requested) {
|
||||
if (!this.heart.ack) {
|
||||
await this.close(ShardSocketCloseCodes.ZombiedConnection, 'Zombied connection');
|
||||
return;
|
||||
}
|
||||
this.heart.ack = false;
|
||||
}
|
||||
|
||||
this.heart.lastBeat = Date.now();
|
||||
|
||||
this.websocket!.send(
|
||||
JSON.stringify({
|
||||
op: GatewayOpcodes.Heartbeat,
|
||||
d: this.data.resumeSeq ?? null
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async disconnect() {
|
||||
this.logger.info(`[Shard #${this.id}] Disconnecting`);
|
||||
await this.close(ShardSocketCloseCodes.Shutdown, 'Shard down request');
|
||||
}
|
||||
|
||||
async reconnect() {
|
||||
this.logger.info(`[Shard #${this.id}] Reconnecting`);
|
||||
await this.disconnect();
|
||||
await this.connect();
|
||||
}
|
||||
|
||||
async onpacket(packet: GatewayReceivePayload) {
|
||||
if (packet.s !== null) {
|
||||
this.data.resumeSeq = packet.s;
|
||||
}
|
||||
|
||||
this.logger.debug(`[Shard #${this.id}]`, packet.t ? packet.t : GatewayOpcodes[packet.op], this.data.resumeSeq);
|
||||
|
||||
switch (packet.op) {
|
||||
case GatewayOpcodes.Hello:
|
||||
clearInterval(this.heart.nodeInterval);
|
||||
|
||||
this.heart.interval = packet.d.heartbeat_interval;
|
||||
|
||||
// await delay(Math.ceil(this.heart.interval * (Math.random() || 0.5)));
|
||||
await this.heartbeat(false);
|
||||
this.heart.nodeInterval = setInterval(() => this.heartbeat(false), this.heart.interval);
|
||||
|
||||
if (this.resumable) {
|
||||
return this.resume();
|
||||
}
|
||||
await this.identify();
|
||||
break;
|
||||
case GatewayOpcodes.HeartbeatAck:
|
||||
this.heart.ack = true;
|
||||
this.heart.lastAck = Date.now();
|
||||
break;
|
||||
case GatewayOpcodes.Heartbeat:
|
||||
this.heartbeat(true);
|
||||
break;
|
||||
case GatewayOpcodes.Reconnect:
|
||||
await this.reconnect();
|
||||
break;
|
||||
case GatewayOpcodes.InvalidSession:
|
||||
if (packet.d) {
|
||||
if (!this.resumable) {
|
||||
return this.logger.fatal(`[Shard #${this.id}] This is a completely unexpected error message.`);
|
||||
}
|
||||
await this.resume();
|
||||
} else {
|
||||
this.data.resumeSeq = 0;
|
||||
this.data.session_id = undefined;
|
||||
await this.identify();
|
||||
}
|
||||
break;
|
||||
case GatewayOpcodes.Dispatch:
|
||||
switch (packet.t) {
|
||||
case GatewayDispatchEvents.Resumed:
|
||||
this.offlineSendQueue.toArray().map((resolve: () => any) => resolve());
|
||||
break;
|
||||
case GatewayDispatchEvents.Ready:
|
||||
this.data.resume_gateway_url = packet.d.resume_gateway_url;
|
||||
this.data.session_id = packet.d.session_id;
|
||||
this.offlineSendQueue.toArray().map((resolve: () => any) => resolve());
|
||||
this.options.handlePayload(this.id, packet);
|
||||
break;
|
||||
default:
|
||||
this.options.handlePayload(this.id, packet);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected async handleClosed(close: CloseEvent) {
|
||||
clearInterval(this.heart.nodeInterval);
|
||||
this.logger.warn(`[Shard #${this.id}] ${GatewayCloseCodes[close.code] ?? close.code}`);
|
||||
|
||||
switch (close.code) {
|
||||
case ShardSocketCloseCodes.Shutdown:
|
||||
break;
|
||||
case 1000:
|
||||
case 1001:
|
||||
case 1006:
|
||||
case ShardSocketCloseCodes.ZombiedConnection:
|
||||
case GatewayCloseCodes.UnknownError:
|
||||
case GatewayCloseCodes.UnknownOpcode:
|
||||
case GatewayCloseCodes.DecodeError:
|
||||
case GatewayCloseCodes.NotAuthenticated:
|
||||
case GatewayCloseCodes.AlreadyAuthenticated:
|
||||
case GatewayCloseCodes.InvalidSeq:
|
||||
case GatewayCloseCodes.RateLimited:
|
||||
case GatewayCloseCodes.SessionTimedOut:
|
||||
this.logger.info(`[Shard #${this.id}] Trying to reconnect`);
|
||||
await this.reconnect();
|
||||
break;
|
||||
|
||||
case GatewayCloseCodes.AuthenticationFailed:
|
||||
case GatewayCloseCodes.DisallowedIntents:
|
||||
case GatewayCloseCodes.InvalidAPIVersion:
|
||||
case GatewayCloseCodes.InvalidIntents:
|
||||
case GatewayCloseCodes.InvalidShard:
|
||||
case GatewayCloseCodes.ShardingRequired:
|
||||
this.logger.fatal(`[Shard #${this.id}] cannot reconnect`);
|
||||
break;
|
||||
|
||||
default:
|
||||
this.logger.warn(`[Shard #${this.id}] Unknown close code, trying to reconnect anyways`);
|
||||
await this.reconnect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async close(code: number, reason: string) {
|
||||
if (this.websocket?.readyState !== WebSocket.OPEN) {
|
||||
return this.logger.warn(`${new Error('418').stack} [Shard #${this.id}] Is not open`);
|
||||
}
|
||||
this.logger.warn(`${new Error('418').stack} [Shard #${this.id}] Called close`);
|
||||
this.websocket?.close(code, reason);
|
||||
}
|
||||
|
||||
protected async handleMessage({ data }: WS.MessageEvent) {
|
||||
if (data instanceof Buffer) {
|
||||
data = inflateSync(data);
|
||||
}
|
||||
/**
|
||||
* Idk why, but Bun sends this event when websocket connects.
|
||||
* MessageEvent {
|
||||
* type: "message",
|
||||
* data: "Already authenticated."
|
||||
* }
|
||||
*/
|
||||
if ((data as string).startsWith('{')) {
|
||||
data = JSON.parse(data as string);
|
||||
}
|
||||
|
||||
const packet = data as unknown as GatewayReceivePayload;
|
||||
|
||||
return this.onpacket(packet);
|
||||
}
|
||||
|
||||
checkOffline(priority: number) {
|
||||
if (!this.isOpen) {
|
||||
return new Promise((resolve) => this.offlineSendQueue.push(resolve, priority));
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
calculateSafeRequests(): number {
|
||||
const safeRequests =
|
||||
this.options.ratelimitOptions!.maxRequestsPerRateLimitTick -
|
||||
Math.ceil(this.options.ratelimitOptions!.rateLimitResetInterval / this.heart.interval) * 2;
|
||||
|
||||
if (safeRequests < 0) {
|
||||
return 0;
|
||||
}
|
||||
return safeRequests;
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
import type {
|
||||
APIGatewayBotInfo,
|
||||
GatewayUpdatePresence,
|
||||
GatewayVoiceStateUpdate,
|
||||
// Logger,
|
||||
ObjectToLower
|
||||
} from '@biscuitland/common';
|
||||
import { Collection, GatewayOpcodes, LogLevels, Logger, Options, toSnakeCase } from '@biscuitland/common';
|
||||
import { ShardManagerDefaults } from '../constants';
|
||||
import { SequentialBucket } from '../structures';
|
||||
import { Shard } from './shard.js';
|
||||
import type { ShardManagerOptions } from './shared';
|
||||
|
||||
export class ShardManager extends Collection<number, Shard> {
|
||||
connectQueue: SequentialBucket;
|
||||
options: ShardManagerOptions;
|
||||
logger: Logger;
|
||||
|
||||
constructor(options: ShardManagerOptions) {
|
||||
super();
|
||||
this.options = Options<Required<ShardManagerOptions>>(ShardManagerDefaults, options, { info: { shards: options.totalShards } });
|
||||
this.connectQueue = new SequentialBucket(this.concurrency);
|
||||
|
||||
this.logger = new Logger({
|
||||
active: this.options.debug,
|
||||
name: '[ShardManager]',
|
||||
logLevel: LogLevels.Debug
|
||||
});
|
||||
}
|
||||
|
||||
get remaining(): number {
|
||||
return this.options.info.session_start_limit.remaining;
|
||||
}
|
||||
|
||||
get concurrency(): number {
|
||||
return this.options.info.session_start_limit.max_concurrency;
|
||||
}
|
||||
|
||||
calculeShardId(guildId: string) {
|
||||
return Number((BigInt(guildId) >> 22n) % BigInt(this.options.totalShards ?? 1));
|
||||
}
|
||||
|
||||
spawn(shardId: number) {
|
||||
this.logger.info(`Spawn shard ${shardId}`);
|
||||
let shard = this.get(shardId);
|
||||
|
||||
shard ??= new Shard(shardId, {
|
||||
token: this.options.token,
|
||||
intents: this.options.intents,
|
||||
info: Options<APIGatewayBotInfo>(this.options.info, { shards: this.options.totalShards }),
|
||||
handlePayload: this.options.handlePayload,
|
||||
properties: this.options.properties,
|
||||
logger: this.logger,
|
||||
compress: false,
|
||||
presence: this.options.presence
|
||||
});
|
||||
|
||||
this.set(shardId, shard);
|
||||
|
||||
return shard;
|
||||
}
|
||||
|
||||
async spawnShards(): Promise<void> {
|
||||
const buckets = this.spawnBuckets();
|
||||
|
||||
this.logger.info('Spawn shards');
|
||||
for (const bucket of buckets) {
|
||||
for (const shard of bucket) {
|
||||
if (!shard) {
|
||||
break;
|
||||
}
|
||||
this.logger.info(`${shard.id} add to connect queue`);
|
||||
await this.connectQueue.push(shard.connect.bind(shard));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* spawns buckets in order
|
||||
* https://discord.com/developers/docs/topics/gateway#sharding-max-concurrency
|
||||
*/
|
||||
spawnBuckets(): Shard[][] {
|
||||
this.logger.info('#0 Preparing buckets');
|
||||
const chunks = SequentialBucket.chunk(new Array(this.options.totalShards), this.concurrency);
|
||||
// biome-ignore lint/complexity/noForEach: in maps its okay
|
||||
chunks.forEach((arr: any[], index: number) => {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const id = i + (index > 0 ? index * this.concurrency : 0);
|
||||
chunks[index][i] = this.spawn(id);
|
||||
}
|
||||
});
|
||||
this.logger.info(`${chunks.length} buckets created`);
|
||||
return chunks;
|
||||
}
|
||||
|
||||
forceIdentify(shardId: number) {
|
||||
this.logger.info(`Shard #${shardId} force identify`);
|
||||
return this.spawn(shardId).identify();
|
||||
}
|
||||
|
||||
disconnect(shardId: number) {
|
||||
this.logger.info(`Force disconnect shard ${shardId}`);
|
||||
return this.get(shardId)?.disconnect();
|
||||
}
|
||||
|
||||
disconnectAll() {
|
||||
this.logger.info('Disconnect all shards');
|
||||
return new Promise((_resolve) => {
|
||||
// biome-ignore lint/complexity/noForEach: in maps its okay
|
||||
this.forEach((shard) => shard.disconnect());
|
||||
_resolve(null);
|
||||
});
|
||||
}
|
||||
|
||||
setShardPresence(shardId: number, payload: GatewayUpdatePresence['d']) {
|
||||
this.logger.info(`Shard #${shardId} update presence`);
|
||||
return this.get(shardId)?.send<GatewayUpdatePresence>(1, {
|
||||
op: GatewayOpcodes.PresenceUpdate,
|
||||
d: payload
|
||||
});
|
||||
}
|
||||
|
||||
setPresence(payload: GatewayUpdatePresence['d']): Promise<void> | undefined {
|
||||
return new Promise((_resolve) => {
|
||||
// biome-ignore lint/complexity/noForEach: in maps its okay
|
||||
this.forEach((_shard) => {
|
||||
this.setShardPresence(_shard.id, payload);
|
||||
}, this);
|
||||
_resolve();
|
||||
});
|
||||
}
|
||||
|
||||
joinVoice(guild_id: string, channel_id: string, options: ObjectToLower<Pick<GatewayVoiceStateUpdate['d'], 'self_deaf' | 'self_mute'>>) {
|
||||
const shardId = this.calculeShardId(guild_id);
|
||||
this.logger.info(`Shard #${shardId} join voice ${channel_id} in ${guild_id}`);
|
||||
|
||||
return this.get(shardId)?.send<GatewayVoiceStateUpdate>(1, {
|
||||
op: GatewayOpcodes.VoiceStateUpdate,
|
||||
d: {
|
||||
guild_id,
|
||||
channel_id,
|
||||
...toSnakeCase(options)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
leaveVoice(guild_id: string) {
|
||||
const shardId = this.calculeShardId(guild_id);
|
||||
this.logger.info(`Shard #${shardId} leave voice in ${guild_id}`);
|
||||
|
||||
return this.get(shardId)?.send<GatewayVoiceStateUpdate>(1, {
|
||||
op: GatewayOpcodes.VoiceStateUpdate,
|
||||
d: {
|
||||
guild_id,
|
||||
channel_id: null,
|
||||
self_mute: false,
|
||||
self_deaf: false
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
import type { APIGatewayBotInfo, GatewayDispatchPayload, GatewayIntentBits, GatewayPresenceUpdateData, Logger } from '@biscuitland/common';
|
||||
import type { IdentifyProperties } from '../constants';
|
||||
|
||||
export interface ShardManagerOptions extends ShardDetails {
|
||||
/** Important data which is used by the manager to connect shards to the gateway. */
|
||||
info: APIGatewayBotInfo;
|
||||
/**
|
||||
* Delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 5100. YOU DON'T WANT TO HIT THE RATE LIMIT!!!
|
||||
* @default 5300
|
||||
*/
|
||||
spawnShardDelay?: number;
|
||||
/**
|
||||
* Total amount of shards your bot uses. Useful for zero-downtime updates or resharding.
|
||||
* @default 1
|
||||
*/
|
||||
totalShards?: number;
|
||||
/**
|
||||
* The payload handlers for messages on the shard.
|
||||
*/
|
||||
handlePayload(shardId: number, packet: GatewayDispatchPayload): unknown;
|
||||
/**
|
||||
* wheter to send debug information to the console
|
||||
*/
|
||||
debug?: boolean;
|
||||
presence?: GatewayPresenceUpdateData;
|
||||
}
|
||||
|
||||
export interface ShardData {
|
||||
/** resume seq to resume connections */
|
||||
resumeSeq: number | null;
|
||||
|
||||
/**
|
||||
* resume_gateway_url is the url to resume the connection
|
||||
* @link https://discord.com/developers/docs/topics/gateway#ready-event
|
||||
*/
|
||||
resume_gateway_url?: string;
|
||||
|
||||
/**
|
||||
* session_id is the unique session id of the gateway
|
||||
* do not mistake with the biscuit client which is named Session
|
||||
*/
|
||||
session_id?: string;
|
||||
}
|
||||
|
||||
export interface ShardDetails {
|
||||
/** Bot token which is used to connect to Discord */
|
||||
token: string;
|
||||
/**
|
||||
* The URL of the gateway which should be connected to.
|
||||
* @default "wss://gateway.discord.gg"
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* The gateway version which should be used.
|
||||
* @default 10
|
||||
*/
|
||||
version?: number;
|
||||
/**
|
||||
* The calculated intent value of the events which the shard should receive.
|
||||
*/
|
||||
intents: GatewayIntentBits | number;
|
||||
/**
|
||||
* Identify properties to use
|
||||
*/
|
||||
properties?: IdentifyProperties;
|
||||
}
|
||||
|
||||
export interface ShardOptions extends ShardDetails {
|
||||
info: APIGatewayBotInfo;
|
||||
handlePayload(shardId: number, packet: GatewayDispatchPayload): unknown;
|
||||
ratelimitOptions?: {
|
||||
maxRequestsPerRateLimitTick: number;
|
||||
rateLimitResetInterval: number;
|
||||
};
|
||||
logger: Logger;
|
||||
compress: boolean;
|
||||
presence?: GatewayPresenceUpdateData;
|
||||
}
|
||||
|
||||
export enum ShardSocketCloseCodes {
|
||||
Shutdown = 3000,
|
||||
ZombiedConnection = 3010
|
||||
}
|
@ -1,343 +0,0 @@
|
||||
import type { Logger } from '@biscuitland/common';
|
||||
import { delay } from '@biscuitland/common';
|
||||
|
||||
export * from './timeout';
|
||||
|
||||
/**
|
||||
* just any kind of request to queue and resolve later
|
||||
*/
|
||||
export type QueuedRequest = (value: void | Promise<void>) => Promise<unknown> | any;
|
||||
|
||||
/**
|
||||
* options of the dynamic bucket
|
||||
*/
|
||||
export interface DynamicBucketOptions {
|
||||
limit: number;
|
||||
refillInterval: number;
|
||||
refillAmount: number;
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* generally useless for interaction based bots
|
||||
* ideally this would only be triggered on certain paths
|
||||
* example: a huge amount of messages being spammed
|
||||
*
|
||||
* a dynamic bucket is just a priority queue implemented using linked lists
|
||||
* we create an empty bucket for every path
|
||||
* dynamically allocating memory improves the final memory footprint
|
||||
*/
|
||||
export class DynamicBucket {
|
||||
limit: number;
|
||||
refillInterval: number;
|
||||
refillAmount: number;
|
||||
|
||||
/** The queue of requests to acquire an available request. Mapped by <shardId, resolve()> */
|
||||
queue = new PriorityQueue<QueuedRequest>();
|
||||
|
||||
/** The amount of requests that have been used up already. */
|
||||
used = 0;
|
||||
|
||||
/** Whether or not the queue is already processing. */
|
||||
processing = false;
|
||||
|
||||
/** The timeout id for the timer to reduce the used amount by the refill amount. */
|
||||
timeoutId?: NodeJS.Timeout;
|
||||
|
||||
/** The timestamp in milliseconds when the next refill is scheduled. */
|
||||
refillsAt?: number;
|
||||
|
||||
logger: Logger;
|
||||
|
||||
constructor(options: DynamicBucketOptions) {
|
||||
this.limit = options.limit;
|
||||
this.refillInterval = options.refillInterval;
|
||||
this.refillAmount = options.refillAmount;
|
||||
this.logger = options.logger;
|
||||
}
|
||||
|
||||
get remaining(): number {
|
||||
if (this.limit < this.used) {
|
||||
return 0;
|
||||
}
|
||||
return this.limit - this.used;
|
||||
}
|
||||
|
||||
refill(): void {
|
||||
// Lower the used amount by the refill amount
|
||||
this.used = this.refillAmount > this.used ? 0 : this.used - this.refillAmount;
|
||||
|
||||
// Reset the refillsAt timestamp since it just got refilled
|
||||
this.refillsAt = undefined;
|
||||
|
||||
if (this.used > 0) {
|
||||
if (this.timeoutId) {
|
||||
clearTimeout(this.timeoutId);
|
||||
}
|
||||
this.timeoutId = setTimeout(() => {
|
||||
this.refill();
|
||||
}, this.refillInterval);
|
||||
this.refillsAt = Date.now() + this.refillInterval;
|
||||
}
|
||||
}
|
||||
|
||||
/** Begin processing the queue. */
|
||||
async processQueue(): Promise<void> {
|
||||
// There is already a queue that is processing
|
||||
if (this.processing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Begin going through the queue.
|
||||
while (!this.queue.isEmpty()) {
|
||||
if (this.remaining) {
|
||||
this.logger.debug(`Processing queue. Remaining: ${this.remaining} Length: ${this.queue.size()}`);
|
||||
// Resolves the promise allowing the paused execution of this request to resolve and continue.
|
||||
this.queue.peek()();
|
||||
this.queue.pop();
|
||||
|
||||
// A request can be made
|
||||
this.used++;
|
||||
|
||||
// Create a new timeout for this request if none exists.
|
||||
if (!this.timeoutId) {
|
||||
this.timeoutId = setTimeout(() => {
|
||||
this.refill();
|
||||
}, this.refillInterval);
|
||||
|
||||
// Set the time for when this refill will occur.
|
||||
this.refillsAt = Date.now() + this.refillInterval;
|
||||
}
|
||||
// Check if a refill is scheduled, since we have used up all available requests
|
||||
} else if (this.refillsAt) {
|
||||
const now = Date.now();
|
||||
// If there is time left until next refill, just delay execution.
|
||||
if (this.refillsAt > now) {
|
||||
await delay(this.refillsAt - now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop has ended mark false so it can restart later when needed
|
||||
this.processing = false;
|
||||
}
|
||||
|
||||
/** Pauses the execution until the request is available to be made. */
|
||||
async acquire(priority: number): Promise<void> {
|
||||
return await new Promise((_resolve) => {
|
||||
this.queue.push(_resolve, priority);
|
||||
// biome-ignore lint/complexity/noVoid: <explanation>
|
||||
void this.processQueue();
|
||||
});
|
||||
}
|
||||
|
||||
toString() {
|
||||
return [...this.queue].toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract node lol
|
||||
*/
|
||||
export interface AbstractNode<T> {
|
||||
data: T;
|
||||
next: this | null;
|
||||
}
|
||||
|
||||
export interface QueuePusher<T> {
|
||||
push(data: T): NonNullable<TNode<T>>;
|
||||
}
|
||||
|
||||
export interface QueuePusherWithPriority<T> {
|
||||
push(data: T, priority: number): NonNullable<PNode<T>>;
|
||||
}
|
||||
|
||||
export class TNode<T> implements AbstractNode<T> {
|
||||
data: T;
|
||||
next: this | null;
|
||||
|
||||
constructor(data: T) {
|
||||
this.data = data;
|
||||
this.next = null;
|
||||
}
|
||||
|
||||
static null<T>(list: AbstractNode<T> | null): list is null {
|
||||
return !list;
|
||||
}
|
||||
}
|
||||
|
||||
export class PNode<T> extends TNode<T> {
|
||||
priority: number;
|
||||
|
||||
constructor(data: T, priority: number) {
|
||||
super(data);
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Queue<T> {
|
||||
protected abstract head: AbstractNode<T> | null;
|
||||
|
||||
/**
|
||||
* O(1)
|
||||
*/
|
||||
public pop() {
|
||||
if (TNode.null(this.head)) {
|
||||
throw new Error('cannot pop a list without elements');
|
||||
}
|
||||
|
||||
return (this.head = this.head.next);
|
||||
}
|
||||
|
||||
/**
|
||||
* O(1)
|
||||
*/
|
||||
public peek(): T {
|
||||
if (TNode.null(this.head)) {
|
||||
throw new Error('cannot peek an empty list');
|
||||
}
|
||||
|
||||
return this.head.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* O(n)
|
||||
*/
|
||||
public size(): number {
|
||||
let aux = this.head;
|
||||
|
||||
if (TNode.null(aux)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let count = 1;
|
||||
|
||||
while (aux.next !== null) {
|
||||
count++;
|
||||
aux = aux.next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* O(1)
|
||||
*/
|
||||
public isEmpty() {
|
||||
return TNode.null(this.head);
|
||||
}
|
||||
|
||||
*[Symbol.iterator](): IterableIterator<T> {
|
||||
let temp = this.head;
|
||||
while (temp !== null) {
|
||||
yield temp.data;
|
||||
temp = temp.next;
|
||||
}
|
||||
}
|
||||
|
||||
public toArray(): T[] {
|
||||
return Array.from(this);
|
||||
}
|
||||
|
||||
public toString() {
|
||||
return this.head?.toString() || '';
|
||||
}
|
||||
}
|
||||
|
||||
export class LinkedList<T> extends Queue<T> implements QueuePusher<T> {
|
||||
protected head: TNode<T> | null = null;
|
||||
|
||||
/**
|
||||
* O(1)
|
||||
*/
|
||||
public push(data: T): NonNullable<TNode<T>> {
|
||||
const temp = new TNode<T>(data);
|
||||
temp.next = this.head;
|
||||
this.head = temp;
|
||||
|
||||
return this.head;
|
||||
}
|
||||
}
|
||||
|
||||
export class PriorityQueue<T> extends Queue<T> implements QueuePusherWithPriority<T> {
|
||||
protected head: PNode<T> | null = null;
|
||||
|
||||
/**
|
||||
* O(#priorities)
|
||||
*/
|
||||
public push(data: T, priority: number): NonNullable<PNode<T>> {
|
||||
let start = this.head;
|
||||
const temp = new PNode(data, priority);
|
||||
|
||||
if (TNode.null(this.head) || TNode.null(start)) {
|
||||
this.head = temp;
|
||||
return this.head;
|
||||
}
|
||||
|
||||
if (this.head.priority > priority) {
|
||||
temp.next = this.head;
|
||||
this.head = temp;
|
||||
return this.head;
|
||||
}
|
||||
|
||||
while (start.next !== null && start.next.priority < priority) {
|
||||
start = start.next;
|
||||
}
|
||||
|
||||
temp.next = start.next as PNode<T>;
|
||||
start.next = temp;
|
||||
|
||||
return this.head;
|
||||
}
|
||||
}
|
||||
|
||||
export class SequentialBucket {
|
||||
private connections: LinkedList<QueuedRequest>;
|
||||
private capacity: number; // max_concurrency
|
||||
private spawnTimeout: number;
|
||||
|
||||
constructor(maxCapacity: number) {
|
||||
this.connections = new LinkedList();
|
||||
this.capacity = maxCapacity;
|
||||
this.spawnTimeout = 5000;
|
||||
}
|
||||
|
||||
public async destroy() {
|
||||
this.connections = new LinkedList();
|
||||
}
|
||||
|
||||
public async push(promise: QueuedRequest) {
|
||||
this.connections.push(promise);
|
||||
|
||||
if (this.capacity <= this.connections.size()) {
|
||||
await this.acquire();
|
||||
await delay(this.spawnTimeout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public async acquire(promises = this.connections) {
|
||||
while (!promises.isEmpty()) {
|
||||
const item = promises.peek();
|
||||
item().catch((...args: any[]) => {
|
||||
Promise.reject(...args);
|
||||
});
|
||||
promises.pop();
|
||||
}
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
public static chunk<T>(array: T[], chunks: number): T[][] {
|
||||
let index = 0;
|
||||
let resIndex = 0;
|
||||
const result = Array(Math.ceil(array.length / chunks));
|
||||
|
||||
while (index < array.length) {
|
||||
result[resIndex] = array.slice(index, (index += chunks));
|
||||
resIndex++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
export class ConnectTimeout {
|
||||
promises: { promise: Promise<boolean>; resolve: (x: boolean) => any }[] = [];
|
||||
interval?: NodeJS.Timeout = undefined;
|
||||
// biome-ignore lint/nursery/noEmptyBlockStatements: <explanation>
|
||||
constructor(readonly intervalTime = 5000) {}
|
||||
|
||||
wait() {
|
||||
let resolve = (_x: boolean) => {
|
||||
//
|
||||
};
|
||||
const promise = new Promise<boolean>((r) => (resolve = r));
|
||||
if (!this.promises.length) {
|
||||
this.interval = setInterval(() => {
|
||||
this.shift();
|
||||
}, this.intervalTime);
|
||||
}
|
||||
this.promises.push({ resolve, promise });
|
||||
return promise;
|
||||
}
|
||||
|
||||
shift() {
|
||||
this.promises.shift()?.resolve(true);
|
||||
if (!this.promises.length) {
|
||||
clearInterval(this.interval);
|
||||
this.interval = undefined;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
export default defineConfig({
|
||||
clean: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
format: ['cjs', 'esm'],
|
||||
minify: isProduction,
|
||||
sourcemap: false
|
||||
});
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
]
|
||||
}
|
328
src/api/CDN.ts
Normal file
328
src/api/CDN.ts
Normal file
@ -0,0 +1,328 @@
|
||||
/* eslint-disable jsdoc/check-param-names */
|
||||
import { CDN_URL } from '../common/index.js';
|
||||
import {
|
||||
ALLOWED_EXTENSIONS,
|
||||
ALLOWED_SIZES,
|
||||
ALLOWED_STICKER_EXTENSIONS,
|
||||
type ImageExtension,
|
||||
type ImageSize,
|
||||
type StickerExtension,
|
||||
} from './utils/constants.js';
|
||||
|
||||
/**
|
||||
* The options used for image URLs
|
||||
*/
|
||||
export interface BaseImageURLOptions {
|
||||
/**
|
||||
* The extension to use for the image URL
|
||||
*
|
||||
* @defaultValue `'webp'`
|
||||
*/
|
||||
extension?: ImageExtension;
|
||||
/**
|
||||
* The size specified in the image URL
|
||||
*/
|
||||
size?: ImageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The options used for image URLs with animated content
|
||||
*/
|
||||
export interface ImageURLOptions extends BaseImageURLOptions {
|
||||
/**
|
||||
* Whether or not to prefer the static version of an image asset.
|
||||
*/
|
||||
forceStatic?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The options to use when making a CDN URL
|
||||
*/
|
||||
export interface MakeURLOptions {
|
||||
/**
|
||||
* The allowed extensions that can be used
|
||||
*/
|
||||
allowedExtensions?: readonly string[];
|
||||
/**
|
||||
* The extension to use for the image URL
|
||||
*
|
||||
* @defaultValue `'webp'`
|
||||
*/
|
||||
extension?: string | undefined;
|
||||
/**
|
||||
* The size specified in the image URL
|
||||
*/
|
||||
size?: ImageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The CDN link builder
|
||||
*/
|
||||
export class CDN {
|
||||
public constructor(private readonly base: string = CDN_URL) {}
|
||||
|
||||
/**
|
||||
* Generates an app asset URL for a client's asset.
|
||||
*
|
||||
* @param clientId - The client id that has the asset
|
||||
* @param assetHash - The hash provided by Discord for this asset
|
||||
* @param options - Optional options for the asset
|
||||
*/
|
||||
public appAsset(clientId: string, assetHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an app icon URL for a client's icon.
|
||||
*
|
||||
* @param clientId - The client id that has the icon
|
||||
* @param iconHash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public appIcon(clientId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an avatar URL, e.g. for a user or a webhook.
|
||||
*
|
||||
* @param id - The id that has the icon
|
||||
* @param avatarHash - The hash provided by Discord for this avatar
|
||||
* @param options - Optional options for the avatar
|
||||
*/
|
||||
public avatar(id: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a user avatar decoration URL.
|
||||
*
|
||||
* @param userId - The id of the user
|
||||
* @param userAvatarDecoration - The hash provided by Discord for this avatar decoration
|
||||
* @param options - Optional options for the avatar decoration
|
||||
*/
|
||||
public avatarDecoration(
|
||||
userId: string,
|
||||
userAvatarDecoration: string,
|
||||
options?: Readonly<BaseImageURLOptions>,
|
||||
): string {
|
||||
return this.makeURL(`/avatar-decorations/${userId}/${userAvatarDecoration}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a banner URL, e.g. for a user or a guild.
|
||||
*
|
||||
* @param id - The id that has the banner splash
|
||||
* @param bannerHash - The hash provided by Discord for this banner
|
||||
* @param options - Optional options for the banner
|
||||
*/
|
||||
public banner(id: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an icon URL for a channel, e.g. a group DM.
|
||||
*
|
||||
* @param channelId - The channel id that has the icon
|
||||
* @param iconHash - The hash provided by Discord for this channel
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public channelIcon(channelId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a default avatar URL
|
||||
*
|
||||
* @param index - The default avatar index
|
||||
* @remarks
|
||||
* To calculate the index for a user do `(userId >> 22) % 6`,
|
||||
* or `discriminator % 5` if they're using the legacy username system.
|
||||
*/
|
||||
public defaultAvatar(index: number): string {
|
||||
return this.makeURL(`/embed/avatars/${index}`, { extension: 'png' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a discovery splash URL for a guild's discovery splash.
|
||||
*
|
||||
* @param guildId - The guild id that has the discovery splash
|
||||
* @param splashHash - The hash provided by Discord for this splash
|
||||
* @param options - Optional options for the splash
|
||||
*/
|
||||
public discoverySplash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an emoji's URL for an emoji.
|
||||
*
|
||||
* @param emojiId - The emoji id
|
||||
* @param options - Optional options for the emoji
|
||||
*/
|
||||
public emoji(emojiId: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
const resolvedOptions = options;
|
||||
|
||||
return this.makeURL(`/emojis/${emojiId}`, resolvedOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a guild member avatar URL.
|
||||
*
|
||||
* @param guildId - The id of the guild
|
||||
* @param userId - The id of the user
|
||||
* @param avatarHash - The hash provided by Discord for this avatar
|
||||
* @param options - Optional options for the avatar
|
||||
*/
|
||||
public guildMemberAvatar(
|
||||
guildId: string,
|
||||
userId: string,
|
||||
avatarHash: string,
|
||||
options?: Readonly<ImageURLOptions>,
|
||||
): string {
|
||||
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/avatars/${avatarHash}`, avatarHash, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a guild member banner URL.
|
||||
*
|
||||
* @param guildId - The id of the guild
|
||||
* @param userId - The id of the user
|
||||
* @param bannerHash - The hash provided by Discord for this banner
|
||||
* @param options - Optional options for the banner
|
||||
*/
|
||||
public guildMemberBanner(
|
||||
guildId: string,
|
||||
userId: string,
|
||||
bannerHash: string,
|
||||
options?: Readonly<ImageURLOptions>,
|
||||
): string {
|
||||
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banner`, bannerHash, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an icon URL, e.g. for a guild.
|
||||
*
|
||||
* @param id - The id that has the icon splash
|
||||
* @param iconHash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public icon(id: string, iconHash: string, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL for the icon of a role
|
||||
*
|
||||
* @param roleId - The id of the role that has the icon
|
||||
* @param roleIconHash - The hash provided by Discord for this role icon
|
||||
* @param options - Optional options for the role icon
|
||||
*/
|
||||
public roleIcon(roleId: string, roleIconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a guild invite splash URL for a guild's invite splash.
|
||||
*
|
||||
* @param guildId - The guild id that has the invite splash
|
||||
* @param splashHash - The hash provided by Discord for this splash
|
||||
* @param options - Optional options for the splash
|
||||
*/
|
||||
public splash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/splashes/${guildId}/${splashHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a sticker URL.
|
||||
*
|
||||
* @param stickerId - The sticker id
|
||||
* @param extension - The extension of the sticker
|
||||
* @privateRemarks
|
||||
* Stickers cannot have a `.webp` extension, so we default to a `.png`
|
||||
*/
|
||||
public sticker(stickerId: string, extension: StickerExtension = 'png'): string {
|
||||
return this.makeURL(`/stickers/${stickerId}`, { allowedExtensions: ALLOWED_STICKER_EXTENSIONS, extension });
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a sticker pack banner URL.
|
||||
*
|
||||
* @param bannerId - The banner id
|
||||
* @param options - Optional options for the banner
|
||||
*/
|
||||
public stickerPackBanner(bannerId: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a team icon URL for a team's icon.
|
||||
*
|
||||
* @param teamId - The team id that has the icon
|
||||
* @param iconHash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public teamIcon(teamId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cover image for a guild scheduled event.
|
||||
*
|
||||
* @param scheduledEventId - The scheduled event id
|
||||
* @param coverHash - The hash provided by discord for this cover image
|
||||
* @param options - Optional options for the cover image
|
||||
*/
|
||||
public guildScheduledEventCover(
|
||||
scheduledEventId: string,
|
||||
coverHash: string,
|
||||
options?: Readonly<BaseImageURLOptions>,
|
||||
): string {
|
||||
return this.makeURL(`/guild-events/${scheduledEventId}/${coverHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`.
|
||||
*
|
||||
* @param route - The base cdn route
|
||||
* @param hash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the link
|
||||
*/
|
||||
private dynamicMakeURL(
|
||||
route: string,
|
||||
hash: string,
|
||||
{ forceStatic = false, ...options }: Readonly<ImageURLOptions> = {},
|
||||
): string {
|
||||
return this.makeURL(route, !forceStatic && hash.startsWith('a_') ? { ...options, extension: 'gif' } : options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the URL for the resource
|
||||
*
|
||||
* @param route - The base cdn route
|
||||
* @param options - The extension/size options for the link
|
||||
*/
|
||||
private makeURL(
|
||||
route: string,
|
||||
{ allowedExtensions = ALLOWED_EXTENSIONS, extension = 'webp', size }: Readonly<MakeURLOptions> = {},
|
||||
): string {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
extension = String(extension).toLowerCase();
|
||||
|
||||
if (!allowedExtensions.includes(extension)) {
|
||||
throw new RangeError(`Invalid extension provided: ${extension}\nMust be one of: ${allowedExtensions.join(', ')}`);
|
||||
}
|
||||
|
||||
if (size && !ALLOWED_SIZES.includes(size)) {
|
||||
throw new RangeError(`Invalid size provided: ${size}\nMust be one of: ${ALLOWED_SIZES.join(', ')}`);
|
||||
}
|
||||
|
||||
const url = new URL(`${this.base}${route}.${extension}`);
|
||||
|
||||
if (size) {
|
||||
url.searchParams.set('size', String(size));
|
||||
}
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
}
|
13
src/api/README.md
Normal file
13
src/api/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
<div align='center'>
|
||||
|
||||
# **Seyfert**
|
||||
|
||||
<img src="../../assets/icon.png" alt="seyfert" width="200px" />
|
||||
|
||||
**A brand new bleeding edge non bloated Discord framework**
|
||||
|
||||
[](https://github.com/tiramisulabs/biscuit/blob/main/LICENSE)
|
||||
[](https://www.npmjs.com/package/seyfert)
|
||||
[](https://discord.com/invite/XNw2RZFzaP)
|
||||
|
||||
</div>
|
64
src/api/Router.ts
Normal file
64
src/api/Router.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { CDN_URL } from '../common';
|
||||
import type { APIRoutes, ApiHandler, CDNRoute } from './index';
|
||||
import type { HttpMethods } from './shared';
|
||||
|
||||
export enum ProxyRequestMethod {
|
||||
Delete = 'delete',
|
||||
Get = 'get',
|
||||
Patch = 'patch',
|
||||
Post = 'post',
|
||||
Put = 'put',
|
||||
}
|
||||
|
||||
const ArrRequestsMethods = Object.freeze(Object.values(ProxyRequestMethod)) as string[];
|
||||
|
||||
export class Router {
|
||||
noop = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
constructor(private rest: ApiHandler) {}
|
||||
|
||||
createProxy(route = [] as string[]): APIRoutes {
|
||||
return new Proxy(this.noop, {
|
||||
get: (_, key: string) => {
|
||||
if (ArrRequestsMethods.includes(key)) {
|
||||
return (...options: any[]) =>
|
||||
this.rest.request(key.toUpperCase() as HttpMethods, `/${route.join('/')}`, ...options);
|
||||
}
|
||||
return this.createProxy([...route, key]);
|
||||
},
|
||||
apply: (...[, _, args]) => {
|
||||
return this.createProxy([...route, ...args.filter(x => x != null)]);
|
||||
},
|
||||
}) as unknown as APIRoutes;
|
||||
}
|
||||
}
|
||||
|
||||
export const CDNRouter = {
|
||||
createProxy(route = [] as string[]): CDNRoute {
|
||||
const noop = () => {
|
||||
return;
|
||||
};
|
||||
return new Proxy(noop, {
|
||||
get: (_, key: string) => {
|
||||
if (key === 'get') {
|
||||
return (value?: string) => {
|
||||
const lastRoute = `${CDN_URL}/${route.join('/')}`;
|
||||
if (value) {
|
||||
if (typeof value !== 'string') {
|
||||
value = String(value);
|
||||
}
|
||||
return `${lastRoute}/${value}`;
|
||||
}
|
||||
return lastRoute;
|
||||
};
|
||||
}
|
||||
return this.createProxy([...route, key]);
|
||||
},
|
||||
apply: (...[, _, args]) => {
|
||||
return this.createProxy([...route, ...args.filter(x => x != null)]);
|
||||
},
|
||||
}) as unknown as CDNRoute;
|
||||
},
|
||||
};
|
105
src/api/Routes/applications.ts
Normal file
105
src/api/Routes/applications.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import type {
|
||||
RESTGetAPIApplicationCommandResult,
|
||||
RESTGetAPIApplicationCommandsQuery,
|
||||
RESTGetAPIApplicationCommandsResult,
|
||||
RESTGetAPIApplicationGuildCommandResult,
|
||||
RESTGetAPIApplicationGuildCommandsQuery,
|
||||
RESTGetAPIApplicationGuildCommandsResult,
|
||||
RESTGetAPIApplicationRoleConnectionMetadataResult,
|
||||
RESTGetAPIGuildApplicationCommandsPermissionsResult,
|
||||
RESTPatchAPIApplicationCommandJSONBody,
|
||||
RESTPatchAPIApplicationCommandResult,
|
||||
RESTPatchAPIApplicationGuildCommandJSONBody,
|
||||
RESTPatchAPIApplicationGuildCommandResult,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
RESTPostAPIApplicationCommandsResult,
|
||||
RESTPostAPIApplicationGuildCommandsJSONBody,
|
||||
RESTPostAPIApplicationGuildCommandsResult,
|
||||
RESTPutAPIApplicationCommandPermissionsJSONBody,
|
||||
RESTPutAPIApplicationCommandsJSONBody,
|
||||
RESTPutAPIApplicationCommandsResult,
|
||||
RESTPutAPIApplicationGuildCommandsJSONBody,
|
||||
RESTPutAPIApplicationGuildCommandsResult,
|
||||
RESTPutAPIApplicationRoleConnectionMetadataJSONBody,
|
||||
RESTPutAPIApplicationRoleConnectionMetadataResult,
|
||||
RESTPutAPIGuildApplicationCommandsPermissionsResult,
|
||||
} from '../../common';
|
||||
import type { RestArguments } from '../api';
|
||||
import type { ProxyRequestMethod } from '../Router';
|
||||
|
||||
export interface ApplicationRoutes {
|
||||
applications: {
|
||||
(
|
||||
id: string,
|
||||
): {
|
||||
guilds: {
|
||||
(
|
||||
id: string,
|
||||
): {
|
||||
commands: {
|
||||
get(
|
||||
args?: RestArguments<ProxyRequestMethod.Get, RESTGetAPIApplicationGuildCommandsQuery>,
|
||||
): Promise<RESTGetAPIApplicationGuildCommandsResult>;
|
||||
post(
|
||||
args: RestArguments<ProxyRequestMethod.Post, RESTPostAPIApplicationGuildCommandsJSONBody>,
|
||||
): Promise<RESTPostAPIApplicationGuildCommandsResult>;
|
||||
put(
|
||||
args?: RestArguments<ProxyRequestMethod.Put, RESTPutAPIApplicationGuildCommandsJSONBody>,
|
||||
): Promise<RESTPutAPIApplicationGuildCommandsResult>;
|
||||
permissions: {
|
||||
get(
|
||||
args?: RestArguments<ProxyRequestMethod.Get>,
|
||||
): Promise<RESTGetAPIGuildApplicationCommandsPermissionsResult>;
|
||||
// put(args?: RestArguments<ProxyRequestMethod.Put, RESTPutAPIGuildApplicationCommandsPermissionsJSONBody>): Promise<RESTPutAPIGuildApplicationCommandsPermissionsResult>
|
||||
};
|
||||
(
|
||||
id: string,
|
||||
): {
|
||||
get(args?: RestArguments<ProxyRequestMethod.Get>): Promise<RESTGetAPIApplicationGuildCommandResult>;
|
||||
patch(
|
||||
args: RestArguments<ProxyRequestMethod.Patch, RESTPatchAPIApplicationGuildCommandJSONBody>,
|
||||
): Promise<RESTPatchAPIApplicationGuildCommandResult>;
|
||||
delete(args?: RestArguments<ProxyRequestMethod.Delete>): Promise<never>;
|
||||
permissions: {
|
||||
get(
|
||||
args?: RestArguments<ProxyRequestMethod.Get>,
|
||||
): Promise<RESTGetAPIGuildApplicationCommandsPermissionsResult>;
|
||||
put(
|
||||
args?: RestArguments<ProxyRequestMethod.Put, RESTPutAPIApplicationCommandPermissionsJSONBody>,
|
||||
): Promise<RESTPutAPIGuildApplicationCommandsPermissionsResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
commands: {
|
||||
get(
|
||||
args?: RestArguments<ProxyRequestMethod.Get, RESTGetAPIApplicationCommandsQuery>,
|
||||
): Promise<RESTGetAPIApplicationCommandsResult>;
|
||||
post(
|
||||
args: RestArguments<ProxyRequestMethod.Post, RESTPostAPIApplicationCommandsJSONBody>,
|
||||
): Promise<RESTPostAPIApplicationCommandsResult>;
|
||||
put(
|
||||
args?: RestArguments<ProxyRequestMethod.Put, RESTPutAPIApplicationCommandsJSONBody>,
|
||||
): Promise<RESTPutAPIApplicationCommandsResult>;
|
||||
(
|
||||
id: string,
|
||||
): {
|
||||
get(args?: RestArguments<ProxyRequestMethod.Get>): Promise<RESTGetAPIApplicationCommandResult>;
|
||||
patch(
|
||||
args: RestArguments<ProxyRequestMethod.Patch, RESTPatchAPIApplicationCommandJSONBody>,
|
||||
): Promise<RESTPatchAPIApplicationCommandResult>;
|
||||
delete(args?: RestArguments<ProxyRequestMethod.Delete>): Promise<never>;
|
||||
};
|
||||
};
|
||||
'role-connections': {
|
||||
metadata: {
|
||||
get(args?: RestArguments<ProxyRequestMethod.Get>): Promise<RESTGetAPIApplicationRoleConnectionMetadataResult>;
|
||||
put(
|
||||
args: RestArguments<ProxyRequestMethod.Put, RESTPutAPIApplicationRoleConnectionMetadataJSONBody>,
|
||||
): Promise<RESTPutAPIApplicationRoleConnectionMetadataResult>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
68
src/api/Routes/cdn.ts
Normal file
68
src/api/Routes/cdn.ts
Normal file
@ -0,0 +1,68 @@
|
||||
export interface CDNRoute {
|
||||
embed: {
|
||||
avatars: {
|
||||
get(embed: UserAvatarDefault): string;
|
||||
};
|
||||
};
|
||||
avatars(id: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
icons(guildId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
splashes(guildId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
'discovery-splashes'(guidId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
banners(id: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
guilds(id: string): {
|
||||
users(id: string): {
|
||||
avatars(hash: string): {
|
||||
get(): string;
|
||||
};
|
||||
banners(hash: string): {
|
||||
get(): string;
|
||||
};
|
||||
};
|
||||
};
|
||||
emojis(id: string): {
|
||||
get(): string;
|
||||
};
|
||||
appIcons(appId: string): {
|
||||
get(iconOrCover: string): string;
|
||||
};
|
||||
'app-assets'(appId: string): {
|
||||
get(asset: string): string;
|
||||
achievements(id: string): {
|
||||
icons(hash: string): {
|
||||
get(): string;
|
||||
};
|
||||
};
|
||||
};
|
||||
'team-icons'(teamId: string): {
|
||||
get(hash: string): string;
|
||||
};
|
||||
stickers(id: string): {
|
||||
get(): string;
|
||||
};
|
||||
'role-icons'(roleId: string): {
|
||||
get(icon: string): string;
|
||||
};
|
||||
'guild-events'(id: string): {
|
||||
get(cover: string): string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CDNRoute {
|
||||
'app-assets'(id: '710982414301790216'): {
|
||||
store(packBannerId: string): {
|
||||
get(): string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type UserAvatarDefault = 1 | 2 | 3 | 4 | 5 | number;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user