mirror of
https://github.com/discordjs/discord.js.git
synced 2026-05-23 03:50:09 +00:00
Compare commits
22 Commits
@discordjs
...
@discordjs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a0cd82566 | ||
|
|
2eaec32414 | ||
|
|
6e45ddc067 | ||
|
|
eee6f948ee | ||
|
|
45bd430c0d | ||
|
|
d20e10305b | ||
|
|
f7bc2d0db8 | ||
|
|
baeeb38185 | ||
|
|
1a0da18b36 | ||
|
|
ca7719e822 | ||
|
|
ec5d921b75 | ||
|
|
b42e499410 | ||
|
|
374a6785ae | ||
|
|
319a73f8e6 | ||
|
|
16d70b9232 | ||
|
|
4476fadd19 | ||
|
|
61251cfcb8 | ||
|
|
e77793898a | ||
|
|
f5b3f842e3 | ||
|
|
e32f0c141a | ||
|
|
fdac8c5bdd | ||
|
|
0d64ea0528 |
121
.github/workflows/documentation.yml
vendored
121
.github/workflows/documentation.yml
vendored
@@ -1,8 +1,6 @@
|
||||
name: Documentation
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths:
|
||||
- 'packages/*/src/**'
|
||||
- '!packages/create-discord-bot/**'
|
||||
@@ -13,14 +11,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA to checkout'
|
||||
required: true
|
||||
ref_type:
|
||||
type: choice
|
||||
description: 'Branch or tag'
|
||||
options:
|
||||
- branch
|
||||
- tag
|
||||
description: 'The tag to checkout'
|
||||
required: true
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
@@ -32,7 +23,6 @@ jobs:
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
REF_TYPE: ${{ inputs.ref_type || github.ref_type }}
|
||||
if: github.repository_owner == 'discordjs'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -52,13 +42,11 @@ jobs:
|
||||
run: pnpm run build
|
||||
|
||||
- name: Checkout main repository
|
||||
if: ${{ inputs.ref && inputs.ref != 'main' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'main'
|
||||
|
||||
- name: Build main
|
||||
if: ${{ inputs.ref && inputs.ref != 'main' }}
|
||||
shell: bash
|
||||
run: |
|
||||
cd main
|
||||
@@ -67,26 +55,20 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Extract package and semver from tag
|
||||
if: ${{ env.REF_TYPE == 'tag' }}
|
||||
id: extract-tag
|
||||
uses: ./packages/actions/src/formatTag
|
||||
with:
|
||||
tag: ${{ inputs.ref || github.ref_name }}
|
||||
|
||||
- name: Apply tag to api-extractor config
|
||||
if: ${{ env.REF_TYPE == 'tag' && !inputs.ref }}
|
||||
run: sed -i 's!https://github.com/discordjs/discord.js/tree/main!https://github.com/discordjs/discord.js/tree/${{ github.ref_name }}!' "packages/${{ steps.extract-tag.outputs.package}}/api-extractor.json"
|
||||
|
||||
- name: Build docs
|
||||
run: pnpm run docs
|
||||
|
||||
- name: Build docs with main api-extractor
|
||||
if: ${{ inputs.ref && inputs.ref != 'main' }}
|
||||
run: |
|
||||
declare -a PACKAGES=("brokers" "builders" "collection" "core" "discord.js" "formatters" "next" "proxy" "rest" "util" "voice" "ws")
|
||||
for PACKAGE in "${PACKAGES[@]}"; do
|
||||
cd "packages/${PACKAGE}"
|
||||
sed -i 's!https://github.com/discordjs/discord.js/tree/main!https://github.com/discordjs/discord.js/tree/${{ inputs.ref }}!' api-extractor.json
|
||||
sed -i 's!https://github.com/discordjs/discord.js/tree/main!https://github.com/discordjs/discord.js/tree/${{ inputs.ref || github.ref_name }}!' api-extractor.json
|
||||
../../main/packages/api-extractor/bin/api-extractor run --local --minify
|
||||
../../main/packages/scripts/bin/generateSplitDocumentation.js
|
||||
cd ../..
|
||||
@@ -100,25 +82,6 @@ jobs:
|
||||
path: 'out'
|
||||
|
||||
- name: Upload documentation to database
|
||||
if: ${{ env.REF_TYPE == 'tag' && (!inputs.ref || inputs.ref == 'main') }}
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
|
||||
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
|
||||
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
|
||||
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
|
||||
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
|
||||
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
|
||||
uses: ./packages/actions/src/uploadDocumentation
|
||||
with:
|
||||
package: ${{ steps.extract-tag.outputs.package }}
|
||||
version: ${{ steps.extract-tag.outputs.semver }}
|
||||
|
||||
- name: Upload documentation to database
|
||||
if: ${{ env.REF_TYPE == 'tag' && inputs.ref && inputs.ref != 'main' }}
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
|
||||
@@ -136,20 +99,6 @@ jobs:
|
||||
version: ${{ steps.extract-tag.outputs.semver }}
|
||||
|
||||
- name: Upload split documentation to blob storage
|
||||
if: ${{ env.REF_TYPE == 'tag' && (!inputs.ref || inputs.ref == 'main') }}
|
||||
env:
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
|
||||
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
|
||||
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
|
||||
uses: ./packages/actions/src/uploadSplitDocumentation
|
||||
with:
|
||||
package: ${{ steps.extract-tag.outputs.package }}
|
||||
version: ${{ steps.extract-tag.outputs.semver }}
|
||||
|
||||
- name: Upload split documentation to blob storage
|
||||
if: ${{ env.REF_TYPE == 'tag' && inputs.ref && inputs.ref != 'main' }}
|
||||
env:
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
@@ -162,7 +111,6 @@ jobs:
|
||||
version: ${{ steps.extract-tag.outputs.semver }}
|
||||
|
||||
- name: Move docs to correct directory
|
||||
if: ${{ env.REF_TYPE == 'tag' }}
|
||||
env:
|
||||
PACKAGE: ${{ steps.extract-tag.outputs.package }}
|
||||
SEMVER: ${{ steps.extract-tag.outputs.semver }}
|
||||
@@ -175,71 +123,6 @@ jobs:
|
||||
mv "packages/${PACKAGE}/docs/docs.api.json" "out/${PACKAGE}/${SEMVER}.api.json"
|
||||
fi
|
||||
|
||||
- name: Upload documentation to database
|
||||
if: ${{ env.REF_TYPE == 'branch' && (!inputs.ref || inputs.ref == 'main') }}
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
|
||||
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
|
||||
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
|
||||
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
|
||||
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
|
||||
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
|
||||
uses: ./packages/actions/src/uploadDocumentation
|
||||
|
||||
- name: Upload documentation to database
|
||||
if: ${{ env.REF_TYPE == 'branch' && inputs.ref && inputs.ref != 'main' }}
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
|
||||
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
|
||||
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
|
||||
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
|
||||
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
|
||||
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
|
||||
uses: ./main/packages/actions/src/uploadDocumentation
|
||||
|
||||
- name: Upload split documentation to blob storage
|
||||
if: ${{ env.REF_TYPE == 'branch' && (!inputs.ref || inputs.ref == 'main') }}
|
||||
env:
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
|
||||
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
|
||||
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
|
||||
uses: ./packages/actions/src/uploadSplitDocumentation
|
||||
|
||||
- name: Upload split documentation to blob storage
|
||||
if: ${{ env.REF_TYPE == 'branch' && inputs.ref && inputs.ref != 'main' }}
|
||||
env:
|
||||
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
|
||||
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
|
||||
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
|
||||
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
|
||||
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
|
||||
uses: ./main/packages/actions/src/uploadSplitDocumentation
|
||||
|
||||
- name: Move docs to correct directory
|
||||
if: ${{ env.REF_TYPE == 'branch' }}
|
||||
run: |
|
||||
declare -a PACKAGES=("brokers" "builders" "collection" "core" "discord.js" "formatters" "next" "proxy" "rest" "util" "voice" "ws")
|
||||
for PACKAGE in "${PACKAGES[@]}"; do
|
||||
if [[ "${PACKAGE}" == "discord.js" ]]; then
|
||||
mkdir -p "out/${PACKAGE}"
|
||||
mv "packages/${PACKAGE}/docs/docs.json" "out/${PACKAGE}/${GITHUB_REF_NAME}.json"
|
||||
mv "packages/${PACKAGE}/docs/docs.api.json" "out/${PACKAGE}/${GITHUB_REF_NAME}.api.json"
|
||||
else
|
||||
mkdir -p "out/${PACKAGE}"
|
||||
mv "packages/${PACKAGE}/docs/docs.api.json" "out/${PACKAGE}/${GITHUB_REF_NAME}.api.json"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Commit and push
|
||||
run: |
|
||||
cd out
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
"allowArbitraryExtensions": false,
|
||||
"allowImportingTsExtensions": false,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "nodenext",
|
||||
"moduleResolution": "Bundler",
|
||||
"resolveJsonModule": true,
|
||||
"resolvePackageJsonExports": false,
|
||||
"resolvePackageJsonImports": false,
|
||||
|
||||
12
package.json
12
package.json
@@ -56,17 +56,17 @@
|
||||
"@unocss/eslint-plugin": "^0.59.4",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"conventional-changelog-cli": "^4.1.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"husky": "^9.1.5",
|
||||
"is-ci": "^3.0.1",
|
||||
"lint-staged": "^15.2.9",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"typescript-eslint": "^8.2.0",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"typescript-eslint": "^8.56.0",
|
||||
"unocss": "^0.60.4",
|
||||
"vercel": "^37.0.0",
|
||||
"vitest": "^2.0.5"
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/glob": "^0.5.0",
|
||||
"@aws-sdk/client-s3": "^3.787.0",
|
||||
"@actions/glob": "^0.5.1",
|
||||
"@aws-sdk/client-s3": "^3.995.0",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@vercel/blob": "^0.27.3",
|
||||
"@vercel/postgres": "^0.9.0",
|
||||
@@ -52,19 +52,19 @@
|
||||
"p-limit": "^6.2.0",
|
||||
"p-queue": "^8.1.0",
|
||||
"tslib": "^2.8.1",
|
||||
"undici": "7.8.0"
|
||||
"undici": "7.22.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.14.0",
|
||||
"@types/node": "^22.19.11",
|
||||
"@vitest/coverage-v8": "^3.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.5.3",
|
||||
"terser": "^5.37.0",
|
||||
"tsup": "^8.4.0",
|
||||
"turbo": "^2.5.0",
|
||||
"prettier": "^3.8.1",
|
||||
"terser": "^5.46.0",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
|
||||
@@ -37,15 +37,15 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4"
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ import { type IApiDeclaredItemOptions, ApiDeclaredItem, type IApiDeclaredItemJso
|
||||
* @public
|
||||
*/
|
||||
export interface IApiPropertyItemOptions
|
||||
extends IApiNameMixinOptions,
|
||||
extends
|
||||
IApiNameMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiOptionalMixinOptions,
|
||||
IApiReadonlyMixinOptions,
|
||||
|
||||
@@ -18,7 +18,8 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export interface IApiCallSignatureOptions
|
||||
extends IApiTypeParameterListMixinOptions,
|
||||
extends
|
||||
IApiTypeParameterListMixinOptions,
|
||||
IApiParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiReturnTypeMixinOptions,
|
||||
|
||||
@@ -32,7 +32,8 @@ import { HeritageType } from './HeritageType.js';
|
||||
* @public
|
||||
*/
|
||||
export interface IApiClassOptions
|
||||
extends IApiItemContainerMixinOptions,
|
||||
extends
|
||||
IApiItemContainerMixinOptions,
|
||||
IApiNameMixinOptions,
|
||||
IApiAbstractMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
@@ -48,10 +49,7 @@ export interface IExcerptTokenRangeWithTypeParameters extends IExcerptTokenRange
|
||||
}
|
||||
|
||||
export interface IApiClassJson
|
||||
extends IApiDeclaredItemJson,
|
||||
IApiAbstractMixinJson,
|
||||
IApiTypeParameterListMixinJson,
|
||||
IApiExportedMixinJson {
|
||||
extends IApiDeclaredItemJson, IApiAbstractMixinJson, IApiTypeParameterListMixinJson, IApiExportedMixinJson {
|
||||
extendsTokenRange?: IExcerptTokenRangeWithTypeParameters | undefined;
|
||||
implementsTokenRanges: IExcerptTokenRangeWithTypeParameters[];
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export interface IApiConstructSignatureOptions
|
||||
extends IApiTypeParameterListMixinOptions,
|
||||
extends
|
||||
IApiTypeParameterListMixinOptions,
|
||||
IApiParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiReturnTypeMixinOptions,
|
||||
|
||||
@@ -14,7 +14,8 @@ import { type IApiReleaseTagMixinOptions, ApiReleaseTagMixin } from '../mixins/A
|
||||
* @public
|
||||
*/
|
||||
export interface IApiConstructorOptions
|
||||
extends IApiParameterListMixinOptions,
|
||||
extends
|
||||
IApiParameterListMixinOptions,
|
||||
IApiProtectedMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiDeclaredItemOptions {}
|
||||
|
||||
@@ -16,7 +16,8 @@ import type { ApiEnumMember } from './ApiEnumMember.js';
|
||||
* @public
|
||||
*/
|
||||
export interface IApiEnumOptions
|
||||
extends IApiItemContainerMixinOptions,
|
||||
extends
|
||||
IApiItemContainerMixinOptions,
|
||||
IApiNameMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiDeclaredItemOptions,
|
||||
|
||||
@@ -14,10 +14,7 @@ import { ApiReleaseTagMixin, type IApiReleaseTagMixinOptions } from '../mixins/A
|
||||
* @public
|
||||
*/
|
||||
export interface IApiEnumMemberOptions
|
||||
extends IApiNameMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiDeclaredItemOptions,
|
||||
IApiInitializerMixinOptions {}
|
||||
extends IApiNameMixinOptions, IApiReleaseTagMixinOptions, IApiDeclaredItemOptions, IApiInitializerMixinOptions {}
|
||||
|
||||
/**
|
||||
* Options for customizing the sort order of {@link ApiEnum} members.
|
||||
|
||||
@@ -14,10 +14,7 @@ import { type IApiReleaseTagMixinOptions, ApiReleaseTagMixin } from '../mixins/A
|
||||
* @public
|
||||
*/
|
||||
export interface IApiEventOptions
|
||||
extends IApiNameMixinOptions,
|
||||
IApiParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiDeclaredItemOptions {}
|
||||
extends IApiNameMixinOptions, IApiParameterListMixinOptions, IApiReleaseTagMixinOptions, IApiDeclaredItemOptions {}
|
||||
|
||||
/**
|
||||
* Represents a TypeScript event declaration that belongs to an `ApiClass`.
|
||||
|
||||
@@ -20,7 +20,8 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export interface IApiFunctionOptions
|
||||
extends IApiNameMixinOptions,
|
||||
extends
|
||||
IApiNameMixinOptions,
|
||||
IApiTypeParameterListMixinOptions,
|
||||
IApiParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
|
||||
@@ -15,7 +15,8 @@ import { type IApiReturnTypeMixinOptions, ApiReturnTypeMixin } from '../mixins/A
|
||||
* @public
|
||||
*/
|
||||
export interface IApiIndexSignatureOptions
|
||||
extends IApiParameterListMixinOptions,
|
||||
extends
|
||||
IApiParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiReturnTypeMixinOptions,
|
||||
IApiReadonlyMixinOptions,
|
||||
|
||||
@@ -35,7 +35,8 @@ import { HeritageType } from './HeritageType.js';
|
||||
* @public
|
||||
*/
|
||||
export interface IApiInterfaceOptions
|
||||
extends IApiItemContainerMixinOptions,
|
||||
extends
|
||||
IApiItemContainerMixinOptions,
|
||||
IApiNameMixinOptions,
|
||||
IApiTypeParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
@@ -45,7 +46,8 @@ export interface IApiInterfaceOptions
|
||||
}
|
||||
|
||||
export interface IApiInterfaceJson
|
||||
extends IApiItemContainerJson,
|
||||
extends
|
||||
IApiItemContainerJson,
|
||||
IApiNameMixinJson,
|
||||
IApiTypeParameterListMixinJson,
|
||||
IApiReleaseTagMixinJson,
|
||||
|
||||
@@ -23,7 +23,8 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export interface IApiMethodOptions
|
||||
extends IApiNameMixinOptions,
|
||||
extends
|
||||
IApiNameMixinOptions,
|
||||
IApiAbstractMixinOptions,
|
||||
IApiOptionalMixinOptions,
|
||||
IApiParameterListMixinOptions,
|
||||
|
||||
@@ -18,7 +18,8 @@ import {
|
||||
* @public
|
||||
*/
|
||||
export interface IApiMethodSignatureOptions
|
||||
extends IApiNameMixinOptions,
|
||||
extends
|
||||
IApiNameMixinOptions,
|
||||
IApiTypeParameterListMixinOptions,
|
||||
IApiParameterListMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
|
||||
@@ -15,7 +15,8 @@ import { ApiReleaseTagMixin, type IApiReleaseTagMixinOptions } from '../mixins/A
|
||||
* @public
|
||||
*/
|
||||
export interface IApiNamespaceOptions
|
||||
extends IApiItemContainerMixinOptions,
|
||||
extends
|
||||
IApiItemContainerMixinOptions,
|
||||
IApiNameMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiDeclaredItemOptions,
|
||||
|
||||
@@ -28,9 +28,7 @@ import { DeserializerContext, ApiJsonSchemaVersion } from './DeserializerContext
|
||||
* @public
|
||||
*/
|
||||
export interface IApiPackageOptions
|
||||
extends IApiItemContainerMixinOptions,
|
||||
IApiNameMixinOptions,
|
||||
IApiDocumentedItemOptions {
|
||||
extends IApiItemContainerMixinOptions, IApiNameMixinOptions, IApiDocumentedItemOptions {
|
||||
dependencies?: Record<string, string> | undefined;
|
||||
projectFolderUrl?: string | undefined;
|
||||
tsdocConfiguration: TSDocConfiguration;
|
||||
|
||||
@@ -15,7 +15,8 @@ import { ApiStaticMixin, type IApiStaticMixinOptions } from '../mixins/ApiStatic
|
||||
* @public
|
||||
*/
|
||||
export interface IApiPropertyOptions
|
||||
extends IApiPropertyItemOptions,
|
||||
extends
|
||||
IApiPropertyItemOptions,
|
||||
IApiAbstractMixinOptions,
|
||||
IApiProtectedMixinOptions,
|
||||
IApiStaticMixinOptions,
|
||||
|
||||
@@ -25,7 +25,8 @@ import type { DeserializerContext } from './DeserializerContext.js';
|
||||
* @public
|
||||
*/
|
||||
export interface IApiTypeAliasOptions
|
||||
extends IApiNameMixinOptions,
|
||||
extends
|
||||
IApiNameMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiDeclaredItemOptions,
|
||||
IApiTypeParameterListMixinOptions,
|
||||
|
||||
@@ -22,7 +22,8 @@ import type { DeserializerContext } from './DeserializerContext.js';
|
||||
* @public
|
||||
*/
|
||||
export interface IApiVariableOptions
|
||||
extends IApiNameMixinOptions,
|
||||
extends
|
||||
IApiNameMixinOptions,
|
||||
IApiReleaseTagMixinOptions,
|
||||
IApiReadonlyMixinOptions,
|
||||
IApiDeclaredItemOptions,
|
||||
|
||||
@@ -267,7 +267,8 @@ function mapParam(
|
||||
}
|
||||
|
||||
interface IApiMethodJson
|
||||
extends IApiAbstractMixinJson,
|
||||
extends
|
||||
IApiAbstractMixinJson,
|
||||
IApiDeclaredItemJson,
|
||||
IApiNameMixinJson,
|
||||
IApiOptionalMixinJson,
|
||||
@@ -279,10 +280,7 @@ interface IApiMethodJson
|
||||
IApiTypeParameterListMixinJson {}
|
||||
|
||||
interface IApiConstructorJson
|
||||
extends IApiParameterListJson,
|
||||
IApiProtectedMixinJson,
|
||||
IApiReleaseTagMixinJson,
|
||||
IApiDeclaredItemJson {}
|
||||
extends IApiParameterListJson, IApiProtectedMixinJson, IApiReleaseTagMixinJson, IApiDeclaredItemJson {}
|
||||
|
||||
function mapMethod(method: DocgenMethodJson, _package: string, parent?: DocgenClassJson): IApiMethodJson {
|
||||
const excerptTokens: IExcerptToken[] = [];
|
||||
|
||||
@@ -50,15 +50,15 @@
|
||||
"@microsoft/tsdoc": "0.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4"
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@@ -77,10 +77,7 @@ export interface ApiParameterListJSON {
|
||||
}
|
||||
|
||||
export interface ApiMethodSignatureJSON
|
||||
extends ApiItemJSON,
|
||||
ApiTypeParameterListJSON,
|
||||
ApiParameterListJSON,
|
||||
ApiInheritableJSON {
|
||||
extends ApiItemJSON, ApiTypeParameterListJSON, ApiParameterListJSON, ApiInheritableJSON {
|
||||
mergedSiblings: ApiMethodSignatureJSON[];
|
||||
optional: boolean;
|
||||
overloadIndex: number;
|
||||
|
||||
@@ -65,18 +65,18 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/lodash": "^4.17.4",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/lodash": "^4.17.23",
|
||||
"@types/node": "^18.19.130",
|
||||
"@types/resolve": "^1.20.6",
|
||||
"@types/semver": "^7.5.8",
|
||||
"cpy-cli": "^5.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14"
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,25 +67,25 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@msgpack/msgpack": "^3.0.0-beta2",
|
||||
"@msgpack/msgpack": "^3.1.3",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"ioredis": "^5.4.1"
|
||||
"ioredis": "^5.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -52,8 +52,7 @@ export interface IBaseBroker<TEvents extends {}> {
|
||||
}
|
||||
|
||||
export interface IPubSubBroker<TEvents extends {}>
|
||||
extends IBaseBroker<TEvents>,
|
||||
AsyncEventEmitter<ToEventMap<TEvents>> {
|
||||
extends IBaseBroker<TEvents>, AsyncEventEmitter<ToEventMap<TEvents>> {
|
||||
/**
|
||||
* Publishes an event
|
||||
*/
|
||||
@@ -61,8 +60,7 @@ export interface IPubSubBroker<TEvents extends {}>
|
||||
}
|
||||
|
||||
export interface IRPCBroker<TEvents extends Record<string, any[]>, TResponses extends Record<keyof TEvents, any>>
|
||||
extends IBaseBroker<TEvents>,
|
||||
AsyncEventEmitter<ToEventMap<TEvents, TResponses>> {
|
||||
extends IBaseBroker<TEvents>, AsyncEventEmitter<ToEventMap<TEvents, TResponses>> {
|
||||
/**
|
||||
* Makes an RPC call
|
||||
*/
|
||||
|
||||
@@ -58,9 +58,9 @@ export const DefaultRedisBrokerOptions = {
|
||||
* Helper class with shared Redis logic
|
||||
*/
|
||||
export abstract class BaseRedisBroker<
|
||||
TEvents extends Record<string, any[]>,
|
||||
TResponses extends Record<keyof TEvents, any> | undefined = undefined,
|
||||
>
|
||||
TEvents extends Record<string, any[]>,
|
||||
TResponses extends Record<keyof TEvents, any> | undefined = undefined,
|
||||
>
|
||||
extends AsyncEventEmitter<ToEventMap<TEvents, TResponses>>
|
||||
implements IBaseBroker<TEvents>
|
||||
{
|
||||
|
||||
@@ -2,6 +2,32 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [@discordjs/builders@1.14.1](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.14.0...@discordjs/builders@1.14.1) - (2026-03-31)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Actually accept rest in RadioGroup/CheckBoxGroupBuilder#setOptions (#11472) ([6e45ddc](https://github.com/discordjs/discord.js/commit/6e45ddc067816b01d6676f04faea54d34469fefc))
|
||||
|
||||
# [@discordjs/builders@1.14.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.13.1...@discordjs/builders@1.14.0) - (2026-03-22)
|
||||
|
||||
## Documentation
|
||||
|
||||
- **builders:** Edited docs to correctly link to splice (#11430) ([ec5d921](https://github.com/discordjs/discord.js/commit/ec5d921b75255cf28fd572a91e715b37305f4cf8))
|
||||
|
||||
## Features
|
||||
|
||||
- **builders:** Add checkbox, checkboxgroup, and radiogroup builders (#11410) ([ca7719e](https://github.com/discordjs/discord.js/commit/ca7719e822e02a83e5a7b769de3c5fd615dc24fd))
|
||||
|
||||
# [@discordjs/builders@1.13.1](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.13.0...@discordjs/builders@1.13.1) - (2025-11-30)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Adjust label predicates (#11318) ([61251cf](https://github.com/discordjs/discord.js/commit/61251cfcb842cc468aca7a581f54be4fd28c2721))
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Container:** Update example usage ([e777938](https://github.com/discordjs/discord.js/commit/e77793898ac36320eeee8b999c618918526ab9c2))
|
||||
|
||||
# [@discordjs/builders@1.13.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.12.2...@discordjs/builders@1.13.0) - (2025-10-24)
|
||||
|
||||
## Features
|
||||
|
||||
415
packages/builders/__tests__/components/checkbox.test.ts
Normal file
415
packages/builders/__tests__/components/checkbox.test.ts
Normal file
@@ -0,0 +1,415 @@
|
||||
import { ComponentType, type APICheckboxComponent } from 'discord-api-types/v10';
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import { LabelBuilder } from '../../src';
|
||||
import { CheckboxBuilder } from '../../src/components/checkbox/Checkbox';
|
||||
import { CheckboxGroupBuilder } from '../../src/components/checkbox/CheckboxGroup';
|
||||
import { CheckboxGroupOptionBuilder } from '../../src/components/checkbox/CheckboxGroupOption';
|
||||
import { RadioGroupBuilder } from '../../src/components/checkbox/RadioGroup';
|
||||
import { RadioGroupOptionBuilder } from '../../src/components/checkbox/RadioGroupOption';
|
||||
|
||||
const longStr = ':3'.repeat(5_000);
|
||||
|
||||
const fiveCheckboxOptions = [
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 3').setValue('option_3'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 4').setValue('option_4'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 5').setValue('option_5'),
|
||||
];
|
||||
|
||||
const elevenCheckboxOptions = [
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 3').setValue('option_3'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 4').setValue('option_4'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 5').setValue('option_5'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 6').setValue('option_6'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 7').setValue('option_7'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 8').setValue('option_8'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 9').setValue('option_9'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 10').setValue('option_10'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 11').setValue('option_11'),
|
||||
];
|
||||
|
||||
const fiveRadioOptions = [
|
||||
new RadioGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 3').setValue('option_3'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 4').setValue('option_4'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 5').setValue('option_5'),
|
||||
];
|
||||
|
||||
const elevenRadioOptions = [
|
||||
new RadioGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 3').setValue('option_3'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 4').setValue('option_4'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 5').setValue('option_5'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 6').setValue('option_6'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 7').setValue('option_7'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 8').setValue('option_8'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 9').setValue('option_9'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 10').setValue('option_10'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 11').setValue('option_11'),
|
||||
];
|
||||
|
||||
describe('Checkbox Components', () => {
|
||||
describe('CheckboxBuilder', () => {
|
||||
test('Valid builder does not throw.', () => {
|
||||
expect(() => new CheckboxBuilder().setCustomId('checkbox').toJSON()).not.toThrowError();
|
||||
expect(() => new CheckboxBuilder().setCustomId('checkbox').setDefault(true).toJSON()).not.toThrowError();
|
||||
});
|
||||
|
||||
test('Invalid builder does throw.', () => {
|
||||
expect(() => new CheckboxBuilder().toJSON()).toThrowError();
|
||||
expect(() => new CheckboxBuilder().setDefault(true).toJSON()).toThrowError();
|
||||
expect(() => new CheckboxBuilder().setCustomId(longStr).toJSON()).toThrowError();
|
||||
});
|
||||
|
||||
test('API data equals toJSON().', () => {
|
||||
const checkboxData = {
|
||||
type: ComponentType.Checkbox,
|
||||
custom_id: 'checkbox',
|
||||
default: true,
|
||||
} satisfies APICheckboxComponent;
|
||||
|
||||
expect(new CheckboxBuilder(checkboxData).toJSON()).toEqual(checkboxData);
|
||||
|
||||
expect(new CheckboxBuilder().setCustomId('checkbox').setDefault(true).toJSON()).toEqual(checkboxData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CheckboxGroupBuilder', () => {
|
||||
test('Valid builder does not throw.', () => {
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder({
|
||||
custom_id: 'checkbox_group',
|
||||
options: fiveCheckboxOptions.map((option) => option.toJSON()),
|
||||
}).toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setCustomId('checkbox_group').setOptions(fiveCheckboxOptions).toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions([
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
])
|
||||
.toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setCustomId('checkbox_group').addOptions(fiveCheckboxOptions).toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setMinValues(1)
|
||||
.setMaxValues(2)
|
||||
.setOptions([
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
])
|
||||
.toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.spliceOptions(2, 1, ...elevenCheckboxOptions.slice(7, 9))
|
||||
.spliceOptions(0, 1, { label: 'New Option', value: 'new_option' }),
|
||||
).not.toThrowError();
|
||||
});
|
||||
|
||||
test('Invalid builder does throw.', () => {
|
||||
expect(() => new CheckboxGroupBuilder().toJSON()).toThrowError();
|
||||
expect(() => new CheckboxGroupBuilder().addOptions([]).toJSON()).toThrowError();
|
||||
expect(() => new CheckboxGroupBuilder().setMinValues(2).setMaxValues(1).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setMinValues(2).setMaxValues(1).addOptions(fiveCheckboxOptions).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setMinValues(2)
|
||||
.setMaxValues(1)
|
||||
.addOptions(fiveCheckboxOptions)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setCustomId('checkbox_group').setMinValues(5).setMaxValues(11).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() => new CheckboxGroupBuilder().setCustomId('checkbox_group').setOptions([]).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.setMinValues(6)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.setMaxValues(6)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setCustomId('checkbox_group').setOptions(elevenCheckboxOptions).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(elevenCheckboxOptions)
|
||||
.setMaxValues(12)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setCustomId(longStr).setOptions(fiveCheckboxOptions).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.setMinValues(0)
|
||||
.setRequired(true)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setMaxValues(4)
|
||||
.setOptions([
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue('option_1').setDefault(true),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 2').setValue('option_2').setDefault(true),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 3').setValue('option_3').setDefault(true),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 4').setValue('option_4').setDefault(true),
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 5').setValue('option_5').setDefault(true),
|
||||
])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.addOptions(fiveCheckboxOptions)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(elevenCheckboxOptions.slice(0, 5))
|
||||
.addOptions(elevenCheckboxOptions.slice(5, 11))
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(
|
||||
() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.spliceOptions(2, 1, new CheckboxGroupOptionBuilder().setLabel('Option 6')), // no value
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder()
|
||||
.setCustomId('checkbox_group')
|
||||
.setOptions(fiveCheckboxOptions)
|
||||
.spliceOptions(2, 1, { value: 'hi', label: longStr }),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupBuilder().setCustomId('checkbox_group').addOptions({ value: 'hi', label: longStr }),
|
||||
).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('CheckboxGroupOptionBuilder', () => {
|
||||
test('Valid builder does not throw.', () => {
|
||||
expect(() =>
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue('option_1').toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupOptionBuilder()
|
||||
.setLabel('Option 2')
|
||||
.setValue('option_2')
|
||||
.setDescription('This is option 2')
|
||||
.toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new CheckboxGroupOptionBuilder().setLabel('Option 3').setValue('option_3').setDefault(true).toJSON(),
|
||||
).not.toThrowError();
|
||||
});
|
||||
|
||||
test('Invalid builder does throw.', () => {
|
||||
expect(() => new CheckboxGroupOptionBuilder().toJSON()).toThrowError();
|
||||
expect(() => new CheckboxGroupOptionBuilder().setValue('option_1').toJSON()).toThrowError();
|
||||
expect(() => new CheckboxGroupOptionBuilder().setLabel('Option 1').toJSON()).toThrowError();
|
||||
expect(() => new CheckboxGroupOptionBuilder().setLabel(longStr).setValue('option_1').toJSON()).toThrowError();
|
||||
expect(() => new CheckboxGroupOptionBuilder().setLabel('Option 1').setValue(longStr).toJSON()).toThrowError();
|
||||
});
|
||||
|
||||
test('toJSON returns correct data.', () => {
|
||||
const option = new CheckboxGroupOptionBuilder()
|
||||
.setLabel('Option 1')
|
||||
.setValue('option_1')
|
||||
.setDescription('This is option 1')
|
||||
.setDefault(true);
|
||||
|
||||
expect(option.toJSON()).toEqual({
|
||||
label: 'Option 1',
|
||||
value: 'option_1',
|
||||
description: 'This is option 1',
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('RadioGroupBuilder', () => {
|
||||
test('Valid builder does not throw.', () => {
|
||||
expect(() =>
|
||||
new RadioGroupBuilder().setCustomId('radio_group').addOptions(fiveRadioOptions).toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.setOptions([
|
||||
new RadioGroupOptionBuilder().setLabel('Option 1').setValue('option_1'),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 2').setValue('option_2'),
|
||||
])
|
||||
.toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder().setCustomId('radio_group').addOptions(fiveRadioOptions).setRequired(false),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder().setCustomId('radio_group').addOptions(fiveRadioOptions).setRequired(true),
|
||||
).not.toThrowError();
|
||||
expect(() => new RadioGroupBuilder().setCustomId('radio_group').setOptions(fiveRadioOptions)).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.setOptions(fiveRadioOptions)
|
||||
.spliceOptions(2, 1, elevenRadioOptions.slice(7, 9)),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.addOptions(elevenRadioOptions.slice(0, 5))
|
||||
.spliceOptions(0, 1, { label: 'New Option', value: 'new_option' }),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder({
|
||||
custom_id: 'radio_group',
|
||||
options: fiveRadioOptions.map((option) => option.toJSON()),
|
||||
}).toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.addOptions(fiveRadioOptions.map((option) => option.toJSON()))
|
||||
.toJSON(),
|
||||
).not.toThrowError();
|
||||
});
|
||||
|
||||
test('Invalid builder does throw.', () => {
|
||||
expect(() => new RadioGroupBuilder().toJSON()).toThrowError();
|
||||
expect(() => new RadioGroupBuilder().addOptions([]).toJSON()).toThrowError();
|
||||
// needs at least 2 options
|
||||
expect(() => new RadioGroupBuilder().addOptions([fiveRadioOptions[0]]).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder().setCustomId('radio_group').setOptions([fiveRadioOptions[0]]).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() => new RadioGroupBuilder().setCustomId('radio_group').setOptions([]).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder().setCustomId('radio_group').setOptions(elevenRadioOptions).toJSON(),
|
||||
).toThrowError();
|
||||
expect(() => new RadioGroupBuilder().setCustomId(longStr).setOptions(fiveRadioOptions).toJSON()).toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.setOptions([
|
||||
new RadioGroupOptionBuilder().setLabel('Option 1').setValue('option_1').setDefault(true),
|
||||
new RadioGroupOptionBuilder().setLabel('Option 2').setValue('option_2').setDefault(true),
|
||||
])
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.addOptions(fiveRadioOptions)
|
||||
.addOptions(fiveRadioOptions)
|
||||
.toJSON(),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder()
|
||||
.setCustomId('radio_group')
|
||||
.setOptions(fiveRadioOptions)
|
||||
.spliceOptions(2, 1, { value: 'hi', label: longStr }),
|
||||
).toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupBuilder().setCustomId('radio_group').addOptions({ value: 'hi', label: longStr }),
|
||||
).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('RadioGroupOptionBuilder', () => {
|
||||
test('Valid builder does not throw.', () => {
|
||||
expect(() => new RadioGroupOptionBuilder().setLabel('Option 1').setValue('option_1').toJSON()).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupOptionBuilder()
|
||||
.setLabel('Option 2')
|
||||
.setValue('option_2')
|
||||
.setDescription('This is option 2')
|
||||
.toJSON(),
|
||||
).not.toThrowError();
|
||||
expect(() =>
|
||||
new RadioGroupOptionBuilder().setLabel('Option 3').setValue('option_3').setDefault(true).toJSON(),
|
||||
).not.toThrowError();
|
||||
});
|
||||
|
||||
test('Invalid builder does throw.', () => {
|
||||
expect(() => new RadioGroupOptionBuilder().toJSON()).toThrowError();
|
||||
expect(() => new RadioGroupOptionBuilder().setValue('option_1').toJSON()).toThrowError();
|
||||
expect(() => new RadioGroupOptionBuilder().setLabel('Option 1').toJSON()).toThrowError();
|
||||
expect(() => new RadioGroupOptionBuilder().setLabel(longStr).setValue('option_1').toJSON()).toThrowError();
|
||||
expect(() => new RadioGroupOptionBuilder().setLabel('Option 1').setValue(longStr).toJSON()).toThrowError();
|
||||
});
|
||||
|
||||
test('toJSON returns correct data.', () => {
|
||||
const option = new RadioGroupOptionBuilder()
|
||||
.setLabel('Option 1')
|
||||
.setValue('option_1')
|
||||
.setDescription('This is option 1')
|
||||
.setDefault(true);
|
||||
|
||||
expect(option.toJSON()).toEqual({
|
||||
label: 'Option 1',
|
||||
value: 'option_1',
|
||||
description: 'This is option 1',
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('LabelBuilder with Checkbox Components', () => {
|
||||
test('LabelBuilder can set Checkbox component.', () => {
|
||||
const checkbox = new CheckboxBuilder().setCustomId('checkbox').setDefault(true);
|
||||
const label = new LabelBuilder().setLabel('Checkbox Label').setCheckboxComponent(checkbox);
|
||||
expect(() => label.toJSON()).not.toThrowError();
|
||||
expect(label.toJSON().component).toEqual(checkbox.toJSON());
|
||||
});
|
||||
|
||||
test('LabelBuilder can set CheckboxGroup component.', () => {
|
||||
const checkboxGroup = new CheckboxGroupBuilder().setCustomId('checkbox_group').setOptions(fiveCheckboxOptions);
|
||||
const label = new LabelBuilder().setLabel('Checkbox Group Label').setCheckboxGroupComponent(checkboxGroup);
|
||||
expect(() => label.toJSON()).not.toThrowError();
|
||||
expect(label.toJSON().component).toEqual(checkboxGroup.toJSON());
|
||||
});
|
||||
|
||||
test('LabelBuilder can set RadioGroup component.', () => {
|
||||
const radioGroup = new RadioGroupBuilder().setCustomId('radio_group').setOptions(fiveRadioOptions);
|
||||
const label = new LabelBuilder().setLabel('Radio Group Label').setRadioGroupComponent(radioGroup);
|
||||
expect(() => label.toJSON()).not.toThrowError();
|
||||
expect(label.toJSON().component).toEqual(radioGroup.toJSON());
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,10 @@ const selectMenu = () => new StringSelectMenuBuilder();
|
||||
const selectMenuOption = () => new StringSelectMenuOptionBuilder();
|
||||
|
||||
const longStr = 'a'.repeat(256);
|
||||
const selectMenuOptionLabelAtLimit = 'a'.repeat(100);
|
||||
const selectMenuOptionLabelAboveLimit = 'a'.repeat(101);
|
||||
const selectMenuOptionValueAboveLimit = 'a'.repeat(101);
|
||||
const selectMenuOptionDescriptionAboveLimit = 'a'.repeat(101);
|
||||
|
||||
const selectMenuOptionData: APISelectMenuOption = {
|
||||
label: 'test',
|
||||
@@ -53,12 +57,12 @@ describe('Select Menu Components', () => {
|
||||
expect(() => selectMenu().setDisabled()).not.toThrowError();
|
||||
expect(() => selectMenu().setPlaceholder('description')).not.toThrowError();
|
||||
const option = selectMenuOption()
|
||||
.setLabel('test')
|
||||
.setLabel(selectMenuOptionLabelAtLimit)
|
||||
.setValue('test')
|
||||
.setDefault(true)
|
||||
.setEmoji({ name: 'test' })
|
||||
.setDescription('description');
|
||||
expect(() => selectMenu().addOptions(option)).not.toThrowError();
|
||||
expect(() => selectMenu().setCustomId('customId').addOptions(option).toJSON()).not.toThrowError();
|
||||
expect(() => selectMenu().setOptions(option)).not.toThrowError();
|
||||
expect(() => selectMenu().setOptions({ label: 'test', value: 'test' })).not.toThrowError();
|
||||
expect(() => selectMenu().addOptions([option])).not.toThrowError();
|
||||
@@ -156,13 +160,13 @@ describe('Select Menu Components', () => {
|
||||
|
||||
expect(() => {
|
||||
selectMenuOption()
|
||||
.setLabel(longStr)
|
||||
.setValue(longStr)
|
||||
.setLabel(selectMenuOptionLabelAboveLimit)
|
||||
.setValue(selectMenuOptionValueAboveLimit)
|
||||
// @ts-expect-error: Invalid default value
|
||||
.setDefault(-1)
|
||||
// @ts-expect-error: Invalid emoji
|
||||
.setEmoji({ name: 1 })
|
||||
.setDescription(longStr);
|
||||
.setDescription(selectMenuOptionDescriptionAboveLimit);
|
||||
}).toThrowError();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/builders",
|
||||
"version": "1.13.0",
|
||||
"version": "1.14.1",
|
||||
"description": "A set of builders that you can use when creating your bot",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
@@ -68,7 +68,7 @@
|
||||
"@discordjs/formatters": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@sapphire/shapeshift": "^4.0.0",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"discord-api-types": "^0.38.40",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.4",
|
||||
"tslib": "^2.6.3"
|
||||
@@ -77,17 +77,17 @@
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^16.18.105",
|
||||
"@types/node": "^16.18.126",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -50,6 +50,9 @@ export const labelValueDescriptionValidator = s
|
||||
.lengthLessThanOrEqual(100)
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
|
||||
/**
|
||||
* @deprecated Replaced with selectMenuStringOptionPredicate.
|
||||
*/
|
||||
export const jsonOptionValidator = s
|
||||
.object({
|
||||
label: labelValueDescriptionValidator,
|
||||
|
||||
@@ -25,8 +25,7 @@ export type AnyAPIActionRowComponent =
|
||||
*/
|
||||
export abstract class ComponentBuilder<
|
||||
DataType extends Partial<APIBaseComponent<ComponentType>> = APIBaseComponent<ComponentType>,
|
||||
> implements JSONEncodable<AnyAPIActionRowComponent>
|
||||
{
|
||||
> implements JSONEncodable<AnyAPIActionRowComponent> {
|
||||
/**
|
||||
* The API data associated with this component.
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,9 @@ import {
|
||||
} from './ActionRow.js';
|
||||
import { ComponentBuilder } from './Component.js';
|
||||
import { ButtonBuilder } from './button/Button.js';
|
||||
import { CheckboxBuilder } from './checkbox/Checkbox.js';
|
||||
import { CheckboxGroupBuilder } from './checkbox/CheckboxGroup.js';
|
||||
import { RadioGroupBuilder } from './checkbox/RadioGroup.js';
|
||||
import { FileUploadBuilder } from './fileUpload/FileUpload.js';
|
||||
import { LabelBuilder } from './label/Label.js';
|
||||
import { ChannelSelectMenuBuilder } from './selectMenu/ChannelSelectMenu.js';
|
||||
@@ -110,6 +113,18 @@ export interface MappedComponentTypes {
|
||||
* The file upload component type is associated with a {@link FileUploadBuilder}.
|
||||
*/
|
||||
[ComponentType.FileUpload]: FileUploadBuilder;
|
||||
/**
|
||||
* The checkbox component type is associated with a {@link CheckboxBuilder}.
|
||||
*/
|
||||
[ComponentType.Checkbox]: CheckboxBuilder;
|
||||
/**
|
||||
* The checkbox group component type is associated with a {@link CheckboxGroupBuilder}.
|
||||
*/
|
||||
[ComponentType.CheckboxGroup]: CheckboxGroupBuilder;
|
||||
/**
|
||||
* The radio group component type is associated with a {@link RadioGroupBuilder}.
|
||||
*/
|
||||
[ComponentType.RadioGroup]: RadioGroupBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,6 +190,12 @@ export function createComponentBuilder(
|
||||
return new LabelBuilder(data);
|
||||
case ComponentType.FileUpload:
|
||||
return new FileUploadBuilder(data);
|
||||
case ComponentType.Checkbox:
|
||||
return new CheckboxBuilder(data);
|
||||
case ComponentType.CheckboxGroup:
|
||||
return new CheckboxGroupBuilder(data);
|
||||
case ComponentType.RadioGroup:
|
||||
return new RadioGroupBuilder(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}`);
|
||||
|
||||
98
packages/builders/src/components/checkbox/Assertions.ts
Normal file
98
packages/builders/src/components/checkbox/Assertions.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { Result, s } from '@sapphire/shapeshift';
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import { isValidationEnabled } from '../../util/validation';
|
||||
import { customIdValidator, idValidator } from '../Assertions';
|
||||
|
||||
export const checkboxPredicate = s
|
||||
.object({
|
||||
type: s.literal(ComponentType.Checkbox),
|
||||
custom_id: customIdValidator,
|
||||
id: idValidator.optional(),
|
||||
default: s.boolean().optional(),
|
||||
})
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
|
||||
export const checkboxGroupOptionPredicate = s
|
||||
.object({
|
||||
label: s.string().lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100),
|
||||
value: s.string().lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100),
|
||||
description: s.string().lengthLessThanOrEqual(100).optional(),
|
||||
default: s.boolean().optional(),
|
||||
})
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
|
||||
export const checkboxGroupPredicate = s
|
||||
.object({
|
||||
type: s.literal(ComponentType.CheckboxGroup),
|
||||
custom_id: customIdValidator,
|
||||
id: idValidator.optional(),
|
||||
options: s.array(checkboxGroupOptionPredicate).lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(10),
|
||||
min_values: s.number().int().greaterThanOrEqual(0).lessThanOrEqual(10).optional(),
|
||||
max_values: s.number().int().greaterThanOrEqual(1).lessThanOrEqual(10).optional(),
|
||||
required: s.boolean().optional(),
|
||||
})
|
||||
.reshape((data) => {
|
||||
// Ensure min_values is not greater than max_values
|
||||
if (data.min_values !== undefined && data.max_values !== undefined && data.min_values > data.max_values) {
|
||||
return Result.err(new RangeError('min_values cannot be greater than max_values'));
|
||||
}
|
||||
|
||||
// Ensure max_values is not greater than the number of options
|
||||
if (data.max_values !== undefined && data.max_values > data.options.length) {
|
||||
return Result.err(new RangeError('max_values cannot be greater than the number of options'));
|
||||
}
|
||||
|
||||
// Ensure min_values is not greater than the number of options
|
||||
if (data.min_values !== undefined && data.min_values > data.options.length) {
|
||||
return Result.err(new RangeError('min_values cannot be greater than the number of options'));
|
||||
}
|
||||
|
||||
// Ensure required is consistent with min_values
|
||||
if (data.required === true && data.min_values === 0) {
|
||||
return Result.err(new RangeError('If required is true, min_values must be at least 1'));
|
||||
}
|
||||
|
||||
// Ensure there are not more default values than max_values
|
||||
const defaultCount = data.options.filter((option) => option.default === true).length;
|
||||
if (data.max_values !== undefined && defaultCount > data.max_values) {
|
||||
return Result.err(new RangeError('The number of default options cannot be greater than max_values'));
|
||||
}
|
||||
|
||||
// Ensure each option's value is unique
|
||||
const values = data.options.map((option) => option.value);
|
||||
const uniqueValues = new Set(values);
|
||||
if (uniqueValues.size !== values.length) {
|
||||
return Result.err(new RangeError('Each option in a checkbox group must have a unique value'));
|
||||
}
|
||||
|
||||
return Result.ok(data);
|
||||
})
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
|
||||
export const radioGroupOptionPredicate = checkboxGroupOptionPredicate;
|
||||
|
||||
export const radioGroupPredicate = s
|
||||
.object({
|
||||
type: s.literal(ComponentType.RadioGroup),
|
||||
custom_id: customIdValidator,
|
||||
id: idValidator.optional(),
|
||||
options: s.array(radioGroupOptionPredicate).lengthGreaterThanOrEqual(2).lengthLessThanOrEqual(10),
|
||||
required: s.boolean().optional(),
|
||||
})
|
||||
.reshape((data) => {
|
||||
// Ensure there is exactly one default option
|
||||
const defaultCount = data.options.filter((option) => option.default === true).length;
|
||||
if (defaultCount > 1) {
|
||||
return Result.err(new RangeError('There can be at most one default option in a radio group'));
|
||||
}
|
||||
|
||||
// Ensure each option's value is unique
|
||||
const values = data.options.map((option) => option.value);
|
||||
const uniqueValues = new Set(values);
|
||||
if (uniqueValues.size !== values.length) {
|
||||
return Result.err(new RangeError('Each option in a radio group must have a unique value'));
|
||||
}
|
||||
|
||||
return Result.ok(data);
|
||||
})
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
63
packages/builders/src/components/checkbox/Checkbox.ts
Normal file
63
packages/builders/src/components/checkbox/Checkbox.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import type { APICheckboxComponent } from 'discord-api-types/v10';
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import { ComponentBuilder } from '../Component';
|
||||
import { checkboxPredicate } from './Assertions';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for checkboxes.
|
||||
*/
|
||||
export class CheckboxBuilder extends ComponentBuilder<APICheckboxComponent> {
|
||||
/**
|
||||
* Creates a new checkbox from API data.
|
||||
*
|
||||
* @param data - The API data to create this checkbox with
|
||||
* @example
|
||||
* Creating a checkbox from an API data object:
|
||||
* ```ts
|
||||
* const checkbox = new CheckboxBuilder({
|
||||
* custom_id: 'accept_terms',
|
||||
* default: false,
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a checkbox using setters and API data:
|
||||
* ```ts
|
||||
* const checkbox = new CheckboxBuilder()
|
||||
* .setCustomId('subscribe_newsletter')
|
||||
* .setDefault(true);
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APICheckboxComponent>) {
|
||||
super({ type: ComponentType.Checkbox, ...data });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id of this checkbox.
|
||||
*
|
||||
* @param customId - The custom id to use
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this checkbox is checked by default.
|
||||
*
|
||||
* @param isDefault - Whether the checkbox should be checked by default
|
||||
*/
|
||||
public setDefault(isDefault: boolean) {
|
||||
this.data.default = isDefault;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public override toJSON(): APICheckboxComponent {
|
||||
checkboxPredicate.parse(this.data);
|
||||
return {
|
||||
...this.data,
|
||||
} as APICheckboxComponent;
|
||||
}
|
||||
}
|
||||
174
packages/builders/src/components/checkbox/CheckboxGroup.ts
Normal file
174
packages/builders/src/components/checkbox/CheckboxGroup.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
import type { APICheckboxGroupComponent, APICheckboxGroupOption } from 'discord-api-types/v10';
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import type { RestOrArray } from '../../util/normalizeArray';
|
||||
import { normalizeArray } from '../../util/normalizeArray';
|
||||
import { ComponentBuilder } from '../Component';
|
||||
import { checkboxGroupOptionPredicate, checkboxGroupPredicate } from './Assertions';
|
||||
import { CheckboxGroupOptionBuilder } from './CheckboxGroupOption';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for checkbox groups.
|
||||
*/
|
||||
export class CheckboxGroupBuilder extends ComponentBuilder<APICheckboxGroupComponent> {
|
||||
/**
|
||||
* The options within this checkbox group.
|
||||
*/
|
||||
public readonly options: CheckboxGroupOptionBuilder[];
|
||||
|
||||
/**
|
||||
* Creates a new checkbox group from API data.
|
||||
*
|
||||
* @param data - The API data to create this checkbox group with
|
||||
* @example
|
||||
* Creating a checkbox group from an API data object:
|
||||
* ```ts
|
||||
* const checkboxGroup = new CheckboxGroupBuilder({
|
||||
* custom_id: 'select_options',
|
||||
* options: [
|
||||
* { label: 'Option 1', value: 'option_1' },
|
||||
* { label: 'Option 2', value: 'option_2' },
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a checkbox group using setters and API data:
|
||||
* ```ts
|
||||
* const checkboxGroup = new CheckboxGroupBuilder()
|
||||
* .setCustomId('choose_items')
|
||||
* .setOptions([
|
||||
* { label: 'Item A', value: 'item_a' },
|
||||
* { label: 'Item B', value: 'item_b' },
|
||||
* ])
|
||||
* .setMinValues(1)
|
||||
* .setMaxValues(2);
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APICheckboxGroupComponent>) {
|
||||
const { options, ...initData } = data ?? {};
|
||||
super({ ...initData, type: ComponentType.CheckboxGroup });
|
||||
this.options = options?.map((option: APICheckboxGroupOption) => new CheckboxGroupOptionBuilder(option)) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id of this checkbox group.
|
||||
*
|
||||
* @param customId - The custom id to use
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options to this checkbox group.
|
||||
*
|
||||
* @param options - The options to add
|
||||
*/
|
||||
public addOptions(...options: RestOrArray<APICheckboxGroupOption | CheckboxGroupOptionBuilder>) {
|
||||
const normalizedOptions = normalizeArray(options);
|
||||
|
||||
this.options.push(
|
||||
...normalizedOptions.map((normalizedOption) => {
|
||||
// I do this because TS' duck typing causes issues,
|
||||
// if I put in a RadioGroupOption, TS lets it pass but
|
||||
// it fails to convert to a checkbox group option at runtime
|
||||
const json = 'toJSON' in normalizedOption ? normalizedOption.toJSON() : normalizedOption;
|
||||
const option = new CheckboxGroupOptionBuilder(json);
|
||||
checkboxGroupOptionPredicate.parse(option.toJSON());
|
||||
return option;
|
||||
}),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options for this checkbox group.
|
||||
*
|
||||
* @param options - The options to use
|
||||
*/
|
||||
public setOptions(...options: RestOrArray<APICheckboxGroupOption | CheckboxGroupOptionBuilder>) {
|
||||
return this.spliceOptions(0, this.options.length, ...options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes, replaces, or inserts options for this checkbox group.
|
||||
*
|
||||
* @remarks
|
||||
* This method behaves similarly
|
||||
* to {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice()}.
|
||||
* It's useful for modifying and adjusting the order of existing options.
|
||||
* @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<APICheckboxGroupOption | CheckboxGroupOptionBuilder>
|
||||
) {
|
||||
const normalizedOptions = normalizeArray(options);
|
||||
|
||||
const clone = [...this.options];
|
||||
|
||||
clone.splice(
|
||||
index,
|
||||
deleteCount,
|
||||
...normalizedOptions.map((normalizedOption) => {
|
||||
// I do this because TS' duck typing causes issues,
|
||||
// if I put in a RadioGroupOption, TS lets it pass but
|
||||
// it fails to convert to a checkbox group option at runtime
|
||||
const json = 'toJSON' in normalizedOption ? normalizedOption.toJSON() : normalizedOption;
|
||||
const option = new CheckboxGroupOptionBuilder(json);
|
||||
checkboxGroupOptionPredicate.parse(option.toJSON());
|
||||
return option;
|
||||
}),
|
||||
);
|
||||
|
||||
this.options.splice(0, this.options.length, ...clone);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum number of options that must be selected.
|
||||
*
|
||||
* @param minValues - The minimum number of options that must be selected
|
||||
*/
|
||||
public setMinValues(minValues: number) {
|
||||
this.data.min_values = minValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of options that can be selected.
|
||||
*
|
||||
* @param maxValues - The maximum number of options that can be selected
|
||||
*/
|
||||
public setMaxValues(maxValues: number) {
|
||||
this.data.max_values = maxValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether selecting options is required.
|
||||
*
|
||||
* @param required - Whether selecting options is required
|
||||
*/
|
||||
public setRequired(required: boolean) {
|
||||
this.data.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public override toJSON(): APICheckboxGroupComponent {
|
||||
const data = {
|
||||
...this.data,
|
||||
options: this.options.map((option) => option.toJSON()),
|
||||
};
|
||||
|
||||
checkboxGroupPredicate.parse(data);
|
||||
|
||||
return data as APICheckboxGroupComponent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APICheckboxGroupOption } from 'discord-api-types/v10';
|
||||
import { checkboxGroupOptionPredicate } from './Assertions';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for checkbox group options.
|
||||
*/
|
||||
export class CheckboxGroupOptionBuilder implements JSONEncodable<APICheckboxGroupOption> {
|
||||
/**
|
||||
* Creates a new checkbox group option from API data.
|
||||
*
|
||||
* @param data - The API data to create this checkbox group option with
|
||||
* @example
|
||||
* Creating a checkbox group option from an API data object:
|
||||
* ```ts
|
||||
* const option = new CheckboxGroupOptionBuilder({
|
||||
* label: 'Option 1',
|
||||
* value: 'option_1',
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a checkbox group option using setters and API data:
|
||||
* ```ts
|
||||
* const option = new CheckboxGroupOptionBuilder()
|
||||
* .setLabel('Option 2')
|
||||
* .setValue('option_2');
|
||||
* ```
|
||||
*/
|
||||
public constructor(public data: Partial<APICheckboxGroupOption> = {}) {}
|
||||
|
||||
/**
|
||||
* Sets the label for this option.
|
||||
*
|
||||
* @param label - The label to use
|
||||
*/
|
||||
public setLabel(label: string) {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for this option.
|
||||
*
|
||||
* @param value - The value to use
|
||||
*/
|
||||
public setValue(value: string) {
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description for this option.
|
||||
*
|
||||
* @param description - The description to use
|
||||
*/
|
||||
public setDescription(description: string) {
|
||||
this.data.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this option is selected by default.
|
||||
*
|
||||
* @param isDefault - Whether the option should be selected by default
|
||||
*/
|
||||
public setDefault(isDefault: boolean) {
|
||||
this.data.default = isDefault;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APICheckboxGroupOption {
|
||||
checkboxGroupOptionPredicate.parse(this.data);
|
||||
|
||||
return {
|
||||
...this.data,
|
||||
} as APICheckboxGroupOption;
|
||||
}
|
||||
}
|
||||
152
packages/builders/src/components/checkbox/RadioGroup.ts
Normal file
152
packages/builders/src/components/checkbox/RadioGroup.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import type { APIRadioGroupComponent, APIRadioGroupOption } from 'discord-api-types/v10';
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import type { RestOrArray } from '../../util/normalizeArray';
|
||||
import { normalizeArray } from '../../util/normalizeArray';
|
||||
import { ComponentBuilder } from '../Component';
|
||||
import { radioGroupOptionPredicate, radioGroupPredicate } from './Assertions';
|
||||
import { RadioGroupOptionBuilder } from './RadioGroupOption';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for radio groups.
|
||||
*/
|
||||
export class RadioGroupBuilder extends ComponentBuilder<APIRadioGroupComponent> {
|
||||
/**
|
||||
* The options within this radio group.
|
||||
*/
|
||||
public readonly options: RadioGroupOptionBuilder[];
|
||||
|
||||
/**
|
||||
* Creates a new radio group from API data.
|
||||
*
|
||||
* @param data - The API data to create this radio group with
|
||||
* @example
|
||||
* Creating a radio group from an API data object:
|
||||
* ```ts
|
||||
* const radioGroup = new RadioGroupBuilder({
|
||||
* custom_id: 'select_options',
|
||||
* options: [
|
||||
* { label: 'Option 1', value: 'option_1' },
|
||||
* { label: 'Option 2', value: 'option_2' },
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a radio group using setters and API data:
|
||||
* ```ts
|
||||
* const radioGroup = new RadioGroupBuilder()
|
||||
* .setCustomId('choose_items')
|
||||
* .setOptions([
|
||||
* { label: 'Item A', value: 'item_a' },
|
||||
* { label: 'Item B', value: 'item_b' },
|
||||
* ])
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: Partial<APIRadioGroupComponent>) {
|
||||
const { options, ...initData } = data ?? {};
|
||||
super({ ...initData, type: ComponentType.RadioGroup });
|
||||
this.options = options?.map((option: APIRadioGroupOption) => new RadioGroupOptionBuilder(option)) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom id of this radio group.
|
||||
*
|
||||
* @param customId - The custom id to use
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options to this radio group.
|
||||
*
|
||||
* @param options - The options to add
|
||||
*/
|
||||
public addOptions(...options: RestOrArray<APIRadioGroupOption | RadioGroupOptionBuilder>) {
|
||||
const normalizedOptions = normalizeArray(options);
|
||||
|
||||
this.options.push(
|
||||
...normalizedOptions.map((normalizedOption) => {
|
||||
// I do this because TS' duck typing causes issues,
|
||||
// if I put in a CheckboxGroupOption, TS lets it pass but
|
||||
// it fails to convert to a checkbox group option at runtime
|
||||
const json = 'toJSON' in normalizedOption ? normalizedOption.toJSON() : normalizedOption;
|
||||
const option = new RadioGroupOptionBuilder(json);
|
||||
radioGroupOptionPredicate.parse(option.toJSON());
|
||||
return option;
|
||||
}),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options for this radio group.
|
||||
*
|
||||
* @param options - The options to use
|
||||
*/
|
||||
public setOptions(...options: RestOrArray<APIRadioGroupOption | RadioGroupOptionBuilder>) {
|
||||
return this.spliceOptions(0, this.options.length, ...options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes, replaces, or inserts options for this radio group.
|
||||
*
|
||||
* @remarks
|
||||
* This method behaves similarly
|
||||
* to {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice()}.
|
||||
* It's useful for modifying and adjusting the order of existing options.
|
||||
* @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<APIRadioGroupOption | RadioGroupOptionBuilder>
|
||||
) {
|
||||
const normalizedOptions = normalizeArray(options);
|
||||
|
||||
const clone = [...this.options];
|
||||
|
||||
clone.splice(
|
||||
index,
|
||||
deleteCount,
|
||||
...normalizedOptions.map((normalizedOption) => {
|
||||
// I do this because TS' duck typing causes issues,
|
||||
// if I put in a CheckboxGroupOption, TS lets it pass but
|
||||
// it fails to convert to a radio group option at runtime
|
||||
const json = 'toJSON' in normalizedOption ? normalizedOption.toJSON() : normalizedOption;
|
||||
const option = new RadioGroupOptionBuilder(json);
|
||||
radioGroupOptionPredicate.parse(option.toJSON());
|
||||
return option;
|
||||
}),
|
||||
);
|
||||
|
||||
this.options.splice(0, this.options.length, ...clone);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether selecting options is required.
|
||||
*
|
||||
* @param required - Whether selecting options is required
|
||||
*/
|
||||
public setRequired(required: boolean) {
|
||||
this.data.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public override toJSON(): APIRadioGroupComponent {
|
||||
const data = {
|
||||
...this.data,
|
||||
options: this.options.map((option) => option.toJSON()),
|
||||
};
|
||||
|
||||
radioGroupPredicate.parse(data);
|
||||
|
||||
return data as APIRadioGroupComponent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import type { JSONEncodable } from '@discordjs/util';
|
||||
import type { APIRadioGroupOption } from 'discord-api-types/v10';
|
||||
import { radioGroupOptionPredicate } from './Assertions';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for radio group options.
|
||||
*/
|
||||
export class RadioGroupOptionBuilder implements JSONEncodable<APIRadioGroupOption> {
|
||||
/**
|
||||
* Creates a new radio group option from API data.
|
||||
*
|
||||
* @param data - The API data to create this radio group option with
|
||||
* @example
|
||||
* Creating a radio group option from an API data object:
|
||||
* ```ts
|
||||
* const option = new RadioGroupOptionBuilder({
|
||||
* label: 'Option 1',
|
||||
* value: 'option_1',
|
||||
* });
|
||||
* ```
|
||||
* @example
|
||||
* Creating a radio group option using setters and API data:
|
||||
* ```ts
|
||||
* const option = new RadioGroupOptionBuilder()
|
||||
* .setLabel('Option 2')
|
||||
* .setValue('option_2');
|
||||
* ```
|
||||
*/
|
||||
public constructor(public data: Partial<APIRadioGroupOption> = {}) {}
|
||||
|
||||
/**
|
||||
* Sets the label for this option.
|
||||
*
|
||||
* @param label - The label to use
|
||||
*/
|
||||
public setLabel(label: string) {
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for this option.
|
||||
*
|
||||
* @param value - The value to use
|
||||
*/
|
||||
public setValue(value: string) {
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description for this option.
|
||||
*
|
||||
* @param description - The description to use
|
||||
*/
|
||||
public setDescription(description: string) {
|
||||
this.data.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this option is selected by default.
|
||||
*
|
||||
* @param isDefault - Whether the option should be selected by default
|
||||
*/
|
||||
public setDefault(isDefault: boolean) {
|
||||
this.data.default = isDefault;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APIRadioGroupOption {
|
||||
radioGroupOptionPredicate.parse(this.data);
|
||||
|
||||
return {
|
||||
...this.data,
|
||||
} as APIRadioGroupOption;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { s } from '@sapphire/shapeshift';
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import { isValidationEnabled } from '../../util/validation.js';
|
||||
import { idValidator } from '../Assertions.js';
|
||||
import { checkboxGroupPredicate, checkboxPredicate, radioGroupPredicate } from '../checkbox/Assertions.js';
|
||||
import { fileUploadPredicate } from '../fileUpload/Assertions.js';
|
||||
import {
|
||||
selectMenuChannelPredicate,
|
||||
@@ -26,6 +27,9 @@ export const labelPredicate = s
|
||||
selectMenuChannelPredicate,
|
||||
selectMenuStringPredicate,
|
||||
fileUploadPredicate,
|
||||
checkboxPredicate,
|
||||
checkboxGroupPredicate,
|
||||
radioGroupPredicate,
|
||||
]),
|
||||
})
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import type {
|
||||
APIChannelSelectComponent,
|
||||
APICheckboxComponent,
|
||||
APICheckboxGroupComponent,
|
||||
APIFileUploadComponent,
|
||||
APILabelComponent,
|
||||
APIMentionableSelectComponent,
|
||||
APIRadioGroupComponent,
|
||||
APIRoleSelectComponent,
|
||||
APIStringSelectComponent,
|
||||
APITextInputComponent,
|
||||
@@ -11,6 +14,9 @@ import type {
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import { ComponentBuilder } from '../Component.js';
|
||||
import { createComponentBuilder, resolveBuilder } from '../Components.js';
|
||||
import { CheckboxBuilder } from '../checkbox/Checkbox.js';
|
||||
import { CheckboxGroupBuilder } from '../checkbox/CheckboxGroup.js';
|
||||
import { RadioGroupBuilder } from '../checkbox/RadioGroup.js';
|
||||
import { FileUploadBuilder } from '../fileUpload/FileUpload.js';
|
||||
import { ChannelSelectMenuBuilder } from '../selectMenu/ChannelSelectMenu.js';
|
||||
import { MentionableSelectMenuBuilder } from '../selectMenu/MentionableSelectMenu.js';
|
||||
@@ -23,8 +29,11 @@ import { labelPredicate } from './Assertions.js';
|
||||
export interface LabelBuilderData extends Partial<Omit<APILabelComponent, 'component'>> {
|
||||
component?:
|
||||
| ChannelSelectMenuBuilder
|
||||
| CheckboxBuilder
|
||||
| CheckboxGroupBuilder
|
||||
| FileUploadBuilder
|
||||
| MentionableSelectMenuBuilder
|
||||
| RadioGroupBuilder
|
||||
| RoleSelectMenuBuilder
|
||||
| StringSelectMenuBuilder
|
||||
| TextInputBuilder
|
||||
@@ -194,6 +203,42 @@ export class LabelBuilder extends ComponentBuilder<LabelBuilderData> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a checkbox component to this label.
|
||||
*
|
||||
* @param input - A function that returns a component builder or an already built builder
|
||||
*/
|
||||
public setCheckboxComponent(
|
||||
input: APICheckboxComponent | CheckboxBuilder | ((builder: CheckboxBuilder) => CheckboxBuilder),
|
||||
): this {
|
||||
this.data.component = resolveBuilder(input, CheckboxBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a checkbox group component to this label.
|
||||
*
|
||||
* @param input - A function that returns a component builder or an already built builder
|
||||
*/
|
||||
public setCheckboxGroupComponent(
|
||||
input: APICheckboxGroupComponent | CheckboxGroupBuilder | ((builder: CheckboxGroupBuilder) => CheckboxGroupBuilder),
|
||||
): this {
|
||||
this.data.component = resolveBuilder(input, CheckboxGroupBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a radio group component to this label.
|
||||
*
|
||||
* @param input - A function that returns a component builder or an already built builder
|
||||
*/
|
||||
public setRadioGroupComponent(
|
||||
input: APIRadioGroupComponent | RadioGroupBuilder | ((builder: RadioGroupBuilder) => RadioGroupBuilder),
|
||||
): this {
|
||||
this.data.component = resolveBuilder(input, RadioGroupBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Result, s } from '@sapphire/shapeshift';
|
||||
import { ChannelType, ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10';
|
||||
import { isValidationEnabled } from '../../util/validation.js';
|
||||
import { customIdValidator, emojiValidator, idValidator } from '../Assertions.js';
|
||||
import { labelValidator } from '../textInput/Assertions.js';
|
||||
|
||||
const selectMenuBasePredicate = s.object({
|
||||
id: idValidator.optional(),
|
||||
@@ -63,7 +62,7 @@ export const selectMenuUserPredicate = selectMenuBasePredicate
|
||||
|
||||
export const selectMenuStringOptionPredicate = s
|
||||
.object({
|
||||
label: labelValidator,
|
||||
label: s.string().lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100),
|
||||
value: s.string().lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100),
|
||||
description: s.string().lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100).optional(),
|
||||
emoji: emojiValidator.optional(),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ComponentType } from 'discord-api-types/v10';
|
||||
import type { APIStringSelectComponent, APISelectMenuOption } from 'discord-api-types/v10';
|
||||
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
||||
import { jsonOptionValidator, optionsLengthValidator, validateRequiredSelectMenuParameters } from '../Assertions.js';
|
||||
import { optionsLengthValidator, validateRequiredSelectMenuParameters } from '../Assertions.js';
|
||||
import { selectMenuStringOptionPredicate } from './Assertions.js';
|
||||
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||
import { StringSelectMenuOptionBuilder } from './StringSelectMenuOption.js';
|
||||
|
||||
@@ -63,7 +64,7 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
|
||||
...normalizedOptions.map((normalizedOption) =>
|
||||
normalizedOption instanceof StringSelectMenuOptionBuilder
|
||||
? normalizedOption
|
||||
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(normalizedOption)),
|
||||
: new StringSelectMenuOptionBuilder(selectMenuStringOptionPredicate.parse(normalizedOption)),
|
||||
),
|
||||
);
|
||||
return this;
|
||||
@@ -83,7 +84,7 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
|
||||
*
|
||||
* @remarks
|
||||
* This method behaves similarly
|
||||
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice()}.
|
||||
* to {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice()}.
|
||||
* It's useful for modifying and adjusting the order of existing options.
|
||||
* @example
|
||||
* Remove the first option:
|
||||
@@ -120,7 +121,7 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
|
||||
...normalizedOptions.map((normalizedOption) =>
|
||||
normalizedOption instanceof StringSelectMenuOptionBuilder
|
||||
? normalizedOption
|
||||
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(normalizedOption)),
|
||||
: new StringSelectMenuOptionBuilder(selectMenuStringOptionPredicate.parse(normalizedOption)),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ export class ContainerBuilder extends ComponentBuilder<APIContainerComponent> {
|
||||
* },
|
||||
* ],
|
||||
* })
|
||||
* .addComponents(separator, section);
|
||||
* .addSeparatorComponents(separator)
|
||||
* .addSectionComponents(section);
|
||||
* ```
|
||||
*/
|
||||
public constructor({ components, ...data }: Partial<APIContainerComponent> = {}) {
|
||||
|
||||
@@ -31,6 +31,7 @@ export {
|
||||
*/
|
||||
StringSelectMenuOptionBuilder as SelectMenuOptionBuilder,
|
||||
} from './components/selectMenu/StringSelectMenuOption.js';
|
||||
export * as SelectMenuAssertions from './components/selectMenu/Assertions.js';
|
||||
export * from './components/selectMenu/StringSelectMenuOption.js';
|
||||
export * from './components/selectMenu/UserSelectMenu.js';
|
||||
|
||||
@@ -50,6 +51,13 @@ export * from './components/v2/Separator.js';
|
||||
export * from './components/v2/TextDisplay.js';
|
||||
export * from './components/v2/Thumbnail.js';
|
||||
|
||||
export * from './components/checkbox/Checkbox.js';
|
||||
export * from './components/checkbox/CheckboxGroup.js';
|
||||
export * from './components/checkbox/CheckboxGroupOption.js';
|
||||
export * from './components/checkbox/RadioGroup.js';
|
||||
export * from './components/checkbox/RadioGroupOption.js';
|
||||
export * as CheckboxAssertions from './components/checkbox/Assertions.js';
|
||||
|
||||
export * as SlashCommandAssertions from './interactions/slashCommands/Assertions.js';
|
||||
export * from './interactions/slashCommands/SlashCommandBuilder.js';
|
||||
export * from './interactions/slashCommands/SlashCommandSubcommands.js';
|
||||
|
||||
@@ -80,7 +80,8 @@ export class SlashCommandBuilder {
|
||||
}
|
||||
|
||||
export interface SlashCommandBuilder
|
||||
extends SharedNameAndDescription,
|
||||
extends
|
||||
SharedNameAndDescription,
|
||||
SharedSlashCommandOptions<SlashCommandOptionsOnlyBuilder>,
|
||||
SharedSlashCommandSubcommands<SlashCommandSubcommandsOnlyBuilder>,
|
||||
SharedSlashCommand {}
|
||||
@@ -89,7 +90,8 @@ export interface SlashCommandBuilder
|
||||
* An interface specifically for slash command subcommands.
|
||||
*/
|
||||
export interface SlashCommandSubcommandsOnlyBuilder
|
||||
extends SharedNameAndDescription,
|
||||
extends
|
||||
SharedNameAndDescription,
|
||||
SharedSlashCommandSubcommands<SlashCommandSubcommandsOnlyBuilder>,
|
||||
SharedSlashCommand {}
|
||||
|
||||
@@ -97,9 +99,7 @@ export interface SlashCommandSubcommandsOnlyBuilder
|
||||
* An interface specifically for slash command options.
|
||||
*/
|
||||
export interface SlashCommandOptionsOnlyBuilder
|
||||
extends SharedNameAndDescription,
|
||||
SharedSlashCommandOptions<SlashCommandOptionsOnlyBuilder>,
|
||||
SharedSlashCommand {}
|
||||
extends SharedNameAndDescription, SharedSlashCommandOptions<SlashCommandOptionsOnlyBuilder>, SharedSlashCommand {}
|
||||
|
||||
/**
|
||||
* An interface that ensures the `toJSON()` call will return something
|
||||
|
||||
@@ -127,5 +127,4 @@ export class SlashCommandSubcommandBuilder implements ToAPIApplicationCommandOpt
|
||||
}
|
||||
|
||||
export interface SlashCommandSubcommandBuilder
|
||||
extends SharedNameAndDescription,
|
||||
SharedSlashCommandOptions<SlashCommandSubcommandBuilder> {}
|
||||
extends SharedNameAndDescription, SharedSlashCommandOptions<SlashCommandSubcommandBuilder> {}
|
||||
|
||||
@@ -62,6 +62,7 @@ export class SlashCommandIntegerOption
|
||||
}
|
||||
|
||||
export interface SlashCommandIntegerOption
|
||||
extends ApplicationCommandNumericOptionMinMaxValueMixin,
|
||||
extends
|
||||
ApplicationCommandNumericOptionMinMaxValueMixin,
|
||||
ApplicationCommandOptionWithChoicesMixin<number>,
|
||||
ApplicationCommandOptionWithAutocompleteMixin {}
|
||||
|
||||
@@ -62,6 +62,7 @@ export class SlashCommandNumberOption
|
||||
}
|
||||
|
||||
export interface SlashCommandNumberOption
|
||||
extends ApplicationCommandNumericOptionMinMaxValueMixin,
|
||||
extends
|
||||
ApplicationCommandNumericOptionMinMaxValueMixin,
|
||||
ApplicationCommandOptionWithChoicesMixin<number>,
|
||||
ApplicationCommandOptionWithAutocompleteMixin {}
|
||||
|
||||
@@ -69,5 +69,4 @@ export class SlashCommandStringOption extends ApplicationCommandOptionBase {
|
||||
}
|
||||
|
||||
export interface SlashCommandStringOption
|
||||
extends ApplicationCommandOptionWithChoicesMixin<string>,
|
||||
ApplicationCommandOptionWithAutocompleteMixin {}
|
||||
extends ApplicationCommandOptionWithChoicesMixin<string>, ApplicationCommandOptionWithAutocompleteMixin {}
|
||||
|
||||
@@ -64,17 +64,17 @@
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -68,25 +68,25 @@
|
||||
"@discordjs/rest": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@discordjs/ws": "workspace:^",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@sapphire/snowflake": "^3.5.5",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.33"
|
||||
"discord-api-types": "^0.38.40"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -17,8 +17,7 @@ import {
|
||||
import type { WebhooksAPI } from './webhook.js';
|
||||
|
||||
export interface CreateInteractionResponseOptions
|
||||
extends APIInteractionResponseCallbackData,
|
||||
RESTPostAPIInteractionCallbackQuery {
|
||||
extends APIInteractionResponseCallbackData, RESTPostAPIInteractionCallbackQuery {
|
||||
files?: RawFile[];
|
||||
}
|
||||
|
||||
|
||||
@@ -58,18 +58,18 @@
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@types/prompts": "^2.4.9",
|
||||
"@types/validate-npm-package-name": "^4.0.2",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"terser": "^5.31.0",
|
||||
"tsup": "^8.2.4",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"terser": "^5.46.0",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "~5.5.4",
|
||||
"typescript": "~5.8.3",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "~5.5.4",
|
||||
"typescript": "~5.8.3",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,32 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [14.26.0](https://github.com/discordjs/discord.js/compare/14.25.1...14.26.0) - (2026-03-31)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Remove manage messages check for pinnable (#11453) ([1a0da18](https://github.com/discordjs/discord.js/commit/1a0da18b3611a31553fd5250b6f882b755d8d003))
|
||||
- **DJSError:** Differentiate error type (#11295) ([f5b3f84](https://github.com/discordjs/discord.js/commit/f5b3f842e39ec1f211a0017fadb683ae3b372e02))
|
||||
|
||||
## Features
|
||||
|
||||
- Allow partial DMChannel without client user (#11462) ([45bd430](https://github.com/discordjs/discord.js/commit/45bd430c0d55ddb98380ea320fab9dc56211e07a))
|
||||
- Modal radio group and checkbox components for v14 (#11437) ([b42e499](https://github.com/discordjs/discord.js/commit/b42e4994109ee83f3e329e810cc8733cf4176dbe))
|
||||
|
||||
## Refactor
|
||||
|
||||
- **DJSError:** Prefer `this.constructor.name` (#11294) ([e32f0c1](https://github.com/discordjs/discord.js/commit/e32f0c141a4ef17383f7a868e26c26a2878fb4f2))
|
||||
|
||||
## Typings
|
||||
|
||||
- BroadcastEval overload order (#11422) ([16d70b9](https://github.com/discordjs/discord.js/commit/16d70b9232559f505f4d6c1a5b1122ebbac5e35d))
|
||||
|
||||
# [14.25.1](https://github.com/discordjs/discord.js/compare/14.25.0...14.25.1) - (2025-11-21)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **GuildEmojiManager:** Allow `CreateGuildExpressions` for retrieving author data (#11288) ([0d64ea0](https://github.com/discordjs/discord.js/commit/0d64ea0528b1591ef9b856b9bcad52e88e2cbd05))
|
||||
|
||||
# [14.25.0](https://github.com/discordjs/discord.js/compare/14.24.2...14.25.0) - (2025-11-18)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "discord.js",
|
||||
"version": "14.25.0",
|
||||
"version": "14.26.0",
|
||||
"description": "A powerful library for interacting with the Discord API",
|
||||
"scripts": {
|
||||
"test": "pnpm run docs:test && pnpm run test:typescript",
|
||||
@@ -73,31 +73,31 @@
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@discordjs/ws": "^1.2.3",
|
||||
"@sapphire/snowflake": "3.5.3",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"discord-api-types": "^0.38.40",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"magic-bytes.js": "^1.13.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.3"
|
||||
"undici": "6.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/docgen": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^16.18.105",
|
||||
"@typescript-eslint/eslint-plugin": "^8.2.0",
|
||||
"@typescript-eslint/parser": "^8.2.0",
|
||||
"@types/node": "^16.18.126",
|
||||
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
||||
"@typescript-eslint/parser": "^8.56.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dtslint": "4.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-formatter-pretty": "^5.0.0",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier": "^3.8.1",
|
||||
"tsd": "^0.31.1",
|
||||
"tslint": "6.1.3",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4"
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@@ -33,10 +33,16 @@ class GenericAction {
|
||||
const payloadData = {};
|
||||
const id = data.channel_id ?? data.id;
|
||||
|
||||
if (!('recipients' in data)) {
|
||||
// Try to resolve the recipient, but do not add the client user.
|
||||
if ('recipients' in data) {
|
||||
// Try to resolve the recipient, but do not add if already existing in recipients.
|
||||
const recipient = data.author ?? data.user ?? { id: data.user_id };
|
||||
if (recipient.id !== this.client.user.id) payloadData.recipients = [recipient];
|
||||
if (!data.recipients.some(existingRecipient => recipient.id === existingRecipient.id)) {
|
||||
payloadData.recipients = [...data.recipients, recipient];
|
||||
}
|
||||
} else {
|
||||
// Try to resolve the recipient.
|
||||
const recipient = data.author ?? data.user ?? { id: data.user_id };
|
||||
payloadData.recipients = [recipient];
|
||||
}
|
||||
|
||||
if (id !== undefined) payloadData.id = id;
|
||||
|
||||
@@ -21,7 +21,9 @@ class InteractionCreateAction extends Action {
|
||||
const client = this.client;
|
||||
|
||||
// Resolve and cache partial channels for Interaction#channel getter
|
||||
const channel = data.channel && this.getChannel(data.channel);
|
||||
const channel =
|
||||
data.channel &&
|
||||
this.getChannel({ ...data.channel, ...('recipients' in data.channel ? { user: data.user } : undefined) });
|
||||
|
||||
// Do not emit this for interactions that cache messages that are non-text-based.
|
||||
let InteractionClass;
|
||||
|
||||
@@ -11,15 +11,19 @@ const Messages = require('./Messages');
|
||||
* @ignore
|
||||
*/
|
||||
function makeDiscordjsError(Base) {
|
||||
return class DiscordjsError extends Base {
|
||||
return class extends Base {
|
||||
static {
|
||||
Object.defineProperty(this, 'name', { value: `Discordjs${Base.name}` });
|
||||
}
|
||||
|
||||
constructor(code, ...args) {
|
||||
super(message(code, args));
|
||||
this.code = code;
|
||||
Error.captureStackTrace?.(this, DiscordjsError);
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return `${super.name} [${this.code}]`;
|
||||
return `${this.constructor.name} [${this.code}]`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -115,7 +115,8 @@ const Messages = {
|
||||
[DjsErrorCodes.EmojiType]: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
|
||||
[DjsErrorCodes.EmojiManaged]: 'Emoji is managed and has no Author.',
|
||||
[DjsErrorCodes.MissingManageGuildExpressionsPermission]: guild =>
|
||||
`Client must have Manage Guild Expressions permission in guild ${guild} to see emoji authors.`,
|
||||
// eslint-disable-next-line max-len
|
||||
`Client must have Create Guild Expressions or Manage Guild Expressions permission in guild ${guild} to see emoji authors.`,
|
||||
[DjsErrorCodes.MissingManageEmojisAndStickersPermission]: guild =>
|
||||
`Client must have Manage Emojis and Stickers permission in guild ${guild} to see emoji authors.`,
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
||||
|
||||
const { me } = this.guild.members;
|
||||
if (!me) throw new DiscordjsError(ErrorCodes.GuildUncachedMe);
|
||||
if (!me.permissions.has(PermissionFlagsBits.ManageGuildExpressions)) {
|
||||
if (!me.permissions.any(PermissionFlagsBits.CreateGuildExpressions | PermissionFlagsBits.ManageGuildExpressions)) {
|
||||
throw new DiscordjsError(ErrorCodes.MissingManageGuildExpressionsPermission, this.guild);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,12 @@ class UserManager extends CachedManager {
|
||||
* @private
|
||||
*/
|
||||
dmChannel(userId) {
|
||||
const expectedRecipientIds = [userId, this.client.user.id];
|
||||
return (
|
||||
this.client.channels.cache.find(channel => channel.type === ChannelType.DM && channel.recipientId === userId) ??
|
||||
null
|
||||
this.client.channels.cache.find(
|
||||
channel =>
|
||||
channel.type === ChannelType.DM && channel.recipientIds.every(id => expectedRecipientIds.includes(id)),
|
||||
) ?? null
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,16 +30,18 @@ class DMChannel extends BaseChannel {
|
||||
super._patch(data);
|
||||
|
||||
if (data.recipients) {
|
||||
const recipient = data.recipients[0];
|
||||
|
||||
/**
|
||||
* The recipient's id
|
||||
* @type {Snowflake}
|
||||
* The recipients' ids
|
||||
* @type {Snowflake[]}
|
||||
*/
|
||||
this.recipientId = recipient.id;
|
||||
this.recipientIds = [
|
||||
...new Set([...(this.recipientIds ?? []), ...data.recipients.map(recipient => recipient.id)]),
|
||||
];
|
||||
|
||||
if ('username' in recipient || this.client.options.partials.includes(Partials.User)) {
|
||||
this.client.users._add(recipient);
|
||||
for (const recipient of data.recipients) {
|
||||
if ('username' in recipient || this.client.options.partials.includes(Partials.User)) {
|
||||
this.client.users._add(recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +73,18 @@ class DMChannel extends BaseChannel {
|
||||
return this.lastMessageId === undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The recipient's id.
|
||||
* <info>For DMChannel the client user is not a part of this might return a wrong id.
|
||||
* This will return `null` in the next major version.</info>
|
||||
* @type {Snowflake}
|
||||
* @readonly
|
||||
*/
|
||||
get recipientId() {
|
||||
// To not be a breaking change this returns the arbitrary first id if this is not a DMChannel with the client user
|
||||
return this.recipientIds.find(recipientId => recipientId !== this.client.user.id) ?? this.recipientIds[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* The recipient on the other end of the DM
|
||||
* @type {?User}
|
||||
|
||||
@@ -256,7 +256,7 @@ class Invite extends Base {
|
||||
if (!guild.members.me) throw new DiscordjsError(ErrorCodes.GuildUncachedMe);
|
||||
return Boolean(
|
||||
this.channel?.permissionsFor(this.client.user).has(PermissionFlagsBits.ManageChannels, false) ||
|
||||
guild.members.me.permissions.has(PermissionFlagsBits.ManageGuild),
|
||||
guild.members.me.permissions.has(PermissionFlagsBits.ManageGuild),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -711,8 +711,8 @@ class Message extends Base {
|
||||
get editable() {
|
||||
const precheck = Boolean(
|
||||
this.author.id === this.client.user.id &&
|
||||
(!this.guild || this.channel?.viewable) &&
|
||||
this.reference?.type !== MessageReferenceType.Forward,
|
||||
(!this.guild || this.channel?.viewable) &&
|
||||
this.reference?.type !== MessageReferenceType.Forward,
|
||||
);
|
||||
|
||||
// Regardless of permissions thread messages cannot be edited if
|
||||
@@ -788,10 +788,7 @@ class Message extends Base {
|
||||
const permissions = channel?.permissionsFor(this.client.user);
|
||||
if (!permissions) return false;
|
||||
|
||||
return (
|
||||
permissions.has(PermissionFlagsBits.ReadMessageHistory | PermissionFlagsBits.PinMessages) ||
|
||||
permissions.has(PermissionFlagsBits.ReadMessageHistory | PermissionFlagsBits.ManageMessages)
|
||||
);
|
||||
return permissions.has(PermissionFlagsBits.ReadMessageHistory | PermissionFlagsBits.PinMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -820,12 +817,12 @@ class Message extends Base {
|
||||
const { channel } = this;
|
||||
return Boolean(
|
||||
channel?.type === ChannelType.GuildAnnouncement &&
|
||||
!this.flags.has(MessageFlags.Crossposted) &&
|
||||
this.reference?.type !== MessageReferenceType.Forward &&
|
||||
this.type === MessageType.Default &&
|
||||
!this.poll &&
|
||||
channel.viewable &&
|
||||
channel.permissionsFor(this.client.user)?.has(bitfield, false),
|
||||
!this.flags.has(MessageFlags.Crossposted) &&
|
||||
this.reference?.type !== MessageReferenceType.Forward &&
|
||||
this.type === MessageType.Default &&
|
||||
!this.poll &&
|
||||
channel.viewable &&
|
||||
channel.permissionsFor(this.client.user)?.has(bitfield, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,6 +227,37 @@ class ModalSubmitFields {
|
||||
getUploadedFiles(customId, required = false) {
|
||||
return this._getTypedComponent(customId, [ComponentType.FileUpload], ['attachments'], required).attachments ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get radio group component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?string} The selected radio group option value, or null if none were selected and not required
|
||||
*/
|
||||
getRadioGroup(customId, required = false) {
|
||||
return this._getTypedComponent(customId, [ComponentType.RadioGroup], ['value'], required).value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get checkbox group component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @returns {string[]} The selected checkbox group option values
|
||||
*/
|
||||
getCheckboxGroup(customId) {
|
||||
return this._getTypedComponent(customId, [ComponentType.CheckboxGroup]).values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get checkbox component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @returns {boolean} Whether this checkbox was selected
|
||||
*/
|
||||
getCheckbox(customId) {
|
||||
return this._getTypedComponent(customId, [ComponentType.Checkbox]).value;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ModalSubmitFields;
|
||||
|
||||
@@ -24,6 +24,24 @@ const getAttachment = lazy(() => require('./Attachment'));
|
||||
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} RadioGroupModalData
|
||||
* @property {string} customId The custom id of the radio group
|
||||
* @property {?string} value The value selected for the radio group
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} CheckboxGroupModalData
|
||||
* @property {string} customId The custom id of the checkbox group
|
||||
* @property {string[]} values The values selected for the checkbox group
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} CheckboxModalData
|
||||
* @property {string} customId The custom id of the checkbox
|
||||
* @property {boolean} value Whether this checkbox was selected
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} TextInputModalData
|
||||
* @property {string} customId The custom id of the field
|
||||
@@ -45,7 +63,8 @@ const getAttachment = lazy(() => require('./Attachment'));
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData} ModalData
|
||||
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData|RadioGroupModalData|
|
||||
* CheckboxGroupModalData|CheckboxModalData} ModalData
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,8 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
/**
|
||||
* @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData|
|
||||
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData|
|
||||
* FileUploadComponentData} ComponentInLabelData
|
||||
* FileUploadComponentData|RadioGroupComponentData|CheckboxGroupComponentData|
|
||||
* CheckboxComponentData} ComponentInLabelData
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -52,6 +53,44 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
* @property {boolean} [required] Whether this component is required in modals
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RadioGroupOption
|
||||
* @property {string} value The value of the radio group option
|
||||
* @property {string} label The label to use
|
||||
* @property {string} [description] The optional description for the radio group option
|
||||
* @property {boolean} [default] Whether this option is default selected
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} RadioGroupComponentData
|
||||
* @property {string} customId The custom id of the radio group
|
||||
* @property {RadioGroupOption[]} options The options in this radio group (2-10)
|
||||
* @property {boolean} [required] Whether this component is required in modals
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} CheckboxGroupOption
|
||||
* @property {string} value The value of the checkbox group option
|
||||
* @property {string} label The label to use
|
||||
* @property {string} [description] The optional description for the checkbox group option
|
||||
* @property {boolean} [default] Whether this option is default selected
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} CheckboxGroupComponentData
|
||||
* @property {string} customId The custom id of the checkbox group
|
||||
* @property {CheckboxGroupOption[]} options The options in this checkbox group
|
||||
* @property {number} [minValues] The minimum number of options that must be selected (0-10)
|
||||
* @property {number} [maxValues] The maximum number of options that can be selected (defaults to options length)
|
||||
* @property {boolean} [required] Whether this component is required in modals
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} CheckboxComponentData
|
||||
* @property {string} customId The custom id of the checkbox
|
||||
* @property {boolean} [default] Whether this component is default selected in modals
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} BaseSelectMenuComponentData
|
||||
* @property {string} customId The custom id of the select menu
|
||||
|
||||
345
packages/discord.js/typings/index.d.ts
vendored
345
packages/discord.js/typings/index.d.ts
vendored
@@ -340,8 +340,9 @@ export type ActionRowComponentData = MessageActionRowComponentData | ModalAction
|
||||
|
||||
export type ActionRowComponent = MessageActionRowComponent | ModalActionRowComponent;
|
||||
|
||||
export interface ActionRowData<ComponentType extends JSONEncodable<APIComponentInActionRow> | ActionRowComponentData>
|
||||
extends BaseComponentData {
|
||||
export interface ActionRowData<
|
||||
ComponentType extends JSONEncodable<APIComponentInActionRow> | ActionRowComponentData,
|
||||
> extends BaseComponentData {
|
||||
components: readonly ComponentType[];
|
||||
}
|
||||
|
||||
@@ -362,6 +363,9 @@ export class ActionRowBuilder<
|
||||
}
|
||||
|
||||
export type ComponentInLabelData =
|
||||
| CheckboxComponentData
|
||||
| CheckboxGroupComponentData
|
||||
| RadioGroupComponentData
|
||||
| StringSelectMenuComponentData
|
||||
| TextInputComponentData
|
||||
| UserSelectMenuComponentData
|
||||
@@ -1097,8 +1101,7 @@ type AsyncEventIteratorDisposability =
|
||||
ReturnType<typeof EventEmitter.on> extends AsyncDisposable ? AsyncDisposable : {};
|
||||
/** @internal */
|
||||
interface AsyncEventIterator<Params extends any[]>
|
||||
extends AsyncIterableIterator<Params>,
|
||||
AsyncEventIteratorDisposability {
|
||||
extends AsyncIterableIterator<Params>, AsyncEventIteratorDisposability {
|
||||
[Symbol.asyncIterator](): AsyncEventIterator<Params>;
|
||||
}
|
||||
|
||||
@@ -1504,15 +1507,15 @@ export class PrimaryEntryPointCommandInteraction<
|
||||
}
|
||||
|
||||
// tslint:disable-next-line no-empty-interface
|
||||
export interface DMChannel
|
||||
extends Omit<
|
||||
TextBasedChannelFields<false, true>,
|
||||
'bulkDelete' | 'fetchWebhooks' | 'createWebhook' | 'setRateLimitPerUser' | 'setNSFW'
|
||||
> {}
|
||||
export interface DMChannel extends Omit<
|
||||
TextBasedChannelFields<false, true>,
|
||||
'bulkDelete' | 'fetchWebhooks' | 'createWebhook' | 'setRateLimitPerUser' | 'setNSFW'
|
||||
> {}
|
||||
export class DMChannel extends BaseChannel {
|
||||
private constructor(client: Client<true>, data?: RawDMChannelData);
|
||||
public flags: Readonly<ChannelFlagsBitField>;
|
||||
public recipientId: Snowflake;
|
||||
public get recipientId(): Snowflake;
|
||||
public recipientIds: Snowflake[];
|
||||
public get recipient(): User | null;
|
||||
public type: ChannelType.DM;
|
||||
public fetch(force?: boolean): Promise<this>;
|
||||
@@ -2393,9 +2396,9 @@ export interface AwaitMessageCollectorOptionsParams<
|
||||
ComponentType extends MessageComponentType,
|
||||
Cached extends boolean = boolean,
|
||||
> extends Pick<
|
||||
InteractionCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>,
|
||||
keyof AwaitMessageComponentOptions<any>
|
||||
> {
|
||||
InteractionCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>,
|
||||
keyof AwaitMessageComponentOptions<any>
|
||||
> {
|
||||
componentType?: ComponentType;
|
||||
}
|
||||
|
||||
@@ -2805,14 +2808,13 @@ export interface TextInputModalData extends BaseModalData<ComponentType.TextInpu
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface SelectMenuModalData<Cached extends CacheType = CacheType>
|
||||
extends BaseModalData<
|
||||
| ComponentType.ChannelSelect
|
||||
| ComponentType.MentionableSelect
|
||||
| ComponentType.RoleSelect
|
||||
| ComponentType.StringSelect
|
||||
| ComponentType.UserSelect
|
||||
> {
|
||||
export interface SelectMenuModalData<Cached extends CacheType = CacheType> extends BaseModalData<
|
||||
| ComponentType.ChannelSelect
|
||||
| ComponentType.MentionableSelect
|
||||
| ComponentType.RoleSelect
|
||||
| ComponentType.StringSelect
|
||||
| ComponentType.UserSelect
|
||||
> {
|
||||
channels?: ReadonlyCollection<
|
||||
Snowflake,
|
||||
CacheTypeReducer<Cached, GuildBasedChannel, APIInteractionDataResolvedChannel>
|
||||
@@ -2830,7 +2832,28 @@ export interface FileUploadModalData extends BaseModalData<ComponentType.FileUpl
|
||||
attachments: ReadonlyCollection<Snowflake, Attachment>;
|
||||
}
|
||||
|
||||
export type ModalData = FileUploadModalData | SelectMenuModalData | TextInputModalData;
|
||||
export interface RadioGroupModalData extends BaseModalData<ComponentType.RadioGroup> {
|
||||
customId: string;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
export interface CheckboxGroupModalData extends BaseModalData<ComponentType.CheckboxGroup> {
|
||||
customId: string;
|
||||
values: readonly string[];
|
||||
}
|
||||
|
||||
export interface CheckboxModalData extends BaseModalData<ComponentType.Checkbox> {
|
||||
customId: string;
|
||||
value: boolean;
|
||||
}
|
||||
|
||||
export type ModalData =
|
||||
| CheckboxGroupModalData
|
||||
| CheckboxModalData
|
||||
| FileUploadModalData
|
||||
| RadioGroupModalData
|
||||
| SelectMenuModalData
|
||||
| TextInputModalData;
|
||||
|
||||
export interface LabelModalData extends BaseModalData<ComponentType.Label> {
|
||||
component: ModalData;
|
||||
@@ -2909,10 +2932,15 @@ export class ModalSubmitFields<Cached extends CacheType = CacheType> {
|
||||
public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables<Cached> | null;
|
||||
public getUploadedFiles(customId: string, required: true): ReadonlyCollection<Snowflake, Attachment>;
|
||||
public getUploadedFiles(customId: string, required?: boolean): ReadonlyCollection<Snowflake, Attachment> | null;
|
||||
public getRadioGroup(customId: string, required: true): string;
|
||||
public getRadioGroup(customId: string, required?: boolean): string | null;
|
||||
public getCheckboxGroup(customId: string): readonly string[];
|
||||
public getCheckbox(customId: string): boolean;
|
||||
}
|
||||
|
||||
export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType>
|
||||
extends ModalSubmitInteraction<Cached> {
|
||||
export interface ModalMessageModalSubmitInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends ModalSubmitInteraction<Cached> {
|
||||
message: Message<BooleanCache<Cached>>;
|
||||
channelId: Snowflake;
|
||||
update(
|
||||
@@ -2998,19 +3026,18 @@ export class OAuth2Guild extends BaseGuild {
|
||||
public permissions: Readonly<PermissionsBitField>;
|
||||
}
|
||||
|
||||
export interface PartialGroupDMChannel
|
||||
extends Omit<
|
||||
TextBasedChannelFields<false, false>,
|
||||
| 'bulkDelete'
|
||||
| 'send'
|
||||
| 'sendTyping'
|
||||
| 'createMessageCollector'
|
||||
| 'awaitMessages'
|
||||
| 'fetchWebhooks'
|
||||
| 'createWebhook'
|
||||
| 'setRateLimitPerUser'
|
||||
| 'setNSFW'
|
||||
> {}
|
||||
export interface PartialGroupDMChannel extends Omit<
|
||||
TextBasedChannelFields<false, false>,
|
||||
| 'bulkDelete'
|
||||
| 'send'
|
||||
| 'sendTyping'
|
||||
| 'createMessageCollector'
|
||||
| 'awaitMessages'
|
||||
| 'fetchWebhooks'
|
||||
| 'createWebhook'
|
||||
| 'setRateLimitPerUser'
|
||||
| 'setNSFW'
|
||||
> {}
|
||||
export class PartialGroupDMChannel extends BaseChannel {
|
||||
private constructor(client: Client<true>, data: RawPartialGroupDMChannelData);
|
||||
public type: ChannelType.GroupDM;
|
||||
@@ -3045,20 +3072,19 @@ export interface DefaultReactionEmoji {
|
||||
name: string | null;
|
||||
}
|
||||
|
||||
export interface ThreadOnlyChannel
|
||||
extends Omit<
|
||||
TextBasedChannelFields,
|
||||
| 'send'
|
||||
| 'lastMessage'
|
||||
| 'lastPinAt'
|
||||
| 'bulkDelete'
|
||||
| 'sendTyping'
|
||||
| 'createMessageCollector'
|
||||
| 'awaitMessages'
|
||||
| 'createMessageComponentCollector'
|
||||
| 'awaitMessageComponent'
|
||||
| 'messages'
|
||||
> {}
|
||||
export interface ThreadOnlyChannel extends Omit<
|
||||
TextBasedChannelFields,
|
||||
| 'send'
|
||||
| 'lastMessage'
|
||||
| 'lastPinAt'
|
||||
| 'bulkDelete'
|
||||
| 'sendTyping'
|
||||
| 'createMessageCollector'
|
||||
| 'awaitMessages'
|
||||
| 'createMessageComponentCollector'
|
||||
| 'awaitMessageComponent'
|
||||
| 'messages'
|
||||
> {}
|
||||
export abstract class ThreadOnlyChannel extends GuildChannel {
|
||||
public type: ChannelType.GuildForum | ChannelType.GuildMedia;
|
||||
public threads: GuildForumThreadManager;
|
||||
@@ -3518,17 +3544,17 @@ export class ShardClientUtil {
|
||||
public mode: ShardingManagerMode;
|
||||
public parentPort: MessagePort | null;
|
||||
public broadcastEval<Result>(fn: (client: Client) => Awaitable<Result>): Promise<Serialized<Result>[]>;
|
||||
public broadcastEval<Result>(
|
||||
fn: (client: Client) => Awaitable<Result>,
|
||||
options: { shard: number },
|
||||
public broadcastEval<Result, Context>(
|
||||
fn: (client: Client<true>, context: Serialized<Context>) => Awaitable<Result>,
|
||||
options: { context: Context; shard: number },
|
||||
): Promise<Serialized<Result>>;
|
||||
public broadcastEval<Result, Context>(
|
||||
fn: (client: Client<true>, context: Serialized<Context>) => Awaitable<Result>,
|
||||
options: { context: Context },
|
||||
): Promise<Serialized<Result>[]>;
|
||||
public broadcastEval<Result, Context>(
|
||||
fn: (client: Client<true>, context: Serialized<Context>) => Awaitable<Result>,
|
||||
options: { context: Context; shard: number },
|
||||
public broadcastEval<Result>(
|
||||
fn: (client: Client) => Awaitable<Result>,
|
||||
options: { shard: number },
|
||||
): Promise<Serialized<Result>>;
|
||||
public fetchClientValues(prop: string): Promise<unknown[]>;
|
||||
public fetchClientValues(prop: string, shard: number): Promise<unknown>;
|
||||
@@ -3554,17 +3580,17 @@ export class ShardingManager extends EventEmitter {
|
||||
public shardList: number[] | 'auto';
|
||||
public broadcast(message: unknown): Promise<Shard[]>;
|
||||
public broadcastEval<Result>(fn: (client: Client) => Awaitable<Result>): Promise<Serialized<Result>[]>;
|
||||
public broadcastEval<Result>(
|
||||
fn: (client: Client) => Awaitable<Result>,
|
||||
options: { shard: number },
|
||||
public broadcastEval<Result, Context>(
|
||||
fn: (client: Client<true>, context: Serialized<Context>) => Awaitable<Result>,
|
||||
options: { context: Context; shard: number },
|
||||
): Promise<Serialized<Result>>;
|
||||
public broadcastEval<Result, Context>(
|
||||
fn: (client: Client<true>, context: Serialized<Context>) => Awaitable<Result>,
|
||||
options: { context: Context },
|
||||
): Promise<Serialized<Result>[]>;
|
||||
public broadcastEval<Result, Context>(
|
||||
fn: (client: Client<true>, context: Serialized<Context>) => Awaitable<Result>,
|
||||
options: { context: Context; shard: number },
|
||||
public broadcastEval<Result>(
|
||||
fn: (client: Client) => Awaitable<Result>,
|
||||
options: { shard: number },
|
||||
): Promise<Serialized<Result>>;
|
||||
public createShard(id: number): Shard;
|
||||
public fetchClientValues(prop: string): Promise<unknown[]>;
|
||||
@@ -3838,8 +3864,10 @@ export interface PrivateThreadChannel extends ThreadChannel<false> {
|
||||
}
|
||||
|
||||
// tslint:disable-next-line no-empty-interface
|
||||
export interface ThreadChannel<ThreadOnly extends boolean = boolean>
|
||||
extends Omit<TextBasedChannelFields<true>, 'fetchWebhooks' | 'createWebhook' | 'setNSFW'> {}
|
||||
export interface ThreadChannel<ThreadOnly extends boolean = boolean> extends Omit<
|
||||
TextBasedChannelFields<true>,
|
||||
'fetchWebhooks' | 'createWebhook' | 'setNSFW'
|
||||
> {}
|
||||
export class ThreadChannel<ThreadOnly extends boolean = boolean> extends BaseChannel {
|
||||
private constructor(guild: Guild, data: RawThreadChannelData, client?: Client<true>);
|
||||
public archived: boolean | null;
|
||||
@@ -5381,8 +5409,10 @@ export interface PartialTextBasedChannelFields<InGuild extends boolean = boolean
|
||||
send(options: string | MessagePayload | MessageCreateOptions): Promise<Message<InGuild>>;
|
||||
}
|
||||
|
||||
export interface TextBasedChannelFields<InGuild extends boolean = boolean, InDM extends boolean = boolean>
|
||||
extends PartialTextBasedChannelFields<InGuild> {
|
||||
export interface TextBasedChannelFields<
|
||||
InGuild extends boolean = boolean,
|
||||
InDM extends boolean = boolean,
|
||||
> extends PartialTextBasedChannelFields<InGuild> {
|
||||
lastMessageId: Snowflake | null;
|
||||
get lastMessage(): Message | null;
|
||||
lastPinTimestamp: number | null;
|
||||
@@ -5583,24 +5613,30 @@ export interface ApplicationCommandAttachmentOption extends BaseApplicationComma
|
||||
type: ApplicationCommandOptionType.Attachment;
|
||||
}
|
||||
|
||||
export interface ApplicationCommandAutocompleteNumericOption
|
||||
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
|
||||
export interface ApplicationCommandAutocompleteNumericOption extends Omit<
|
||||
BaseApplicationCommandOptionsData,
|
||||
'autocomplete'
|
||||
> {
|
||||
type: CommandOptionNumericResolvableType;
|
||||
minValue?: number;
|
||||
maxValue?: number;
|
||||
autocomplete: true;
|
||||
}
|
||||
|
||||
export interface ApplicationCommandAutocompleteStringOption
|
||||
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
|
||||
export interface ApplicationCommandAutocompleteStringOption extends Omit<
|
||||
BaseApplicationCommandOptionsData,
|
||||
'autocomplete'
|
||||
> {
|
||||
type: ApplicationCommandOptionType.String;
|
||||
minLength?: number;
|
||||
maxLength?: number;
|
||||
autocomplete: true;
|
||||
}
|
||||
|
||||
export interface ApplicationCommandAutocompleteNumericOptionData
|
||||
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
|
||||
export interface ApplicationCommandAutocompleteNumericOptionData extends Omit<
|
||||
BaseApplicationCommandOptionsData,
|
||||
'autocomplete'
|
||||
> {
|
||||
type: CommandOptionNumericResolvableType;
|
||||
minValue?: number;
|
||||
min_value?: number;
|
||||
@@ -5609,8 +5645,10 @@ export interface ApplicationCommandAutocompleteNumericOptionData
|
||||
autocomplete: true;
|
||||
}
|
||||
|
||||
export interface ApplicationCommandAutocompleteStringOptionData
|
||||
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
|
||||
export interface ApplicationCommandAutocompleteStringOptionData extends Omit<
|
||||
BaseApplicationCommandOptionsData,
|
||||
'autocomplete'
|
||||
> {
|
||||
type: ApplicationCommandOptionType.String;
|
||||
minLength?: number;
|
||||
min_length?: number;
|
||||
@@ -5619,15 +5657,19 @@ export interface ApplicationCommandAutocompleteStringOptionData
|
||||
autocomplete: true;
|
||||
}
|
||||
|
||||
export interface ApplicationCommandChoicesData<Type extends string | number = string | number>
|
||||
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
|
||||
export interface ApplicationCommandChoicesData<Type extends string | number = string | number> extends Omit<
|
||||
BaseApplicationCommandOptionsData,
|
||||
'autocomplete'
|
||||
> {
|
||||
type: CommandOptionChoiceResolvableType;
|
||||
choices?: readonly ApplicationCommandOptionChoiceData<Type>[];
|
||||
autocomplete?: false;
|
||||
}
|
||||
|
||||
export interface ApplicationCommandChoicesOption<Type extends string | number = string | number>
|
||||
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
|
||||
export interface ApplicationCommandChoicesOption<Type extends string | number = string | number> extends Omit<
|
||||
BaseApplicationCommandOptionsData,
|
||||
'autocomplete'
|
||||
> {
|
||||
type: CommandOptionChoiceResolvableType;
|
||||
choices?: readonly ApplicationCommandOptionChoiceData<Type>[];
|
||||
autocomplete?: false;
|
||||
@@ -5805,14 +5847,20 @@ export interface AutoModerationTriggerMetadata {
|
||||
mentionRaidProtectionEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface AwaitMessageComponentOptions<Interaction extends CollectedMessageInteraction>
|
||||
extends Omit<MessageComponentCollectorOptions<Interaction>, 'max' | 'maxComponents' | 'maxUsers'> {}
|
||||
export interface AwaitMessageComponentOptions<Interaction extends CollectedMessageInteraction> extends Omit<
|
||||
MessageComponentCollectorOptions<Interaction>,
|
||||
'max' | 'maxComponents' | 'maxUsers'
|
||||
> {}
|
||||
|
||||
export interface ModalSubmitInteractionCollectorOptions<Interaction extends ModalSubmitInteraction>
|
||||
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'message' | 'guild' | 'interactionType'> {}
|
||||
export interface ModalSubmitInteractionCollectorOptions<Interaction extends ModalSubmitInteraction> extends Omit<
|
||||
InteractionCollectorOptions<Interaction>,
|
||||
'channel' | 'message' | 'guild' | 'interactionType'
|
||||
> {}
|
||||
|
||||
export interface AwaitModalSubmitOptions<Interaction extends ModalSubmitInteraction>
|
||||
extends Omit<ModalSubmitInteractionCollectorOptions<Interaction>, 'max' | 'maxComponents' | 'maxUsers'> {
|
||||
export interface AwaitModalSubmitOptions<Interaction extends ModalSubmitInteraction> extends Omit<
|
||||
ModalSubmitInteractionCollectorOptions<Interaction>,
|
||||
'max' | 'maxComponents' | 'maxUsers'
|
||||
> {
|
||||
time: number;
|
||||
}
|
||||
|
||||
@@ -6200,8 +6248,9 @@ export interface BaseInteractionResolvedData<Cached extends CacheType = CacheTyp
|
||||
users?: ReadonlyCollection<Snowflake, User>;
|
||||
}
|
||||
|
||||
export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType>
|
||||
extends BaseInteractionResolvedData<Cached> {
|
||||
export interface CommandInteractionResolvedData<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends BaseInteractionResolvedData<Cached> {
|
||||
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
|
||||
}
|
||||
|
||||
@@ -7240,11 +7289,15 @@ export type CollectedMessageInteraction<Cached extends CacheType = CacheType> =
|
||||
ModalSubmitInteraction
|
||||
>;
|
||||
|
||||
export interface MessageComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
|
||||
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'message' | 'guild' | 'interactionType'> {}
|
||||
export interface MessageComponentCollectorOptions<Interaction extends CollectedMessageInteraction> extends Omit<
|
||||
InteractionCollectorOptions<Interaction>,
|
||||
'channel' | 'message' | 'guild' | 'interactionType'
|
||||
> {}
|
||||
|
||||
export interface MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
|
||||
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'guild' | 'interactionType'> {}
|
||||
export interface MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction> extends Omit<
|
||||
InteractionCollectorOptions<Interaction>,
|
||||
'channel' | 'guild' | 'interactionType'
|
||||
> {}
|
||||
|
||||
export interface MessageInteractionMetadata {
|
||||
id: Snowflake;
|
||||
@@ -7280,25 +7333,24 @@ export interface MessageMentionOptions {
|
||||
|
||||
export type MessageMentionTypes = 'roles' | 'users' | 'everyone';
|
||||
|
||||
export interface MessageSnapshot
|
||||
extends Partialize<
|
||||
Message,
|
||||
null,
|
||||
Exclude<
|
||||
keyof Message,
|
||||
| 'attachments'
|
||||
| 'client'
|
||||
| 'components'
|
||||
| 'content'
|
||||
| 'createdTimestamp'
|
||||
| 'editedTimestamp'
|
||||
| 'embeds'
|
||||
| 'flags'
|
||||
| 'mentions'
|
||||
| 'stickers'
|
||||
| 'type'
|
||||
>
|
||||
> {}
|
||||
export interface MessageSnapshot extends Partialize<
|
||||
Message,
|
||||
null,
|
||||
Exclude<
|
||||
keyof Message,
|
||||
| 'attachments'
|
||||
| 'client'
|
||||
| 'components'
|
||||
| 'content'
|
||||
| 'createdTimestamp'
|
||||
| 'editedTimestamp'
|
||||
| 'embeds'
|
||||
| 'flags'
|
||||
| 'mentions'
|
||||
| 'stickers'
|
||||
| 'type'
|
||||
>
|
||||
> {}
|
||||
|
||||
export interface BaseMessageOptions {
|
||||
content?: string;
|
||||
@@ -7340,8 +7392,7 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
|
||||
}
|
||||
|
||||
export interface GuildForumThreadMessageCreateOptions
|
||||
extends BaseMessageOptions,
|
||||
Pick<MessageCreateOptions, 'flags' | 'stickers'> {}
|
||||
extends BaseMessageOptions, Pick<MessageCreateOptions, 'flags' | 'stickers'> {}
|
||||
|
||||
export interface MessageEditAttachmentData {
|
||||
id: Snowflake;
|
||||
@@ -7447,6 +7498,40 @@ export interface FileUploadComponentData extends BaseComponentData {
|
||||
type: ComponentType.FileUpload;
|
||||
}
|
||||
|
||||
export interface RadioGroupOption {
|
||||
default?: boolean;
|
||||
description?: string;
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
export interface RadioGroupComponentData extends BaseComponentData {
|
||||
customId: string;
|
||||
options: readonly RadioGroupOption[];
|
||||
required?: boolean;
|
||||
type: ComponentType.RadioGroup;
|
||||
}
|
||||
|
||||
export interface CheckboxGroupOption {
|
||||
default?: boolean;
|
||||
description?: string;
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
export interface CheckboxGroupComponentData extends BaseComponentData {
|
||||
customId: string;
|
||||
maxValues?: number;
|
||||
minValues?: number;
|
||||
options: readonly CheckboxGroupOption[];
|
||||
required?: boolean;
|
||||
type: ComponentType.CheckboxGroup;
|
||||
}
|
||||
|
||||
export interface CheckboxComponentData extends BaseComponentData {
|
||||
customId: string;
|
||||
default?: boolean;
|
||||
type: ComponentType.Checkbox;
|
||||
}
|
||||
|
||||
export type MessageTarget =
|
||||
| Interaction
|
||||
| InteractionWebhook
|
||||
@@ -7549,18 +7634,20 @@ export interface PartialDMChannel extends Partialize<DMChannel, null, null, 'las
|
||||
|
||||
export interface PartialGuildMember extends Partialize<GuildMember, 'joinedAt' | 'joinedTimestamp' | 'pending'> {}
|
||||
|
||||
export interface PartialMessage<InGuild extends boolean = boolean>
|
||||
extends Partialize<Message<InGuild>, 'type' | 'system' | 'pinned' | 'tts', 'content' | 'cleanContent' | 'author'> {}
|
||||
export interface PartialMessage<InGuild extends boolean = boolean> extends Partialize<
|
||||
Message<InGuild>,
|
||||
'type' | 'system' | 'pinned' | 'tts',
|
||||
'content' | 'cleanContent' | 'author'
|
||||
> {}
|
||||
|
||||
export interface PartialMessageReaction extends Partialize<MessageReaction, 'count'> {}
|
||||
|
||||
export interface PartialPoll
|
||||
extends Partialize<
|
||||
Poll,
|
||||
'allowMultiselect' | 'layoutType' | 'expiresTimestamp',
|
||||
null,
|
||||
'question' | 'message' | 'answers'
|
||||
> {
|
||||
export interface PartialPoll extends Partialize<
|
||||
Poll,
|
||||
'allowMultiselect' | 'layoutType' | 'expiresTimestamp',
|
||||
null,
|
||||
'question' | 'message' | 'answers'
|
||||
> {
|
||||
question: { text: null };
|
||||
message: PartialMessage;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
@@ -7571,8 +7658,11 @@ export interface PartialPollAnswer extends Partialize<PollAnswer, 'emoji' | 'tex
|
||||
readonly poll: PartialPoll;
|
||||
}
|
||||
|
||||
export interface PartialGuildScheduledEvent
|
||||
extends Partialize<GuildScheduledEvent, 'userCount', 'status' | 'privacyLevel' | 'name' | 'entityType'> {}
|
||||
export interface PartialGuildScheduledEvent extends Partialize<
|
||||
GuildScheduledEvent,
|
||||
'userCount',
|
||||
'status' | 'privacyLevel' | 'name' | 'entityType'
|
||||
> {}
|
||||
|
||||
export interface PartialThreadMember extends Partialize<ThreadMember, 'flags' | 'joinedAt' | 'joinedTimestamp'> {}
|
||||
|
||||
@@ -7912,8 +8002,7 @@ export interface WebhookMessageEditOptions extends MessageEditOptions {
|
||||
}
|
||||
|
||||
export interface InteractionEditReplyOptions
|
||||
extends WebhookMessageEditOptions,
|
||||
Pick<BaseMessageOptionsWithPoll, 'poll'> {
|
||||
extends WebhookMessageEditOptions, Pick<BaseMessageOptionsWithPoll, 'poll'> {
|
||||
message?: MessageResolvable | '@original';
|
||||
}
|
||||
|
||||
@@ -7921,8 +8010,10 @@ export interface WebhookFetchMessageOptions {
|
||||
threadId?: Snowflake;
|
||||
}
|
||||
|
||||
export interface WebhookMessageCreateOptions
|
||||
extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers' | 'forward'> {
|
||||
export interface WebhookMessageCreateOptions extends Omit<
|
||||
MessageCreateOptions,
|
||||
'nonce' | 'reply' | 'stickers' | 'forward'
|
||||
> {
|
||||
username?: string;
|
||||
avatarURL?: string;
|
||||
threadId?: Snowflake;
|
||||
|
||||
@@ -68,15 +68,15 @@
|
||||
"devDependencies": {
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/jsdoc-to-markdown": "^7.0.6",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4"
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@@ -55,23 +55,23 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.38.33"
|
||||
"discord-api-types": "^0.38.40"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^16.18.105",
|
||||
"@types/node": "^16.18.126",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -697,7 +697,6 @@ export function email<Email extends string>(
|
||||
*/
|
||||
export function email<Email extends string>(email: Email, headers?: Record<string, string | readonly string[]>) {
|
||||
if (headers) {
|
||||
// eslint-disable-next-line n/prefer-global/url-search-params
|
||||
const searchParams = new URLSearchParams(
|
||||
Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
|
||||
);
|
||||
|
||||
@@ -72,23 +72,23 @@
|
||||
"@discordjs/rest": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@discordjs/ws": "workspace:^",
|
||||
"discord-api-types": "^0.38.33"
|
||||
"discord-api-types": "^0.38.40"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -50,15 +50,15 @@
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4"
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@@ -68,25 +68,25 @@
|
||||
"@discordjs/rest": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.1"
|
||||
"undici": "6.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"supertest": "^7.0.0",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"supertest": "^7.2.2",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [@discordjs/rest@2.6.1](https://github.com/discordjs/discord.js/compare/@discordjs/rest@2.6.0...@discordjs/rest@2.6.1) - (2026-03-22)
|
||||
|
||||
# [@discordjs/rest@2.6.0](https://github.com/discordjs/discord.js/compare/@discordjs/rest@2.5.1...@discordjs/rest@2.6.0) - (2025-08-20)
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/rest",
|
||||
"version": "2.6.0",
|
||||
"version": "2.6.1",
|
||||
"description": "The REST API for discord.js",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
@@ -86,12 +86,12 @@
|
||||
"@discordjs/collection": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@sapphire/async-queue": "^1.5.3",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@sapphire/snowflake": "^3.5.5",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"discord-api-types": "^0.38.40",
|
||||
"magic-bytes.js": "^1.13.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.3"
|
||||
"undici": "6.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
@@ -101,12 +101,12 @@
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.5.4",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
|
||||
@@ -229,8 +229,10 @@ export interface APIRequest {
|
||||
route: string;
|
||||
}
|
||||
|
||||
export interface ResponseLike
|
||||
extends Pick<Response, 'arrayBuffer' | 'bodyUsed' | 'headers' | 'json' | 'ok' | 'status' | 'statusText' | 'text'> {
|
||||
export interface ResponseLike extends Pick<
|
||||
Response,
|
||||
'arrayBuffer' | 'bodyUsed' | 'headers' | 'json' | 'ok' | 'status' | 'statusText' | 'text'
|
||||
> {
|
||||
body: Readable | ReadableStream | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@actions/glob": "^0.5.0",
|
||||
"@actions/glob": "^0.5.1",
|
||||
"@discordjs/api-extractor-model": "workspace:^",
|
||||
"@discordjs/api-extractor-utils": "workspace:^",
|
||||
"@microsoft/tsdoc": "0.14.2",
|
||||
@@ -68,22 +68,22 @@
|
||||
"@vercel/postgres": "^0.9.0",
|
||||
"commander": "^12.1.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.1",
|
||||
"yaml": "^2.5.0"
|
||||
"undici": "6.24.1",
|
||||
"yaml": "^2.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@turbo/gen": "^2.0.14",
|
||||
"@types/node": "^18.19.45",
|
||||
"@turbo/gen": "^2.8.10",
|
||||
"@types/node": "^18.19.130",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"env-cmd": "^10.1.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -63,14 +63,14 @@
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@storybook/addon-essentials": "^8.1.5",
|
||||
"@storybook/addon-interactions": "^8.1.5",
|
||||
"@storybook/addon-links": "^8.1.5",
|
||||
"@storybook/addon-links": "^8.6.17",
|
||||
"@storybook/addon-styling": "^1.3.7",
|
||||
"@storybook/blocks": "^8.1.5",
|
||||
"@storybook/react": "^8.1.5",
|
||||
"@storybook/react-vite": "^8.1.5",
|
||||
"@storybook/react": "^8.6.17",
|
||||
"@storybook/react-vite": "^8.6.17",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/node": "^18.19.130",
|
||||
"@types/react": "^18.3.28",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@unocss/eslint-plugin": "^0.60.4",
|
||||
"@unocss/reset": "^0.60.4",
|
||||
@@ -78,14 +78,14 @@
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"chromatic": "^11.5.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier": "^3.8.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"storybook": "^8.1.5",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"storybook": "^8.6.17",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"unocss": "^0.60.4",
|
||||
"vite": "^5.2.12",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
|
||||
@@ -62,24 +62,24 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.38.33"
|
||||
"discord-api-types": "^0.38.40"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^16.18.105",
|
||||
"@types/node": "^16.18.126",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier": "^3.8.1",
|
||||
"tsd": "^0.31.1",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -64,14 +64,14 @@
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@types/ws": "^8.5.12",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"discord-api-types": "^0.38.40",
|
||||
"prism-media": "^1.3.5",
|
||||
"tslib": "^2.6.3",
|
||||
"ws": "^8.18.0"
|
||||
"ws": "^8.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.6",
|
||||
"@babel/preset-env": "^7.24.6",
|
||||
"@babel/core": "^7.29.0",
|
||||
"@babel/preset-env": "^7.29.0",
|
||||
"@babel/preset-typescript": "^7.24.6",
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
@@ -80,17 +80,17 @@
|
||||
"@types/node": "^18.19.130",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"jest-websocket-mock": "^2.5.0",
|
||||
"mock-socket": "^9.3.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"typescript": "~5.5.4"
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@@ -79,28 +79,28 @@
|
||||
"@sapphire/async-queue": "^1.5.3",
|
||||
"@types/ws": "^8.5.12",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.33",
|
||||
"discord-api-types": "^0.38.40",
|
||||
"tslib": "^2.6.3",
|
||||
"ws": "^8.18.0"
|
||||
"ws": "^8.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^4.1.0",
|
||||
"@types/node": "^18.19.45",
|
||||
"@types/node": "^18.19.130",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild-plugin-version-injector": "^1.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-neon": "^0.1.62",
|
||||
"eslint-formatter-pretty": "^6.0.1",
|
||||
"mock-socket": "^9.3.1",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier": "^3.8.1",
|
||||
"tsd": "^0.31.1",
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"undici": "6.21.3",
|
||||
"tsup": "^8.5.1",
|
||||
"turbo": "^2.8.10",
|
||||
"typescript": "~5.8.3",
|
||||
"undici": "6.24.1",
|
||||
"vitest": "^2.0.5",
|
||||
"zlib-sync": "^0.1.10"
|
||||
},
|
||||
|
||||
@@ -2,22 +2,21 @@ import type { Awaitable } from '@discordjs/util';
|
||||
import type { APIGatewayBotInfo } from 'discord-api-types/v10';
|
||||
import type { SessionInfo, WebSocketManager, WebSocketManagerOptions } from '../../ws/WebSocketManager.js';
|
||||
|
||||
export interface FetchingStrategyOptions
|
||||
extends Pick<
|
||||
WebSocketManagerOptions,
|
||||
| 'compression'
|
||||
| 'encoding'
|
||||
| 'handshakeTimeout'
|
||||
| 'helloTimeout'
|
||||
| 'identifyProperties'
|
||||
| 'initialPresence'
|
||||
| 'intents'
|
||||
| 'largeThreshold'
|
||||
| 'readyTimeout'
|
||||
| 'token'
|
||||
| 'useIdentifyCompression'
|
||||
| 'version'
|
||||
> {
|
||||
export interface FetchingStrategyOptions extends Pick<
|
||||
WebSocketManagerOptions,
|
||||
| 'compression'
|
||||
| 'encoding'
|
||||
| 'handshakeTimeout'
|
||||
| 'helloTimeout'
|
||||
| 'identifyProperties'
|
||||
| 'initialPresence'
|
||||
| 'intents'
|
||||
| 'largeThreshold'
|
||||
| 'readyTimeout'
|
||||
| 'token'
|
||||
| 'useIdentifyCompression'
|
||||
| 'version'
|
||||
> {
|
||||
readonly gatewayInformation: APIGatewayBotInfo;
|
||||
readonly shardCount: number;
|
||||
}
|
||||
|
||||
@@ -195,8 +195,7 @@ export interface OptionalWebSocketManagerOptions {
|
||||
export interface WebSocketManagerOptions extends OptionalWebSocketManagerOptions, RequiredWebSocketManagerOptions {}
|
||||
|
||||
export interface CreateWebSocketManagerOptions
|
||||
extends Partial<OptionalWebSocketManagerOptions>,
|
||||
RequiredWebSocketManagerOptions {}
|
||||
extends Partial<OptionalWebSocketManagerOptions>, RequiredWebSocketManagerOptions {}
|
||||
|
||||
export interface ManagerShardEventsMap {
|
||||
[WebSocketShardEvents.Closed]: [code: number, shardId: number];
|
||||
|
||||
8662
pnpm-lock.yaml
generated
8662
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user