mirror of
https://github.com/xHyroM/roles-bot.git
synced 2024-11-12 20:18:06 +01:00
refactor!: rewrite
🎉🎉
This commit is contained in:
commit
7c63c373c1
143 changed files with 14424 additions and 11554 deletions
|
@ -1,4 +0,0 @@
|
|||
dist/
|
||||
tests/
|
||||
packages/website/
|
||||
webpack.config.js
|
|
@ -1,33 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
"tab"
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"prefer-const": "error",
|
||||
"@typescript-eslint/no-explicit-any": "off"
|
||||
}
|
||||
}
|
32
.github/actions/avatar-changer/index.js
vendored
32
.github/actions/avatar-changer/index.js
vendored
|
@ -1,32 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const hyttpo = require('hyttpo').default;
|
||||
|
||||
const list = fs.readFileSync('./list.txt', 'utf-8').split('\n');
|
||||
let now = Number(fs.readFileSync('./now.txt', 'utf-8'));
|
||||
|
||||
(async() => {
|
||||
if (now === list.length) now = 0;
|
||||
|
||||
const url = list[now + 1];
|
||||
|
||||
const req = await hyttpo.request({
|
||||
method: 'GET',
|
||||
responseType: 'buffer',
|
||||
url
|
||||
}).catch(e => e)
|
||||
|
||||
const base64 = `data:image/png;base64,${req.data.toString('base64')}`;
|
||||
|
||||
const bot = await hyttpo.request({
|
||||
url: 'https://discord.com/api/v9/applications/745599648110215260',
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': 'Bot'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
icon: base64
|
||||
})
|
||||
}).catch(e => e)
|
||||
|
||||
console.log(bot)
|
||||
})();
|
6
.github/actions/avatar-changer/list.txt
vendored
6
.github/actions/avatar-changer/list.txt
vendored
|
@ -1,6 +0,0 @@
|
|||
https://izboxo.cz/sources/images/Bucket_of_Cod_JE2_BE2.png
|
||||
https://izboxo.cz/sources/images/Bucket_of_Axolotl_JE1_BE1.png
|
||||
https://izboxo.cz/sources/images/Bucket_of_Pufferfish_JE2_BE2.png
|
||||
https://izboxo.cz/sources/images/Bucket_of_Salmon_JE2_BE2.png
|
||||
https://izboxo.cz/sources/images/Bucket_of_Tadpole_BE1.png
|
||||
https://izboxo.cz/sources/images/Bucket_of_Tropical_Fish_JE3_BE2.png
|
1
.github/actions/avatar-changer/now.txt
vendored
1
.github/actions/avatar-changer/now.txt
vendored
|
@ -1 +0,0 @@
|
|||
0
|
BIN
.github/actions/avatar-changer/out.png
vendored
BIN
.github/actions/avatar-changer/out.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 966 B |
61
.github/actions/avatar-changer/package-lock.json
generated
vendored
61
.github/actions/avatar-changer/package-lock.json
generated
vendored
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
"name": "avatar-changer",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "avatar-changer",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"hyttpo": "^0.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.14.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz",
|
||||
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/hyttpo": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hyttpo/-/hyttpo-0.3.2.tgz",
|
||||
"integrity": "sha512-Y1QJlBXOZtHKhME6AEBdxPrzJrV5xcORZm/+rbHwXGlau2n2OBNAbsiIJ3eiT1ZizJClm+RmwjytDSySOXJcOg==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.x"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"follow-redirects": {
|
||||
"version": "1.14.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz",
|
||||
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A=="
|
||||
},
|
||||
"hyttpo": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hyttpo/-/hyttpo-0.3.2.tgz",
|
||||
"integrity": "sha512-Y1QJlBXOZtHKhME6AEBdxPrzJrV5xcORZm/+rbHwXGlau2n2OBNAbsiIJ3eiT1ZizJClm+RmwjytDSySOXJcOg==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
.github/actions/avatar-changer/package.json
vendored
15
.github/actions/avatar-changer/package.json
vendored
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"name": "avatar-changer",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"hyttpo": "^0.3.2"
|
||||
}
|
||||
}
|
30
.github/workflows/pages.yml
vendored
30
.github/workflows/pages.yml
vendored
|
@ -1,30 +0,0 @@
|
|||
name: Pages Deployment
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
website:
|
||||
name: Website
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd packages/website
|
||||
npm i
|
||||
npm run build
|
||||
npm run export
|
||||
|
||||
- name: Deploy site
|
||||
uses: JamesIves/github-pages-deploy-action@4.1.4
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: packages/website/out
|
49
.gitignore
vendored
49
.gitignore
vendored
|
@ -1,9 +1,5 @@
|
|||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node
|
||||
|
||||
# My
|
||||
wrangler.toml
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,node
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,node
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
|
@ -62,6 +58,9 @@ web_modules/
|
|||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
|
@ -77,10 +76,12 @@ web_modules/
|
|||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.test
|
||||
.env.production
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
@ -103,6 +104,12 @@ dist
|
|||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
|
@ -130,9 +137,29 @@ dist
|
|||
.webpack/
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# SvelteKit build / generate output
|
||||
.svelte-kit
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,node
|
||||
|
||||
.turbo
|
19
.vscode/settings.json
vendored
19
.vscode/settings.json
vendored
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"liveServer.settings.port": 5501,
|
||||
"liveSassCompile.settings.formats": [
|
||||
{
|
||||
"format": "expanded",
|
||||
"extensionName": ".css",
|
||||
"savePath": "/packages/website/styles/css"
|
||||
}
|
||||
]
|
||||
}
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "rome.rome"
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "rome.rome"
|
||||
},
|
||||
"[astro]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
|
|
113
CONTRIBUTING.md
Normal file
113
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,113 @@
|
|||
## <a name="commit"></a> Commit Message Format
|
||||
|
||||
_This specification is inspired by and supersedes the [Brainclements commit message format](https://gist.github.com/brianclements/841ea7bffdb01346392c)._
|
||||
|
||||
We have very precise rules over how our Git commit messages must be formatted.
|
||||
This format leads to **easier to read commit history**.
|
||||
|
||||
Each commit message consists of a **header**, a **body**, and a **footer**.
|
||||
|
||||
```
|
||||
<header>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
|
||||
|
||||
The `body` is mandatory for all commits except for those of type "docs".
|
||||
When the body is present it must be at least 20 characters long and must conform to the [Commit Message Body](#commit-body) format.
|
||||
|
||||
The `footer` is optional. The [Commit Message Footer](#commit-footer) format describes what the footer is used for and the structure it must have.
|
||||
|
||||
#### <a name="commit-header"></a>Commit Message Header
|
||||
|
||||
```
|
||||
<type>(<scope>)(!?): <short summary>
|
||||
│ │ │ │
|
||||
│ │ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
||||
│ │ │
|
||||
│ │ └─⫸ Exclamation mark: breaking change
|
||||
│ │
|
||||
│ └─⫸ Commit Scope: bot|website|serialize|redis-api|redis-api-client|builders
|
||||
│
|
||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
|
||||
```
|
||||
|
||||
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
|
||||
Exclamation mark is optional too, but it's used to mark breaking changes.
|
||||
|
||||
##### Type
|
||||
|
||||
Must be one of the following:
|
||||
|
||||
- **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
- **ci**: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
|
||||
- **docs**: Documentation only changes
|
||||
- **feat**: A new feature
|
||||
- **fix**: A bug fix
|
||||
- **perf**: A code change that improves performance
|
||||
- **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
- **test**: Adding missing tests or correcting existing tests
|
||||
|
||||
##### Scope
|
||||
|
||||
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
|
||||
|
||||
The following is the list of supported scopes:
|
||||
|
||||
- `bot`
|
||||
- `website`
|
||||
- `serialize`
|
||||
- `redis-api`
|
||||
- `redis-api-client`
|
||||
- `builders`
|
||||
|
||||
There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
- none/empty string: useful for `test` and `refactor` changes that are done across all packages (e.g. `test: add missing unit tests`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
|
||||
|
||||
##### Summary
|
||||
|
||||
Use the summary field to provide a succinct description of the change:
|
||||
|
||||
- use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
- don't capitalize the first letter
|
||||
- no dot (.) at the end
|
||||
|
||||
#### <a name="commit-body"></a>Commit Message Body
|
||||
|
||||
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
|
||||
|
||||
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
|
||||
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
|
||||
|
||||
#### <a name="commit-footer"></a>Commit Message Footer
|
||||
|
||||
The footer is optional and is used for two purposes:
|
||||
|
||||
- To reference issues that this commit closes
|
||||
- To include information that doesn't fit in the header or body, such as a link to a file or a suggestion to review a pull request
|
||||
|
||||
The format for the footer is as follows:
|
||||
|
||||
```
|
||||
Closes/Fixes #<issue number>
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
See pull request #<pull request number>
|
||||
```
|
||||
|
||||
### Revert commits
|
||||
|
||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
|
||||
|
||||
The content of the commit message body should contain:
|
||||
|
||||
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
|
||||
- a clear description of the reason for reverting the commit message.
|
2
LICENSE
2
LICENSE
|
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
47
README.md
47
README.md
|
@ -1,7 +1,46 @@
|
|||
<div align="center">
|
||||
<h1>Discord Roles Bot</h1>
|
||||
</div>
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<img src="https://github.com/xHyroM/website/blob/main/src/assets/logo.png?raw=true" alt="Hyro" width="256">
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<h4 align="center">Source code for Roles Bot, a discord bot.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/kFPKmEKeMS/" alt="Discord">
|
||||
<img src="https://img.shields.io/discord/1046534628577640528?label=discord&style=for-the-badge&color=2fbfc4"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Informations
|
||||
|
||||
Discord bot for reaction roles that works with [Cloudflare Workers](https://workers.cloudflare.com/).
|
||||
|
||||
You can add the bot to your server, just click [here](https://discord.com/api/oauth2/authorize?client_id=923267906941370368&permissions=268435456&scope=bot%20applications.commands).
|
||||
You can add the bot to your server, just click [here](https://discord.com/api/oauth2/authorize?client_id=923267906941370368&permissions=268435456&scope=bot%20applications.commands).
|
||||
|
||||
## Setup
|
||||
|
||||
1. Clone this repository: `git clone https://github.com/xHyroM/roles-bot.git`
|
||||
2. Navigate to the project directory: `cd roles-bot`
|
||||
3. Install the dependencies: `pnpm install`
|
||||
|
||||
## Usage
|
||||
|
||||
- To run the development server: `pnpm run dev`
|
||||
- To build the project for production: `pnpm run build`
|
||||
- To preview the production build of website: `pnpm run preview`
|
||||
- To deploy bot to CF workers: `pnpm run deploy`
|
||||
|
||||
## Contributing
|
||||
|
||||
To contribute to this project, please follow the [standard Git workflow](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository#The-Standard-Git-Workflow) and [CONTRIBUTING](./CONTRIBUTING.md).
|
||||
|
||||
1. Fork this repository
|
||||
2. Create a new branch for your changes: `git checkout -b my-feature`
|
||||
3. Commit your changes: `git commit -am "Add my feature"`
|
||||
4. Push the branch: `git push origin my-feature`
|
||||
5. Open a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT License](./LICENSE).
|
||||
|
|
21
apps/redis-api/LICENSE
Normal file
21
apps/redis-api/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Jozef Steinhübl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
2
apps/redis-api/README.md
Normal file
2
apps/redis-api/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
For caching user selected options, we use the [Redis](http://redis.io/) key-value store. This package provides a simple API for interacting with Redis.
|
||||
We need this API because CloudFlare Workers (they doesn't support TCP)
|
20
apps/redis-api/package.json
Normal file
20
apps/redis-api/package.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "redis-api",
|
||||
"version": "0.0.1",
|
||||
"author": "xHyroM",
|
||||
"main": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "node scripts/build.mjs",
|
||||
"dev": "node scripts/build.mjs --dev && node dist/index.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.15.11",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "^16.0.3",
|
||||
"fastify": "^4.15.0",
|
||||
"ioredis": "^5.3.1"
|
||||
}
|
||||
}
|
49
apps/redis-api/scripts/build.mjs
Normal file
49
apps/redis-api/scripts/build.mjs
Normal file
|
@ -0,0 +1,49 @@
|
|||
import esbuild from "esbuild";
|
||||
import { rmSync, existsSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
if (existsSync(join(__dirname, "..", "dist")))
|
||||
rmSync(join(__dirname, "..", "dist"), { recursive: true });
|
||||
|
||||
const watch = process.argv.includes("--watch");
|
||||
const dev = process.argv.includes("--dev");
|
||||
|
||||
Promise.all([
|
||||
esbuild.build({
|
||||
bundle: true,
|
||||
logLevel: "info",
|
||||
format: "esm",
|
||||
platform: "node",
|
||||
target: "es2020",
|
||||
entryPoints: ["./src/index.ts"],
|
||||
outfile: "./dist/index.mjs",
|
||||
sourcemap: dev,
|
||||
charset: "utf8",
|
||||
minify: !dev,
|
||||
watch: watch,
|
||||
plugins: [
|
||||
{
|
||||
name: "make-all-packages-external",
|
||||
setup(build) {
|
||||
const filter = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/; // Must not start with "/" or "./" or "../"
|
||||
build.onResolve({ filter }, (args) => ({
|
||||
path: args.path,
|
||||
external: true,
|
||||
}));
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
])
|
||||
.catch((err) => {
|
||||
console.error("Redis api failed to build");
|
||||
console.error(err.message);
|
||||
})
|
||||
.then(() => {
|
||||
console.log(
|
||||
watch ? "Waiting for your changes..." : "Redis api has been built",
|
||||
);
|
||||
});
|
45
apps/redis-api/src/index.ts
Normal file
45
apps/redis-api/src/index.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import "dotenv/config";
|
||||
import redis from "./redis";
|
||||
|
||||
import Fastify from "fastify";
|
||||
const fastify = Fastify();
|
||||
|
||||
fastify.addHook("preHandler", async (request, reply) => {
|
||||
const Authorization = request.headers.authorization?.replace("Bearer ", "");
|
||||
if (Authorization !== process.env.API_KEY)
|
||||
reply.status(401).send("Unauthorized");
|
||||
});
|
||||
|
||||
fastify.post("/set", async (request, reply) => {
|
||||
const { key, value } = request.body as { key: string; value: string };
|
||||
|
||||
reply.send(await redis.set(key, value));
|
||||
});
|
||||
|
||||
fastify.post("/setex", async (request, reply) => {
|
||||
const { key, value, seconds } = request.body as {
|
||||
key: string;
|
||||
value: string;
|
||||
seconds: number;
|
||||
};
|
||||
|
||||
reply.send(await redis.setex(key, seconds, value));
|
||||
});
|
||||
|
||||
fastify.get("/get", async (request, reply) => {
|
||||
const { key } = request.query as { key: string };
|
||||
|
||||
reply.send(await redis.get(key));
|
||||
});
|
||||
|
||||
fastify.delete("/del", async (request, reply) => {
|
||||
const { key } = (request.body || request.query) as { key: string };
|
||||
|
||||
reply.send(await redis.del(key));
|
||||
});
|
||||
|
||||
fastify.post("/flush", async (request, reply) => {
|
||||
reply.send(await redis.flushdb());
|
||||
});
|
||||
|
||||
fastify.listen({ port: 51253 }, console.log);
|
11
apps/redis-api/src/redis.ts
Normal file
11
apps/redis-api/src/redis.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import Redis from "ioredis";
|
||||
const redis = new Redis(
|
||||
// rome-ignore lint/style/noNonNullAssertion: env vars are always defined
|
||||
parseInt(process.env.REDIS_PORT!),
|
||||
process.env.REDIS_HOST as string,
|
||||
{
|
||||
password: process.env.REDIS_PASSWORD,
|
||||
},
|
||||
);
|
||||
|
||||
export default redis;
|
4
apps/redis-api/template.env
Normal file
4
apps/redis-api/template.env
Normal file
|
@ -0,0 +1,4 @@
|
|||
REDIS_PORT=
|
||||
REDIS_HOST=
|
||||
REDIS_PASSWORD=
|
||||
API_KEY=
|
15
apps/redis-api/tsconfig.json
Normal file
15
apps/redis-api/tsconfig.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
"target": "ESNext",
|
||||
"lib": ["ESNext"],
|
||||
"module": "ESNext",
|
||||
"strict": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true
|
||||
}
|
||||
}
|
21
apps/website/.gitignore
vendored
Normal file
21
apps/website/.gitignore
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# build output
|
||||
dist/
|
||||
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
1
apps/website/.prettierignore
Normal file
1
apps/website/.prettierignore
Normal file
|
@ -0,0 +1 @@
|
|||
dist/*
|
14
apps/website/.prettierrc.cjs
Normal file
14
apps/website/.prettierrc.cjs
Normal file
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
plugins: [
|
||||
require.resolve("prettier-plugin-astro"),
|
||||
require.resolve("prettier-plugin-tailwindcss"),
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
files: "*.astro",
|
||||
options: {
|
||||
parser: "astro",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
55
apps/website/README.md
Normal file
55
apps/website/README.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Astro Starter Kit: Basics
|
||||
|
||||
```
|
||||
npm create astro@latest -- --template basics
|
||||
```
|
||||
|
||||
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
|
||||
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
![basics](https://user-images.githubusercontent.com/4677417/186188965-73453154-fdec-4d6b-9c34-cb35c248ae5b.png)
|
||||
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```
|
||||
/
|
||||
├── public/
|
||||
│ └── favicon.svg
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ └── Card.astro
|
||||
│ ├── layouts/
|
||||
│ │ └── Layout.astro
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
46
apps/website/astro.config.ts
Normal file
46
apps/website/astro.config.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
import { defineConfig } from "astro/config";
|
||||
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
import robotsTxt from "astro-robots-txt";
|
||||
import compress from "astro-compress";
|
||||
import tailwind from "@astrojs/tailwind";
|
||||
|
||||
import { CONFIG } from "./src/config";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export default defineConfig({
|
||||
site: CONFIG.origin,
|
||||
base: "/",
|
||||
trailingSlash: "always",
|
||||
output: "static",
|
||||
integrations: [
|
||||
sitemap(),
|
||||
robotsTxt({
|
||||
policy: [
|
||||
{
|
||||
userAgent: "*",
|
||||
},
|
||||
],
|
||||
sitemap: true,
|
||||
}),
|
||||
compress({
|
||||
css: true,
|
||||
html: true,
|
||||
img: true,
|
||||
js: true,
|
||||
svg: true,
|
||||
}),
|
||||
tailwind(),
|
||||
],
|
||||
vite: {
|
||||
resolve: {
|
||||
alias: {
|
||||
"~": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
31
apps/website/package.json
Normal file
31
apps/website/package.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "website",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/prefetch": "^0.2.1",
|
||||
"@astrojs/sitemap": "^1.2.1",
|
||||
"@astrojs/tailwind": "^3.1.1",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"astro": "^2.1.9",
|
||||
"astro-compress": "^1.1.35",
|
||||
"astro-google-fonts-optimizer": "^0.2.2",
|
||||
"astro-icon": "^0.8.0",
|
||||
"astro-robots-txt": "^0.4.1",
|
||||
"tailwindcss": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.14",
|
||||
"cssnano": "^6.0.0",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-astro": "^0.8.0",
|
||||
"prettier-plugin-tailwindcss": "^0.2.6"
|
||||
}
|
||||
}
|
17
apps/website/postcss.config.cjs
Normal file
17
apps/website/postcss.config.cjs
Normal file
|
@ -0,0 +1,17 @@
|
|||
const tailwindcss = require("tailwindcss");
|
||||
const autoprefixer = require("autoprefixer");
|
||||
const cssnano = require("cssnano");
|
||||
|
||||
const mode = process.env.NODE_ENV;
|
||||
const dev = mode === "development";
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
tailwindcss,
|
||||
autoprefixer,
|
||||
!dev &&
|
||||
cssnano({
|
||||
preset: "default",
|
||||
}),
|
||||
],
|
||||
};
|
BIN
apps/website/public/logo.png
Normal file
BIN
apps/website/public/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 200 KiB |
15
apps/website/src/components/Computer.astro
Normal file
15
apps/website/src/components/Computer.astro
Normal file
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" class="h-6 w-6"
|
||||
><path
|
||||
fill="#CCD6DD"
|
||||
d="M36 22c0 2.209-1.791 4-4 4H4c-2.209 0-4-1.791-4-4V4c0-2.209 1.791-4 4-4h28c2.209 0 4 1.791 4 4v18z"
|
||||
></path><path fill="#5DADEC" d="M4 4h28v18H4z"></path><path
|
||||
fill="#CCD6DD"
|
||||
d="M13 26h10v6H13z"></path><path fill="#9AAAB4" d="M13 26h10v2H13z"
|
||||
></path><path
|
||||
fill="#E1E8ED"
|
||||
d="M36 33c0-1.657-1.343-3-3-3H3c-1.657 0-3 1.343-3 3s1.343 3 3 3h30c1.657 0 3-1.343 3-3z"
|
||||
></path><path
|
||||
fill="#F5F8FA"
|
||||
d="M3 32h2v2H3zm4 0h2v2H7zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2z"
|
||||
></path></svg
|
||||
>
|
After Width: | Height: | Size: 650 B |
18
apps/website/src/components/Invite.astro
Normal file
18
apps/website/src/components/Invite.astro
Normal file
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" class="h-8 w-8"
|
||||
><path
|
||||
fill="#55ACEE"
|
||||
d="M7 12c0 .552-.448 1-1 1H1c-.552 0-1-.448-1-1s.448-1 1-1h5c.552 0 1 .448 1 1m-2 5c0 .552-.448 1-1 1H1c-.552 0-1-.448-1-1s.448-1 1-1h3c.552 0 1 .448 1 1m-2 5c0 .553-.448 1-1 1H1c-.552 0-1-.447-1-1s.448-1 1-1h1c.552 0 1 .447 1 1"
|
||||
></path><path
|
||||
fill="#CCD6DD"
|
||||
d="M32.301 25c-.626 2.209-2.925 4-5.134 4h-20c-2.209 0-3.492-1.791-2.866-4l3.398-12c.626-2.209 2.924-4 5.133-4h20c2.209 0 3.493 1.791 2.867 4l-3.398 12z"
|
||||
></path><path
|
||||
fill="#99AAB5"
|
||||
d="M17.336 17.636L4.384 26.949c-.034.028-.054.063-.085.091.179.57.518 1.043.992 1.384.035-.023.073-.033.107-.06L18.35 19.05c.501-.391.681-1.023.401-1.414-.281-.391-.913-.391-1.415 0m13.81 9.404c-.015-.028-.016-.063-.034-.09l-7.674-9.314c-.281-.391-.913-.391-1.416 0-.501.391-.68 1.023-.4 1.414l7.676 9.314c.018.026.051.037.072.06.666-.34 1.274-.814 1.776-1.384"
|
||||
></path><path
|
||||
fill="#99AAB5"
|
||||
d="M35.699 13c.626-2.209-.658-4-2.867-4h-20c-2.209 0-4.507 1.791-5.133 4l-.021.074 8.806 8.452c1.631 1.584 3.788 1.475 5.725.371l13.227-7.964.263-.933z"
|
||||
></path><path
|
||||
fill="#E1E8ED"
|
||||
d="M32.832 9h-20c-1.578 0-3.189.921-4.217 2.248l9.217 8.794c.749.719 2.434.729 3.656 0l14.294-8.768C35.516 9.933 34.42 9 32.832 9z"
|
||||
></path></svg
|
||||
>
|
After Width: | Height: | Size: 1.3 KiB |
7
apps/website/src/config.ts
Normal file
7
apps/website/src/config.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export const CONFIG = {
|
||||
name: "Roles Bot",
|
||||
description:
|
||||
"Ultimate solution for managing reaction roles in your Discord server, and the best part is, it's completely free! No hidden charges or payments like other bots. Try it out today and see for yourself how easy it is to use!",
|
||||
themeColor: "#fbc11a",
|
||||
origin: "https://roles-bot.xhyrom.dev",
|
||||
};
|
1
apps/website/src/env.d.ts
vendored
Normal file
1
apps/website/src/env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/// <reference types="astro/client" />
|
43
apps/website/src/layouts/Layout.astro
Normal file
43
apps/website/src/layouts/Layout.astro
Normal file
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
import { CONFIG } from "~/config";
|
||||
import { GoogleFontsOptimizer } from "astro-google-fonts-optimizer";
|
||||
---
|
||||
|
||||
<html lang="sk-SK">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>{CONFIG.name}</title>
|
||||
<meta name="title" content={CONFIG.name} />
|
||||
<meta name="description" content={CONFIG.name} />
|
||||
|
||||
<link rel="icon" href="logo.png" type="image/png" sizes="64x64" />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={CONFIG.origin} />
|
||||
<meta property="og:site_name" content={CONFIG.name} />
|
||||
<meta property="og:title" content={CONFIG.name} />
|
||||
<meta property="og:description" content={CONFIG.description} />
|
||||
<!-- <meta property="og:image" content={image} /> -->
|
||||
<!-- <meta property="og:image:alt" content={imageAlt} /> -->
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={CONFIG.origin} />
|
||||
<meta property="twitter:title" content={CONFIG.name} />
|
||||
<meta property="twitter:description" content={CONFIG.description} />
|
||||
<!--<meta property="twitter:image" content={image} /> -->
|
||||
<!-- <meta name="twitter:image:alt" content={imageAlt} /> -->
|
||||
<meta name="theme-color" content={CONFIG.themeColor} />
|
||||
<GoogleFontsOptimizer
|
||||
url="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,500;1,700;1,900&display=swap"
|
||||
/>
|
||||
<link rel="stylesheet" href="../src/assets/styles/base.css" />
|
||||
</head>
|
||||
<body class="bg-dark font-body">
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
46
apps/website/src/pages/index.astro
Normal file
46
apps/website/src/pages/index.astro
Normal file
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
import Layout from "~/layouts/Layout.astro";
|
||||
import Invite from "~/components/Invite.astro";
|
||||
import Computer from "~/components/Computer.astro";
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<main class="flex h-screen items-center justify-center text-center">
|
||||
<div
|
||||
class="flex flex-col items-center px-4 text-center md:flex-row md:text-left"
|
||||
>
|
||||
<img
|
||||
src="https://raw.githubusercontent.com/Hyro-Blobs/blobs/main/other/hyro_santa_bucket.png"
|
||||
alt=""
|
||||
class="mb-6 h-48 w-48 rounded-full md:h-64 md:w-64"
|
||||
/>
|
||||
<div>
|
||||
<h1 class="mb-4 text-6xl font-extrabold text-white md:text-7xl">
|
||||
Roles Bot
|
||||
</h1>
|
||||
<p class="max-w-3xl text-lg text-gray-300 md:text-xl">
|
||||
Ultimate solution for managing reaction roles in your Discord server,
|
||||
and the best part is, it's completely <strong>free</strong>! No hidden
|
||||
charges or payments like other bots. Try it out today and see for
|
||||
yourself how <strong>easy</strong> it is to use!
|
||||
</p>
|
||||
<div class="mt-6 flex flex-col gap-6 md:flex-row">
|
||||
<a
|
||||
href=""
|
||||
class="broder-1 flex items-center justify-center gap-x-3 rounded-lg border border-[#4e59d6] bg-[#373a54]/50 px-10 py-3 text-lg font-semibold text-white transition-colors hover:bg-[#373a54]"
|
||||
>
|
||||
<Computer />
|
||||
GitHub</a
|
||||
>
|
||||
<a
|
||||
href=""
|
||||
class="broder-1 flex items-center justify-center gap-x-3 rounded-lg border border-[#fbc11a] bg-[#735d1d]/50 px-10 py-3 text-lg font-semibold text-white transition-colors hover:bg-[#735d1d]"
|
||||
>
|
||||
<Invite />
|
||||
Invite</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
15
apps/website/tailwind.config.cjs
Normal file
15
apps/website/tailwind.config.cjs
Normal file
|
@ -0,0 +1,15 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
dark: "#111111",
|
||||
},
|
||||
fontFamily: {
|
||||
body: ["Montserrat", "sans-serif"],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
11
apps/website/tsconfig.json
Normal file
11
apps/website/tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"compilerOptions": {
|
||||
"strictNullChecks": true,
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["src/*"]
|
||||
}
|
||||
}
|
||||
}
|
5071
package-lock.json
generated
5071
package-lock.json
generated
File diff suppressed because it is too large
Load diff
30
package.json
30
package.json
|
@ -1,25 +1,21 @@
|
|||
{
|
||||
"name": "roles-bot",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/worker.production.js",
|
||||
"description": "",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack ./packages/bot",
|
||||
"dev": "cross-env NODE_ENV=development npm run build"
|
||||
"build": "turbo run build",
|
||||
"dev": "turbo run dev",
|
||||
"preview": "turbo run preview",
|
||||
"deploy": "turbo run deploy",
|
||||
"test": "turbo run test",
|
||||
"lint": "rome check .",
|
||||
"format": "rome format --write ."
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"author": "xHyroM",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@8.1.0",
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^3.3.0",
|
||||
"@types/jest": "^27.0.3",
|
||||
"@types/service-worker-mock": "^2.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.8.1",
|
||||
"discord-api-types": "^0.25.2",
|
||||
"eslint": "^8.6.0",
|
||||
"service-worker-mock": "^2.0.5",
|
||||
"ts-loader": "^9.2.6",
|
||||
"typescript": "^4.5.4",
|
||||
"webpack": "^5.65.0",
|
||||
"webpack-cli": "^4.9.1"
|
||||
"rome": "^12.0.0"
|
||||
}
|
||||
}
|
||||
|
|
21
packages/bot/LICENSE
Normal file
21
packages/bot/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Jozef Steinhübl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
7
packages/bot/README.md
Normal file
7
packages/bot/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div align="center">
|
||||
<h1>Discord Roles Bot</h1>
|
||||
</div>
|
||||
|
||||
Discord bot for reaction roles that works with [Cloudflare Workers](https://workers.cloudflare.com/).
|
||||
|
||||
You can add the bot to your server, just click [here](https://discord.com/api/oauth2/authorize?client_id=923267906941370368&permissions=268435456&scope=bot%20applications.commands).
|
|
@ -1,100 +0,0 @@
|
|||
import { APIApplicationCommandInteraction, APIMessageComponentInteraction, APIPingInteraction, ApplicationCommandType, ComponentType, InteractionResponseType, InteractionType, MessageFlags, RouteBases, Routes } from 'discord-api-types/v9';
|
||||
import { badFormatting } from './utils/badFormatting';
|
||||
import { isJSON } from './utils/isJson';
|
||||
import { resolveButtonComponents, resolveSelectMenuComponents } from './utils/resolveComponents';
|
||||
import { respond } from './utils/respond';
|
||||
import { verify } from './utils/verify';
|
||||
|
||||
export const handleRequest = async(request: Request): Promise<Response> => {
|
||||
if (!request.headers.get('X-Signature-Ed25519') || !request.headers.get('X-Signature-Timestamp')) return Response.redirect('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
if (!await verify(request)) return new Response('', { status: 401 });
|
||||
|
||||
const interaction = await request.json() as APIPingInteraction | APIApplicationCommandInteraction | APIMessageComponentInteraction;
|
||||
|
||||
if (interaction.type === InteractionType.Ping)
|
||||
return respond({
|
||||
type: InteractionResponseType.Pong
|
||||
});
|
||||
|
||||
if (interaction.type === InteractionType.ApplicationCommand && interaction.data.type === ApplicationCommandType.ChatInput && interaction.data.name === 'setup') {
|
||||
if ((Number(interaction.member?.permissions) & 0x10) !== 0x10) return respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: 64,
|
||||
content: 'Required permissions: `MANAGE_ROLES`'
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-expect-error No typings for value
|
||||
const json = isJSON(interaction.data.options?.[0]?.value) ? JSON.parse(interaction.data.options?.[0]?.value) : null;
|
||||
if (!json) return badFormatting();
|
||||
|
||||
const channelId = json.channel;
|
||||
let message = json.message?.toString();
|
||||
let roles = json.roles;
|
||||
|
||||
if (!channelId) return badFormatting();
|
||||
if (!message) message = '';
|
||||
if (!roles || Object.values(json.roles).filter((role: any) => role.id && role.label).length === 0 || roles.length === 0 || roles.length > 25) return badFormatting(roles.length > 25);
|
||||
|
||||
const finalComponents = json.type === "1" ? resolveButtonComponents(roles) : resolveSelectMenuComponents(roles, json.placeholder?.toString());
|
||||
|
||||
const fetched = await fetch(`${RouteBases.api}/channels/${channelId}/messages`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bot ${CLIENT_TOKEN}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: message,
|
||||
components: finalComponents
|
||||
})
|
||||
}).catch(e => e);
|
||||
|
||||
return respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: 64,
|
||||
content: fetched?.ok ? 'Done!' : 'Error, bad channel id/missing permissions/invalid emojis.'
|
||||
}
|
||||
});
|
||||
} else if (interaction.type === InteractionType.MessageComponent) {
|
||||
const roleId = interaction.data.component_type === ComponentType.Button ? interaction.data.custom_id : interaction.data.values[0];
|
||||
const url = `${RouteBases.api}${Routes.guildMemberRole(interaction.guild_id || '', interaction.member?.user.id || '', roleId)}`;
|
||||
|
||||
let method = '';
|
||||
let content = '';
|
||||
|
||||
if (!interaction?.member?.roles?.includes(roleId)) {
|
||||
content = `Gave the <@&${roleId}> role!`;
|
||||
method = 'PUT';
|
||||
} else {
|
||||
content = `Removed the <@&${roleId}> role!`;
|
||||
method = 'DELETE';
|
||||
}
|
||||
|
||||
await fetch(url, {
|
||||
method: method,
|
||||
headers: {
|
||||
'Authorization': `Bot ${CLIENT_TOKEN}`
|
||||
}
|
||||
}).catch(e => e);
|
||||
|
||||
return respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: MessageFlags.Ephemeral,
|
||||
content: content,
|
||||
allowed_mentions: { parse: [] }
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: MessageFlags.Ephemeral,
|
||||
content: 'Beep boop, boop beep?'
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
import { handleRequest } from './bot';
|
||||
|
||||
addEventListener('fetch', (event) => {
|
||||
event.respondWith(handleRequest(event.request));
|
||||
});
|
29
packages/bot/package.json
Normal file
29
packages/bot/package.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "bot",
|
||||
"main": "dist/worker.mjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node scripts/build.mjs",
|
||||
"dev": "miniflare --watch --debug --port 8787",
|
||||
"dev:tunnel": "cloudflared tunnel --url localhost:8787/",
|
||||
"deploy": "cross-env NODE_ENV=production wrangler publish"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "xHyroM",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^3.17.0",
|
||||
"@types/jest": "^29.1.2",
|
||||
"esbuild": "^0.15.11",
|
||||
"eslint": "^8.25.0",
|
||||
"jest": "^29.2.0",
|
||||
"miniflare": "^2.10.0",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"builders": "workspace:*",
|
||||
"serialize": "workspace:*",
|
||||
"redis-api-client": "workspace:*",
|
||||
"discord-api-types": "^0.37.37"
|
||||
}
|
||||
}
|
39
packages/bot/scripts/build.mjs
Normal file
39
packages/bot/scripts/build.mjs
Normal file
|
@ -0,0 +1,39 @@
|
|||
import esbuild from "esbuild";
|
||||
import { rmSync, existsSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
if (existsSync(join(__dirname, "..", "dist")))
|
||||
rmSync(join(__dirname, "..", "dist"), { recursive: true });
|
||||
|
||||
const watch = process.argv.includes("--watch");
|
||||
const dev = process.argv.includes("--dev");
|
||||
|
||||
Promise.all([
|
||||
esbuild.build({
|
||||
bundle: true,
|
||||
logLevel: "info",
|
||||
format: "esm",
|
||||
mainFields: ["browser", "module", "main"],
|
||||
platform: "neutral",
|
||||
target: "es2020",
|
||||
entryPoints: ["./src/index.ts"],
|
||||
outfile: "./dist/worker.mjs",
|
||||
sourcemap: dev,
|
||||
charset: "utf8",
|
||||
minify: !dev,
|
||||
watch: watch,
|
||||
external: ["node:events"],
|
||||
}),
|
||||
])
|
||||
.catch((err) => {
|
||||
console.error("Roles Bot failed to build");
|
||||
console.error(err.message);
|
||||
})
|
||||
.then(() => {
|
||||
console.log(
|
||||
watch ? "Waiting for your changes..." : "Roles Bot has been built",
|
||||
);
|
||||
});
|
61
packages/bot/src/commands/setup.ts
Normal file
61
packages/bot/src/commands/setup.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { Command } from "../structs/Command";
|
||||
import {
|
||||
APIRole,
|
||||
ChannelType,
|
||||
MessageFlags,
|
||||
RouteBases,
|
||||
Routes,
|
||||
} from "discord-api-types/v10";
|
||||
import { ActionRowBuilder, ChannelSelectMenuBuilder } from "builders";
|
||||
import { REDIS } from "../things";
|
||||
import { encodeToHex } from "serialize";
|
||||
|
||||
// Part 1 ## select channel
|
||||
new Command({
|
||||
name: "setup",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
if (!ctx.guildId)
|
||||
return await ctx.editReply({
|
||||
content: "Guild not found.",
|
||||
});
|
||||
|
||||
// Delete the data if it exists
|
||||
await REDIS.del(`roles-bot-setup:${ctx.guildId}`);
|
||||
|
||||
const roles = (await (
|
||||
await fetch(`${RouteBases.api}${Routes.guildRoles(ctx.guildId)}`, {
|
||||
headers: {
|
||||
Authorization: `Bot ${ctx.env.token}`,
|
||||
},
|
||||
})
|
||||
).json()) as APIRole[];
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup-roles:${ctx.guildId}`,
|
||||
encodeToHex(
|
||||
roles.map((r) => ({
|
||||
id: r.id,
|
||||
name: r.name,
|
||||
})),
|
||||
),
|
||||
3600,
|
||||
);
|
||||
|
||||
await ctx.editReply({
|
||||
content: "Select the channel to which the panel will be sent.",
|
||||
components: [
|
||||
new ActionRowBuilder<ChannelSelectMenuBuilder>()
|
||||
.addComponents(
|
||||
new ChannelSelectMenuBuilder()
|
||||
.setCustomId("setup:part-channel")
|
||||
.addChannelTypes(
|
||||
ChannelType.GuildAnnouncement,
|
||||
ChannelType.GuildText,
|
||||
),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
61
packages/bot/src/components/select.ts
Normal file
61
packages/bot/src/components/select.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import {
|
||||
ComponentType,
|
||||
MessageFlags,
|
||||
RouteBases,
|
||||
Routes,
|
||||
} from "discord-api-types/v10";
|
||||
import { Component } from "../structs/Component";
|
||||
|
||||
new Component({
|
||||
id: "select:role",
|
||||
default: true,
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
if (!ctx.guildId)
|
||||
return ctx.editReply({
|
||||
content: "Guild not found.",
|
||||
});
|
||||
|
||||
if (!ctx.interaction.member)
|
||||
return ctx.editReply({
|
||||
content: "Member not found.",
|
||||
});
|
||||
|
||||
const roleId =
|
||||
ctx.interaction.data.component_type === ComponentType.StringSelect
|
||||
? ctx.interaction.data.values[0].startsWith("role:")
|
||||
? ctx.interaction.data.values[0].split(":")[1]
|
||||
: // support for legacy select menus
|
||||
ctx.interaction.data.values[0]
|
||||
: ctx.interaction.data.custom_id.startsWith("role:")
|
||||
? ctx.interaction.data.custom_id.split(":")[1]
|
||||
: // support for legacy select menus
|
||||
ctx.interaction.data.custom_id;
|
||||
|
||||
const content = !ctx.interaction.member?.roles.includes(roleId)
|
||||
? `Gave the <@&${roleId}> role!`
|
||||
: `Removed the <@&${roleId}> role!`;
|
||||
|
||||
const method = !ctx.interaction.member?.roles.includes(roleId)
|
||||
? "PUT"
|
||||
: "DELETE";
|
||||
|
||||
await fetch(
|
||||
`${RouteBases.api}${Routes.guildMemberRole(
|
||||
ctx.guildId,
|
||||
ctx.interaction.member.user.id,
|
||||
roleId,
|
||||
)}`,
|
||||
{
|
||||
method,
|
||||
headers: {
|
||||
Authorization: `Bot ${ctx.env.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await ctx.editReply({
|
||||
content,
|
||||
});
|
||||
},
|
||||
});
|
268
packages/bot/src/components/setup.ts
Normal file
268
packages/bot/src/components/setup.ts
Normal file
|
@ -0,0 +1,268 @@
|
|||
import {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
RoleSelectMenuBuilder,
|
||||
TextInputBuilder,
|
||||
} from "builders";
|
||||
import { Component } from "../structs/Component";
|
||||
import {
|
||||
APIMessageComponentSelectMenuInteraction,
|
||||
ButtonStyle,
|
||||
InteractionResponseType,
|
||||
MessageFlags,
|
||||
TextInputStyle,
|
||||
} from "discord-api-types/v10";
|
||||
import returnRoleLpe from "../utils/returnRoleLpe";
|
||||
import { REDIS } from "../things";
|
||||
import { encodeToHex, decodeFromString } from "serialize";
|
||||
import sendFinal from "../utils/sendFinal";
|
||||
|
||||
// Part 2 Channels ## select button/dropdowns
|
||||
new Component({
|
||||
id: "setup:part-channel",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
if (!ctx.interaction.guild_id)
|
||||
return await ctx.editReply({
|
||||
content: "Guild not found.",
|
||||
});
|
||||
|
||||
const interaction =
|
||||
ctx.interaction as APIMessageComponentSelectMenuInteraction;
|
||||
|
||||
const data = {
|
||||
channelId: interaction.data.values[0],
|
||||
};
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup:${interaction.guild_id}`,
|
||||
encodeToHex(data),
|
||||
600,
|
||||
);
|
||||
|
||||
await ctx.editReply({
|
||||
content:
|
||||
"Choose whether you want to use buttons or dropdown menu (select menu).",
|
||||
components: [
|
||||
new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setLabel("Buttons")
|
||||
.setCustomId("setup:part-selecting:buttons")
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
new ButtonBuilder()
|
||||
.setLabel("Dropdowns")
|
||||
.setCustomId("setup:part-selecting:dropdowns")
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Part 3 Selecting ## select roles
|
||||
new Component({
|
||||
id: "setup:part-selecting",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
if (!ctx.interaction.guild_id)
|
||||
return await ctx.editReply({ content: "Guild not found." });
|
||||
|
||||
const rawData = await REDIS.get(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
);
|
||||
if (!rawData)
|
||||
return await ctx.editReply({
|
||||
content: "Data not found. Try running setup again.",
|
||||
});
|
||||
|
||||
const data = decodeFromString(rawData);
|
||||
data.selecting = ctx.interaction.data.custom_id.split(":")[2];
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
encodeToHex(data),
|
||||
600,
|
||||
);
|
||||
|
||||
await ctx.editReply({
|
||||
content: "Select the roles that will be available in the menu.",
|
||||
components: [
|
||||
new ActionRowBuilder<RoleSelectMenuBuilder>()
|
||||
.addComponents(
|
||||
new RoleSelectMenuBuilder()
|
||||
.setCustomId("setup:part-roles")
|
||||
.setPlaceholder("Select roles")
|
||||
.setMinValues(1)
|
||||
.setMaxValues(25),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Part 4 Roles ## open modal for role lpe OR message preview
|
||||
new Component({
|
||||
id: "setup:part-roles",
|
||||
acknowledge: false,
|
||||
run: async (ctx) => {
|
||||
if (!ctx.interaction.guild_id)
|
||||
return await ctx.editReply({ content: "Guild not found." });
|
||||
|
||||
const interaction =
|
||||
ctx.interaction as APIMessageComponentSelectMenuInteraction;
|
||||
|
||||
const rawData = await REDIS.get(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
);
|
||||
if (!rawData)
|
||||
return ctx.respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
content: "Data not found. Try running setup again.",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
},
|
||||
});
|
||||
|
||||
const data = decodeFromString(rawData);
|
||||
const rawRoleIds = (data.rawRoleIds as string[]) ?? interaction.data.values;
|
||||
|
||||
data.rawRoleIds = rawRoleIds;
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
encodeToHex(data),
|
||||
600,
|
||||
);
|
||||
|
||||
return rawRoleIds.length > 0
|
||||
? returnRoleLpe(data, ctx, rawRoleIds[0])
|
||||
: ctx.returnModal({
|
||||
title: "Message Preview",
|
||||
custom_id: "setup:part-messageContent",
|
||||
components: [
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Content")
|
||||
.setCustomId("content")
|
||||
.setPlaceholder("Select beautiful roles <3")
|
||||
.setStyle(TextInputStyle.Paragraph)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Embed Title")
|
||||
.setCustomId("embedTitle")
|
||||
.setPlaceholder("I love you")
|
||||
.setStyle(TextInputStyle.Paragraph)
|
||||
.setMaxLength(256)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Embed Description")
|
||||
.setCustomId("embedDescription")
|
||||
.setPlaceholder("1. lol\n2. lol\n3. lol")
|
||||
.setStyle(TextInputStyle.Paragraph)
|
||||
.setMaxLength(4000)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Embed Color")
|
||||
.setCustomId("embedColor")
|
||||
.setPlaceholder("#4287f5")
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setMaxLength(7)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Part 7 Send As ## finish or open modal for webhook preview
|
||||
new Component({
|
||||
id: "setup:part-sendAs",
|
||||
acknowledge: false,
|
||||
run: async (ctx) => {
|
||||
if (!ctx.guildId)
|
||||
return await ctx.editReply({ content: "Guild not found." });
|
||||
|
||||
const rawData = await REDIS.get(`roles-bot-setup:${ctx.guildId}`);
|
||||
if (!rawData)
|
||||
return ctx.respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
content: "Data not found. Try running setup again.",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
},
|
||||
});
|
||||
|
||||
const data = decodeFromString(rawData);
|
||||
const sendAs = ctx.interaction.data.custom_id.split(":")[2];
|
||||
data.sendAs = sendAs;
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
encodeToHex(data),
|
||||
600,
|
||||
);
|
||||
|
||||
switch (sendAs) {
|
||||
case "webhook": {
|
||||
return ctx.returnModal({
|
||||
title: "Webhook Preview",
|
||||
custom_id: "setup:part-webhook",
|
||||
components: [
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Webhook Name")
|
||||
.setCustomId("name")
|
||||
.setPlaceholder("Roles Bot")
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setMaxLength(80)
|
||||
.setRequired(true),
|
||||
)
|
||||
.toJSON(),
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Webhook Avatar URL")
|
||||
.setCustomId("avatarUrl")
|
||||
.setPlaceholder(
|
||||
"https://raw.githubusercontent.com/Hyro-Blobs/blobs/main/base/hyro_blob-upscaled.png",
|
||||
)
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
}
|
||||
case "bot": {
|
||||
sendFinal(ctx, data);
|
||||
|
||||
return ctx.respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
content: "Setup completed!",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
120
packages/bot/src/index.ts
Normal file
120
packages/bot/src/index.ts
Normal file
|
@ -0,0 +1,120 @@
|
|||
import "./commands/setup";
|
||||
import "./components/setup";
|
||||
import "./components/select";
|
||||
import "./modals/setup";
|
||||
|
||||
import {
|
||||
APIApplicationCommandInteraction,
|
||||
APIMessageComponentInteraction,
|
||||
APIModalSubmitInteraction,
|
||||
APIPingInteraction,
|
||||
InteractionResponseType,
|
||||
InteractionType,
|
||||
} from "discord-api-types/v10";
|
||||
import { COMMANDS, COMPONENTS, MODALS, REDIS, setRedis } from "./things";
|
||||
import { verify } from "./utils/verify";
|
||||
import respond from "./utils/respond";
|
||||
import { CommandContext } from "./structs/contexts/CommandContext";
|
||||
import { ComponentContext } from "./structs/contexts/ComponentContext";
|
||||
import { ModalContext } from "./structs/contexts/ModalContext";
|
||||
import { Env } from "./types";
|
||||
|
||||
export default {
|
||||
fetch: async (request: Request, env: Env) => {
|
||||
if (!REDIS) setRedis(env.redisApiClientKey, env.redisApiClientHost);
|
||||
|
||||
if (
|
||||
!request.headers.get("X-Signature-Ed25519") ||
|
||||
!request.headers.get("X-Signature-Timestamp")
|
||||
)
|
||||
return Response.redirect("https://xhyrom.dev");
|
||||
if (!(await verify(request, env)))
|
||||
return new Response("Invalid request signature", { status: 401 });
|
||||
|
||||
const interaction = (await request.json()) as
|
||||
| APIPingInteraction
|
||||
| APIApplicationCommandInteraction
|
||||
| APIModalSubmitInteraction
|
||||
| APIMessageComponentInteraction;
|
||||
|
||||
if (interaction.type === InteractionType.Ping)
|
||||
return respond({
|
||||
type: InteractionResponseType.Pong,
|
||||
});
|
||||
|
||||
switch (interaction.type) {
|
||||
case InteractionType.ApplicationCommand: {
|
||||
const command = COMMANDS.find(
|
||||
(cmd) => cmd.name === interaction.data.name,
|
||||
);
|
||||
|
||||
if (!command) return new Response("Unknown command", { status: 404 });
|
||||
|
||||
try {
|
||||
if (command.acknowledge)
|
||||
return respond({
|
||||
type: InteractionResponseType.DeferredChannelMessageWithSource,
|
||||
data: {
|
||||
flags: command.flags,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
if (command.acknowledge)
|
||||
command.run(new CommandContext(interaction, env));
|
||||
// rome-ignore lint/correctness/noUnsafeFinally: it works, must do better typings etc...
|
||||
else return command.run(new CommandContext(interaction, env));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case InteractionType.ModalSubmit: {
|
||||
const context = new ModalContext(interaction, env);
|
||||
const modal = MODALS.find((md) =>
|
||||
context.interaction.data.custom_id.startsWith(md.id),
|
||||
);
|
||||
|
||||
if (!modal) return new Response("Unknown modal", { status: 404 });
|
||||
|
||||
try {
|
||||
if (modal.acknowledge)
|
||||
return respond({
|
||||
type: InteractionResponseType.DeferredChannelMessageWithSource,
|
||||
data: {
|
||||
flags: modal.flags,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
if (modal.acknowledge) modal.run(context);
|
||||
// rome-ignore lint/correctness/noUnsafeFinally: it works, must do better typings etc...
|
||||
else return modal.run(context);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case InteractionType.MessageComponent: {
|
||||
const context = new ComponentContext(interaction, env);
|
||||
const component =
|
||||
COMPONENTS.find((cmp) =>
|
||||
context.interaction.data.custom_id.startsWith(cmp.id),
|
||||
) ?? COMPONENTS.find((cmp) => cmp.default);
|
||||
|
||||
if (!component)
|
||||
return new Response("Unknown component", { status: 404 });
|
||||
|
||||
try {
|
||||
if (component.acknowledge)
|
||||
return respond({
|
||||
type: InteractionResponseType.DeferredChannelMessageWithSource,
|
||||
data: {
|
||||
flags: component.flags,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
if (component.acknowledge) component.run(context);
|
||||
// rome-ignore lint/correctness/noUnsafeFinally: it works, must do better typings etc...
|
||||
else return component.run(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
189
packages/bot/src/modals/setup.ts
Normal file
189
packages/bot/src/modals/setup.ts
Normal file
|
@ -0,0 +1,189 @@
|
|||
import {
|
||||
APIWebhook,
|
||||
ButtonStyle,
|
||||
MessageFlags,
|
||||
RouteBases,
|
||||
Routes,
|
||||
} from "discord-api-types/v10";
|
||||
import { Modal } from "../structs/Modal";
|
||||
import { ActionRowBuilder, ButtonBuilder } from "builders";
|
||||
import { encodeToHex, decodeFromString } from "serialize";
|
||||
import { REDIS } from "../things";
|
||||
import sendFinal from "../utils/sendFinal";
|
||||
import { RoleId } from "../types";
|
||||
|
||||
// Part 5 Roles ## add label, placeholder, emoji OR message content
|
||||
new Modal({
|
||||
id: "setup:part-roles-lpe",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
const rawData = await REDIS.get(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
);
|
||||
if (!rawData)
|
||||
return await ctx.editReply({
|
||||
content: "Data not found. Try running setup again.",
|
||||
});
|
||||
|
||||
const data = decodeFromString(rawData);
|
||||
const rawRoleIds = data.rawRoleIds as string[];
|
||||
const roleIds = (data.roleIds ?? []) as RoleId[];
|
||||
|
||||
const label = ctx.interaction.data.components[0].components[0].value;
|
||||
const emoji = ctx.interaction.data.components[1].components[0].value;
|
||||
|
||||
switch (data.selecting) {
|
||||
case "buttons": {
|
||||
const style = ctx.interaction.data.components[2].components[0].value;
|
||||
|
||||
roleIds.push({ label, style, emoji, id: rawRoleIds[0] });
|
||||
|
||||
break;
|
||||
}
|
||||
case "dropdowns": {
|
||||
const description =
|
||||
ctx.interaction.data.components[2].components[0].value;
|
||||
|
||||
roleIds.push({ label, description, emoji, id: rawRoleIds[0] });
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rawRoleIds.shift();
|
||||
data.rawRoleIds = rawRoleIds;
|
||||
data.roleIds = roleIds;
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
encodeToHex(data),
|
||||
600,
|
||||
);
|
||||
|
||||
return await ctx.editReply({
|
||||
content:
|
||||
rawRoleIds.length > 0
|
||||
? "Click the button to set the label, placeholder and emoji for next role."
|
||||
: "Click the button to set message content or embed.",
|
||||
components: [
|
||||
new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setLabel(rawRoleIds.length > 0 ? "Next Role" : "Message Content")
|
||||
.setCustomId("setup:part-roles")
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Part 6 Message Content ## select send as webhook/as bot
|
||||
new Modal({
|
||||
id: "setup:part-messageContent",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
const rawData = await REDIS.get(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
);
|
||||
if (!rawData)
|
||||
return await ctx.editReply({
|
||||
content: "Data not found. Try running setup again.",
|
||||
});
|
||||
|
||||
const data = decodeFromString(rawData);
|
||||
|
||||
const content = ctx.interaction.data.components[0].components[0].value;
|
||||
const embedTitle = ctx.interaction.data.components[1].components[0].value;
|
||||
const embedDescription =
|
||||
ctx.interaction.data.components[2].components[0].value;
|
||||
const embedColor = ctx.interaction.data.components[3].components[0].value;
|
||||
|
||||
if (!content && !embedTitle && !embedDescription) {
|
||||
await ctx.editReply({
|
||||
content: "You must provide a message content or embed.",
|
||||
components: [],
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data.message = { content, embedTitle, embedDescription, embedColor };
|
||||
|
||||
await REDIS.setex(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
encodeToHex(data),
|
||||
600,
|
||||
);
|
||||
|
||||
await ctx.editReply({
|
||||
content:
|
||||
"Choose whether you want to send the message as a webhook or as a bot.",
|
||||
components: [
|
||||
new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(
|
||||
new ButtonBuilder()
|
||||
.setLabel("Webhook")
|
||||
.setCustomId("setup:part-sendAs:webhook")
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
new ButtonBuilder()
|
||||
.setLabel("Bot")
|
||||
.setCustomId("setup:part-sendAs:bot")
|
||||
.setStyle(ButtonStyle.Primary),
|
||||
)
|
||||
.toJSON(),
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Part 8 (ONLY IF WEBHOOK) Webhook ## send webhook
|
||||
new Modal({
|
||||
id: "setup:part-webhook",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
run: async (ctx) => {
|
||||
const rawData = await REDIS.get(
|
||||
`roles-bot-setup:${ctx.interaction.guild_id}`,
|
||||
);
|
||||
if (!rawData)
|
||||
return await ctx.editReply({
|
||||
content: "Data not found. Try running setup again.",
|
||||
});
|
||||
|
||||
const data = decodeFromString(rawData);
|
||||
|
||||
const webhookName = ctx.interaction.data.components[0].components[0].value;
|
||||
const webhookAvatarUrl =
|
||||
ctx.interaction.data.components[1].components[0].value;
|
||||
|
||||
const webhook = (await (
|
||||
await fetch(
|
||||
`${RouteBases.api}${Routes.channelWebhooks(data.channelId)}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bot ${ctx.env.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: "Roles Bot Webhook",
|
||||
}),
|
||||
},
|
||||
)
|
||||
).json()) as APIWebhook;
|
||||
|
||||
data.webhook = {
|
||||
name: webhookName,
|
||||
avatarUrl: webhookAvatarUrl,
|
||||
id: webhook.id,
|
||||
token: webhook.token,
|
||||
};
|
||||
|
||||
sendFinal(ctx, data);
|
||||
|
||||
await ctx.editReply({
|
||||
content: "Setup completed!",
|
||||
});
|
||||
},
|
||||
});
|
26
packages/bot/src/structs/Command.ts
Normal file
26
packages/bot/src/structs/Command.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { MessageFlags } from "discord-api-types/v10";
|
||||
import { registerCommand } from "../things";
|
||||
import { CommandContext } from "./contexts/CommandContext";
|
||||
|
||||
interface CommandOptions {
|
||||
name: string;
|
||||
acknowledge?: boolean;
|
||||
flags?: MessageFlags;
|
||||
run: (interaction: CommandContext) => void;
|
||||
}
|
||||
|
||||
export class Command {
|
||||
public name: string;
|
||||
public acknowledge: boolean;
|
||||
public flags: MessageFlags | undefined;
|
||||
public run: (interaction: CommandContext) => void | Response;
|
||||
|
||||
constructor(options: CommandOptions) {
|
||||
this.name = options.name;
|
||||
this.acknowledge = options.acknowledge ?? true;
|
||||
this.flags = options.flags;
|
||||
this.run = options.run;
|
||||
|
||||
registerCommand(this);
|
||||
}
|
||||
}
|
29
packages/bot/src/structs/Component.ts
Normal file
29
packages/bot/src/structs/Component.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { MessageFlags } from "discord-api-types/v10";
|
||||
import { registerComponent } from "../things";
|
||||
import { ComponentContext } from "./contexts/ComponentContext";
|
||||
|
||||
interface ComponentOptions {
|
||||
id: string;
|
||||
acknowledge?: boolean;
|
||||
default?: boolean;
|
||||
flags?: MessageFlags;
|
||||
run: (interaction: ComponentContext) => void;
|
||||
}
|
||||
|
||||
export class Component {
|
||||
public id: string;
|
||||
public acknowledge: boolean;
|
||||
public default: boolean;
|
||||
public flags: MessageFlags | undefined;
|
||||
public run: (interaction: ComponentContext) => void | Response;
|
||||
|
||||
constructor(options: ComponentOptions) {
|
||||
this.id = options.id;
|
||||
this.acknowledge = options.acknowledge ?? true;
|
||||
this.default = options.default ?? false;
|
||||
this.flags = options.flags;
|
||||
this.run = options.run;
|
||||
|
||||
registerComponent(this);
|
||||
}
|
||||
}
|
26
packages/bot/src/structs/Modal.ts
Normal file
26
packages/bot/src/structs/Modal.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { MessageFlags } from "discord-api-types/v10";
|
||||
import { registerModal } from "../things";
|
||||
import { ModalContext } from "./contexts/ModalContext";
|
||||
|
||||
interface ModalOptions {
|
||||
id: string;
|
||||
acknowledge?: boolean;
|
||||
flags?: MessageFlags;
|
||||
run: (interaction: ModalContext) => void;
|
||||
}
|
||||
|
||||
export class Modal {
|
||||
public id: string;
|
||||
public acknowledge: boolean;
|
||||
public flags: MessageFlags | undefined;
|
||||
public run: (interaction: ModalContext) => void;
|
||||
|
||||
constructor(options: ModalOptions) {
|
||||
this.id = options.id;
|
||||
this.acknowledge = options.acknowledge ?? true;
|
||||
this.flags = options.flags;
|
||||
this.run = options.run;
|
||||
|
||||
registerModal(this);
|
||||
}
|
||||
}
|
13
packages/bot/src/structs/contexts/CommandContext.ts
Normal file
13
packages/bot/src/structs/contexts/CommandContext.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { APIApplicationCommandInteraction } from "discord-api-types/v10";
|
||||
import { Context } from "./Context";
|
||||
import { Env } from "../../types";
|
||||
|
||||
export class CommandContext extends Context {
|
||||
public interaction: APIApplicationCommandInteraction;
|
||||
|
||||
constructor(interaction: APIApplicationCommandInteraction, env: Env) {
|
||||
super(interaction, env);
|
||||
|
||||
this.interaction = interaction;
|
||||
}
|
||||
}
|
13
packages/bot/src/structs/contexts/ComponentContext.ts
Normal file
13
packages/bot/src/structs/contexts/ComponentContext.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { APIMessageComponentInteraction } from "discord-api-types/v10";
|
||||
import { Env } from "../../types";
|
||||
import { Context } from "./Context";
|
||||
|
||||
export class ComponentContext extends Context {
|
||||
public interaction: APIMessageComponentInteraction;
|
||||
|
||||
constructor(interaction: APIMessageComponentInteraction, env: Env) {
|
||||
super(interaction, env);
|
||||
|
||||
this.interaction = interaction;
|
||||
}
|
||||
}
|
70
packages/bot/src/structs/contexts/Context.ts
Normal file
70
packages/bot/src/structs/contexts/Context.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import {
|
||||
APIInteraction,
|
||||
APIInteractionResponseCallbackData,
|
||||
APIModalInteractionResponseCallbackData,
|
||||
InteractionResponseType,
|
||||
RouteBases,
|
||||
Routes,
|
||||
} from "discord-api-types/v10";
|
||||
import respond from "../../utils/respond";
|
||||
import { Env } from "../../types";
|
||||
|
||||
export class Context {
|
||||
public interaction: APIInteraction;
|
||||
public env: Env;
|
||||
|
||||
constructor(interaction: APIInteraction, env: Env) {
|
||||
this.interaction = interaction;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
get guildId() {
|
||||
return this.interaction.guild_id;
|
||||
}
|
||||
|
||||
public respond = respond;
|
||||
|
||||
public async editReply(content: APIInteractionResponseCallbackData) {
|
||||
return await fetch(
|
||||
`${RouteBases.api}${Routes.webhookMessage(
|
||||
this.interaction.application_id,
|
||||
this.interaction.token,
|
||||
)}`,
|
||||
{
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(content),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bot ${this.env.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async showModal(content: APIModalInteractionResponseCallbackData) {
|
||||
return await fetch(
|
||||
`${RouteBases.api}${Routes.interactionCallback(
|
||||
this.interaction.id,
|
||||
this.interaction.token,
|
||||
)}`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
type: InteractionResponseType.Modal,
|
||||
data: content,
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bot ${this.env.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async returnModal(content: APIModalInteractionResponseCallbackData) {
|
||||
return respond({
|
||||
type: InteractionResponseType.Modal,
|
||||
data: content,
|
||||
});
|
||||
}
|
||||
}
|
13
packages/bot/src/structs/contexts/ModalContext.ts
Normal file
13
packages/bot/src/structs/contexts/ModalContext.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { APIModalSubmitInteraction } from "discord-api-types/v10";
|
||||
import { Context } from "./Context";
|
||||
import { Env } from "../../types";
|
||||
|
||||
export class ModalContext extends Context {
|
||||
public interaction: APIModalSubmitInteraction;
|
||||
|
||||
constructor(interaction: APIModalSubmitInteraction, env: Env) {
|
||||
super(interaction, env);
|
||||
|
||||
this.interaction = interaction;
|
||||
}
|
||||
}
|
25
packages/bot/src/things.ts
Normal file
25
packages/bot/src/things.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { RedisAPIClient } from "redis-api-client";
|
||||
import { Command } from "./structs/Command";
|
||||
import { Component } from "./structs/Component";
|
||||
import { Modal } from "./structs/Modal";
|
||||
|
||||
export const COMMANDS: Command[] = [];
|
||||
export const COMPONENTS: Component[] = [];
|
||||
export const MODALS: Modal[] = [];
|
||||
export let REDIS: RedisAPIClient;
|
||||
|
||||
export const setRedis = (apiKey: string, host: string) => {
|
||||
REDIS = new RedisAPIClient(apiKey, host);
|
||||
};
|
||||
|
||||
export const registerCommand = (command: Command) => {
|
||||
COMMANDS.push(command);
|
||||
};
|
||||
|
||||
export const registerComponent = (component: Component) => {
|
||||
COMPONENTS.push(component);
|
||||
};
|
||||
|
||||
export const registerModal = (modal: Modal) => {
|
||||
MODALS.push(modal);
|
||||
};
|
43
packages/bot/src/types.d.ts
vendored
Normal file
43
packages/bot/src/types.d.ts
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
import type { Generic } from "serialize";
|
||||
|
||||
// secrets: wrangler secret put <name>
|
||||
declare let MINIFLARE; // just check because algorithm is different
|
||||
|
||||
declare type DeclaredId = Record<
|
||||
string,
|
||||
| string
|
||||
| {
|
||||
[key: string]: Generic;
|
||||
}
|
||||
> & {
|
||||
data: {
|
||||
[key: string]: Generic;
|
||||
};
|
||||
};
|
||||
|
||||
declare interface Env {
|
||||
publicKey: string;
|
||||
token: string;
|
||||
redisApiClientKey: string;
|
||||
redisApiClientHost: string;
|
||||
}
|
||||
|
||||
declare interface RoleId {
|
||||
label: string;
|
||||
description?: string;
|
||||
emoji: string;
|
||||
id: string;
|
||||
style?: string;
|
||||
}
|
||||
|
||||
declare interface BasicData {
|
||||
channelId: string;
|
||||
selecting: "buttons" | "dropdowns";
|
||||
roleIds: RoleId[];
|
||||
message: {
|
||||
content: string;
|
||||
embedTitle: string;
|
||||
embedDescription: string;
|
||||
embedColor: string;
|
||||
};
|
||||
}
|
12
packages/bot/src/utils/hexToRGB.ts
Normal file
12
packages/bot/src/utils/hexToRGB.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { RGBTuple } from "builders";
|
||||
|
||||
export default function (hex: string): RGBTuple | null {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? [
|
||||
parseInt(result[1], 16),
|
||||
parseInt(result[2], 16),
|
||||
parseInt(result[3], 16),
|
||||
]
|
||||
: null;
|
||||
}
|
16
packages/bot/src/utils/resolveButtonStyle.ts
Normal file
16
packages/bot/src/utils/resolveButtonStyle.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { ButtonStyle } from "discord-api-types/v10";
|
||||
|
||||
export default function (style: string) {
|
||||
switch (style.toLowerCase()) {
|
||||
case "primary":
|
||||
return ButtonStyle.Primary;
|
||||
case "secondary":
|
||||
return ButtonStyle.Secondary;
|
||||
case "success":
|
||||
return ButtonStyle.Success;
|
||||
case "danger":
|
||||
return ButtonStyle.Danger;
|
||||
default:
|
||||
return ButtonStyle.Primary;
|
||||
}
|
||||
}
|
18
packages/bot/src/utils/resolveEmoji.ts
Normal file
18
packages/bot/src/utils/resolveEmoji.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
// https://github.com/discordjs/discord.js/blob/6412da4921a5fd9ed0987205508bacd2b4868fd6/packages/discord.js/src/util/Util.js#L90-L109
|
||||
|
||||
export function parseEmoji(text: string) {
|
||||
if (text.includes("%")) text = decodeURIComponent(text);
|
||||
if (!text.includes(":"))
|
||||
return { animated: false, name: text, id: undefined };
|
||||
const match = text.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
|
||||
return match && { animated: Boolean(match[1]), name: match[2], id: match[3] };
|
||||
}
|
||||
|
||||
export function resolvePartialEmoji(emoji: string) {
|
||||
if (!emoji) return null;
|
||||
if (typeof emoji === "string")
|
||||
return /^\d{17,19}$/.test(emoji) ? { id: emoji } : parseEmoji(emoji);
|
||||
const { id, name, animated } = emoji;
|
||||
if (!id && !name) return null;
|
||||
return { id, name, animated: Boolean(animated) };
|
||||
}
|
7
packages/bot/src/utils/respond.ts
Normal file
7
packages/bot/src/utils/respond.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { APIInteractionResponse } from "discord-api-types/v10";
|
||||
|
||||
export default function (response: APIInteractionResponse) {
|
||||
return new Response(JSON.stringify(response), {
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
}
|
90
packages/bot/src/utils/returnRoleLpe.ts
Normal file
90
packages/bot/src/utils/returnRoleLpe.ts
Normal file
|
@ -0,0 +1,90 @@
|
|||
import { Context } from "../structs/contexts/Context";
|
||||
import { ActionRowBuilder, TextInputBuilder } from "builders";
|
||||
import {
|
||||
APIRole,
|
||||
InteractionResponseType,
|
||||
MessageFlags,
|
||||
TextInputStyle,
|
||||
} from "discord-api-types/v10";
|
||||
import { REDIS } from "../things";
|
||||
import { decodeFromString } from "serialize";
|
||||
import { BasicData } from "../types";
|
||||
|
||||
export default async function (data: BasicData, ctx: Context, rawRole: string) {
|
||||
const rolesRaw = await REDIS.get(`roles-bot-setup-roles:${ctx.guildId}`);
|
||||
if (!rolesRaw)
|
||||
return ctx.respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
content:
|
||||
"Something went wrong. Please try again.\nIf this problem persists, please contact [Support Server](https://discord.gg/kFPKmEKeMS/).",
|
||||
flags: MessageFlags.Ephemeral,
|
||||
},
|
||||
});
|
||||
|
||||
const roles = decodeFromString(rolesRaw) as Partial<APIRole>[];
|
||||
|
||||
const roleName = roles?.find((r) => r.id === rawRole)?.name;
|
||||
|
||||
const components = [
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Label")
|
||||
.setCustomId("label")
|
||||
.setPlaceholder("Ping")
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setRequired(true),
|
||||
)
|
||||
.toJSON(),
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Emoji")
|
||||
.setCustomId("emoji")
|
||||
.setPlaceholder("emoji 💡")
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
];
|
||||
|
||||
switch (data.selecting) {
|
||||
case "buttons": {
|
||||
components.push(
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Style")
|
||||
.setCustomId("style")
|
||||
.setPlaceholder("Primary, Secondary, Success or Danger")
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setRequired(true),
|
||||
)
|
||||
.toJSON(),
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case "dropdowns": {
|
||||
components.push(
|
||||
new ActionRowBuilder<TextInputBuilder>()
|
||||
.addComponents(
|
||||
new TextInputBuilder()
|
||||
.setLabel("Description")
|
||||
.setCustomId("description")
|
||||
.setPlaceholder("pingping pong pong")
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setRequired(false),
|
||||
)
|
||||
.toJSON(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.returnModal({
|
||||
title: `${roleName?.slice(0, 39)} Role`,
|
||||
custom_id: "setup:part-roles-lpe",
|
||||
components,
|
||||
});
|
||||
}
|
174
packages/bot/src/utils/sendFinal.ts
Normal file
174
packages/bot/src/utils/sendFinal.ts
Normal file
|
@ -0,0 +1,174 @@
|
|||
import {
|
||||
APIActionRowComponent,
|
||||
APIEmbed,
|
||||
APIMessageActionRowComponent,
|
||||
ButtonStyle,
|
||||
RouteBases,
|
||||
Routes,
|
||||
} from "discord-api-types/v10";
|
||||
import { Context } from "../structs/contexts/Context";
|
||||
import { REDIS } from "../things";
|
||||
import {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
EmbedBuilder,
|
||||
StringSelectMenuBuilder,
|
||||
StringSelectMenuOptionBuilder,
|
||||
} from "builders";
|
||||
import hexToRGB from "./hexToRGB";
|
||||
import splitArray from "./splitArray";
|
||||
import { resolvePartialEmoji } from "./resolveEmoji";
|
||||
import { BasicData } from "../types";
|
||||
import resolveButtonStyle from "./resolveButtonStyle";
|
||||
|
||||
type DataBot = BasicData & {
|
||||
sendAs: "bot";
|
||||
};
|
||||
|
||||
type DataWebhook = BasicData & {
|
||||
sendAs: "webhook";
|
||||
webhook: {
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
id: string;
|
||||
token: string;
|
||||
};
|
||||
};
|
||||
|
||||
type Data = DataBot | DataWebhook;
|
||||
|
||||
export default async function (ctx: Context, data: Data) {
|
||||
await REDIS.del(`roles-bot-setup:${ctx.guildId}`);
|
||||
await REDIS.del(`roles-bot-setup-roles:${ctx.guildId}`);
|
||||
|
||||
const payload: {
|
||||
content?: string;
|
||||
embeds?: APIEmbed[];
|
||||
components: APIActionRowComponent<APIMessageActionRowComponent>[];
|
||||
} = {
|
||||
components: [],
|
||||
};
|
||||
|
||||
if (data.message.content) payload.content = data.message.content;
|
||||
if (data.message.embedTitle || data.message.embedDescription) {
|
||||
payload.embeds = [
|
||||
new EmbedBuilder()
|
||||
.setTitle(data.message.embedTitle)
|
||||
.setDescription(data.message.embedDescription)
|
||||
.setColor(
|
||||
data.message.embedColor ? hexToRGB(data.message.embedColor) : null,
|
||||
)
|
||||
.toJSON(),
|
||||
];
|
||||
}
|
||||
|
||||
const components: APIActionRowComponent<APIMessageActionRowComponent>[] = [];
|
||||
const array = splitArray(data.roleIds, 25);
|
||||
for (const items of array) {
|
||||
const actionRow = new ActionRowBuilder();
|
||||
|
||||
const selectMenu = new StringSelectMenuBuilder().setCustomId("select:role");
|
||||
|
||||
for (const item of items) {
|
||||
switch (data.selecting) {
|
||||
case "buttons": {
|
||||
const button = new ButtonBuilder()
|
||||
.setLabel(item.label)
|
||||
.setCustomId(`role:${item.id}`)
|
||||
// rome-ignore lint/style/noNonNullAssertion: defined
|
||||
.setStyle(resolveButtonStyle(item.style!));
|
||||
|
||||
if (item.emoji && resolvePartialEmoji(item.emoji))
|
||||
// rome-ignore lint/style/noNonNullAssertion: its fine
|
||||
button.setEmoji(resolvePartialEmoji(item.emoji)!);
|
||||
|
||||
actionRow.addComponents(button);
|
||||
|
||||
break;
|
||||
}
|
||||
case "dropdowns": {
|
||||
const option = new StringSelectMenuOptionBuilder()
|
||||
.setLabel(item.label)
|
||||
// rome-ignore lint/style/noNonNullAssertion: defined
|
||||
.setDescription(item.description!)
|
||||
.setValue(`role:${item.id}`);
|
||||
|
||||
if (item.emoji && resolvePartialEmoji(item.emoji))
|
||||
// rome-ignore lint/style/noNonNullAssertion: its fine
|
||||
option.setEmoji(resolvePartialEmoji(item.emoji)!);
|
||||
|
||||
option.setValue(item.id);
|
||||
selectMenu.addOptions(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.selecting === "dropdowns") actionRow.addComponents(selectMenu);
|
||||
|
||||
// @ts-expect-error i know i know
|
||||
components.push(actionRow);
|
||||
}
|
||||
|
||||
payload.components = components;
|
||||
|
||||
switch (data.sendAs) {
|
||||
case "bot": {
|
||||
const res = await fetch(
|
||||
`${RouteBases.api}${Routes.channelMessages(data.channelId)}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bot ${ctx.env.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
},
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
const json: { message: string; code: string } = await res.json();
|
||||
await ctx.editReply({
|
||||
content: `Error: ${json.message} (${json.code})`,
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "webhook": {
|
||||
const res = await fetch(
|
||||
`${RouteBases.api}${Routes.webhook(
|
||||
data.webhook.id,
|
||||
data.webhook.token,
|
||||
)}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...payload,
|
||||
username: data.webhook.name,
|
||||
avatar_url: data.webhook.avatarUrl,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
const json: { message: string; code: string } = await res.json();
|
||||
await ctx.editReply({
|
||||
content: `Error: ${json.message} (${json.code})`,
|
||||
});
|
||||
} else {
|
||||
await fetch(
|
||||
`${RouteBases.api}${Routes.webhook(
|
||||
data.webhook.id,
|
||||
data.webhook.token,
|
||||
)}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
packages/bot/src/utils/splitArray.ts
Normal file
7
packages/bot/src/utils/splitArray.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default function <T>(array: T[], x: number): T[][] {
|
||||
const result: T[][] = [];
|
||||
for (let i = 0; i < array.length; i += x) {
|
||||
result.push(array.slice(i, i + x));
|
||||
}
|
||||
return result;
|
||||
}
|
40
packages/bot/src/utils/verify.ts
Normal file
40
packages/bot/src/utils/verify.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
// from https://gist.github.com/devsnek/77275f6e3f810a9545440931ed314dc1
|
||||
|
||||
"use strict";
|
||||
|
||||
import type { Env } from "../types";
|
||||
|
||||
function hex2bin(hex: string) {
|
||||
const buf = new Uint8Array(Math.ceil(hex.length / 2));
|
||||
for (let i = 0; i < buf.length; i++) {
|
||||
buf[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
export async function verify(request: Request, env: Env) {
|
||||
const subtle = await crypto.subtle.importKey(
|
||||
"raw",
|
||||
hex2bin(env.publicKey),
|
||||
{
|
||||
name: typeof MINIFLARE !== "undefined" ? "Ed25519" : "NODE-ED25519",
|
||||
namedCurve: typeof MINIFLARE !== "undefined" ? "Ed25519" : "NODE-ED25519",
|
||||
},
|
||||
true,
|
||||
["verify"],
|
||||
);
|
||||
|
||||
// rome-ignore lint/style/noNonNullAssertion: its fine
|
||||
const signature = hex2bin(request.headers.get("X-Signature-Ed25519")!);
|
||||
const timestamp = request.headers.get("X-Signature-Timestamp");
|
||||
const unknown = await request.clone().text();
|
||||
|
||||
return await crypto.subtle.verify(
|
||||
typeof MINIFLARE !== "undefined" ? "Ed25519" : "NODE-ED25519",
|
||||
subtle,
|
||||
signature,
|
||||
encoder.encode(timestamp + unknown),
|
||||
);
|
||||
}
|
12
packages/bot/tsconfig.json
Normal file
12
packages/bot/tsconfig.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"downlevelIteration": true,
|
||||
"lib": ["esnext", "webworker"],
|
||||
"strict": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"types": ["@cloudflare/workers-types", "jest"]
|
||||
}
|
||||
}
|
2
packages/bot/types.d.ts
vendored
2
packages/bot/types.d.ts
vendored
|
@ -1,2 +0,0 @@
|
|||
declare const CLIENT_PUBLIC_KEY: string;
|
||||
declare const CLIENT_TOKEN: string;
|
|
@ -1,12 +0,0 @@
|
|||
import { InteractionResponseType } from 'discord-api-types/v9';
|
||||
import { respond } from './respond';
|
||||
|
||||
export const badFormatting = (rolesMax?: boolean) => {
|
||||
return respond({
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: 64,
|
||||
content: `${rolesMax ? 'You can have maximum 25 buttons. (5x5)' : 'Bad formatting, generate [here](https://xhyrom.github.io/roles-bot)'}`
|
||||
}
|
||||
});
|
||||
};
|
|
@ -1,11 +0,0 @@
|
|||
export const isJSON = (data: any): boolean => {
|
||||
if (typeof data !== 'string') return false;
|
||||
try {
|
||||
const result = JSON.parse(data);
|
||||
const type = result.toString();
|
||||
|
||||
return type === '[object Object]' || type === '[object Array]';
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
|
@ -1,73 +0,0 @@
|
|||
import { ButtonStyle, ComponentType, Snowflake } from 'discord-api-types/v9';
|
||||
import { resolvePartialEmoji } from './resolveEmoji';
|
||||
|
||||
interface Role {
|
||||
id: Snowflake;
|
||||
style?: ButtonStyle;
|
||||
label: string;
|
||||
description?: string;
|
||||
emoji: string | null;
|
||||
}
|
||||
|
||||
export const resolveButtonComponents = (roles: Array<Role>) => {
|
||||
roles = roles.map((r: Role) => {
|
||||
const o: any = {
|
||||
type: ComponentType.Button,
|
||||
style: r.style || ButtonStyle.Secondary,
|
||||
label: r.label,
|
||||
custom_id: r.id
|
||||
};
|
||||
|
||||
if (r.emoji) o.emoji = resolvePartialEmoji(r.emoji);
|
||||
|
||||
return o;
|
||||
});
|
||||
|
||||
let finalComponents = [];
|
||||
for (let i = 0; i <= roles.length; i += 5) {
|
||||
const row: any = {
|
||||
type: ComponentType.ActionRow,
|
||||
components: []
|
||||
};
|
||||
|
||||
const btnslice: any = roles.slice(i, i + 5);
|
||||
for (let y = 0; y < btnslice.length; y++) row.components.push(btnslice[y]);
|
||||
|
||||
finalComponents.push(row);
|
||||
}
|
||||
|
||||
finalComponents = finalComponents.filter(a => a.components.length > 0);
|
||||
return finalComponents;
|
||||
}
|
||||
|
||||
export const resolveSelectMenuComponents = (roles: Array<Role>, placeholder?: string) => {
|
||||
roles = roles.map((r: Role) => {
|
||||
const o: any = {
|
||||
label: r.label,
|
||||
value: r.id,
|
||||
description: r.description,
|
||||
};
|
||||
|
||||
if (r.emoji) o.emoji = resolvePartialEmoji(r.emoji);
|
||||
|
||||
return o;
|
||||
});
|
||||
|
||||
const actionRow = [
|
||||
{
|
||||
type: ComponentType.ActionRow,
|
||||
components: [
|
||||
{
|
||||
type: ComponentType.SelectMenu,
|
||||
custom_id: 'role_select',
|
||||
options: roles,
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// @ts-expect-error No typings
|
||||
if (placeholder) actionRow[0].components[0].placeholder = placeholder;
|
||||
|
||||
return actionRow;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* https://github.com/discordjs/discord.js/blob/3c0bbac82fa9988af4a62ff00c66d149fbe6b921/packages/discord.js/src/util/Util.js#L292-L311
|
||||
*/
|
||||
|
||||
export const resolvePartialEmoji = (emoji: string) => {
|
||||
if (!emoji) return null;
|
||||
if (typeof emoji === 'string') return /^\d{17,19}$/.test(emoji) ? { id: emoji } : parseEmoji(emoji);
|
||||
const { id, name, animated } = emoji;
|
||||
if (!id && !name) return null;
|
||||
return { id, name, animated: Boolean(animated) };
|
||||
};
|
||||
|
||||
export const parseEmoji = (text: string) => {
|
||||
if (text.includes('%')) text = decodeURIComponent(text);
|
||||
if (!text.includes(':')) return { animated: false, name: text, id: null };
|
||||
|
||||
const match = text.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
|
||||
return match && { animated: Boolean(match[1]), name: match[2], id: match[3] ?? null };
|
||||
};
|
|
@ -1,3 +0,0 @@
|
|||
import { APIInteractionResponse } from 'discord-api-types/v9';
|
||||
|
||||
export const respond = (response: APIInteractionResponse) => new Response(JSON.stringify(response), {headers: {'content-type': 'application/json'}});
|
|
@ -1,37 +0,0 @@
|
|||
// from https://github.com/advaith1/activities/blob/main/src/verify.ts
|
||||
|
||||
'use strict';
|
||||
|
||||
function hex2bin(hex: string) {
|
||||
const buf = new Uint8Array(Math.ceil(hex.length / 2));
|
||||
for (let i = 0; i < buf.length; i++) {
|
||||
buf[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
const PUBLIC_KEY = crypto.subtle.importKey(
|
||||
'raw',
|
||||
hex2bin(CLIENT_PUBLIC_KEY || ''),
|
||||
{
|
||||
name: 'NODE-ED25519',
|
||||
namedCurve: 'NODE-ED25519',
|
||||
},
|
||||
true,
|
||||
['verify'],
|
||||
);
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
export async function verify(request: Request) {
|
||||
const signature = hex2bin(request.headers.get('X-Signature-Ed25519') || '');
|
||||
const timestamp = request.headers.get('X-Signature-Timestamp');
|
||||
const unknown = await request.clone().text();
|
||||
|
||||
return await crypto.subtle.verify(
|
||||
'NODE-ED25519',
|
||||
await PUBLIC_KEY,
|
||||
signature,
|
||||
encoder.encode(timestamp + unknown),
|
||||
);
|
||||
}
|
12
packages/bot/wrangler.toml
Normal file
12
packages/bot/wrangler.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
name = "roles-bot"
|
||||
type = "javascript"
|
||||
account_id = "294bee38d448e390dab3757215c63f03"
|
||||
compatibility_date = "2022-07-12"
|
||||
|
||||
main = "dist/worker.mjs"
|
||||
|
||||
[build]
|
||||
command = "pnpm build"
|
||||
[build.upload]
|
||||
format = "modules"
|
||||
main = "./worker.mjs"
|
191
packages/builders/LICENSE
Normal file
191
packages/builders/LICENSE
Normal file
|
@ -0,0 +1,191 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
1
packages/builders/README.md
Normal file
1
packages/builders/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
Just [https://github.com/discordjs/discord.js/tree/main/packages/builders](https://github.com/discordjs/discord.js/tree/main/packages/builders) without validators and other bloated stuff.
|
17
packages/builders/package.json
Normal file
17
packages/builders/package.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "builders",
|
||||
"version": "0.0.1",
|
||||
"main": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "node scripts/build.mjs && tsc --declaration --emitDeclarationOnly src/index.ts --outDir dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.15.11",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordjs/util": "^0.2.0",
|
||||
"discord-api-types": "^0.37.37"
|
||||
}
|
||||
}
|
38
packages/builders/scripts/build.mjs
Normal file
38
packages/builders/scripts/build.mjs
Normal file
|
@ -0,0 +1,38 @@
|
|||
import esbuild from "esbuild";
|
||||
import { rmSync, existsSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
if (existsSync(join(__dirname, "..", "dist")))
|
||||
rmSync(join(__dirname, "..", "dist"), { recursive: true });
|
||||
|
||||
const watch = process.argv.includes("--watch");
|
||||
const dev = process.argv.includes("--dev");
|
||||
|
||||
Promise.all([
|
||||
esbuild.build({
|
||||
bundle: true,
|
||||
logLevel: "info",
|
||||
format: "esm",
|
||||
mainFields: ["browser", "module", "main"],
|
||||
platform: "neutral",
|
||||
target: "es2020",
|
||||
entryPoints: ["./src/index.ts"],
|
||||
outfile: "./dist/index.mjs",
|
||||
sourcemap: dev,
|
||||
charset: "utf8",
|
||||
minify: !dev,
|
||||
watch: watch,
|
||||
}),
|
||||
])
|
||||
.catch((err) => {
|
||||
console.error("Builders failed to build");
|
||||
console.error(err.message);
|
||||
})
|
||||
.then(() => {
|
||||
console.log(
|
||||
watch ? "Waiting for your changes..." : "Builders has been built",
|
||||
);
|
||||
});
|
326
packages/builders/src/components/ActionRow.ts
Normal file
326
packages/builders/src/components/ActionRow.ts
Normal file
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// https://github.com/discordjs/discord/blob/main/packages/builders/src/components/ActionRow.ts
|
||||
|
||||
import {
|
||||
type APIActionRowComponent,
|
||||
ComponentType,
|
||||
type APIMessageActionRowComponent,
|
||||
type APIModalActionRowComponent,
|
||||
type APIActionRowComponentTypes,
|
||||
} from "discord-api-types/v10";
|
||||
import { normalizeArray, type RestOrArray } from "../util/normalizeArray";
|
||||
import { ComponentBuilder } from "./Component";
|
||||
import { createComponentBuilder } from "./Components";
|
||||
import type { ButtonBuilder } from "./button/Button";
|
||||
import type { ChannelSelectMenuBuilder } from "./selectMenu/ChannelSelectMenu";
|
||||
import type { MentionableSelectMenuBuilder } from "./selectMenu/MentionableSelectMenu";
|
||||
import type { RoleSelectMenuBuilder } from "./selectMenu/RoleSelectMenu";
|
||||
import type { StringSelectMenuBuilder } from "./selectMenu/StringSelectMenu";
|
||||
import type { UserSelectMenuBuilder } from "./selectMenu/UserSelectMenu";
|
||||
import type { TextInputBuilder } from "./textInput/TextInput";
|
||||
|
||||
export type MessageComponentBuilder =
|
||||
| ActionRowBuilder<MessageActionRowComponentBuilder>
|
||||
| MessageActionRowComponentBuilder;
|
||||
export type ModalComponentBuilder =
|
||||
| ActionRowBuilder<ModalActionRowComponentBuilder>
|
||||
| ModalActionRowComponentBuilder;
|
||||
export type MessageActionRowComponentBuilder =
|
||||
| ButtonBuilder
|
||||
| ChannelSelectMenuBuilder
|
||||
| MentionableSelectMenuBuilder
|
||||
| RoleSelectMenuBuilder
|
||||
| StringSelectMenuBuilder
|
||||
| UserSelectMenuBuilder;
|
||||
export type ModalActionRowComponentBuilder = TextInputBuilder;
|
||||
export type AnyComponentBuilder =
|
||||
| MessageActionRowComponentBuilder
|
||||
| ModalActionRowComponentBuilder;
|
||||
|
||||
/**
|
||||
* Represents an action row component
|
||||
*
|
||||
* @typeParam T - The types of components this action row holds
|
||||
*/
|
||||
export class ActionRowBuilder<
|
||||
T extends AnyComponentBuilder,
|
||||
> extends ComponentBuilder<
|
||||
APIActionRowComponent<
|
||||
APIMessageActionRowComponent | APIModalActionRowComponent
|
||||
>
|
||||
> {
|
||||
/**
|
||||
* The components within this action row
|
||||
*/
|
||||
public readonly components: T[];
|
||||
|
||||
/**
|
||||
* Creates a new action row from API data
|
||||
*
|
||||
* @param data - The API data to create this action row with
|
||||
* @example
|
||||
* Creating an action row from an API data object
|
||||
* ```ts
|
||||
* const actionRow = new ActionRowBuilder({
|
||||
* components: [
|
||||
* {
|
||||
* custom_id: "custom id",
|
||||
* label: "Type something",
|
||||
* style: TextInputStyle.Short,
|
||||
* type: ComponentType.TextInput,
|
||||
* },
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating an action row using setters and API data
|
||||
* ```ts
|
||||
* const actionRow = new ActionRowBuilder({
|
||||
* components: [
|
||||
* {
|
||||
* custom_id: "custom id",
|
||||
* label: "Click me",
|
||||
* style: ButtonStyle.Primary,
|
||||
* type: ComponentType.Button,
|
||||
* },
|
||||
* ],
|
||||
* })
|
||||
* .addComponents(button2, button3);
|
||||
* ```
|
||||
*/
|
||||
public constructor({
|
||||
components,
|
||||
...data
|
||||
}: Partial<APIActionRowComponent<APIActionRowComponentTypes>> = {}) {
|
||||
super({ type: ComponentType.ActionRow, ...data });
|
||||
this.components = (components?.map((component) =>
|
||||
createComponentBuilder(component),
|
||||
) ?? []) as T[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds components to this action row.
|
||||
*
|
||||
* @param components - The components to add to this action row.
|
||||
*/
|
||||
public addComponents(...components: RestOrArray<T>) {
|
||||
this.components.push(...normalizeArray(components));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the components in this action row
|
||||
*
|
||||
* @param components - The components to set this row to
|
||||
*/
|
||||
public setComponents(...components: RestOrArray<T>) {
|
||||
this.components.splice(
|
||||
0,
|
||||
this.components.length,
|
||||
...normalizeArray(components),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APIActionRowComponent<ReturnType<T["toJSON"]>> {
|
||||
return {
|
||||
...this.data,
|
||||
components: this.components.map((component) => component.toJSON()),
|
||||
} as APIActionRowComponent<ReturnType<T["toJSON"]>>;
|
||||
}
|
||||
}
|
235
packages/builders/src/components/Component.ts
Normal file
235
packages/builders/src/components/Component.ts
Normal file
|
@ -0,0 +1,235 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import type { JSONEncodable } from "../util/JSONEncodable";
|
||||
import type {
|
||||
APIActionRowComponent,
|
||||
APIActionRowComponentTypes,
|
||||
APIBaseComponent,
|
||||
ComponentType,
|
||||
} from "discord-api-types/v10";
|
||||
|
||||
export type AnyAPIActionRowComponent =
|
||||
| APIActionRowComponent<APIActionRowComponentTypes>
|
||||
| APIActionRowComponentTypes;
|
||||
|
||||
/**
|
||||
* Represents a discord component
|
||||
*
|
||||
* @typeParam DataType - The type of internal API data that is stored within the component
|
||||
*/
|
||||
export abstract class ComponentBuilder<
|
||||
DataType extends Partial<
|
||||
APIBaseComponent<ComponentType>
|
||||
> = APIBaseComponent<ComponentType>,
|
||||
> implements JSONEncodable<AnyAPIActionRowComponent>
|
||||
{
|
||||
/**
|
||||
* The API data associated with this component
|
||||
*/
|
||||
public readonly data: Partial<DataType>;
|
||||
|
||||
/**
|
||||
* Serializes this component to an API-compatible JSON object
|
||||
*
|
||||
* @remarks
|
||||
* This method runs validations on the data before serializing it.
|
||||
* As such, it may throw an error if the data is invalid.
|
||||
*/
|
||||
public abstract toJSON(): AnyAPIActionRowComponent;
|
||||
|
||||
public constructor(data: Partial<DataType>) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
265
packages/builders/src/components/Components.ts
Normal file
265
packages/builders/src/components/Components.ts
Normal file
|
@ -0,0 +1,265 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import {
|
||||
ComponentType,
|
||||
type APIMessageComponent,
|
||||
type APIModalComponent,
|
||||
} from "discord-api-types/v10";
|
||||
import {
|
||||
ActionRowBuilder,
|
||||
type AnyComponentBuilder,
|
||||
type MessageComponentBuilder,
|
||||
type ModalComponentBuilder,
|
||||
} from "./ActionRow";
|
||||
import { ComponentBuilder } from "./Component";
|
||||
import { ButtonBuilder } from "./button/Button";
|
||||
import { ChannelSelectMenuBuilder } from "./selectMenu/ChannelSelectMenu";
|
||||
import { MentionableSelectMenuBuilder } from "./selectMenu/MentionableSelectMenu";
|
||||
import { RoleSelectMenuBuilder } from "./selectMenu/RoleSelectMenu";
|
||||
import { StringSelectMenuBuilder } from "./selectMenu/StringSelectMenu";
|
||||
import { UserSelectMenuBuilder } from "./selectMenu/UserSelectMenu";
|
||||
import { TextInputBuilder } from "./textInput/TextInput";
|
||||
|
||||
export interface MappedComponentTypes {
|
||||
[ComponentType.ActionRow]: ActionRowBuilder<AnyComponentBuilder>;
|
||||
[ComponentType.Button]: ButtonBuilder;
|
||||
[ComponentType.StringSelect]: StringSelectMenuBuilder;
|
||||
[ComponentType.TextInput]: TextInputBuilder;
|
||||
[ComponentType.UserSelect]: UserSelectMenuBuilder;
|
||||
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
|
||||
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
|
||||
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for creating components from API data
|
||||
*
|
||||
* @param data - The api data to transform to a component class
|
||||
*/
|
||||
export function createComponentBuilder<T extends keyof MappedComponentTypes>(
|
||||
// eslint-disable-next-line @typescript-eslint/sort-type-union-intersection-members
|
||||
data: (APIModalComponent | APIMessageComponent) & { type: T },
|
||||
): MappedComponentTypes[T];
|
||||
export function createComponentBuilder<
|
||||
C extends MessageComponentBuilder | ModalComponentBuilder,
|
||||
>(data: C): C;
|
||||
export function createComponentBuilder(
|
||||
data: APIMessageComponent | APIModalComponent | MessageComponentBuilder,
|
||||
): ComponentBuilder {
|
||||
if (data instanceof ComponentBuilder) {
|
||||
return data;
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
case ComponentType.ActionRow:
|
||||
return new ActionRowBuilder(data);
|
||||
case ComponentType.Button:
|
||||
return new ButtonBuilder(data);
|
||||
case ComponentType.StringSelect:
|
||||
return new StringSelectMenuBuilder(data);
|
||||
case ComponentType.TextInput:
|
||||
return new TextInputBuilder(data);
|
||||
case ComponentType.UserSelect:
|
||||
return new UserSelectMenuBuilder(data);
|
||||
case ComponentType.RoleSelect:
|
||||
return new RoleSelectMenuBuilder(data);
|
||||
case ComponentType.MentionableSelect:
|
||||
return new MentionableSelectMenuBuilder(data);
|
||||
case ComponentType.ChannelSelect:
|
||||
return new ChannelSelectMenuBuilder(data);
|
||||
default:
|
||||
// @ts-expect-error: This case can still occur if we get a newer unsupported component type
|
||||
throw new Error(`Cannot properly serialize component type: ${data.type}`);
|
||||
}
|
||||
}
|
314
packages/builders/src/components/button/Button.ts
Normal file
314
packages/builders/src/components/button/Button.ts
Normal file
|
@ -0,0 +1,314 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ComponentType,
|
||||
type APIMessageComponentEmoji,
|
||||
type APIButtonComponent,
|
||||
type APIButtonComponentWithURL,
|
||||
type APIButtonComponentWithCustomId,
|
||||
type ButtonStyle,
|
||||
} from "discord-api-types/v10";
|
||||
import { ComponentBuilder } from "../Component";
|
||||
|
||||
/**
|
||||
* Represents a button component
|
||||
*/
|
||||
export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
||||
/**
|
||||
* Creates a new button from API data
|
||||
*
|
||||
* @param data - The API data to create this button with
|
||||
* @example
|
||||
* Creating a button from an API data object
|
||||
* ```ts
|
||||
* const button = new ButtonBuilder({
|
||||
* custom_id: 'a cool button',
|
||||
* style: ButtonStyle.Primary,
|
||||
* label: 'Click Me',
|
||||
* emoji: {
|
||||
* name: 'smile',
|
||||
* id: '123456789012345678',
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a button using setters and API data
|
||||
* ```ts
|
||||
* const button = new ButtonBuilder({
|
||||
* style: ButtonStyle.Secondary,
|
||||
* label: 'Click Me',
|
||||
* })
|
||||
* .setEmoji({ name: '🙂' })
|
||||
* .setCustomId('another cool button');
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIButtonComponent>) {
|
||||
super({ type: ComponentType.Button, ...data });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style of this button
|
||||
*
|
||||
* @param style - The style of the button
|
||||
*/
|
||||
public setStyle(style: ButtonStyle) {
|
||||
this.data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL for this button
|
||||
*
|
||||
* @remarks
|
||||
* This method is only available to buttons using the `Link` button style.
|
||||
* Only three types of URL schemes are currently supported: `https://`, `http://` and `discord://`
|
||||
* @param url - The URL to open when this button is clicked
|
||||
*/
|
||||
public setURL(url: string) {
|
||||
(this.data as APIButtonComponentWithURL).url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id for this button
|
||||
*
|
||||
* @remarks
|
||||
* This method is only applicable to buttons that are not using the `Link` button style.
|
||||
* @param customId - The custom id to use for this button
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
(this.data as APIButtonComponentWithCustomId).custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the emoji to display on this button
|
||||
*
|
||||
* @param emoji - The emoji to display on this button
|
||||
*/
|
||||
public setEmoji(emoji: APIMessageComponentEmoji) {
|
||||
this.data.emoji = emoji;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this button is disabled
|
||||
*
|
||||
* @param disabled - Whether to disable this button
|
||||
*/
|
||||
public setDisabled(disabled = true) {
|
||||
this.data.disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the label for this button
|
||||
*
|
||||
* @param label - The label to display on this button
|
||||
*/
|
||||
public setLabel(label: string) {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APIButtonComponent {
|
||||
return {
|
||||
...this.data,
|
||||
} as APIButtonComponent;
|
||||
}
|
||||
}
|
255
packages/builders/src/components/selectMenu/BaseSelectMenu.ts
Normal file
255
packages/builders/src/components/selectMenu/BaseSelectMenu.ts
Normal file
|
@ -0,0 +1,255 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import type { APISelectMenuComponent } from "discord-api-types/v10";
|
||||
import { ComponentBuilder } from "../Component";
|
||||
|
||||
export class BaseSelectMenuBuilder<
|
||||
SelectMenuType extends APISelectMenuComponent,
|
||||
> extends ComponentBuilder<SelectMenuType> {
|
||||
/**
|
||||
* Sets the placeholder for this select menu
|
||||
*
|
||||
* @param placeholder - The placeholder to use for this select menu
|
||||
*/
|
||||
public setPlaceholder(placeholder: string) {
|
||||
this.data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum values that must be selected in the select menu
|
||||
*
|
||||
* @param minValues - The minimum values that must be selected
|
||||
*/
|
||||
public setMinValues(minValues: number) {
|
||||
this.data.min_values = minValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum values that must be selected in the select menu
|
||||
*
|
||||
* @param maxValues - The maximum values that must be selected
|
||||
*/
|
||||
public setMaxValues(maxValues: number) {
|
||||
this.data.max_values = maxValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id for this select menu
|
||||
*
|
||||
* @param customId - The custom id to use for this select menu
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this select menu is disabled
|
||||
*
|
||||
* @param disabled - Whether this select menu is disabled
|
||||
*/
|
||||
public setDisabled(disabled = true) {
|
||||
this.data.disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public toJSON(): SelectMenuType {
|
||||
return {
|
||||
...this.data,
|
||||
} as SelectMenuType;
|
||||
}
|
||||
}
|
256
packages/builders/src/components/selectMenu/ChannelSelectMenu.ts
Normal file
256
packages/builders/src/components/selectMenu/ChannelSelectMenu.ts
Normal file
|
@ -0,0 +1,256 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import type {
|
||||
APIChannelSelectComponent,
|
||||
ChannelType,
|
||||
} from "discord-api-types/v10";
|
||||
import { ComponentType } from "discord-api-types/v10";
|
||||
import { normalizeArray, type RestOrArray } from "../../util/normalizeArray";
|
||||
import { BaseSelectMenuBuilder } from "./BaseSelectMenu";
|
||||
|
||||
export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSelectComponent> {
|
||||
/**
|
||||
* Creates a new select menu from API data
|
||||
*
|
||||
* @param data - The API data to create this select menu with
|
||||
* @example
|
||||
* Creating a select menu from an API data object
|
||||
* ```ts
|
||||
* const selectMenu = new ChannelSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* placeholder: 'select an option',
|
||||
* max_values: 2,
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a select menu using setters and API data
|
||||
* ```ts
|
||||
* const selectMenu = new ChannelSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* })
|
||||
* .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
|
||||
* .setMinValues(2)
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIChannelSelectComponent>) {
|
||||
super({ ...data, type: ComponentType.ChannelSelect });
|
||||
}
|
||||
|
||||
public addChannelTypes(...types: RestOrArray<ChannelType>) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
types = normalizeArray(types);
|
||||
|
||||
this.data.channel_types ??= [];
|
||||
this.data.channel_types.push(...types);
|
||||
return this;
|
||||
}
|
||||
|
||||
public setChannelTypes(...types: RestOrArray<ChannelType>) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
types = normalizeArray(types);
|
||||
|
||||
this.data.channel_types ??= [];
|
||||
this.data.channel_types.splice(0, this.data.channel_types.length, ...types);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public override toJSON(): APIChannelSelectComponent {
|
||||
return {
|
||||
...this.data,
|
||||
} as APIChannelSelectComponent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import type { APIMentionableSelectComponent } from "discord-api-types/v10";
|
||||
import { ComponentType } from "discord-api-types/v10";
|
||||
import { BaseSelectMenuBuilder } from "./BaseSelectMenu";
|
||||
|
||||
export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMentionableSelectComponent> {
|
||||
/**
|
||||
* Creates a new select menu from API data
|
||||
*
|
||||
* @param data - The API data to create this select menu with
|
||||
* @example
|
||||
* Creating a select menu from an API data object
|
||||
* ```ts
|
||||
* const selectMenu = new MentionableSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* placeholder: 'select an option',
|
||||
* max_values: 2,
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a select menu using setters and API data
|
||||
* ```ts
|
||||
* const selectMenu = new MentionableSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* })
|
||||
* .setMinValues(1)
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIMentionableSelectComponent>) {
|
||||
super({ ...data, type: ComponentType.MentionableSelect });
|
||||
}
|
||||
}
|
224
packages/builders/src/components/selectMenu/RoleSelectMenu.ts
Normal file
224
packages/builders/src/components/selectMenu/RoleSelectMenu.ts
Normal file
|
@ -0,0 +1,224 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import type { APIRoleSelectComponent } from "discord-api-types/v10";
|
||||
import { ComponentType } from "discord-api-types/v10";
|
||||
import { BaseSelectMenuBuilder } from "./BaseSelectMenu";
|
||||
|
||||
export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectComponent> {
|
||||
/**
|
||||
* Creates a new select menu from API data
|
||||
*
|
||||
* @param data - The API data to create this select menu with
|
||||
* @example
|
||||
* Creating a select menu from an API data object
|
||||
* ```ts
|
||||
* const selectMenu = new RoleSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* placeholder: 'select an option',
|
||||
* max_values: 2,
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a select menu using setters and API data
|
||||
* ```ts
|
||||
* const selectMenu = new RoleSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* })
|
||||
* .setMinValues(1)
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIRoleSelectComponent>) {
|
||||
super({ ...data, type: ComponentType.RoleSelect });
|
||||
}
|
||||
}
|
348
packages/builders/src/components/selectMenu/StringSelectMenu.ts
Normal file
348
packages/builders/src/components/selectMenu/StringSelectMenu.ts
Normal file
|
@ -0,0 +1,348 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import { ComponentType } from "discord-api-types/v10";
|
||||
import type {
|
||||
APIStringSelectComponent,
|
||||
APISelectMenuOption,
|
||||
} from "discord-api-types/v10";
|
||||
import { normalizeArray, type RestOrArray } from "../../util/normalizeArray";
|
||||
import { BaseSelectMenuBuilder } from "./BaseSelectMenu";
|
||||
import { StringSelectMenuOptionBuilder } from "./StringSelectMenuOption";
|
||||
|
||||
/**
|
||||
* Represents a string select menu component
|
||||
*/
|
||||
export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSelectComponent> {
|
||||
/**
|
||||
* The options within this select menu
|
||||
*/
|
||||
public readonly options: StringSelectMenuOptionBuilder[];
|
||||
|
||||
/**
|
||||
* Creates a new select menu from API data
|
||||
*
|
||||
* @param data - The API data to create this select menu with
|
||||
* @example
|
||||
* Creating a select menu from an API data object
|
||||
* ```ts
|
||||
* const selectMenu = new StringSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* placeholder: 'select an option',
|
||||
* max_values: 2,
|
||||
* options: [
|
||||
* { label: 'option 1', value: '1' },
|
||||
* { label: 'option 2', value: '2' },
|
||||
* { label: 'option 3', value: '3' },
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a select menu using setters and API data
|
||||
* ```ts
|
||||
* const selectMenu = new StringSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* })
|
||||
* .setMinValues(1)
|
||||
* .addOptions({
|
||||
* label: 'Catchy',
|
||||
* value: 'catch',
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIStringSelectComponent>) {
|
||||
const { options, ...initData } = data ?? {};
|
||||
super({ ...initData, type: ComponentType.StringSelect });
|
||||
this.options =
|
||||
options?.map(
|
||||
(option: APISelectMenuOption) =>
|
||||
new StringSelectMenuOptionBuilder(option),
|
||||
) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options to this select menu
|
||||
*
|
||||
* @param options - The options to add to this select menu
|
||||
* @returns
|
||||
*/
|
||||
public addOptions(
|
||||
...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>
|
||||
) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = normalizeArray(options);
|
||||
|
||||
this.options.push(
|
||||
...options.map((option) =>
|
||||
option instanceof StringSelectMenuOptionBuilder
|
||||
? option
|
||||
: new StringSelectMenuOptionBuilder(option),
|
||||
),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options on this select menu
|
||||
*
|
||||
* @param options - The options to set on this select menu
|
||||
*/
|
||||
public setOptions(
|
||||
...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>
|
||||
) {
|
||||
return this.spliceOptions(0, this.options.length, ...options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes, replaces, or inserts options in the string select menu.
|
||||
*
|
||||
* @remarks
|
||||
* This method behaves similarly
|
||||
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice}.
|
||||
*
|
||||
* It's useful for modifying and adjusting order of the already-existing options of a string select menu.
|
||||
* @example
|
||||
* Remove the first option
|
||||
* ```ts
|
||||
* selectMenu.spliceOptions(0, 1);
|
||||
* ```
|
||||
* @example
|
||||
* Remove the first n option
|
||||
* ```ts
|
||||
* const n = 4
|
||||
* selectMenu.spliceOptions(0, n);
|
||||
* ```
|
||||
* @example
|
||||
* Remove the last option
|
||||
* ```ts
|
||||
* selectMenu.spliceOptions(-1, 1);
|
||||
* ```
|
||||
* @param index - The index to start at
|
||||
* @param deleteCount - The number of options to remove
|
||||
* @param options - The replacing option objects or builders
|
||||
*/
|
||||
public spliceOptions(
|
||||
index: number,
|
||||
deleteCount: number,
|
||||
...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>
|
||||
) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = normalizeArray(options);
|
||||
|
||||
const clone = [...this.options];
|
||||
|
||||
clone.splice(
|
||||
index,
|
||||
deleteCount,
|
||||
...options.map((option) =>
|
||||
option instanceof StringSelectMenuOptionBuilder
|
||||
? option
|
||||
: new StringSelectMenuOptionBuilder(option),
|
||||
),
|
||||
);
|
||||
|
||||
this.options.splice(0, this.options.length, ...clone);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public override toJSON(): APIStringSelectComponent {
|
||||
return {
|
||||
...this.data,
|
||||
options: this.options.map((option) => option.toJSON()),
|
||||
} as APIStringSelectComponent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import type { JSONEncodable } from "../../util/JSONEncodable";
|
||||
import type {
|
||||
APIMessageComponentEmoji,
|
||||
APISelectMenuOption,
|
||||
} from "discord-api-types/v10";
|
||||
|
||||
/**
|
||||
* Represents an option within a string select menu component
|
||||
*/
|
||||
export class StringSelectMenuOptionBuilder
|
||||
implements JSONEncodable<APISelectMenuOption>
|
||||
{
|
||||
/**
|
||||
* Creates a new string select menu option from API data
|
||||
*
|
||||
* @param data - The API data to create this string select menu option with
|
||||
* @example
|
||||
* Creating a string select menu option from an API data object
|
||||
* ```ts
|
||||
* const selectMenuOption = new SelectMenuOptionBuilder({
|
||||
* label: 'catchy label',
|
||||
* value: '1',
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a string select menu option using setters and API data
|
||||
* ```ts
|
||||
* const selectMenuOption = new SelectMenuOptionBuilder({
|
||||
* default: true,
|
||||
* value: '1',
|
||||
* })
|
||||
* .setLabel('woah')
|
||||
* ```
|
||||
*/
|
||||
public constructor(public data: Partial<APISelectMenuOption> = {}) {}
|
||||
|
||||
/**
|
||||
* Sets the label of this option
|
||||
*
|
||||
* @param label - The label to show on this option
|
||||
*/
|
||||
public setLabel(label: string) {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this option
|
||||
*
|
||||
* @param value - The value of this option
|
||||
*/
|
||||
public setValue(value: string) {
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of this option
|
||||
*
|
||||
* @param description - The description of this option
|
||||
*/
|
||||
public setDescription(description: string) {
|
||||
this.data.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this option is selected by default
|
||||
*
|
||||
* @param isDefault - Whether this option is selected by default
|
||||
*/
|
||||
public setDefault(isDefault = true) {
|
||||
this.data.default = isDefault;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the emoji to display on this option
|
||||
*
|
||||
* @param emoji - The emoji to display on this option
|
||||
*/
|
||||
public setEmoji(emoji: APIMessageComponentEmoji) {
|
||||
this.data.emoji = emoji;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APISelectMenuOption {
|
||||
return {
|
||||
...this.data,
|
||||
} as APISelectMenuOption;
|
||||
}
|
||||
}
|
224
packages/builders/src/components/selectMenu/UserSelectMenu.ts
Normal file
224
packages/builders/src/components/selectMenu/UserSelectMenu.ts
Normal file
|
@ -0,0 +1,224 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import type { APIUserSelectComponent } from "discord-api-types/v10";
|
||||
import { ComponentType } from "discord-api-types/v10";
|
||||
import { BaseSelectMenuBuilder } from "./BaseSelectMenu";
|
||||
|
||||
export class UserSelectMenuBuilder extends BaseSelectMenuBuilder<APIUserSelectComponent> {
|
||||
/**
|
||||
* Creates a new select menu from API data
|
||||
*
|
||||
* @param data - The API data to create this select menu with
|
||||
* @example
|
||||
* Creating a select menu from an API data object
|
||||
* ```ts
|
||||
* const selectMenu = new UserSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* placeholder: 'select an option',
|
||||
* max_values: 2,
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a select menu using setters and API data
|
||||
* ```ts
|
||||
* const selectMenu = new UserSelectMenuBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* })
|
||||
* .setMinValues(1)
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIUserSelectComponent>) {
|
||||
super({ ...data, type: ComponentType.UserSelect });
|
||||
}
|
||||
}
|
336
packages/builders/src/components/textInput/TextInput.ts
Normal file
336
packages/builders/src/components/textInput/TextInput.ts
Normal file
|
@ -0,0 +1,336 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import type { JSONEncodable } from "../../util/JSONEncodable";
|
||||
import type { Equatable } from "../../util/Equatable";
|
||||
import {
|
||||
ComponentType,
|
||||
type TextInputStyle,
|
||||
type APITextInputComponent,
|
||||
} from "discord-api-types/v10";
|
||||
import { ComponentBuilder } from "../Component";
|
||||
|
||||
export class TextInputBuilder
|
||||
extends ComponentBuilder<APITextInputComponent>
|
||||
implements
|
||||
Equatable<APITextInputComponent | JSONEncodable<APITextInputComponent>>
|
||||
{
|
||||
/**
|
||||
* Creates a new text input from API data
|
||||
*
|
||||
* @param data - The API data to create this text input with
|
||||
* @example
|
||||
* Creating a select menu option from an API data object
|
||||
* ```ts
|
||||
* const textInput = new TextInputBuilder({
|
||||
* custom_id: 'a cool select menu',
|
||||
* label: 'Type something',
|
||||
* style: TextInputStyle.Short,
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a select menu option using setters and API data
|
||||
* ```ts
|
||||
* const textInput = new TextInputBuilder({
|
||||
* label: 'Type something else',
|
||||
* })
|
||||
* .setCustomId('woah')
|
||||
* .setStyle(TextInputStyle.Paragraph);
|
||||
* ```
|
||||
*/
|
||||
public constructor(
|
||||
data?: APITextInputComponent & { type?: ComponentType.TextInput },
|
||||
) {
|
||||
super({ type: ComponentType.TextInput, ...data });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id for this text input
|
||||
*
|
||||
* @param customId - The custom id of this text input
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the label for this text input
|
||||
*
|
||||
* @param label - The label for this text input
|
||||
*/
|
||||
public setLabel(label: string) {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style for this text input
|
||||
*
|
||||
* @param style - The style for this text input
|
||||
*/
|
||||
public setStyle(style: TextInputStyle) {
|
||||
this.data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum length of text for this text input
|
||||
*
|
||||
* @param minLength - The minimum length of text for this text input
|
||||
*/
|
||||
public setMinLength(minLength: number) {
|
||||
this.data.min_length = minLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum length of text for this text input
|
||||
*
|
||||
* @param maxLength - The maximum length of text for this text input
|
||||
*/
|
||||
public setMaxLength(maxLength: number) {
|
||||
this.data.max_length = maxLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the placeholder of this text input
|
||||
*
|
||||
* @param placeholder - The placeholder of this text input
|
||||
*/
|
||||
public setPlaceholder(placeholder: string) {
|
||||
this.data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this text input
|
||||
*
|
||||
* @param value - The value for this text input
|
||||
*/
|
||||
public setValue(value: string) {
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this text input is required
|
||||
*
|
||||
* @param required - Whether this text input is required
|
||||
*/
|
||||
public setRequired(required = true) {
|
||||
this.data.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APITextInputComponent {
|
||||
return {
|
||||
...this.data,
|
||||
} as APITextInputComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc Equatable.equals}
|
||||
*/
|
||||
public equals(
|
||||
other: APITextInputComponent | JSONEncodable<APITextInputComponent>,
|
||||
): boolean {
|
||||
// imagine using this lol
|
||||
return true;
|
||||
}
|
||||
}
|
225
packages/builders/src/index.ts
Normal file
225
packages/builders/src/index.ts
Normal file
|
@ -0,0 +1,225 @@
|
|||
/**
|
||||
* Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2021 Vlad Frangu
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
export * from "./messages/embed/Embed.js";
|
||||
|
||||
export * from "./components/ActionRow";
|
||||
export * from "./components/button/Button";
|
||||
export * from "./components/Component";
|
||||
export * from "./components/Components";
|
||||
export * from "./components/textInput/TextInput";
|
||||
|
||||
export * from "./components/selectMenu/BaseSelectMenu";
|
||||
export * from "./components/selectMenu/ChannelSelectMenu";
|
||||
export * from "./components/selectMenu/MentionableSelectMenu";
|
||||
export * from "./components/selectMenu/RoleSelectMenu";
|
||||
export * from "./components/selectMenu/StringSelectMenu";
|
||||
// TODO: Remove those aliases in v2
|
||||
export {
|
||||
/**
|
||||
* @deprecated Will be removed in the next major version, use {@link StringSelectMenuBuilder} instead.
|
||||
*/
|
||||
StringSelectMenuBuilder as SelectMenuBuilder,
|
||||
} from "./components/selectMenu/StringSelectMenu";
|
||||
export {
|
||||
/**
|
||||
* @deprecated Will be removed in the next major version, use {@link StringSelectMenuOptionBuilder} instead.
|
||||
*/
|
||||
StringSelectMenuOptionBuilder as SelectMenuOptionBuilder,
|
||||
} from "./components/selectMenu/StringSelectMenuOption";
|
||||
export * from "./components/selectMenu/StringSelectMenuOption";
|
||||
export * from "./components/selectMenu/UserSelectMenu";
|
||||
|
||||
export * from "./util/componentUtil";
|
||||
export * from "./util/normalizeArray";
|
262
packages/builders/src/messages/embed/Embed.ts
Normal file
262
packages/builders/src/messages/embed/Embed.ts
Normal file
|
@ -0,0 +1,262 @@
|
|||
import type {
|
||||
APIEmbed,
|
||||
APIEmbedAuthor,
|
||||
APIEmbedField,
|
||||
APIEmbedFooter,
|
||||
APIEmbedImage,
|
||||
} from "discord-api-types/v10";
|
||||
import { normalizeArray, type RestOrArray } from "../../util/normalizeArray.js";
|
||||
|
||||
export type RGBTuple = [red: number, green: number, blue: number];
|
||||
|
||||
export interface IconData {
|
||||
/**
|
||||
* The URL of the icon
|
||||
*/
|
||||
iconURL?: string;
|
||||
/**
|
||||
* The proxy URL of the icon
|
||||
*/
|
||||
proxyIconURL?: string;
|
||||
}
|
||||
|
||||
export type EmbedAuthorData = IconData &
|
||||
Omit<APIEmbedAuthor, "icon_url" | "proxy_icon_url">;
|
||||
|
||||
export type EmbedAuthorOptions = Omit<EmbedAuthorData, "proxyIconURL">;
|
||||
|
||||
export type EmbedFooterData = IconData &
|
||||
Omit<APIEmbedFooter, "icon_url" | "proxy_icon_url">;
|
||||
|
||||
export type EmbedFooterOptions = Omit<EmbedFooterData, "proxyIconURL">;
|
||||
|
||||
export interface EmbedImageData extends Omit<APIEmbedImage, "proxy_url"> {
|
||||
/**
|
||||
* The proxy URL for the image
|
||||
*/
|
||||
proxyURL?: string;
|
||||
}
|
||||
/**
|
||||
* Represents a embed in a message (image/video preview, rich embed, etc.)
|
||||
*/
|
||||
export class EmbedBuilder {
|
||||
public readonly data: APIEmbed;
|
||||
|
||||
public constructor(data: APIEmbed = {}) {
|
||||
this.data = { ...data };
|
||||
if (data.timestamp)
|
||||
this.data.timestamp = new Date(data.timestamp).toISOString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends fields to the embed
|
||||
*
|
||||
* @remarks
|
||||
* This method accepts either an array of fields or a variable number of field parameters.
|
||||
* The maximum amount of fields that can be added is 25.
|
||||
* @example
|
||||
* Using an array
|
||||
* ```ts
|
||||
* const fields: APIEmbedField[] = ...;
|
||||
* const embed = new EmbedBuilder()
|
||||
* .addFields(fields);
|
||||
* ```
|
||||
* @example
|
||||
* Using rest parameters (variadic)
|
||||
* ```ts
|
||||
* const embed = new EmbedBuilder()
|
||||
* .addFields(
|
||||
* { name: 'Field 1', value: 'Value 1' },
|
||||
* { name: 'Field 2', value: 'Value 2' },
|
||||
* );
|
||||
* ```
|
||||
* @param fields - The fields to add
|
||||
*/
|
||||
public addFields(...fields: RestOrArray<APIEmbedField>): this {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
fields = normalizeArray(fields);
|
||||
|
||||
if (this.data.fields) this.data.fields.push(...fields);
|
||||
else this.data.fields = fields;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes, replaces, or inserts fields in the embed.
|
||||
*
|
||||
* @remarks
|
||||
* This method behaves similarly
|
||||
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice}.
|
||||
* The maximum amount of fields that can be added is 25.
|
||||
*
|
||||
* It's useful for modifying and adjusting order of the already-existing fields of an embed.
|
||||
* @example
|
||||
* Remove the first field
|
||||
* ```ts
|
||||
* embed.spliceFields(0, 1);
|
||||
* ```
|
||||
* @example
|
||||
* Remove the first n fields
|
||||
* ```ts
|
||||
* const n = 4
|
||||
* embed.spliceFields(0, n);
|
||||
* ```
|
||||
* @example
|
||||
* Remove the last field
|
||||
* ```ts
|
||||
* embed.spliceFields(-1, 1);
|
||||
* ```
|
||||
* @param index - The index to start at
|
||||
* @param deleteCount - The number of fields to remove
|
||||
* @param fields - The replacing field objects
|
||||
*/
|
||||
public spliceFields(
|
||||
index: number,
|
||||
deleteCount: number,
|
||||
...fields: APIEmbedField[]
|
||||
): this {
|
||||
if (this.data.fields)
|
||||
this.data.fields.splice(index, deleteCount, ...fields);
|
||||
else this.data.fields = fields;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the embed's fields
|
||||
*
|
||||
* @remarks
|
||||
* This method is an alias for {@link EmbedBuilder.spliceFields}. More specifically,
|
||||
* it splices the entire array of fields, replacing them with the provided fields.
|
||||
*
|
||||
* You can set a maximum of 25 fields.
|
||||
* @param fields - The fields to set
|
||||
*/
|
||||
public setFields(...fields: RestOrArray<APIEmbedField>) {
|
||||
this.spliceFields(
|
||||
0,
|
||||
this.data.fields?.length ?? 0,
|
||||
...normalizeArray(fields),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the author of this embed
|
||||
*
|
||||
* @param options - The options for the author
|
||||
*/
|
||||
|
||||
public setAuthor(options: EmbedAuthorOptions | null): this {
|
||||
if (options === null) {
|
||||
this.data.author = undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.data.author = {
|
||||
name: options.name,
|
||||
url: options.url,
|
||||
icon_url: options.iconURL,
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of this embed
|
||||
*
|
||||
* @param color - The color of the embed
|
||||
*/
|
||||
public setColor(color: RGBTuple | number | null): this {
|
||||
if (Array.isArray(color)) {
|
||||
const [red, green, blue] = color;
|
||||
this.data.color = (red << 16) + (green << 8) + blue;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.data.color = color ?? undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of this embed
|
||||
*
|
||||
* @param description - The description
|
||||
*/
|
||||
public setDescription(description: string | null): this {
|
||||
this.data.description = description ?? undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the footer of this embed
|
||||
*
|
||||
* @param options - The options for the footer
|
||||
*/
|
||||
public setFooter(options: EmbedFooterOptions | null): this {
|
||||
if (options === null) {
|
||||
this.data.footer = undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.data.footer = { text: options.text, icon_url: options.iconURL };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image of this embed
|
||||
*
|
||||
* @param url - The URL of the image
|
||||
*/
|
||||
public setImage(url: string | null): this {
|
||||
this.data.image = url ? { url } : undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the thumbnail of this embed
|
||||
*
|
||||
* @param url - The URL of the thumbnail
|
||||
*/
|
||||
public setThumbnail(url: string | null): this {
|
||||
this.data.thumbnail = url ? { url } : undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timestamp of this embed
|
||||
*
|
||||
* @param timestamp - The timestamp or date
|
||||
*/
|
||||
public setTimestamp(timestamp: number | null = Date.now()): this {
|
||||
this.data.timestamp = timestamp
|
||||
? new Date(timestamp).toISOString()
|
||||
: undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of this embed
|
||||
*
|
||||
* @param title - The title
|
||||
*/
|
||||
public setTitle(title: string | null): this {
|
||||
this.data.title = title ?? undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL of this embed
|
||||
*
|
||||
* @param url - The URL
|
||||
*/
|
||||
public setURL(url: string | null): this {
|
||||
this.data.url = url ?? undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the embed to a plain object
|
||||
*/
|
||||
public toJSON(): APIEmbed {
|
||||
return { ...this.data };
|
||||
}
|
||||
}
|
27
packages/builders/src/util/Equatable.ts
Normal file
27
packages/builders/src/util/Equatable.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Represents a structure that can be checked against another
|
||||
* given structure for equality
|
||||
*
|
||||
* @typeParam T - The type of object to compare the current object to
|
||||
*/
|
||||
export interface Equatable<T> {
|
||||
/**
|
||||
* Whether or not this is equal to another structure
|
||||
*/
|
||||
equals(other: T): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if an object is equatable or not.
|
||||
*
|
||||
* @param maybeEquatable - The object to check against
|
||||
*/
|
||||
export function isEquatable(
|
||||
maybeEquatable: unknown,
|
||||
): maybeEquatable is Equatable<unknown> {
|
||||
return (
|
||||
maybeEquatable !== null &&
|
||||
typeof maybeEquatable === "object" &&
|
||||
"equals" in maybeEquatable
|
||||
);
|
||||
}
|
26
packages/builders/src/util/JSONEncodable.ts
Normal file
26
packages/builders/src/util/JSONEncodable.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Represents an object capable of representing itself as a JSON object
|
||||
*
|
||||
* @typeParam T - The JSON type corresponding to {@link JSONEncodable.toJSON} outputs.
|
||||
*/
|
||||
export interface JSONEncodable<T> {
|
||||
/**
|
||||
* Transforms this object to its JSON format
|
||||
*/
|
||||
toJSON(): T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if an object is encodable or not.
|
||||
*
|
||||
* @param maybeEncodable - The object to check against
|
||||
*/
|
||||
export function isJSONEncodable(
|
||||
maybeEncodable: unknown,
|
||||
): maybeEncodable is JSONEncodable<unknown> {
|
||||
return (
|
||||
maybeEncodable !== null &&
|
||||
typeof maybeEncodable === "object" &&
|
||||
"toJSON" in maybeEncodable
|
||||
);
|
||||
}
|
14
packages/builders/src/util/componentUtil.ts
Normal file
14
packages/builders/src/util/componentUtil.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import type { APIEmbed } from "discord-api-types/v10";
|
||||
|
||||
export function embedLength(data: APIEmbed) {
|
||||
return (
|
||||
(data.title?.length ?? 0) +
|
||||
(data.description?.length ?? 0) +
|
||||
(data.fields?.reduce(
|
||||
(prev, curr) => prev + curr.name.length + curr.value.length,
|
||||
0,
|
||||
) ?? 0) +
|
||||
(data.footer?.text.length ?? 0) +
|
||||
(data.author?.name.length ?? 0)
|
||||
);
|
||||
}
|
6
packages/builders/src/util/normalizeArray.ts
Normal file
6
packages/builders/src/util/normalizeArray.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export function normalizeArray<T>(arr: RestOrArray<T>): T[] {
|
||||
if (Array.isArray(arr[0])) return arr[0];
|
||||
return arr as T[];
|
||||
}
|
||||
|
||||
export type RestOrArray<T> = T[] | [T[]];
|
21
packages/redis-api-client/LICENSE
Normal file
21
packages/redis-api-client/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Jozef Steinhübl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue