mirror of
https://github.com/discordjs/discord.js.git
synced 2026-05-23 12:00:09 +00:00
Compare commits
62 Commits
@discordjs
...
@discordjs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2f7d3ad54 | ||
|
|
b532df61ed | ||
|
|
d60e0bf30b | ||
|
|
baa08b8fbb | ||
|
|
f469f74aca | ||
|
|
90d3b28268 | ||
|
|
a271e9b51e | ||
|
|
8ac0e1e5d6 | ||
|
|
9d6fdf8979 | ||
|
|
cafe58b3bd | ||
|
|
7eca844f6d | ||
|
|
63f5261f4c | ||
|
|
5be774db64 | ||
|
|
b36b751bde | ||
|
|
500712d5ea | ||
|
|
040c66ae15 | ||
|
|
82378fc2e8 | ||
|
|
d4f742e99e | ||
|
|
51ceb203fa | ||
|
|
1404e32849 | ||
|
|
9fc3e5ea72 | ||
|
|
19e74b1533 | ||
|
|
de22a10038 | ||
|
|
8ab30cdefa | ||
|
|
c2a43b685e | ||
|
|
507b696792 | ||
|
|
15f7571243 | ||
|
|
3fa429c7df | ||
|
|
7713627fd1 | ||
|
|
6a5c0fb32d | ||
|
|
eb5acd1e30 | ||
|
|
127021d5ab | ||
|
|
0943bc2efb | ||
|
|
a1c83c17d6 | ||
|
|
c0eae344c2 | ||
|
|
f2f757ce52 | ||
|
|
65cfa3ffd3 | ||
|
|
ee2eb7349f | ||
|
|
2d19163d76 | ||
|
|
9bca4af5fd | ||
|
|
fe5e344adc | ||
|
|
c8f6066d6a | ||
|
|
7e21a9474e | ||
|
|
d0a535ea6a | ||
|
|
8124fc68be | ||
|
|
dbd5354056 | ||
|
|
2ebb5cbd53 | ||
|
|
096cd92b87 | ||
|
|
37ef57b880 | ||
|
|
e3c247e423 | ||
|
|
5f3fc170fb | ||
|
|
20fade2a87 | ||
|
|
e827644b5a | ||
|
|
62815928ab | ||
|
|
7fb6630c02 | ||
|
|
737b80b5f2 | ||
|
|
481ccd228b | ||
|
|
a3fff7b8be | ||
|
|
8cdbe23766 | ||
|
|
d920933dc5 | ||
|
|
2d817df3b5 | ||
|
|
1605a2c289 |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,5 +1,5 @@
|
||||
# Learn how to add code owners here:
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
# https://help.github.com/articles/about-code-owners
|
||||
|
||||
* @iCrawl
|
||||
|
||||
|
||||
2
.github/workflows/cleanup-cache.yml
vendored
2
.github/workflows/cleanup-cache.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
|
||||
# https://docs.github.com/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
|
||||
name: Cleanup caches
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
48
.github/workflows/documentation.yml
vendored
48
.github/workflows/documentation.yml
vendored
@@ -103,7 +103,15 @@ jobs:
|
||||
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 }}
|
||||
@@ -113,7 +121,15 @@ jobs:
|
||||
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: ./main/packages/actions/src/uploadDocumentation
|
||||
with:
|
||||
package: ${{ steps.extract-tag.outputs.package }}
|
||||
@@ -123,6 +139,10 @@ jobs:
|
||||
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 }}
|
||||
@@ -132,6 +152,10 @@ jobs:
|
||||
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: ./main/packages/actions/src/uploadSplitDocumentation
|
||||
with:
|
||||
package: ${{ steps.extract-tag.outputs.package }}
|
||||
@@ -155,26 +179,50 @@ jobs:
|
||||
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
|
||||
|
||||
@@ -41,28 +41,32 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/glob": "^0.5.0",
|
||||
"@aws-sdk/client-s3": "^3.787.0",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@vercel/blob": "^0.23.4",
|
||||
"@vercel/blob": "^0.27.3",
|
||||
"@vercel/postgres": "^0.9.0",
|
||||
"cloudflare": "^4.2.0",
|
||||
"meilisearch": "^0.38.0",
|
||||
"p-limit": "^6.1.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.1"
|
||||
"p-limit": "^6.2.0",
|
||||
"p-queue": "^8.1.0",
|
||||
"tslib": "^2.8.1",
|
||||
"undici": "7.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.19.45",
|
||||
"@vitest/coverage-v8": "^2.0.5",
|
||||
"@types/node": "^22.14.0",
|
||||
"@vitest/coverage-v8": "^3.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"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",
|
||||
"vitest": "^2.0.5"
|
||||
"prettier": "^3.5.3",
|
||||
"terser": "^5.37.0",
|
||||
"tsup": "^8.4.0",
|
||||
"turbo": "^2.5.0",
|
||||
"typescript": "~5.8.3",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@@ -9,7 +9,7 @@ runs:
|
||||
with:
|
||||
swap-size-gb: 10
|
||||
|
||||
- uses: pnpm/action-setup@v4.0.0
|
||||
- uses: pnpm/action-setup@v4.1.0
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
/* eslint-disable @typescript-eslint/no-loop-func */
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import process from 'node:process';
|
||||
import { getInput, setFailed } from '@actions/core';
|
||||
import { create } from '@actions/glob';
|
||||
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
||||
import { put } from '@vercel/blob';
|
||||
import { createPool } from '@vercel/postgres';
|
||||
import Cloudflare from 'cloudflare';
|
||||
import pLimit from 'p-limit';
|
||||
|
||||
if (!process.env.DATABASE_URL) {
|
||||
setFailed('DATABASE_URL is not set');
|
||||
if (
|
||||
!process.env.DATABASE_URL ||
|
||||
!process.env.CF_R2_DOCS_URL ||
|
||||
!process.env.CF_R2_DOCS_ACCESS_KEY_ID ||
|
||||
!process.env.CF_R2_DOCS_SECRET_ACCESS_KEY ||
|
||||
!process.env.CF_R2_DOCS_BUCKET ||
|
||||
!process.env.CF_R2_DOCS_BUCKET_URL ||
|
||||
!process.env.CF_D1_DOCS_API_KEY ||
|
||||
!process.env.CF_D1_DOCS_ID ||
|
||||
!process.env.CF_ACCOUNT_ID
|
||||
) {
|
||||
setFailed('Missing environment variables');
|
||||
}
|
||||
|
||||
const pkg = getInput('package') || '*';
|
||||
@@ -17,6 +30,21 @@ const pool = createPool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
});
|
||||
|
||||
const S3 = new S3Client({
|
||||
region: 'auto',
|
||||
endpoint: process.env.CF_R2_DOCS_URL!,
|
||||
credentials: {
|
||||
accessKeyId: process.env.CF_R2_DOCS_ACCESS_KEY_ID!,
|
||||
secretAccessKey: process.env.CF_R2_DOCS_SECRET_ACCESS_KEY!,
|
||||
},
|
||||
requestChecksumCalculation: 'WHEN_REQUIRED',
|
||||
responseChecksumValidation: 'WHEN_REQUIRED',
|
||||
});
|
||||
|
||||
const client = new Cloudflare({
|
||||
apiToken: process.env.CF_D1_DOCS_API_KEY,
|
||||
});
|
||||
|
||||
const limit = pLimit(10);
|
||||
const promises = [];
|
||||
|
||||
@@ -26,12 +54,14 @@ for await (const file of globber.globGenerator()) {
|
||||
const data = await readFile(file, 'utf8');
|
||||
try {
|
||||
promises.push(
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
limit(async () => {
|
||||
console.log(`Uploading ${file} with ${version}...`);
|
||||
const json = JSON.parse(data);
|
||||
const name = json.name ?? json.n;
|
||||
const { url } = await put(`${name.replace('@discordjs/', '')}/${version}.json`, data, {
|
||||
|
||||
const key = `${name.replace('@discordjs/', '')}/${version}.json`;
|
||||
|
||||
const { url } = await put(key, data, {
|
||||
access: 'public',
|
||||
addRandomSuffix: false,
|
||||
});
|
||||
@@ -39,6 +69,19 @@ for await (const file of globber.globGenerator()) {
|
||||
'@discordjs/',
|
||||
'',
|
||||
)}, ${version}, ${url}) on conflict (name, version) do update set url = EXCLUDED.url`;
|
||||
|
||||
await S3.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: process.env.CF_R2_DOCS_BUCKET,
|
||||
Key: key,
|
||||
Body: data,
|
||||
}),
|
||||
);
|
||||
await client.d1.database.raw(process.env.CF_D1_DOCS_ID!, {
|
||||
account_id: process.env.CF_ACCOUNT_ID!,
|
||||
sql: `insert into documentation (name, version, url) values (?, ?, ?) on conflict (name, version) do update set url = excluded.url;`,
|
||||
params: [name.replace('@discordjs/', ''), version, process.env.CF_R2_DOCS_BUCKET_URL + '/' + key],
|
||||
});
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,32 +1,82 @@
|
||||
/* eslint-disable @typescript-eslint/no-loop-func */
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { basename, dirname, relative, sep } from 'node:path';
|
||||
import { cwd } from 'node:process';
|
||||
import { getInput } from '@actions/core';
|
||||
import process from 'node:process';
|
||||
import { setTimeout as sleep } from 'node:timers/promises';
|
||||
import { setFailed, getInput } from '@actions/core';
|
||||
import { create } from '@actions/glob';
|
||||
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { put } from '@vercel/blob';
|
||||
import pLimit from 'p-limit';
|
||||
import PQueue from 'p-queue';
|
||||
|
||||
if (
|
||||
!process.env.CF_R2_DOCS_URL ||
|
||||
!process.env.CF_R2_DOCS_ACCESS_KEY_ID ||
|
||||
!process.env.CF_R2_DOCS_SECRET_ACCESS_KEY ||
|
||||
!process.env.CF_R2_DOCS_BUCKET
|
||||
) {
|
||||
setFailed('Missing environment variables');
|
||||
}
|
||||
|
||||
const pkg = getInput('package') || '*';
|
||||
const version = getInput('version') || 'main';
|
||||
|
||||
const limit = pLimit(10);
|
||||
const queue = new PQueue({ concurrency: 10, interval: 60_000, intervalCap: 1_000 });
|
||||
const promises = [];
|
||||
const failedUploads: string[] = [];
|
||||
|
||||
const S3 = new S3Client({
|
||||
region: 'auto',
|
||||
endpoint: process.env.CF_R2_DOCS_URL!,
|
||||
credentials: {
|
||||
accessKeyId: process.env.CF_R2_DOCS_ACCESS_KEY_ID!,
|
||||
secretAccessKey: process.env.CF_R2_DOCS_SECRET_ACCESS_KEY!,
|
||||
},
|
||||
requestChecksumCalculation: 'WHEN_REQUIRED',
|
||||
responseChecksumValidation: 'WHEN_REQUIRED',
|
||||
});
|
||||
|
||||
const globber = await create(`packages/${pkg}/docs/${pkg}/split/*.api.json`);
|
||||
console.log('Glob: ', await globber.glob());
|
||||
for await (const file of globber.globGenerator()) {
|
||||
const data = await readFile(file, 'utf8');
|
||||
const pkgName = dirname(relative(cwd(), file)).split(sep)[1];
|
||||
const pkgName = dirname(relative(process.cwd(), file)).split(sep)[1];
|
||||
try {
|
||||
promises.push(
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
limit(async () => {
|
||||
queue.add(async () => {
|
||||
console.log(`Uploading ${file} with ${version} from ${pkgName}...`);
|
||||
const name = basename(file).replace('main.', '');
|
||||
await put(`rewrite/${pkgName}/${version}.${name}`, data, {
|
||||
access: 'public',
|
||||
addRandomSuffix: false,
|
||||
});
|
||||
async function upload(retries = 0) {
|
||||
try {
|
||||
await put(`rewrite/${pkgName}/${version}.${name}`, data, {
|
||||
access: 'public',
|
||||
addRandomSuffix: false,
|
||||
});
|
||||
await S3.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: process.env.CF_R2_DOCS_BUCKET,
|
||||
Key: `${pkgName}/${version}.${name}`,
|
||||
Body: data,
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
if (retries > 3) {
|
||||
console.error(`Could not upload ${file} after 3 retries`, error);
|
||||
failedUploads.push(name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof error === 'object' && error && 'retryAfter' in error && typeof error.retryAfter === 'number') {
|
||||
await sleep(error.retryAfter * 1_000);
|
||||
return upload(retries + 1);
|
||||
} else {
|
||||
console.error(`Could not upload ${file}`, error);
|
||||
failedUploads.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await upload();
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -36,6 +86,9 @@ for await (const file of globber.globGenerator()) {
|
||||
|
||||
try {
|
||||
await Promise.all(promises);
|
||||
if (failedUploads.length) {
|
||||
setFailed(`Failed to upload ${failedUploads.length} files: ${failedUploads.join(', ')}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
10
packages/actions/tsconfig.test.json
Normal file
10
packages/actions/tsconfig.test.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig.json",
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["__tests__/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -83,7 +83,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/slice | Array.prototype.splice()}.
|
||||
* It's useful for modifying and adjusting the order of existing options.
|
||||
* @example
|
||||
* Remove the first option:
|
||||
|
||||
@@ -125,7 +125,7 @@ export class EmbedBuilder {
|
||||
*
|
||||
* @remarks
|
||||
* This method behaves similarly
|
||||
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice()}.
|
||||
* to {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice()}.
|
||||
* The maximum amount of fields that can be added is 25.
|
||||
*
|
||||
* It's useful for modifying and adjusting order of the already-existing fields of an embed.
|
||||
|
||||
@@ -2,6 +2,18 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [@discordjs/core@2.2.0](https://github.com/discordjs/discord.js/compare/@discordjs/core@2.1.1...@discordjs/core@2.2.0) - (2025-06-25)
|
||||
|
||||
## Features
|
||||
|
||||
- **webhook:** Support `with_components` (#10945) ([7713627](https://github.com/discordjs/discord.js/commit/7713627fd18599a6187b325e1e4bc9a17cf23e21))
|
||||
|
||||
# [@discordjs/core@2.1.1](https://github.com/discordjs/discord.js/compare/@discordjs/core@2.1.0...@discordjs/core@2.1.1) - (2025-06-16)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **guild:** Fix incorrectly-detected deprecated overload ([d0a535e](https://github.com/discordjs/discord.js/commit/d0a535ea6a66861276691a51547adfb2bcef0384))
|
||||
|
||||
# [@discordjs/core@2.1.0](https://github.com/discordjs/discord.js/compare/@discordjs/core@2.0.1...@discordjs/core@2.1.0) - (2025-04-25)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/core",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"description": "A thinly abstracted wrapper around the rest API, and gateway.",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
@@ -70,7 +70,7 @@
|
||||
"@discordjs/ws": "workspace:^",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.1"
|
||||
"discord-api-types": "^0.38.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
@@ -223,9 +223,13 @@ export class ChannelsAPI {
|
||||
public async edit(
|
||||
channelId: Snowflake,
|
||||
body: RESTPatchAPIChannelJSONBody,
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
{ signal, reason }: Pick<RequestData, 'reason' | 'signal'> = {},
|
||||
) {
|
||||
return this.rest.patch(Routes.channel(channelId), { body, signal }) as Promise<RESTPatchAPIChannelResult>;
|
||||
return this.rest.patch(Routes.channel(channelId), {
|
||||
reason,
|
||||
body,
|
||||
signal,
|
||||
}) as Promise<RESTPatchAPIChannelResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,8 +239,8 @@ export class ChannelsAPI {
|
||||
* @param channelId - The id of the channel to delete
|
||||
* @param options - The options for deleting the channel
|
||||
*/
|
||||
public async delete(channelId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
|
||||
return this.rest.delete(Routes.channel(channelId), { signal }) as Promise<RESTDeleteAPIChannelResult>;
|
||||
public async delete(channelId: Snowflake, { signal, reason }: Pick<RequestData, 'reason' | 'signal'> = {}) {
|
||||
return this.rest.delete(Routes.channel(channelId), { signal, reason }) as Promise<RESTDeleteAPIChannelResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,11 +445,12 @@ export class ChannelsAPI {
|
||||
channelId: Snowflake,
|
||||
body: RESTPostAPIChannelThreadsJSONBody,
|
||||
messageId?: Snowflake,
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
{ signal, reason }: Pick<RequestData, 'reason' | 'signal'> = {},
|
||||
) {
|
||||
return this.rest.post(Routes.threads(channelId, messageId), {
|
||||
body,
|
||||
signal,
|
||||
reason,
|
||||
}) as Promise<RESTPostAPIChannelThreadsResult>;
|
||||
}
|
||||
|
||||
@@ -460,7 +465,7 @@ export class ChannelsAPI {
|
||||
public async createForumThread(
|
||||
channelId: Snowflake,
|
||||
{ message, ...optionsBody }: StartForumThreadOptions,
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
{ signal, reason }: Pick<RequestData, 'reason' | 'signal'> = {},
|
||||
) {
|
||||
const { files, ...messageBody } = message;
|
||||
|
||||
@@ -469,7 +474,12 @@ export class ChannelsAPI {
|
||||
message: messageBody,
|
||||
};
|
||||
|
||||
return this.rest.post(Routes.threads(channelId), { files, body, signal }) as Promise<APIThreadChannel>;
|
||||
return this.rest.post(Routes.threads(channelId), {
|
||||
files,
|
||||
body,
|
||||
reason,
|
||||
signal,
|
||||
}) as Promise<APIThreadChannel>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -115,7 +115,7 @@ export class GuildsAPI {
|
||||
* @param options - The options for fetching the guild
|
||||
* @deprecated Use the overload with a query instead.
|
||||
*/
|
||||
public async get(guildId: Snowflake, { signal }?: Pick<RequestData, 'signal'>): Promise<RESTGetAPIGuildResult>;
|
||||
public async get(guildId: Snowflake, { signal }: Pick<RequestData, 'signal'>): Promise<RESTGetAPIGuildResult>;
|
||||
|
||||
/**
|
||||
* Fetches a guild
|
||||
@@ -198,8 +198,8 @@ export class GuildsAPI {
|
||||
* @param guildId - The id of the guild to delete
|
||||
* @param options - The options for deleting this guild
|
||||
*/
|
||||
public async delete(guildId: Snowflake, { signal, reason }: Pick<RequestData, 'reason' | 'signal'> = {}) {
|
||||
await this.rest.delete(Routes.guild(guildId), { reason, signal });
|
||||
public async delete(guildId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
|
||||
await this.rest.delete(Routes.guild(guildId), { signal });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,7 +44,7 @@ export class OAuth2API {
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
return this.rest.post(Routes.oauth2TokenExchange(), {
|
||||
body: makeURLSearchParams(body),
|
||||
body: makeURLSearchParams<RESTPostOAuth2AccessTokenURLEncodedData>(body),
|
||||
passThroughBody: true,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
@@ -66,7 +66,7 @@ export class OAuth2API {
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
return this.rest.post(Routes.oauth2TokenExchange(), {
|
||||
body: makeURLSearchParams(body),
|
||||
body: makeURLSearchParams<RESTPostOAuth2RefreshTokenURLEncodedData>(body),
|
||||
passThroughBody: true,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
type RESTPatchAPIWebhookJSONBody,
|
||||
type RESTPatchAPIWebhookResult,
|
||||
type RESTPatchAPIWebhookWithTokenMessageJSONBody,
|
||||
type RESTPatchAPIWebhookWithTokenMessageQuery,
|
||||
type RESTPatchAPIWebhookWithTokenMessageResult,
|
||||
type RESTPostAPIWebhookWithTokenGitHubQuery,
|
||||
type RESTPostAPIWebhookWithTokenJSONBody,
|
||||
@@ -127,13 +128,14 @@ export class WebhooksAPI {
|
||||
{
|
||||
wait,
|
||||
thread_id,
|
||||
with_components,
|
||||
files,
|
||||
...body
|
||||
}: RESTPostAPIWebhookWithTokenJSONBody & RESTPostAPIWebhookWithTokenQuery & { files?: RawFile[] },
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
return this.rest.post(Routes.webhook(id, token), {
|
||||
query: makeURLSearchParams({ wait, thread_id }),
|
||||
query: makeURLSearchParams({ wait, thread_id, with_components }),
|
||||
files,
|
||||
body,
|
||||
auth: false,
|
||||
@@ -232,13 +234,14 @@ export class WebhooksAPI {
|
||||
messageId: Snowflake,
|
||||
{
|
||||
thread_id,
|
||||
with_components,
|
||||
files,
|
||||
...body
|
||||
}: RESTPatchAPIWebhookWithTokenMessageJSONBody & { files?: RawFile[]; thread_id?: string },
|
||||
}: RESTPatchAPIWebhookWithTokenMessageJSONBody & RESTPatchAPIWebhookWithTokenMessageQuery & { files?: RawFile[] },
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
return this.rest.patch(Routes.webhookMessage(id, token, messageId), {
|
||||
query: makeURLSearchParams({ thread_id }),
|
||||
query: makeURLSearchParams({ thread_id, with_components }),
|
||||
auth: false,
|
||||
body,
|
||||
signal,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/lintstagedrc.schema.json",
|
||||
"*": "prettier --ignore-unknown --write",
|
||||
"{src/**,test/**,typings/**,scripts/**}.{mjs,js,ts}": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint --ext mjs,js,ts --fix"
|
||||
"{src/**,typings/**,scripts/**}.{mjs,js,ts}": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint --ext mjs,js,ts --fix"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,88 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [14.21.0](https://github.com/discordjs/discord.js/compare/14.20.0...14.21.0) - (2025-06-25)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **ClientUser:** Remove token assignment (#10953) ([507b696](https://github.com/discordjs/discord.js/commit/507b696792d61ae49565b4613439aceb08dcf38a))
|
||||
|
||||
## Features
|
||||
|
||||
- **GuildMember:** Add `avatarDecorationData` (#10942) ([15f7571](https://github.com/discordjs/discord.js/commit/15f7571243d5b206141290478fd5164d299c0850))
|
||||
- **ClientApplication:** Add `approximateUserAuthorizationCount` (#10933) ([3fa429c](https://github.com/discordjs/discord.js/commit/3fa429c7dfa3bb3e6f099cd2f068c474a01677b1))
|
||||
|
||||
## Typings
|
||||
|
||||
- **ClientEventTypes:** Add missing `guildSoundboardSoundsUpdate` (#10928) ([c2a43b6](https://github.com/discordjs/discord.js/commit/c2a43b685e01eff878a399e8c00df8e473c185ad))
|
||||
|
||||
# [14.20.0](https://github.com/discordjs/discord.js/compare/14.19.3...14.20.0) - (2025-06-16)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Use resolvePartialEmoji on MessagePayload#options#components (#10910) ([f2f757c](https://github.com/discordjs/discord.js/commit/f2f757ce52b76d5e571f47f9bf1c5188627b80d5))
|
||||
- **ChannelManager:** Remove threads from cache upon deletion (#10883) ([ee2eb73](https://github.com/discordjs/discord.js/commit/ee2eb7349f2467451880baaea54e02074916015f))
|
||||
- **PartialGroupDMChannel:** Prevent `undefined` values (#10889) ([9bca4af](https://github.com/discordjs/discord.js/commit/9bca4af5fdb78fae7b970498db7f93df31f55ef9))
|
||||
|
||||
## Features
|
||||
|
||||
- Backport entrypoint command (#10908) ([c0eae34](https://github.com/discordjs/discord.js/commit/c0eae344c2ed43fa67be9fda8e3d3e479693d2d1))
|
||||
- **BaseInteraction:** Add `attachmentSizeLimit` (#10830) ([7e21a94](https://github.com/discordjs/discord.js/commit/7e21a9474e532c5b22c6e0600c446fca47352617))
|
||||
|
||||
## Performance
|
||||
|
||||
- **Components:** Hash table (#10893) ([2d19163](https://github.com/discordjs/discord.js/commit/2d19163d764705667691430e438499fd330ffb65))
|
||||
|
||||
## Refactor
|
||||
|
||||
- **Client:** Remove `with_expiration` query parameter (#10800) ([c8f6066](https://github.com/discordjs/discord.js/commit/c8f6066d6a0a1fc6ac23a49d66604d95b588af3e))
|
||||
|
||||
# [14.19.3](https://github.com/discordjs/discord.js/compare/14.19.2...14.19.3) - (2025-05-02)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Regression in allowedMentions when replying (#10866) ([2ebb5cb](https://github.com/discordjs/discord.js/commit/2ebb5cbd53d869a52cba4549e7acc417963741cd))
|
||||
|
||||
# [14.19.2](https://github.com/discordjs/discord.js/compare/14.19.1...14.19.2) - (2025-04-28)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **WebSocketManager:** Always emit shardDisconnect on unresumable close (#10826) ([37ef57b](https://github.com/discordjs/discord.js/commit/37ef57b88079db2f87036dfd9d57af9a2e5d1b9f))
|
||||
- **SoundboardSound:** Wrong emoji comparison in `equals` (#10861) ([5f3fc17](https://github.com/discordjs/discord.js/commit/5f3fc170fbfd49fa4f117901578c309f00f65d0b))
|
||||
- AllowedMentions, container, media item `toJSON()` for components v2 (#10852) ([20fade2](https://github.com/discordjs/discord.js/commit/20fade2a875695aa677e32b983320e746fd4d69c))
|
||||
- **Guild:** Cache soundboard sounds when patching (#10857) ([e827644](https://github.com/discordjs/discord.js/commit/e827644b5aecf05f7551e4e31a620894cc7aa71f))
|
||||
- **GuildSoundboardSoundManager:** Value "undefined" is not snowflake (#10854) ([6281592](https://github.com/discordjs/discord.js/commit/62815928aba0baa96b3422a4a7f1c4321c123dc7))
|
||||
|
||||
## Typings
|
||||
|
||||
- **GuildSoundboardSoundEditOptions:** Add missing `reason` (#10863) ([e3c247e](https://github.com/discordjs/discord.js/commit/e3c247e423c91b9d9e1d40d0521b6eddf0bc53c9))
|
||||
|
||||
# [14.19.1](https://github.com/discordjs/discord.js/compare/14.19.0...14.19.1) - (2025-04-26)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Add in `withComponents` to Webhook ([481ccd2](https://github.com/discordjs/discord.js/commit/481ccd228bc240e32ac552475f8427a8042e1add))
|
||||
|
||||
# [14.19.0](https://github.com/discordjs/discord.js/compare/14.18.0...14.19.0) - (2025-04-26)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Set `with_components` when sending components through webhooks ([8cdbe23](https://github.com/discordjs/discord.js/commit/8cdbe23766c6e5fe1e0acc040120e839511fea2c))
|
||||
- **GuildAuditLogEntry:** Fix some incorrect types and runtime logic (#10849) ([d920933](https://github.com/discordjs/discord.js/commit/d920933dc5b3c518754f526a9864582fc2c92a43))
|
||||
- Spread out section components next to accessory ([1605a2c](https://github.com/discordjs/discord.js/commit/1605a2c2894c4bb834c604f13a5a91cdbffac3a8))
|
||||
- Correctly extend CachedManager in GuildSoundboardSoundManager ([532c384](https://github.com/discordjs/discord.js/commit/532c3842bc293c965dd9fee846257c9e0bbb450a))
|
||||
- **MessagePayload:** Preserve existing flags when editing (#10766) ([ebfd526](https://github.com/discordjs/discord.js/commit/ebfd52695e205bccda3ae6f4ec39d4e5e8891ab0))
|
||||
|
||||
## Features
|
||||
|
||||
- Soundboard missing things (#10850) ([2d817df](https://github.com/discordjs/discord.js/commit/2d817df3b5894da84a1990cb4e0cfded8a925e75))
|
||||
- Components v2 in v14 (#10781) ([edace17](https://github.com/discordjs/discord.js/commit/edace17a131f857547163a3acf4bb6fec0c1e415))
|
||||
- Add soundboard in v14 (#10843) ([d3154cf](https://github.com/discordjs/discord.js/commit/d3154cf8f1eb027b5b4921d4048a32f464a3cd85))
|
||||
|
||||
## Typings
|
||||
|
||||
- Make `Client.on()` compatible with esnext.disposable in TS5.6+ (#10773) ([45552fa](https://github.com/discordjs/discord.js/commit/45552faf02c67b5079f34567c0214203cd927d2e))
|
||||
|
||||
# [14.18.0](https://github.com/discordjs/discord.js/compare/14.17.3...14.18.0) - (2025-02-10)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "discord.js",
|
||||
"version": "14.18.0",
|
||||
"version": "14.21.0",
|
||||
"description": "A powerful library for interacting with the Discord API",
|
||||
"scripts": {
|
||||
"test": "pnpm run docs:test && pnpm run test:typescript",
|
||||
@@ -36,7 +36,8 @@
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"typings"
|
||||
"typings/*.d.ts",
|
||||
"typings/*.d.mts"
|
||||
],
|
||||
"contributors": [
|
||||
"Crawl <icrawltogo@gmail.com>",
|
||||
@@ -65,19 +66,19 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.11.1",
|
||||
"@discordjs/builders": "^1.11.2",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.6.1",
|
||||
"@discordjs/rest": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@discordjs/ws": "^1.2.2",
|
||||
"@discordjs/ws": "^1.2.3",
|
||||
"@sapphire/snowflake": "3.5.3",
|
||||
"discord-api-types": "^0.38.1",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.1"
|
||||
"undici": "6.21.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
@@ -277,7 +277,6 @@ class Client extends BaseClient {
|
||||
const code = resolveInviteCode(invite);
|
||||
const query = makeURLSearchParams({
|
||||
with_counts: true,
|
||||
with_expiration: true,
|
||||
guild_scheduled_event_id: options?.guildScheduledEventId,
|
||||
});
|
||||
const data = await this.rest.get(Routes.invite(code), { query });
|
||||
@@ -523,7 +522,7 @@ class Client extends BaseClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
|
||||
* Calls {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
|
||||
* with the client as `this`.
|
||||
* @param {string} script Script to eval
|
||||
* @returns {*}
|
||||
@@ -605,7 +604,7 @@ module.exports = Client;
|
||||
*/
|
||||
|
||||
/**
|
||||
* A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake},
|
||||
* A {@link https://docs.x.com/resources/fundamentals/x-ids Twitter snowflake},
|
||||
* except the epoch is 2015-01-01T00:00:00.000Z.
|
||||
*
|
||||
* If we have a snowflake '266241948824764416' we can represent it as binary:
|
||||
@@ -639,6 +638,11 @@ module.exports = Client;
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external EmojiURLOptions
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/EmojiURLOptions:TypeAlias}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external BaseImageURLOptions
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/BaseImageURLOptions:Interface}
|
||||
|
||||
@@ -9,6 +9,7 @@ const ChatInputCommandInteraction = require('../../structures/ChatInputCommandIn
|
||||
const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction');
|
||||
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
|
||||
const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction');
|
||||
const PrimaryEntryPointCommandInteraction = require('../../structures/PrimaryEntryPointCommandInteraction');
|
||||
const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction');
|
||||
const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction');
|
||||
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
|
||||
@@ -38,6 +39,9 @@ class InteractionCreateAction extends Action {
|
||||
if (channel && !channel.isTextBased()) return;
|
||||
InteractionClass = MessageContextMenuCommandInteraction;
|
||||
break;
|
||||
case ApplicationCommandType.PrimaryEntryPoint:
|
||||
InteractionClass = PrimaryEntryPointCommandInteraction;
|
||||
break;
|
||||
default:
|
||||
client.emit(
|
||||
Events.Debug,
|
||||
|
||||
@@ -19,6 +19,7 @@ const Status = require('../../util/Status');
|
||||
const WebSocketShardEvents = require('../../util/WebSocketShardEvents');
|
||||
|
||||
let zlib;
|
||||
let deprecationEmitted = false;
|
||||
|
||||
try {
|
||||
zlib = require('zlib-sync');
|
||||
@@ -36,10 +37,13 @@ const BeforeReadyWhitelist = [
|
||||
|
||||
const WaitingForGuildEvents = [GatewayDispatchEvents.GuildCreate, GatewayDispatchEvents.GuildDelete];
|
||||
|
||||
const UNRESUMABLE_CLOSE_CODES = [
|
||||
CloseCodes.Normal,
|
||||
GatewayCloseCodes.AlreadyAuthenticated,
|
||||
GatewayCloseCodes.InvalidSeq,
|
||||
const UNRECOVERABLE_CLOSE_CODES = [
|
||||
GatewayCloseCodes.AuthenticationFailed,
|
||||
GatewayCloseCodes.InvalidShard,
|
||||
GatewayCloseCodes.ShardingRequired,
|
||||
GatewayCloseCodes.InvalidAPIVersion,
|
||||
GatewayCloseCodes.InvalidIntents,
|
||||
GatewayCloseCodes.DisallowedIntents,
|
||||
];
|
||||
|
||||
const reasonIsDeprecated = 'the reason property is deprecated, use the code property to determine the reason';
|
||||
@@ -242,7 +246,7 @@ class WebSocketManager extends EventEmitter {
|
||||
this._ws.on(WSWebSocketShardEvents.Closed, ({ code, shardId }) => {
|
||||
const shard = this.shards.get(shardId);
|
||||
shard.emit(WebSocketShardEvents.Close, { code, reason: reasonIsDeprecated, wasClean: true });
|
||||
if (UNRESUMABLE_CLOSE_CODES.includes(code) && this.destroyed) {
|
||||
if (UNRECOVERABLE_CLOSE_CODES.includes(code)) {
|
||||
shard.status = Status.Disconnected;
|
||||
/**
|
||||
* Emitted when a shard's WebSocket disconnects and will no longer reconnect.
|
||||
@@ -251,7 +255,7 @@ class WebSocketManager extends EventEmitter {
|
||||
* @param {number} id The shard id that disconnected
|
||||
*/
|
||||
this.client.emit(Events.ShardDisconnect, { code, reason: reasonIsDeprecated, wasClean: true }, shardId);
|
||||
this.debug([`Shard not resumable: ${code} (${GatewayCloseCodes[code] ?? CloseCodes[code]})`], shardId);
|
||||
this.debug([`Shard not recoverable: ${code} (${GatewayCloseCodes[code] ?? CloseCodes[code]})`], shardId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -376,6 +380,22 @@ class WebSocketManager extends EventEmitter {
|
||||
/**
|
||||
* Emitted when the client becomes ready to start working.
|
||||
* @event Client#ready
|
||||
* @deprecated Use {@link Client#event:clientReady} instead.
|
||||
* @param {Client} client The client
|
||||
*/
|
||||
if (this.client.emit('ready', this.client) && !deprecationEmitted) {
|
||||
deprecationEmitted = true;
|
||||
|
||||
process.emitWarning(
|
||||
// eslint-disable-next-line max-len
|
||||
'The ready event has been renamed to clientReady to distinguish it from the gateway READY event and will only emit under that name in v15. Please use clientReady instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitted when the client becomes ready to start working.
|
||||
* @event Client#clientReady
|
||||
* @param {Client} client The client
|
||||
*/
|
||||
this.client.emit(Events.ClientReady, this.client);
|
||||
|
||||
@@ -126,6 +126,7 @@ exports.CommandInteractionOptionResolver = require('./structures/CommandInteract
|
||||
exports.Component = require('./structures/Component');
|
||||
exports.ContainerComponent = require('./structures/ContainerComponent');
|
||||
exports.ContextMenuCommandInteraction = require('./structures/ContextMenuCommandInteraction');
|
||||
exports.DirectoryChannel = require('./structures/DirectoryChannel');
|
||||
exports.DMChannel = require('./structures/DMChannel');
|
||||
exports.Embed = require('./structures/Embed');
|
||||
exports.EmbedBuilder = require('./structures/EmbedBuilder');
|
||||
@@ -180,6 +181,7 @@ exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel');
|
||||
exports.PermissionOverwrites = require('./structures/PermissionOverwrites');
|
||||
exports.Poll = require('./structures/Poll').Poll;
|
||||
exports.PollAnswer = require('./structures/PollAnswer').PollAnswer;
|
||||
exports.PrimaryEntryPointCommandInteraction = require('./structures/PrimaryEntryPointCommandInteraction');
|
||||
exports.Presence = require('./structures/Presence').Presence;
|
||||
exports.ReactionCollector = require('./structures/ReactionCollector');
|
||||
exports.ReactionEmoji = require('./structures/ReactionEmoji');
|
||||
|
||||
@@ -261,6 +261,7 @@ class ApplicationCommandManager extends CachedManager {
|
||||
dm_permission: command.dmPermission ?? command.dm_permission,
|
||||
integration_types: command.integrationTypes ?? command.integration_types,
|
||||
contexts: command.contexts,
|
||||
handler: command.handler,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,13 @@ class ChannelManager extends CachedManager {
|
||||
|
||||
channel?.parent?.threads?.cache.delete(id);
|
||||
this.cache.delete(id);
|
||||
|
||||
if (channel?.threads) {
|
||||
for (const threadId of channel.threads.cache.keys()) {
|
||||
this.cache.delete(threadId);
|
||||
channel.guild?.channels.cache.delete(threadId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -230,13 +230,13 @@ class GuildChannelManager extends CachedManager {
|
||||
async createWebhook({ channel, name, avatar, reason }) {
|
||||
const id = this.resolveId(channel);
|
||||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
if (typeof avatar === 'string' && !avatar.startsWith('data:')) {
|
||||
avatar = await resolveImage(avatar);
|
||||
}
|
||||
|
||||
const resolvedImage = await resolveImage(avatar);
|
||||
|
||||
const data = await this.client.rest.post(Routes.channelWebhooks(id), {
|
||||
body: {
|
||||
name,
|
||||
avatar,
|
||||
avatar: resolvedImage,
|
||||
},
|
||||
reason,
|
||||
});
|
||||
|
||||
@@ -65,7 +65,7 @@ class GuildMemberRoleManager extends DataManager {
|
||||
* @readonly
|
||||
*/
|
||||
get color() {
|
||||
const coloredRoles = this.cache.filter(role => role.color);
|
||||
const coloredRoles = this.cache.filter(role => role.colors.primaryColor);
|
||||
if (!coloredRoles.size) return null;
|
||||
return coloredRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class GuildSoundboardSoundManager extends CachedManager {
|
||||
* Data for editing a soundboard sound.
|
||||
* @typedef {Object} GuildSoundboardSoundEditOptions
|
||||
* @property {string} [name] The name of the soundboard sound
|
||||
* @property {?number} [volume] The volume of the soundboard sound, from 0 to 1
|
||||
* @property {?number} [volume] The volume (a double) of the soundboard sound, from 0 (inclusive) to 1
|
||||
* @property {?Snowflake} [emojiId] The emoji id of the soundboard sound
|
||||
* @property {?string} [emojiName] The emoji name of the soundboard sound
|
||||
* @property {string} [reason] The reason for editing the soundboard sound
|
||||
@@ -157,35 +157,57 @@ class GuildSoundboardSoundManager extends CachedManager {
|
||||
await this.client.rest.delete(Routes.guildSoundboardSound(this.guild.id, soundId), { reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used to fetch a soundboard sound.
|
||||
* @typedef {BaseFetchOptions} FetchSoundboardSoundOptions
|
||||
* @property {SoundboardSoundResolvable} soundboardSound The soundboard sound to fetch
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options used to fetch soundboard sounds from Discord
|
||||
* @typedef {Object} FetchGuildSoundboardSoundsOptions
|
||||
* @property {boolean} [cache] Whether to cache the fetched soundboard sounds
|
||||
*/
|
||||
|
||||
/* eslint-disable max-len */
|
||||
/**
|
||||
* Obtains one or more soundboard sounds from Discord, or the soundboard sound cache if they're already available.
|
||||
* @param {Snowflake} [id] The soundboard sound's id
|
||||
* @param {BaseFetchOptions} [options] Additional options for this fetch
|
||||
* @param {SoundboardSoundResolvable|FetchSoundboardSoundOptions|FetchGuildSoundboardSoundsOptions} [options] Options for fetching soundboard sound(s)
|
||||
* @returns {Promise<SoundboardSound|Collection<Snowflake, SoundboardSound>>}
|
||||
* @example
|
||||
* // Fetch all soundboard sounds from the guild
|
||||
* guild.soundboardSounds.fetch()
|
||||
* .then(sounds => console.log(`There are ${sounds.size} soundboard sounds.`))
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Fetch a single soundboard sound
|
||||
* guild.soundboardSounds.fetch('222078108977594368')
|
||||
* .then(sound => console.log(`The soundboard sound name is: ${sound.name}`))
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Fetch all soundboard sounds from the guild
|
||||
* guild.soundboardSounds.fetch()
|
||||
* .then(sounds => console.log(`There are ${sounds.size} soundboard sounds.`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async fetch(id, { cache = true, force = false } = {}) {
|
||||
if (id) {
|
||||
if (!force) {
|
||||
const existing = this.cache.get(id);
|
||||
if (existing) return existing;
|
||||
}
|
||||
/* eslint-enable max-len */
|
||||
async fetch(options) {
|
||||
if (!options) return this._fetchMany();
|
||||
const { cache, force, soundboardSound } = options;
|
||||
const resolvedSoundboardSound = this.resolveId(soundboardSound ?? options);
|
||||
if (resolvedSoundboardSound) return this._fetchSingle({ cache, force, soundboardSound: resolvedSoundboardSound });
|
||||
return this._fetchMany({ cache });
|
||||
}
|
||||
|
||||
const sound = await this.client.rest.get(Routes.guildSoundboardSound(this.guild.id, id));
|
||||
return this._add(sound, cache);
|
||||
async _fetchSingle({ cache, force, soundboardSound } = {}) {
|
||||
if (!force) {
|
||||
const existing = this.cache.get(soundboardSound);
|
||||
if (existing) return existing;
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.guildSoundboardSound(this.guild.id, soundboardSound));
|
||||
return this._add(data, cache);
|
||||
}
|
||||
|
||||
async _fetchMany({ cache } = {}) {
|
||||
const data = await this.client.rest.get(Routes.guildSoundboardSounds(this.guild.id));
|
||||
return new Collection(data.map(sound => [sound.sound_id, this._add(sound, cache)]));
|
||||
|
||||
return data.items.reduce((coll, sound) => coll.set(sound.sound_id, this._add(sound, cache)), new Collection());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const process = require('node:process');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
@@ -10,6 +11,8 @@ const MessagePayload = require('../structures/MessagePayload');
|
||||
const { MakeCacheOverrideSymbol } = require('../util/Symbols');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
let deprecationEmittedForFetchPinned = false;
|
||||
|
||||
/**
|
||||
* Manages API methods for Messages and holds their cache.
|
||||
* @extends {CachedManager}
|
||||
@@ -116,19 +119,83 @@ class MessageManager extends CachedManager {
|
||||
return data.reduce((_data, message) => _data.set(message.id, this._add(message, options.cache)), new Collection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used to fetch pinned messages.
|
||||
*
|
||||
* @typedef {Object} FetchPinnedMessagesOptions
|
||||
* @property {DateResolvable} [before] Consider only pinned messages before this time
|
||||
* @property {number} [limit] The maximum number of pinned messages to return
|
||||
* @property {boolean} [cache] Whether to cache the pinned messages
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data returned from fetching pinned messages.
|
||||
*
|
||||
* @typedef {Object} FetchPinnedMessagesResponse
|
||||
* @property {MessagePin[]} items The pinned messages
|
||||
* @property {boolean} hasMore Whether there are additional pinned messages that require a subsequent call
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pinned message data returned from fetching pinned messages.
|
||||
*
|
||||
* @typedef {Object} MessagePin
|
||||
* @property {Date} pinnedAt The time the message was pinned at
|
||||
* @property {number} pinnedTimestamp The timestamp the message was pinned at
|
||||
* @property {Message} message The pinned message
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches the pinned messages of this channel and returns a collection of them.
|
||||
* <info>The returned Collection does not contain any reaction data of the messages.
|
||||
* Those need to be fetched separately.</info>
|
||||
*
|
||||
* @param {FetchPinnedMessagesOptions} [options={}] Options for fetching pinned messages
|
||||
* @returns {Promise<FetchPinnedMessagesResponse>}
|
||||
* @example
|
||||
* // Get pinned messages
|
||||
* channel.messages.fetchPins()
|
||||
* .then(messages => console.log(`Received ${messages.items.length} messages`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async fetchPins(options = {}) {
|
||||
const data = await this.client.rest.get(Routes.channelMessagesPins(this.channel.id), {
|
||||
query: makeURLSearchParams({
|
||||
...options,
|
||||
before: options.before && new Date(options.before).toISOString(),
|
||||
}),
|
||||
});
|
||||
|
||||
return {
|
||||
items: data.items.map(item => ({
|
||||
pinnedTimestamp: Date.parse(item.pinned_at),
|
||||
get pinnedAt() {
|
||||
return new Date(this.pinnedTimestamp);
|
||||
},
|
||||
message: this._add(item.message, options.cache),
|
||||
})),
|
||||
hasMore: data.has_more,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the pinned messages of this channel and returns a collection of them.
|
||||
* <info>The returned Collection does not contain any reaction data of the messages.
|
||||
* Those need to be fetched separately.</info>
|
||||
* @param {boolean} [cache=true] Whether to cache the message(s)
|
||||
* @deprecated Use {@link MessageManager#fetchPins} instead.
|
||||
* @returns {Promise<Collection<Snowflake, Message>>}
|
||||
* @example
|
||||
* // Get pinned messages
|
||||
* channel.messages.fetchPinned()
|
||||
* .then(messages => console.log(`Received ${messages.size} messages`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async fetchPinned(cache = true) {
|
||||
if (!deprecationEmittedForFetchPinned) {
|
||||
process.emitWarning(
|
||||
'The MessageManager#fetchPinned() method is deprecated. Use MessageManager#fetchPins() instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
|
||||
deprecationEmittedForFetchPinned = true;
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.channelPins(this.channel.id));
|
||||
const messages = new Collection();
|
||||
for (const message of data) messages.set(message.id, this._add(message, cache));
|
||||
@@ -219,7 +286,7 @@ class MessageManager extends CachedManager {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
await this.client.rest.put(Routes.channelPin(this.channel.id, message), { reason });
|
||||
await this.client.rest.put(Routes.channelMessagesPin(this.channel.id, message), { reason });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +299,7 @@ class MessageManager extends CachedManager {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
await this.client.rest.delete(Routes.channelPin(this.channel.id, message), { reason });
|
||||
await this.client.rest.delete(Routes.channelMessagesPin(this.channel.id, message), { reason });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,8 @@ const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
const { setPosition, resolveColor } = require('../util/Util');
|
||||
|
||||
let cacheWarningEmitted = false;
|
||||
let deprecationEmittedForCreate = false;
|
||||
let deprecationEmittedForEdit = false;
|
||||
|
||||
/**
|
||||
* Manages API methods for roles and stores their cache.
|
||||
@@ -58,7 +60,7 @@ class RoleManager extends CachedManager {
|
||||
* @example
|
||||
* // Fetch a single role
|
||||
* message.guild.roles.fetch('222078108977594368')
|
||||
* .then(role => console.log(`The role color is: ${role.color}`))
|
||||
* .then(role => console.log(`The role color is: ${role.colors.primaryColor}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async fetch(id, { cache = true, force = false } = {}) {
|
||||
@@ -112,11 +114,24 @@ class RoleManager extends CachedManager {
|
||||
* @returns {?Snowflake}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RoleColorsResolvable
|
||||
* @property {ColorResolvable} primaryColor The primary color of the role
|
||||
* @property {ColorResolvable} [secondaryColor] The secondary color of the role.
|
||||
* This will make the role a gradient between the other provided colors
|
||||
* @property {ColorResolvable} [tertiaryColor] The tertiary color of the role.
|
||||
* When sending `tertiaryColor` the API enforces the role color to be a holographic style
|
||||
* with values of `primaryColor = 11127295`, `secondaryColor = 16759788`, and `tertiaryColor = 16761760`.
|
||||
* These values are available as a constant: `Constants.HolographicStyle`
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options used to create a new role.
|
||||
* @typedef {Object} RoleCreateOptions
|
||||
* @property {string} [name] The name of the new role
|
||||
* @property {ColorResolvable} [color] The data to create the role with
|
||||
* <warn>This property is deprecated. Use `colors` instead.</warn>
|
||||
* @property {RoleColorsResolvable} [colors] The colors to create the role with
|
||||
* @property {boolean} [hoist] Whether or not the new role should be hoisted
|
||||
* @property {PermissionResolvable} [permissions] The permissions for the new role
|
||||
* @property {number} [position] The position of the new role
|
||||
@@ -142,15 +157,30 @@ class RoleManager extends CachedManager {
|
||||
* // Create a new role with data and a reason
|
||||
* guild.roles.create({
|
||||
* name: 'Super Cool Blue People',
|
||||
* color: Colors.Blue,
|
||||
* reason: 'we needed a role for Super Cool People',
|
||||
* colors: {
|
||||
* primaryColor: Colors.Blue,
|
||||
* },
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Create a role with holographic colors
|
||||
* guild.roles.create({
|
||||
* name: 'Holographic Role',
|
||||
* reason: 'Creating a role with holographic effect',
|
||||
* colors: {
|
||||
* primaryColor: Constants.HolographicStyle.Primary,
|
||||
* secondaryColor: Constants.HolographicStyle.Secondary,
|
||||
* tertiaryColor: Constants.HolographicStyle.Tertiary,
|
||||
* },
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async create(options = {}) {
|
||||
let { name, color, hoist, permissions, position, mentionable, reason, icon, unicodeEmoji } = options;
|
||||
color &&= resolveColor(color);
|
||||
let { permissions, icon } = options;
|
||||
const { name, color, hoist, position, mentionable, reason, unicodeEmoji } = options;
|
||||
if (permissions !== undefined) permissions = new PermissionsBitField(permissions);
|
||||
if (icon) {
|
||||
const guildEmojiURL = this.guild.emojis.resolve(icon)?.imageURL();
|
||||
@@ -158,10 +188,30 @@ class RoleManager extends CachedManager {
|
||||
if (typeof icon !== 'string') icon = undefined;
|
||||
}
|
||||
|
||||
let colors = options.colors && {
|
||||
primary_color: resolveColor(options.colors.primaryColor),
|
||||
secondary_color: options.colors.secondaryColor && resolveColor(options.colors.secondaryColor),
|
||||
tertiary_color: options.colors.tertiaryColor && resolveColor(options.colors.tertiaryColor),
|
||||
};
|
||||
|
||||
if (color !== undefined) {
|
||||
if (!deprecationEmittedForCreate) {
|
||||
process.emitWarning(`Passing "color" to RoleManager#create() is deprecated. Use "colors" instead.`);
|
||||
}
|
||||
|
||||
deprecationEmittedForCreate = true;
|
||||
|
||||
colors = {
|
||||
primary_color: resolveColor(color),
|
||||
secondary_color: null,
|
||||
tertiary_color: null,
|
||||
};
|
||||
}
|
||||
|
||||
const data = await this.client.rest.post(Routes.guildRoles(this.guild.id), {
|
||||
body: {
|
||||
name,
|
||||
color,
|
||||
colors,
|
||||
hoist,
|
||||
permissions,
|
||||
mentionable,
|
||||
@@ -210,9 +260,29 @@ class RoleManager extends CachedManager {
|
||||
if (typeof icon !== 'string') icon = undefined;
|
||||
}
|
||||
|
||||
let colors = options.colors && {
|
||||
primary_color: resolveColor(options.colors.primaryColor),
|
||||
secondary_color: options.colors.secondaryColor && resolveColor(options.colors.secondaryColor),
|
||||
tertiary_color: options.colors.tertiaryColor && resolveColor(options.colors.tertiaryColor),
|
||||
};
|
||||
|
||||
if (options.color !== undefined) {
|
||||
if (!deprecationEmittedForEdit) {
|
||||
process.emitWarning(`Passing "color" to RoleManager#edit() is deprecated. Use "colors" instead.`);
|
||||
}
|
||||
|
||||
deprecationEmittedForEdit = true;
|
||||
|
||||
colors = {
|
||||
primary_color: resolveColor(options.color),
|
||||
secondary_color: null,
|
||||
tertiary_color: null,
|
||||
};
|
||||
}
|
||||
|
||||
const body = {
|
||||
name: options.name,
|
||||
color: options.color === undefined ? undefined : resolveColor(options.color),
|
||||
colors,
|
||||
hoist: options.hoist,
|
||||
permissions: options.permissions === undefined ? undefined : new PermissionsBitField(options.permissions),
|
||||
mentionable: options.mentionable,
|
||||
|
||||
@@ -174,6 +174,18 @@ class ApplicationCommand extends Base {
|
||||
this.contexts ??= null;
|
||||
}
|
||||
|
||||
if ('handler' in data) {
|
||||
/**
|
||||
* Determines whether the interaction is handled by the app's interactions handler or by Discord.
|
||||
* <info>Only available for {@link ApplicationCommandType.PrimaryEntryPoint} commands on
|
||||
* applications with the {@link ApplicationFlags.Embedded} flag (i.e, those that have an Activity)</info>
|
||||
* @type {?EntryPointCommandHandlerType}
|
||||
*/
|
||||
this.handler = data.handler;
|
||||
} else {
|
||||
this.handler ??= null;
|
||||
}
|
||||
|
||||
if ('version' in data) {
|
||||
/**
|
||||
* Autoincrementing version identifier updated during substantial record changes
|
||||
@@ -216,15 +228,20 @@ class ApplicationCommand extends Base {
|
||||
* @property {string} name The name of the command, must be in all lowercase if type is
|
||||
* {@link ApplicationCommandType.ChatInput}
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name
|
||||
* @property {string} description The description of the command, if type is {@link ApplicationCommandType.ChatInput}
|
||||
* @property {string} description The description of the command,
|
||||
* if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
|
||||
* @property {boolean} [nsfw] Whether the command is age-restricted
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description,
|
||||
* if type is {@link ApplicationCommandType.ChatInput}
|
||||
* if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
|
||||
* @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
|
||||
* @property {ApplicationCommandOptionData[]} [options] Options for the command
|
||||
* @property {?PermissionResolvable} [defaultMemberPermissions] The bitfield used to determine the default permissions
|
||||
* a member needs in order to run the command
|
||||
* @property {boolean} [dmPermission] Whether the command is enabled in DMs
|
||||
* @property {ApplicationIntegrationType[]} [integrationTypes] Installation contexts where the command is available
|
||||
* @property {InteractionContextType[]} [contexts] Interaction contexts where the command can be used
|
||||
* @property {EntryPointCommandHandlerType} [handler] Whether the interaction is handled by the app's
|
||||
* interactions handler or by Discord.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -295,7 +312,7 @@ class ApplicationCommand extends Base {
|
||||
* @returns {Promise<ApplicationCommand>}
|
||||
* @example
|
||||
* // Edit the name localizations of this command
|
||||
* command.setLocalizedNames({
|
||||
* command.setNameLocalizations({
|
||||
* 'en-GB': 'test',
|
||||
* 'pt-BR': 'teste',
|
||||
* })
|
||||
@@ -419,7 +436,8 @@ class ApplicationCommand extends Base {
|
||||
this.descriptionLocalizations ?? {},
|
||||
) ||
|
||||
!isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? []) ||
|
||||
!isEqual(command.contexts ?? [], this.contexts ?? [])
|
||||
!isEqual(command.contexts ?? [], this.contexts ?? []) ||
|
||||
('handler' in command && command.handler !== this.handler)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,37 +16,42 @@ class ApplicationEmoji extends Emoji {
|
||||
*/
|
||||
this.application = application;
|
||||
|
||||
/**
|
||||
* The user who created this emoji
|
||||
* @type {?User}
|
||||
*/
|
||||
this.author = null;
|
||||
|
||||
this.managed = null;
|
||||
this.requiresColons = null;
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
if ('name' in data) this.name = data.name;
|
||||
if (data.user) this.author = this.client.users._add(data.user);
|
||||
if (data.user) {
|
||||
/**
|
||||
* The user who created this emoji
|
||||
* @type {User}
|
||||
*/
|
||||
this.author = this.client.users._add(data.user);
|
||||
}
|
||||
|
||||
if ('managed' in data) {
|
||||
/**
|
||||
* Whether this emoji is managed by an external service
|
||||
* @type {?boolean}
|
||||
* Whether this emoji is managed by an external service. Always `false` for application emojis
|
||||
* @type {false}
|
||||
*/
|
||||
this.managed = data.managed;
|
||||
}
|
||||
|
||||
if ('require_colons' in data) {
|
||||
/**
|
||||
* Whether or not this emoji requires colons surrounding it
|
||||
* @type {?boolean}
|
||||
* Whether this emoji requires colons surrounding it. Always `true` for application emojis
|
||||
* @type {true}
|
||||
*/
|
||||
this.requiresColons = data.require_colons;
|
||||
}
|
||||
|
||||
if ('available' in data) {
|
||||
/**
|
||||
* Whether this emoji is available. Always `true` for application emojis
|
||||
* @type {true}
|
||||
*/
|
||||
this.available = data.available;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +112,8 @@ class ApplicationEmoji extends Emoji {
|
||||
other.id === this.id &&
|
||||
other.name === this.name &&
|
||||
other.managed === this.managed &&
|
||||
other.requiresColons === this.requiresColons
|
||||
other.requiresColons === this.requiresColons &&
|
||||
other.available === this.available
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,4 +121,49 @@ class ApplicationEmoji extends Emoji {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The emoji's name
|
||||
* @name name
|
||||
* @memberof ApplicationEmoji
|
||||
* @instance
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the emoji is animated
|
||||
* @name animated
|
||||
* @memberof ApplicationEmoji
|
||||
* @instance
|
||||
* @type {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a URL for the emoji.
|
||||
* @method imageURL
|
||||
* @memberof ApplicationEmoji
|
||||
* @instance
|
||||
* @param {EmojiURLOptions} [options] Options for the image URL
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The time the emoji was created at
|
||||
* @name createdAt
|
||||
* @memberof ApplicationEmoji
|
||||
* @instance
|
||||
* @type {Date}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* The timestamp the emoji was created at
|
||||
* @name createdTimestamp
|
||||
* @memberof ApplicationEmoji
|
||||
* @instance
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
module.exports = ApplicationEmoji;
|
||||
|
||||
@@ -58,7 +58,7 @@ class BaseGuildEmoji extends Emoji {
|
||||
* @method imageURL
|
||||
* @memberof BaseGuildEmoji
|
||||
* @instance
|
||||
* @param {BaseImageURLOptions} [options] Options for the image URL
|
||||
* @param {EmojiURLOptions} [options] Options for the emoji URL
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
@@ -72,4 +72,40 @@ class BaseGuildEmoji extends Emoji {
|
||||
* @deprecated Use {@link BaseGuildEmoji#imageURL} instead.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The emoji's name
|
||||
* @name name
|
||||
* @memberof BaseGuildEmoji
|
||||
* @instance
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether or not the emoji is animated
|
||||
* @name animated
|
||||
* @memberof BaseGuildEmoji
|
||||
* @instance
|
||||
* @type {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* The time the emoji was created at.
|
||||
* @name createdAt
|
||||
* @memberof BaseGuildEmoji
|
||||
* @instance
|
||||
* @type {Date}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* The timestamp the emoji was created at.
|
||||
* @name createdTimestamp
|
||||
* @memberof BaseGuildEmoji
|
||||
* @instance
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
module.exports = BaseGuildEmoji;
|
||||
|
||||
@@ -122,6 +122,12 @@ class BaseInteraction extends Base {
|
||||
* @type {?InteractionContextType}
|
||||
*/
|
||||
this.context = data.context ?? null;
|
||||
|
||||
/**
|
||||
* Attachment size limit in bytes
|
||||
* @type {number}
|
||||
*/
|
||||
this.attachmentSizeLimit = data.attachment_size_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,6 +225,16 @@ class BaseInteraction extends Base {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link PrimaryEntryPointCommandInteraction}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isPrimaryEntryPointCommand() {
|
||||
return (
|
||||
this.type === InteractionType.ApplicationCommand && this.commandType === ApplicationCommandType.PrimaryEntryPoint
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link MessageComponentInteraction}
|
||||
* @returns {boolean}
|
||||
|
||||
@@ -163,6 +163,17 @@ class ClientApplication extends Application {
|
||||
this.approximateUserInstallCount ??= null;
|
||||
}
|
||||
|
||||
if ('approximate_user_authorization_count' in data) {
|
||||
/**
|
||||
* An approximate amount of users that have OAuth2 authorizations for this application.
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
this.approximateUserAuthorizationCount = data.approximate_user_authorization_count;
|
||||
} else {
|
||||
this.approximateUserAuthorizationCount ??= null;
|
||||
}
|
||||
|
||||
if ('guild_id' in data) {
|
||||
/**
|
||||
* The id of the guild associated with this application.
|
||||
|
||||
@@ -64,8 +64,6 @@ class ClientUser extends User {
|
||||
},
|
||||
});
|
||||
|
||||
this.client.token = data.token;
|
||||
this.client.rest.setToken(data.token);
|
||||
const { updated } = this.client.actions.UserUpdate.handle(data);
|
||||
return updated ?? this;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ class CommandInteraction extends BaseInteraction {
|
||||
editReply() {}
|
||||
deleteReply() {}
|
||||
followUp() {}
|
||||
launchActivity() {}
|
||||
showModal() {}
|
||||
sendPremiumRequired() {}
|
||||
awaitModalSubmit() {}
|
||||
|
||||
@@ -45,7 +45,7 @@ class Emoji extends Base {
|
||||
|
||||
/**
|
||||
* Returns a URL for the emoji or `null` if this is not a custom emoji.
|
||||
* @param {BaseImageURLOptions} [options] Options for the image URL
|
||||
* @param {EmojiURLOptions} [options] Options for the emoji URL
|
||||
* @returns {?string}
|
||||
*/
|
||||
imageURL(options) {
|
||||
|
||||
@@ -499,6 +499,13 @@ class Guild extends AnonymousGuild {
|
||||
} else {
|
||||
this.incidentsData ??= null;
|
||||
}
|
||||
|
||||
if (data.soundboard_sounds) {
|
||||
this.soundboardSounds.cache.clear();
|
||||
for (const soundboardSound of data.soundboard_sounds) {
|
||||
this.soundboardSounds._add(soundboardSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ const Targets = {
|
||||
AutoModeration: 'AutoModeration',
|
||||
GuildOnboarding: 'GuildOnboarding',
|
||||
GuildOnboardingPrompt: 'GuildOnboardingPrompt',
|
||||
SoundboardSound: 'SoundboardSound',
|
||||
Unknown: 'Unknown',
|
||||
};
|
||||
|
||||
@@ -87,6 +88,8 @@ const Targets = {
|
||||
* * ApplicationCommandPermission
|
||||
* * GuildOnboarding
|
||||
* * GuildOnboardingPrompt
|
||||
* * SoundboardSound
|
||||
* * AutoModeration
|
||||
* * Unknown
|
||||
* @typedef {string} AuditLogTargetType
|
||||
*/
|
||||
@@ -200,7 +203,6 @@ class GuildAuditLogsEntry {
|
||||
|
||||
case AuditLogEvent.MemberMove:
|
||||
case AuditLogEvent.MessageDelete:
|
||||
case AuditLogEvent.MessageBulkDelete:
|
||||
this.extra = {
|
||||
channel: guild.channels.cache.get(data.options.channel_id) ?? { id: data.options.channel_id },
|
||||
count: Number(data.options.count),
|
||||
@@ -215,6 +217,7 @@ class GuildAuditLogsEntry {
|
||||
};
|
||||
break;
|
||||
|
||||
case AuditLogEvent.MessageBulkDelete:
|
||||
case AuditLogEvent.MemberDisconnect:
|
||||
this.extra = {
|
||||
count: Number(data.options.count),
|
||||
@@ -366,12 +369,14 @@ class GuildAuditLogsEntry {
|
||||
data.action_type === AuditLogEvent.OnboardingPromptCreate
|
||||
? new GuildOnboardingPrompt(guild.client, changesReduce(this.changes, { id: data.target_id }), guild.id)
|
||||
: changesReduce(this.changes, { id: data.target_id });
|
||||
} else if (targetType === Targets.GuildOnboarding) {
|
||||
this.target = changesReduce(this.changes, { id: data.target_id });
|
||||
} else if (targetType === Targets.Role) {
|
||||
this.target = guild.roles.cache.get(data.target_id) ?? { id: data.target_id };
|
||||
} else if (targetType === Targets.Emoji) {
|
||||
this.target = guild.emojis.cache.get(data.target_id) ?? { id: data.target_id };
|
||||
} else if (targetType === Targets.SoundboardSound) {
|
||||
this.target = guild.soundboardSounds.cache.get(data.target_id) ?? { id: data.target_id };
|
||||
} else if (data.target_id) {
|
||||
this.target = guild[`${targetType.toLowerCase()}s`]?.cache.get(data.target_id) ?? { id: data.target_id };
|
||||
this.target = { id: data.target_id };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +400,9 @@ class GuildAuditLogsEntry {
|
||||
if (target < 110) return Targets.GuildScheduledEvent;
|
||||
if (target < 120) return Targets.Thread;
|
||||
if (target < 130) return Targets.ApplicationCommand;
|
||||
if (target >= 140 && target < 150) return Targets.AutoModeration;
|
||||
if (target < 140) return Targets.SoundboardSound;
|
||||
if (target < 143) return Targets.AutoModeration;
|
||||
if (target < 146) return Targets.User;
|
||||
if (target >= 163 && target <= 165) return Targets.GuildOnboardingPrompt;
|
||||
if (target >= 160 && target < 170) return Targets.GuildOnboarding;
|
||||
return Targets.Unknown;
|
||||
@@ -423,6 +430,7 @@ class GuildAuditLogsEntry {
|
||||
AuditLogEvent.StickerCreate,
|
||||
AuditLogEvent.GuildScheduledEventCreate,
|
||||
AuditLogEvent.ThreadCreate,
|
||||
AuditLogEvent.SoundboardSoundCreate,
|
||||
AuditLogEvent.AutoModerationRuleCreate,
|
||||
AuditLogEvent.AutoModerationBlockMessage,
|
||||
AuditLogEvent.OnboardingPromptCreate,
|
||||
@@ -452,6 +460,7 @@ class GuildAuditLogsEntry {
|
||||
AuditLogEvent.StickerDelete,
|
||||
AuditLogEvent.GuildScheduledEventDelete,
|
||||
AuditLogEvent.ThreadDelete,
|
||||
AuditLogEvent.SoundboardSoundDelete,
|
||||
AuditLogEvent.AutoModerationRuleDelete,
|
||||
AuditLogEvent.OnboardingPromptDelete,
|
||||
].includes(action)
|
||||
@@ -476,8 +485,12 @@ class GuildAuditLogsEntry {
|
||||
AuditLogEvent.StickerUpdate,
|
||||
AuditLogEvent.GuildScheduledEventUpdate,
|
||||
AuditLogEvent.ThreadUpdate,
|
||||
AuditLogEvent.SoundboardSoundUpdate,
|
||||
AuditLogEvent.ApplicationCommandPermissionUpdate,
|
||||
AuditLogEvent.AutoModerationRuleUpdate,
|
||||
AuditLogEvent.AutoModerationBlockMessage,
|
||||
AuditLogEvent.AutoModerationFlagToChannel,
|
||||
AuditLogEvent.AutoModerationUserCommunicationDisabled,
|
||||
AuditLogEvent.OnboardingPromptUpdate,
|
||||
AuditLogEvent.OnboardingUpdate,
|
||||
].includes(action)
|
||||
|
||||
@@ -122,6 +122,20 @@ class GuildMember extends Base {
|
||||
} else {
|
||||
this.flags ??= new GuildMemberFlagsBitField().freeze();
|
||||
}
|
||||
|
||||
if (data.avatar_decoration_data) {
|
||||
/**
|
||||
* The member avatar decoration's data
|
||||
*
|
||||
* @type {?AvatarDecorationData}
|
||||
*/
|
||||
this.avatarDecorationData = {
|
||||
asset: data.avatar_decoration_data.asset,
|
||||
skuId: data.avatar_decoration_data.sku_id,
|
||||
};
|
||||
} else {
|
||||
this.avatarDecorationData = null;
|
||||
}
|
||||
}
|
||||
|
||||
_clone() {
|
||||
@@ -166,6 +180,15 @@ class GuildMember extends Base {
|
||||
return this.avatar && this.client.rest.cdn.guildMemberAvatar(this.guild.id, this.id, this.avatar, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to the member's avatar decoration.
|
||||
*
|
||||
* @returns {?string}
|
||||
*/
|
||||
avatarDecorationURL() {
|
||||
return this.avatarDecorationData ? this.client.rest.cdn.avatarDecoration(this.avatarDecorationData.asset) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to the member's banner.
|
||||
* @param {ImageURLOptions} [options={}] Options for the banner URL
|
||||
@@ -195,6 +218,16 @@ class GuildMember extends Base {
|
||||
return this.bannerURL(options) ?? this.user.bannerURL(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to the member's guild avatar decoration if they have one.
|
||||
* Otherwise, a link to their {@link User#avatarDecorationURL} will be returned.
|
||||
*
|
||||
* @returns {?string}
|
||||
*/
|
||||
displayAvatarDecorationURL() {
|
||||
return this.avatarDecorationURL() ?? this.user.avatarDecorationURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* The time this member joined the guild
|
||||
* @type {?Date}
|
||||
@@ -237,7 +270,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get displayColor() {
|
||||
return this.roles.color?.color ?? 0;
|
||||
return this.roles.color?.colors.primaryColor ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,7 +532,10 @@ class GuildMember extends Base {
|
||||
this.communicationDisabledUntilTimestamp === member.communicationDisabledUntilTimestamp &&
|
||||
this.flags.bitfield === member.flags.bitfield &&
|
||||
(this._roles === member._roles ||
|
||||
(this._roles.length === member._roles.length && this._roles.every((role, i) => role === member._roles[i])))
|
||||
(this._roles.length === member._roles.length &&
|
||||
this._roles.every((role, index) => role === member._roles[index]))) &&
|
||||
this.avatarDecorationData?.asset === member.avatarDecorationData?.asset &&
|
||||
this.avatarDecorationData?.skuId === member.avatarDecorationData?.skuId
|
||||
);
|
||||
}
|
||||
|
||||
@@ -525,6 +561,7 @@ class GuildMember extends Base {
|
||||
json.bannerURL = this.bannerURL();
|
||||
json.displayAvatarURL = this.displayAvatarURL();
|
||||
json.displayBannerURL = this.displayBannerURL();
|
||||
json.avatarDecorationURL = this.avatarDecorationURL();
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,6 +812,7 @@ class Message extends Base {
|
||||
return Boolean(
|
||||
channel?.type === ChannelType.GuildAnnouncement &&
|
||||
!this.flags.has(MessageFlags.Crossposted) &&
|
||||
this.reference?.type !== MessageReferenceType.Forward &&
|
||||
this.type === MessageType.Default &&
|
||||
!this.poll &&
|
||||
channel.viewable &&
|
||||
|
||||
@@ -97,6 +97,7 @@ class MessageComponentInteraction extends BaseInteraction {
|
||||
followUp() {}
|
||||
deferUpdate() {}
|
||||
update() {}
|
||||
launchActivity() {}
|
||||
showModal() {}
|
||||
sendPremiumRequired() {}
|
||||
awaitModalSubmit() {}
|
||||
|
||||
@@ -248,7 +248,10 @@ class MessagePayload {
|
||||
components,
|
||||
username,
|
||||
avatar_url: avatarURL,
|
||||
allowed_mentions: content === undefined && message_reference === undefined ? undefined : allowedMentions,
|
||||
allowed_mentions:
|
||||
this.isMessage && message_reference === undefined && this.target.author.id !== this.target.client.user.id
|
||||
? undefined
|
||||
: allowedMentions,
|
||||
flags,
|
||||
message_reference,
|
||||
attachments: this.options.attachments,
|
||||
|
||||
@@ -119,6 +119,7 @@ class ModalSubmitInteraction extends BaseInteraction {
|
||||
deferUpdate() {}
|
||||
update() {}
|
||||
sendPremiumRequired() {}
|
||||
launchActivity() {}
|
||||
}
|
||||
|
||||
InteractionResponses.applyToClass(ModalSubmitInteraction, 'showModal');
|
||||
|
||||
@@ -27,7 +27,7 @@ class PartialGroupDMChannel extends BaseChannel {
|
||||
* The hash of the channel icon
|
||||
* @type {?string}
|
||||
*/
|
||||
this.icon = data.icon;
|
||||
this.icon = data.icon ?? null;
|
||||
|
||||
/**
|
||||
* Recipient data received in a {@link PartialGroupDMChannel}.
|
||||
@@ -39,7 +39,7 @@ class PartialGroupDMChannel extends BaseChannel {
|
||||
* The recipients of this Group DM Channel.
|
||||
* @type {PartialRecipient[]}
|
||||
*/
|
||||
this.recipients = data.recipients;
|
||||
this.recipients = data.recipients ?? [];
|
||||
|
||||
/**
|
||||
* A manager of the messages belonging to this channel
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const CommandInteraction = require('./CommandInteraction.js');
|
||||
|
||||
/**
|
||||
* Represents a primary entry point command interaction.
|
||||
* @extends {CommandInteraction}
|
||||
*/
|
||||
class PrimaryEntryPointCommandInteraction extends CommandInteraction {}
|
||||
|
||||
module.exports = PrimaryEntryPointCommandInteraction;
|
||||
@@ -54,11 +54,37 @@ class Role extends Base {
|
||||
if ('color' in data) {
|
||||
/**
|
||||
* The base 10 color of the role
|
||||
*
|
||||
* @type {number}
|
||||
* @deprecated Use {@link Role#colors} instead.
|
||||
*/
|
||||
this.color = data.color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} RoleColors
|
||||
* @property {number} primaryColor The primary color of the role
|
||||
* @property {?number} secondaryColor The secondary color of the role.
|
||||
* This will make the role a gradient between the other provided colors
|
||||
* @property {?number} tertiaryColor The tertiary color of the role.
|
||||
* When sending `tertiaryColor` the API enforces the role color to be a holographic style
|
||||
* with values of `primaryColor = 11127295`, `secondaryColor = 16759788`, and `tertiaryColor = 16761760`.
|
||||
* These values are available as a constant: `Constants.HolographicStyle`
|
||||
*/
|
||||
|
||||
if ('colors' in data) {
|
||||
/**
|
||||
* The colors of the role
|
||||
*
|
||||
* @type {RoleColors}
|
||||
*/
|
||||
this.colors = {
|
||||
primaryColor: data.colors.primary_color,
|
||||
secondaryColor: data.colors.secondary_color,
|
||||
tertiaryColor: data.colors.tertiary_color,
|
||||
};
|
||||
}
|
||||
|
||||
if ('hoist' in data) {
|
||||
/**
|
||||
* If true, users that are part of this role will appear in a separate category in the users list
|
||||
@@ -170,7 +196,7 @@ class Role extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get hexColor() {
|
||||
return `#${this.color.toString(16).padStart(6, '0')}`;
|
||||
return `#${this.colors.primaryColor.toString(16).padStart(6, '0')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,6 +257,8 @@ class Role extends Base {
|
||||
* @typedef {Object} RoleData
|
||||
* @property {string} [name] The name of the role
|
||||
* @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number
|
||||
* <warn>This property is deprecated. Use `colors` instead.</warn>
|
||||
* @property {RoleColorsResolvable} [colors] The colors of the role
|
||||
* @property {boolean} [hoist] Whether or not the role should be hoisted
|
||||
* @property {number} [position] The position of the role
|
||||
* @property {PermissionResolvable} [permissions] The permissions of the role
|
||||
@@ -286,17 +314,39 @@ class Role extends Base {
|
||||
|
||||
/**
|
||||
* Sets a new color for the role.
|
||||
*
|
||||
* @param {ColorResolvable} color The color of the role
|
||||
* @param {string} [reason] Reason for changing the role's color
|
||||
* @returns {Promise<Role>}
|
||||
* @deprecated Use {@link Role#setColors} instead.
|
||||
*/
|
||||
async setColor(color, reason) {
|
||||
return this.edit({ color, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets new colors for the role.
|
||||
*
|
||||
* @param {RoleColorsResolvable} colors The colors of the role
|
||||
* @param {string} [reason] Reason for changing the role's colors
|
||||
* @returns {Promise<Role>}
|
||||
* @example
|
||||
* // Set the color of a role
|
||||
* role.setColor('#FF0000')
|
||||
* .then(updated => console.log(`Set color of role to ${updated.color}`))
|
||||
* // Set the colors of a role
|
||||
* role.setColors({ primaryColor: '#FF0000', secondaryColor: '#00FF00', tertiaryColor: '#0000FF' })
|
||||
* .then(updated => console.log(`Set colors of role to ${updated.colors}`))
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Set holographic colors using constants
|
||||
* role.setColors({
|
||||
* primaryColor: Constants.HolographicStyle.Primary,
|
||||
* secondaryColor: Constants.HolographicStyle.Secondary,
|
||||
* tertiaryColor: Constants.HolographicStyle.Tertiary,
|
||||
* })
|
||||
* .then(updated => console.log(`Set holographic colors for role ${updated.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setColor(color, reason) {
|
||||
return this.edit({ color, reason });
|
||||
async setColors(colors, reason) {
|
||||
return this.edit({ colors, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,7 +484,9 @@ class Role extends Base {
|
||||
role &&
|
||||
this.id === role.id &&
|
||||
this.name === role.name &&
|
||||
this.color === role.color &&
|
||||
this.colors.primaryColor === role.colors.primaryColor &&
|
||||
this.colors.secondaryColor === role.colors.secondaryColor &&
|
||||
this.colors.tertiaryColor === role.colors.tertiaryColor &&
|
||||
this.hoist === role.hoist &&
|
||||
this.position === role.position &&
|
||||
this.permissions.bitfield === role.permissions.bitfield &&
|
||||
|
||||
@@ -181,8 +181,8 @@ class SoundboardSound extends Base {
|
||||
this.available === other.available &&
|
||||
this.name === other.name &&
|
||||
this.volume === other.volume &&
|
||||
this.emojiId === other.emojiId &&
|
||||
this.emojiName === other.emojiName &&
|
||||
this._emoji?.id === other._emoji?.id &&
|
||||
this._emoji?.name === other._emoji?.name &&
|
||||
this.guildId === other.guildId &&
|
||||
this.user?.id === other.user?.id
|
||||
);
|
||||
@@ -193,8 +193,8 @@ class SoundboardSound extends Base {
|
||||
this.available === other.available &&
|
||||
this.name === other.name &&
|
||||
this.volume === other.volume &&
|
||||
this.emojiId === other.emoji_id &&
|
||||
this.emojiName === other.emoji_name &&
|
||||
(this._emoji?.id ?? null) === other.emoji_id &&
|
||||
(this._emoji?.name ?? null) === other.emoji_name &&
|
||||
this.guildId === other.guild_id &&
|
||||
this.user?.id === other.user?.id
|
||||
);
|
||||
|
||||
@@ -351,7 +351,7 @@ class ThreadChannel extends BaseChannel {
|
||||
async edit(options) {
|
||||
const newData = await this.client.rest.patch(Routes.channel(this.id), {
|
||||
body: {
|
||||
name: (options.name ?? this.name).trim(),
|
||||
name: options.name,
|
||||
archived: options.archived,
|
||||
auto_archive_duration: options.autoArchiveDuration,
|
||||
rate_limit_per_user: options.rateLimitPerUser,
|
||||
|
||||
@@ -20,6 +20,14 @@ class UnfurledMediaItem {
|
||||
get url() {
|
||||
return this.data.url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the API-compatible JSON for this media item
|
||||
* @returns {APIUnfurledMediaItem}
|
||||
*/
|
||||
toJSON() {
|
||||
return { ...this.data };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UnfurledMediaItem;
|
||||
|
||||
@@ -5,6 +5,7 @@ const { calculateUserDefaultAvatarIndex } = require('@discordjs/rest');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const Base = require('./Base');
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { _transformCollectibles } = require('../util/Transformers.js');
|
||||
const UserFlagsBitField = require('../util/UserFlagsBitField');
|
||||
const { emitDeprecationWarningForUserFetchFlags } = require('../util/Util');
|
||||
|
||||
@@ -140,18 +141,74 @@ class User extends Base {
|
||||
* @property {string} asset The avatar decoration hash
|
||||
* @property {Snowflake} skuId The id of the avatar decoration's SKU
|
||||
*/
|
||||
|
||||
if (data.avatar_decoration_data) {
|
||||
/**
|
||||
* The user avatar decoration's data
|
||||
* @type {?AvatarDecorationData}
|
||||
*/
|
||||
this.avatarDecorationData = {
|
||||
asset: data.avatar_decoration_data.asset,
|
||||
skuId: data.avatar_decoration_data.sku_id,
|
||||
};
|
||||
if ('avatar_decoration_data' in data) {
|
||||
if (data.avatar_decoration_data) {
|
||||
/**
|
||||
* The user avatar decoration's data
|
||||
*
|
||||
* @type {?AvatarDecorationData}
|
||||
*/
|
||||
this.avatarDecorationData = {
|
||||
asset: data.avatar_decoration_data.asset,
|
||||
skuId: data.avatar_decoration_data.sku_id,
|
||||
};
|
||||
} else {
|
||||
this.avatarDecorationData = null;
|
||||
}
|
||||
} else {
|
||||
this.avatarDecorationData = null;
|
||||
this.avatarDecorationData ??= null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} NameplateData
|
||||
* @property {Snowflake} skuId The id of the nameplate's SKU
|
||||
* @property {string} asset The nameplate's asset path
|
||||
* @property {string} label The nameplate's label
|
||||
* @property {NameplatePalette} palette Background color of the nameplate
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Collectibles
|
||||
* @property {?NameplateData} nameplate The user's nameplate data
|
||||
*/
|
||||
|
||||
if (data.collectibles) {
|
||||
/**
|
||||
* The user's collectibles
|
||||
*
|
||||
* @type {?Collectibles}
|
||||
*/
|
||||
this.collectibles = _transformCollectibles(data.collectibles);
|
||||
} else {
|
||||
this.collectibles = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} UserPrimaryGuild
|
||||
* @property {?Snowflake} identityGuildId The id of the user's primary guild
|
||||
* @property {?boolean} identityEnabled Whether the user is displaying the primary guild's tag
|
||||
* @property {?string} tag The user's guild tag. Limited to 4 characters
|
||||
* @property {?string} badge The guild tag badge hash
|
||||
*/
|
||||
|
||||
if ('primary_guild' in data) {
|
||||
if (data.primary_guild) {
|
||||
/**
|
||||
* The primary guild of the user
|
||||
*
|
||||
* @type {?UserPrimaryGuild}
|
||||
*/
|
||||
this.primaryGuild = {
|
||||
identityGuildId: data.primary_guild.identity_guild_id,
|
||||
identityEnabled: data.primary_guild.identity_enabled,
|
||||
tag: data.primary_guild.tag,
|
||||
badge: data.primary_guild.badge,
|
||||
};
|
||||
} else {
|
||||
this.primaryGuild = null;
|
||||
}
|
||||
} else {
|
||||
this.primaryGuild ??= null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +301,18 @@ class User extends Base {
|
||||
return this.banner && this.client.rest.cdn.banner(this.id, this.banner, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to the user's guild tag badge.
|
||||
*
|
||||
* @param {ImageURLOptions} [options={}] Options for the image URL
|
||||
* @returns {?string}
|
||||
*/
|
||||
guildTagBadgeURL(options = {}) {
|
||||
return this.primaryGuild?.badge
|
||||
? this.client.rest.cdn.guildTagBadge(this.primaryGuild.identityGuildId, this.primaryGuild.badge, options)
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The tag of this user
|
||||
* <info>This user's username, or their legacy tag (e.g. `hydrabolt#0001`)
|
||||
@@ -314,7 +383,15 @@ class User extends Base {
|
||||
this.accentColor === user.accentColor &&
|
||||
this.avatarDecoration === user.avatarDecoration &&
|
||||
this.avatarDecorationData?.asset === user.avatarDecorationData?.asset &&
|
||||
this.avatarDecorationData?.skuId === user.avatarDecorationData?.skuId
|
||||
this.avatarDecorationData?.skuId === user.avatarDecorationData?.skuId &&
|
||||
this.collectibles?.nameplate?.skuId === user.collectibles?.nameplate?.skuId &&
|
||||
this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset &&
|
||||
this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label &&
|
||||
this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette &&
|
||||
this.primaryGuild?.identityGuildId === user.primaryGuild?.identityGuildId &&
|
||||
this.primaryGuild?.identityEnabled === user.primaryGuild?.identityEnabled &&
|
||||
this.primaryGuild?.tag === user.primaryGuild?.tag &&
|
||||
this.primaryGuild?.badge === user.primaryGuild?.badge
|
||||
);
|
||||
}
|
||||
|
||||
@@ -339,6 +416,18 @@ class User extends Base {
|
||||
('avatar_decoration_data' in user
|
||||
? this.avatarDecorationData?.asset === user.avatar_decoration_data?.asset &&
|
||||
this.avatarDecorationData?.skuId === user.avatar_decoration_data?.sku_id
|
||||
: true) &&
|
||||
('collectibles' in user
|
||||
? this.collectibles?.nameplate?.skuId === user.collectibles?.nameplate?.sku_id &&
|
||||
this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset &&
|
||||
this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label &&
|
||||
this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette
|
||||
: true) &&
|
||||
('primary_guild' in user
|
||||
? this.primaryGuild?.identityGuildId === user.primary_guild?.identity_guild_id &&
|
||||
this.primaryGuild?.identityEnabled === user.primary_guild?.identity_enabled &&
|
||||
this.primaryGuild?.tag === user.primary_guild?.tag &&
|
||||
this.primaryGuild?.badge === user.primary_guild?.badge
|
||||
: true)
|
||||
);
|
||||
}
|
||||
@@ -388,6 +477,7 @@ class User extends Base {
|
||||
json.avatarURL = this.avatarURL();
|
||||
json.displayAvatarURL = this.displayAvatarURL();
|
||||
json.bannerURL = this.banner ? this.bannerURL() : this.banner;
|
||||
json.guildTagBadgeURL = this.guildTagBadgeURL();
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,8 @@ class Webhook {
|
||||
* @property {string} [threadName] Name of the thread to create (only available if the webhook is in a forum channel)
|
||||
* @property {Snowflake[]} [appliedTags]
|
||||
* The tags to apply to the created thread (only available if the webhook is in a forum channel)
|
||||
* @property {boolean} [withComponents] Whether to allow sending non-interactive components in the message.
|
||||
* <info>For application-owned webhooks, this property is ignored</info>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -214,12 +216,14 @@ class Webhook {
|
||||
messagePayload = MessagePayload.create(this, options).resolveBody();
|
||||
}
|
||||
|
||||
const { body, files } = await messagePayload.resolveFiles();
|
||||
|
||||
const query = makeURLSearchParams({
|
||||
wait: true,
|
||||
thread_id: messagePayload.options.threadId,
|
||||
with_components: messagePayload.options.withComponents,
|
||||
});
|
||||
|
||||
const { body, files } = await messagePayload.resolveFiles();
|
||||
const d = await this.client.rest.post(Routes.webhook(this.id, this.token), {
|
||||
body,
|
||||
files,
|
||||
@@ -298,6 +302,8 @@ class Webhook {
|
||||
* @property {boolean} [cache=true] Whether to cache the message.
|
||||
* @property {Snowflake} [threadId] The id of the thread this message belongs to.
|
||||
* <info>For interaction webhooks, this property is ignored</info>
|
||||
* @property {boolean} [withComponents] Whether to allow sending non-interactive components in the message.
|
||||
* <info>For application-owned webhooks, this property is ignored</info>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -337,14 +343,17 @@ class Webhook {
|
||||
|
||||
const { body, files } = await messagePayload.resolveBody().resolveFiles();
|
||||
|
||||
const query = makeURLSearchParams({
|
||||
thread_id: messagePayload.options.threadId,
|
||||
with_components: messagePayload.options.withComponents,
|
||||
});
|
||||
|
||||
const d = await this.client.rest.patch(
|
||||
Routes.webhookMessage(this.id, this.token, typeof message === 'string' ? message : message.id),
|
||||
{
|
||||
body,
|
||||
files,
|
||||
query: messagePayload.options.threadId
|
||||
? makeURLSearchParams({ thread_id: messagePayload.options.threadId })
|
||||
: undefined,
|
||||
query,
|
||||
auth: false,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -267,7 +267,7 @@ class Collector extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Allows collectors to be consumed with for-await-of loops
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of}
|
||||
* @see {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for-await...of}
|
||||
*/
|
||||
async *[Symbol.asyncIterator]() {
|
||||
const queue = [];
|
||||
|
||||
@@ -69,6 +69,12 @@ class InteractionResponses {
|
||||
* <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for launching activity in response to a {@link BaseInteraction}
|
||||
* @typedef {Object} LaunchActivityOptions
|
||||
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for showing a modal in response to a {@link BaseInteraction}
|
||||
* @typedef {Object} ShowModalOptions
|
||||
@@ -370,6 +376,25 @@ class InteractionResponses {
|
||||
: new InteractionResponse(this, this.message.interactionMetadata?.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches this application's activity, if enabled
|
||||
* @param {LaunchActivityOptions} [options={}] Options for launching the activity
|
||||
* @returns {Promise<InteractionCallbackResponse|undefined>}
|
||||
*/
|
||||
async launchActivity({ withResponse } = {}) {
|
||||
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
|
||||
const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
|
||||
query: makeURLSearchParams({ with_response: withResponse ?? false }),
|
||||
body: {
|
||||
type: InteractionResponseType.LaunchActivity,
|
||||
},
|
||||
auth: false,
|
||||
});
|
||||
this.replied = true;
|
||||
|
||||
return withResponse ? new InteractionCallbackResponse(this.client, response) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a modal component
|
||||
* @param {ModalBuilder|ModalComponentData|APIModalInteractionResponseCallbackData} modal The modal to show
|
||||
@@ -450,6 +475,7 @@ class InteractionResponses {
|
||||
'followUp',
|
||||
'deferUpdate',
|
||||
'update',
|
||||
'launchActivity',
|
||||
'showModal',
|
||||
'sendPremiumRequired',
|
||||
'awaitModalSubmit',
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
|
||||
/**
|
||||
* @external APIMediaGalleryItem
|
||||
* @se {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMediaGalleryItem}
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMediaGalleryItem}
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -370,6 +370,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntitlementType}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external EntryPointCommandHandlerType
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntryPointCommandHandlerType}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external ForumLayoutType
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ForumLayoutType}
|
||||
@@ -545,6 +550,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageFlags}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external NameplatePalette
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/NameplatePalette}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external OAuth2Scopes
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/OAuth2Scopes}
|
||||
|
||||
@@ -141,44 +141,7 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
* @ignore
|
||||
*/
|
||||
function createComponent(data) {
|
||||
if (data instanceof Component) {
|
||||
return data;
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
case ComponentType.ActionRow:
|
||||
return new ActionRow(data);
|
||||
case ComponentType.Button:
|
||||
return new ButtonComponent(data);
|
||||
case ComponentType.StringSelect:
|
||||
return new StringSelectMenuComponent(data);
|
||||
case ComponentType.TextInput:
|
||||
return new TextInputComponent(data);
|
||||
case ComponentType.UserSelect:
|
||||
return new UserSelectMenuComponent(data);
|
||||
case ComponentType.RoleSelect:
|
||||
return new RoleSelectMenuComponent(data);
|
||||
case ComponentType.MentionableSelect:
|
||||
return new MentionableSelectMenuComponent(data);
|
||||
case ComponentType.ChannelSelect:
|
||||
return new ChannelSelectMenuComponent(data);
|
||||
case ComponentType.Container:
|
||||
return new ContainerComponent(data);
|
||||
case ComponentType.TextDisplay:
|
||||
return new TextDisplayComponent(data);
|
||||
case ComponentType.File:
|
||||
return new FileComponent(data);
|
||||
case ComponentType.MediaGallery:
|
||||
return new MediaGalleryComponent(data);
|
||||
case ComponentType.Section:
|
||||
return new SectionComponent(data);
|
||||
case ComponentType.Separator:
|
||||
return new SeparatorComponent(data);
|
||||
case ComponentType.Thumbnail:
|
||||
return new ThumbnailComponent(data);
|
||||
default:
|
||||
return new Component(data);
|
||||
}
|
||||
return data instanceof Component ? data : new (ComponentTypeToComponent[data.type] ?? Component)(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,29 +151,25 @@ function createComponent(data) {
|
||||
* @ignore
|
||||
*/
|
||||
function createComponentBuilder(data) {
|
||||
if (data instanceof ComponentBuilder) {
|
||||
return data;
|
||||
}
|
||||
return data instanceof ComponentBuilder ? data : new (ComponentTypeToBuilder[data.type] ?? ComponentBuilder)(data);
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
/**
|
||||
* Extracts all interactive components from the component tree
|
||||
* @param {Component|APIMessageComponent} component The component to find all interactive components in
|
||||
* @returns {Array<Component|APIMessageComponent>}
|
||||
* @ignore
|
||||
*/
|
||||
function extractInteractiveComponents(component) {
|
||||
switch (component.type) {
|
||||
case ComponentType.ActionRow:
|
||||
return new ActionRowBuilder(data);
|
||||
case ComponentType.Button:
|
||||
return new ButtonBuilder(data);
|
||||
case ComponentType.StringSelect:
|
||||
return new StringSelectMenuBuilder(data);
|
||||
case ComponentType.TextInput:
|
||||
return new TextInputBuilder(data);
|
||||
case ComponentType.UserSelect:
|
||||
return new UserSelectMenuBuilder(data);
|
||||
case ComponentType.RoleSelect:
|
||||
return new RoleSelectMenuBuilder(data);
|
||||
case ComponentType.MentionableSelect:
|
||||
return new MentionableSelectMenuBuilder(data);
|
||||
case ComponentType.ChannelSelect:
|
||||
return new ChannelSelectMenuBuilder(data);
|
||||
return component.components;
|
||||
case ComponentType.Section:
|
||||
return [...component.components, component.accessory];
|
||||
case ComponentType.Container:
|
||||
return component.components.flatMap(extractInteractiveComponents);
|
||||
default:
|
||||
return new ComponentBuilder(data);
|
||||
return [component];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,20 +178,12 @@ function createComponentBuilder(data) {
|
||||
* @param {Array<Component|APIMessageComponent>} components The components to search in
|
||||
* @param {string} customId The customId to search for
|
||||
* @returns {Component|APIMessageComponent}
|
||||
* @ignore
|
||||
*/
|
||||
function findComponentByCustomId(components, customId) {
|
||||
return (
|
||||
components
|
||||
.flatMap(component => {
|
||||
switch (component.type) {
|
||||
case ComponentType.ActionRow:
|
||||
return component.components;
|
||||
case ComponentType.Section:
|
||||
return [component.accessory];
|
||||
default:
|
||||
return [component];
|
||||
}
|
||||
})
|
||||
.flatMap(extractInteractiveComponents)
|
||||
.find(component => (component.customId ?? component.custom_id) === customId) ?? null
|
||||
);
|
||||
}
|
||||
@@ -263,3 +214,32 @@ const TextInputComponent = require('../structures/TextInputComponent');
|
||||
const ThumbnailComponent = require('../structures/ThumbnailComponent');
|
||||
const UserSelectMenuBuilder = require('../structures/UserSelectMenuBuilder');
|
||||
const UserSelectMenuComponent = require('../structures/UserSelectMenuComponent');
|
||||
|
||||
const ComponentTypeToComponent = {
|
||||
[ComponentType.ActionRow]: ActionRow,
|
||||
[ComponentType.Button]: ButtonComponent,
|
||||
[ComponentType.StringSelect]: StringSelectMenuComponent,
|
||||
[ComponentType.TextInput]: TextInputComponent,
|
||||
[ComponentType.UserSelect]: UserSelectMenuComponent,
|
||||
[ComponentType.RoleSelect]: RoleSelectMenuComponent,
|
||||
[ComponentType.MentionableSelect]: MentionableSelectMenuComponent,
|
||||
[ComponentType.ChannelSelect]: ChannelSelectMenuComponent,
|
||||
[ComponentType.Container]: ContainerComponent,
|
||||
[ComponentType.TextDisplay]: TextDisplayComponent,
|
||||
[ComponentType.File]: FileComponent,
|
||||
[ComponentType.MediaGallery]: MediaGalleryComponent,
|
||||
[ComponentType.Section]: SectionComponent,
|
||||
[ComponentType.Separator]: SeparatorComponent,
|
||||
[ComponentType.Thumbnail]: ThumbnailComponent,
|
||||
};
|
||||
|
||||
const ComponentTypeToBuilder = {
|
||||
[ComponentType.ActionRow]: ActionRowBuilder,
|
||||
[ComponentType.Button]: ButtonBuilder,
|
||||
[ComponentType.StringSelect]: StringSelectMenuBuilder,
|
||||
[ComponentType.TextInput]: TextInputBuilder,
|
||||
[ComponentType.UserSelect]: UserSelectMenuBuilder,
|
||||
[ComponentType.RoleSelect]: RoleSelectMenuBuilder,
|
||||
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder,
|
||||
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder,
|
||||
};
|
||||
|
||||
@@ -254,6 +254,21 @@ exports.StickerFormatExtensionMap = {
|
||||
[StickerFormatType.GIF]: ImageFormat.GIF,
|
||||
};
|
||||
|
||||
/**
|
||||
* Holographic color values for role styling.
|
||||
* When using `tertiaryColor`, the API enforces these specific values for holographic effect.
|
||||
*
|
||||
* @typedef {Object} HolographicStyle
|
||||
* @property {number} Primary 11127295 (0xA9FFFF)
|
||||
* @property {number} Secondary 16759788 (0xFFCCCC)
|
||||
* @property {number} Tertiary 16761760 (0xFFE0A0)
|
||||
*/
|
||||
exports.HolographicStyle = {
|
||||
Primary: 11_127_295,
|
||||
Secondary: 16_759_788,
|
||||
Tertiary: 16_761_760,
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Object} Constants Constants that can be used in an enum or object-like way.
|
||||
* @property {number} MaxBulkDeletableMessageAge Max bulk deletable message age
|
||||
@@ -264,4 +279,5 @@ exports.StickerFormatExtensionMap = {
|
||||
* @property {VoiceBasedChannelTypes} VoiceBasedChannelTypes The types of channels that are voice-based
|
||||
* @property {SelectMenuTypes} SelectMenuTypes The types of components that are select menus.
|
||||
* @property {Object} StickerFormatExtensionMap A mapping between sticker formats and their respective image formats.
|
||||
* @property {HolographicStyle} HolographicStyle Holographic color values for role styling.
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* @property {string} ChannelDelete channelDelete
|
||||
* @property {string} ChannelPinsUpdate channelPinsUpdate
|
||||
* @property {string} ChannelUpdate channelUpdate
|
||||
* @property {string} ClientReady ready
|
||||
* @property {string} ClientReady clientReady
|
||||
* @property {string} Debug debug
|
||||
* @property {string} EntitlementCreate entitlementCreate
|
||||
* @property {string} EntitlementUpdate entitlementUpdate
|
||||
@@ -89,7 +89,7 @@
|
||||
* @property {string} VoiceServerUpdate voiceServerUpdate
|
||||
* @property {string} VoiceStateUpdate voiceStateUpdate
|
||||
* @property {string} Warn warn
|
||||
* @property {string} WebhooksUpdate webhookUpdate
|
||||
* @property {string} WebhooksUpdate webhooksUpdate
|
||||
*/
|
||||
|
||||
// JSDoc for IntelliSense purposes
|
||||
@@ -108,7 +108,7 @@ module.exports = {
|
||||
ChannelDelete: 'channelDelete',
|
||||
ChannelPinsUpdate: 'channelPinsUpdate',
|
||||
ChannelUpdate: 'channelUpdate',
|
||||
ClientReady: 'ready',
|
||||
ClientReady: 'clientReady',
|
||||
Debug: 'debug',
|
||||
EntitlementCreate: 'entitlementCreate',
|
||||
EntitlementUpdate: 'entitlementUpdate',
|
||||
@@ -186,5 +186,5 @@ module.exports = {
|
||||
VoiceServerUpdate: 'voiceServerUpdate',
|
||||
VoiceStateUpdate: 'voiceStateUpdate',
|
||||
Warn: 'warn',
|
||||
WebhooksUpdate: 'webhookUpdate',
|
||||
WebhooksUpdate: 'webhooksUpdate',
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const snakeCase = require('lodash.snakecase');
|
||||
const { resolvePartialEmoji } = require('./Util');
|
||||
|
||||
/**
|
||||
* Transforms camel-cased keys into snake cased keys
|
||||
@@ -13,7 +14,14 @@ function toSnakeCase(obj) {
|
||||
if (obj instanceof Date) return obj;
|
||||
if (isJSONEncodable(obj)) return toSnakeCase(obj.toJSON());
|
||||
if (Array.isArray(obj)) return obj.map(toSnakeCase);
|
||||
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [snakeCase(key), toSnakeCase(value)]));
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj).map(([key, value]) => [
|
||||
snakeCase(key),
|
||||
// TODO: The special handling of 'emoji' is just a temporary fix for v14, will be dropped in v15.
|
||||
// See https://github.com/discordjs/discord.js/issues/10909
|
||||
key === 'emoji' && typeof value === 'string' ? resolvePartialEmoji(value) : toSnakeCase(value),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,10 +95,31 @@ function _transformAPIIncidentsData(data) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a collectibles object to a camel-cased variant.
|
||||
*
|
||||
* @param {APICollectibles} collectibles The collectibles to transform
|
||||
* @returns {Collectibles}
|
||||
* @ignore
|
||||
*/
|
||||
function _transformCollectibles(collectibles) {
|
||||
if (!collectibles.nameplate) return { nameplate: null };
|
||||
|
||||
return {
|
||||
nameplate: {
|
||||
skuId: collectibles.nameplate.sku_id,
|
||||
asset: collectibles.nameplate.asset,
|
||||
label: collectibles.nameplate.label,
|
||||
palette: collectibles.nameplate.palette,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
toSnakeCase,
|
||||
_transformAPIAutoModerationAction,
|
||||
_transformAPIMessageInteractionMetadata,
|
||||
_transformGuildScheduledEventRecurrenceRule,
|
||||
_transformAPIIncidentsData,
|
||||
_transformCollectibles,
|
||||
};
|
||||
|
||||
148
packages/discord.js/test/messages.js
Normal file
148
packages/discord.js/test/messages.js
Normal file
@@ -0,0 +1,148 @@
|
||||
'use strict';
|
||||
|
||||
const { readFile } = require('node:fs/promises');
|
||||
const { createReadStream } = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { setTimeout: sleep } = require('node:timers/promises');
|
||||
const util = require('node:util');
|
||||
const { fetch } = require('undici');
|
||||
const { Client, GatewayIntentBits, AttachmentBuilder, EmbedBuilder, MessageFlags, ComponentType } = require('../src');
|
||||
|
||||
const client = new Client({
|
||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
|
||||
});
|
||||
|
||||
const buffer = l =>
|
||||
fetch(l)
|
||||
.then(res => res.arrayBuffer())
|
||||
.then(Buffer.from);
|
||||
|
||||
const linkA = 'https://discord.js.org/static/logo.svg';
|
||||
const fileA = path.join(__dirname, 'blobReach.png');
|
||||
|
||||
const embed = () => new EmbedBuilder();
|
||||
const attach = (attachment, name) => new AttachmentBuilder(attachment, { name });
|
||||
|
||||
const tests = [
|
||||
m => m.channel.send('x'),
|
||||
|
||||
m => m.channel.send({ content: 'x', embeds: [{ description: 'a' }] }),
|
||||
m => m.channel.send({ embeds: [{ description: 'a' }] }),
|
||||
m => m.channel.send({ files: [{ attachment: fileA }] }),
|
||||
m =>
|
||||
m.channel.send({
|
||||
embeds: [{ description: 'a' }],
|
||||
files: [{ attachment: fileA, name: 'xyz.png' }],
|
||||
}),
|
||||
|
||||
m => m.channel.send({ content: 'x', embeds: [embed().setDescription('a')] }),
|
||||
m => m.channel.send({ embeds: [embed().setDescription('a')] }),
|
||||
m => m.channel.send({ embeds: [embed().setDescription('a'), embed().setDescription('b')] }),
|
||||
|
||||
m => m.channel.send({ content: 'x', files: [attach(fileA)] }),
|
||||
m => m.channel.send({ files: [fileA] }),
|
||||
m => m.channel.send({ files: [attach(fileA)] }),
|
||||
async m => m.channel.send({ files: [await buffer(linkA)] }),
|
||||
async m => m.channel.send({ files: [{ attachment: await buffer(linkA) }] }),
|
||||
m => m.channel.send({ files: [attach(fileA), attach(fileA)] }),
|
||||
|
||||
m => m.channel.send({ embeds: [{ description: 'a' }] }).then(m2 => m2.edit('x')),
|
||||
m => m.channel.send({ embeds: [embed().setDescription('a')] }).then(m2 => m2.edit('x')),
|
||||
|
||||
m => m.channel.send('x').then(m2 => m2.edit({ embeds: [{ description: 'a' }] })),
|
||||
m => m.channel.send('x').then(m2 => m2.edit({ embeds: [embed().setDescription('a')] })),
|
||||
|
||||
m => m.channel.send({ embeds: [{ description: 'a' }] }).then(m2 => m2.edit({ content: 'x', embeds: [] })),
|
||||
m => m.channel.send({ embeds: [embed().setDescription('a')] }).then(m2 => m2.edit({ content: 'x', embeds: [] })),
|
||||
|
||||
m => m.channel.send({ content: 'x', embeds: [embed().setDescription('a')], files: [attach(fileA)] }),
|
||||
m => m.channel.send({ content: 'x', files: [attach(fileA), attach(fileA)] }),
|
||||
|
||||
m => m.channel.send({ embeds: [embed().setDescription('a')], files: [attach(fileA)] }),
|
||||
m =>
|
||||
m.channel.send({
|
||||
embeds: [embed().setImage('attachment://two.png')],
|
||||
files: [attach(fileA, 'two.png')],
|
||||
}),
|
||||
m => m.channel.send({ content: 'x', files: [attach(fileA)] }),
|
||||
m => m.channel.send({ files: [fileA] }),
|
||||
m => m.channel.send({ files: [attach(fileA)] }),
|
||||
async m => m.channel.send({ files: [await readFile(fileA)] }),
|
||||
|
||||
m => m.channel.send({ content: 'x', files: [attach(createReadStream(fileA))] }),
|
||||
m => m.channel.send({ files: [createReadStream(fileA)] }),
|
||||
m => m.channel.send({ files: [{ attachment: createReadStream(fileA) }] }),
|
||||
|
||||
m => m.reply({ content: 'x', allowedMentions: { repliedUser: false } }),
|
||||
m => m.reply({ content: 'x', allowedMentions: { repliedUser: true } }),
|
||||
m => m.reply({ content: 'x' }),
|
||||
m => m.reply({ content: `${m.author}`, allowedMentions: { repliedUser: false } }),
|
||||
m => m.reply({ content: `${m.author}`, allowedMentions: { parse: ['users'], repliedUser: false } }),
|
||||
m => m.reply({ content: `${m.author}`, allowedMentions: { parse: ['users'], repliedUser: true } }),
|
||||
m => m.reply({ content: `${m.author}` }),
|
||||
|
||||
m => m.edit({ flags: MessageFlags.SuppressEmbeds }),
|
||||
m => m.edit({ flags: MessageFlags.SuppressEmbeds, allowedMentions: { repliedUser: false } }),
|
||||
|
||||
m =>
|
||||
m
|
||||
.reply({ content: 'x', allowedMentions: { repliedUser: false } })
|
||||
.then(msg => msg.edit({ content: 'a', allowedMentions: { repliedUser: true } })),
|
||||
|
||||
m =>
|
||||
m.channel.send({
|
||||
components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }],
|
||||
flags: MessageFlags.IsComponentsV2,
|
||||
}),
|
||||
m =>
|
||||
m.channel.send({
|
||||
components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }],
|
||||
flags: MessageFlags.IsComponentsV2,
|
||||
allowedMentions: { parse: ['users'] },
|
||||
}),
|
||||
m =>
|
||||
m.channel.send({
|
||||
components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }],
|
||||
flags: MessageFlags.IsComponentsV2,
|
||||
allowedMentions: { parse: [] },
|
||||
}),
|
||||
m =>
|
||||
m.reply({
|
||||
components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }],
|
||||
flags: MessageFlags.IsComponentsV2,
|
||||
allowedMentions: { parse: [], repliedUser: true },
|
||||
}),
|
||||
m =>
|
||||
m.reply({
|
||||
components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }],
|
||||
flags: MessageFlags.IsComponentsV2,
|
||||
allowedMentions: { parse: [], repliedUser: false },
|
||||
}),
|
||||
|
||||
m => m.channel.send('Done!'),
|
||||
];
|
||||
|
||||
client.on('messageCreate', async message => {
|
||||
if (message.author.id !== process.env.OWNER) return;
|
||||
const match = message.content.match(/^do (.+)$/);
|
||||
if (match?.[1] === 'it') {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
for (const [i, test] of tests.entries()) {
|
||||
await message.channel.send(`**#${i}**\n\`\`\`js\n${test.toString()}\`\`\``);
|
||||
await test(message).catch(e => message.channel.send(`Error!\n\`\`\`\n${e}\`\`\``));
|
||||
await sleep(1_000);
|
||||
}
|
||||
/* eslint-enable no-await-in-loop */
|
||||
} else if (match) {
|
||||
const n = parseInt(match[1]) || 0;
|
||||
const test = tests.slice(n)[0];
|
||||
const i = tests.indexOf(test);
|
||||
await message.channel.send(`**#${i}**\n\`\`\`js\n${test.toString()}\`\`\``);
|
||||
await test(message).catch(e => message.channel.send(`Error!\n\`\`\`\n${e}\`\`\``));
|
||||
}
|
||||
});
|
||||
|
||||
client.login();
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
process.on('unhandledRejection', console.error);
|
||||
316
packages/discord.js/typings/index.d.ts
vendored
316
packages/discord.js/typings/index.d.ts
vendored
@@ -37,7 +37,7 @@ import {
|
||||
} from '@discordjs/formatters';
|
||||
import { Awaitable, JSONEncodable } from '@discordjs/util';
|
||||
import { Collection, ReadonlyCollection } from '@discordjs/collection';
|
||||
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
||||
import { BaseImageURLOptions, EmojiURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
||||
import {
|
||||
WebSocketManager as WSWebSocketManager,
|
||||
IShardingStrategy,
|
||||
@@ -80,6 +80,7 @@ import {
|
||||
InteractionType,
|
||||
InviteTargetType,
|
||||
MessageType,
|
||||
NameplatePalette,
|
||||
OAuth2Scopes,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
Snowflake,
|
||||
@@ -213,6 +214,7 @@ import {
|
||||
SeparatorSpacingSize,
|
||||
APIFileComponent,
|
||||
APIMessageTopLevelComponent,
|
||||
EntryPointCommandHandlerType,
|
||||
} from 'discord-api-types/v10';
|
||||
import { ChildProcess } from 'node:child_process';
|
||||
import { EventEmitter } from 'node:events';
|
||||
@@ -480,6 +482,7 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
|
||||
public get manager(): ApplicationCommandManager;
|
||||
public id: Snowflake;
|
||||
public integrationTypes: ApplicationIntegrationType[] | null;
|
||||
public handler: EntryPointCommandHandlerType | null;
|
||||
public name: string;
|
||||
public nameLocalizations: LocalizationMap | null;
|
||||
public nameLocalized: string | null;
|
||||
@@ -583,23 +586,6 @@ export type BooleanCache<Cached extends CacheType> = Cached extends 'cached' ? t
|
||||
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends BaseInteraction<Cached> {
|
||||
public type: InteractionType.ApplicationCommand;
|
||||
public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
|
||||
public options: Omit<
|
||||
CommandInteractionOptionResolver<Cached>,
|
||||
| 'getMessage'
|
||||
| 'getFocused'
|
||||
| 'getMentionable'
|
||||
| 'getRole'
|
||||
| 'getUser'
|
||||
| 'getMember'
|
||||
| 'getAttachment'
|
||||
| 'getNumber'
|
||||
| 'getInteger'
|
||||
| 'getString'
|
||||
| 'getChannel'
|
||||
| 'getBoolean'
|
||||
| 'getSubcommandGroup'
|
||||
| 'getSubcommand'
|
||||
>;
|
||||
public channelId: Snowflake;
|
||||
public commandId: Snowflake;
|
||||
public commandName: string;
|
||||
@@ -614,7 +600,7 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
|
||||
public inRawGuild(): this is CommandInteraction<'raw'>;
|
||||
public deferReply(
|
||||
options: InteractionDeferReplyOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public deferReply(
|
||||
options: InteractionDeferReplyOptions & { fetchReply: true },
|
||||
@@ -626,26 +612,35 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
|
||||
): Promise<Message<BooleanCache<Cached>>>;
|
||||
public fetchReply(message?: Snowflake | '@original'): Promise<Message<BooleanCache<Cached>>>;
|
||||
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<Message<BooleanCache<Cached>>>;
|
||||
public reply(options: InteractionReplyOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
|
||||
public reply(
|
||||
options: InteractionReplyOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<Message<BooleanCache<Cached>>>;
|
||||
public reply(
|
||||
options: string | MessagePayload | InteractionReplyOptions,
|
||||
): Promise<InteractionResponse<BooleanCache<Cached>>>;
|
||||
public launchActivity(
|
||||
options: LaunchActivityOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise<undefined>;
|
||||
public launchActivity(
|
||||
options?: LaunchActivityOptions,
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>> | undefined>;
|
||||
public showModal(
|
||||
modal:
|
||||
| JSONEncodable<APIModalInteractionResponseCallbackData>
|
||||
| ModalComponentData
|
||||
| APIModalInteractionResponseCallbackData,
|
||||
options: ShowModalOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
public showModal(
|
||||
modal:
|
||||
| JSONEncodable<APIModalInteractionResponseCallbackData>
|
||||
| ModalComponentData
|
||||
| APIModalInteractionResponseCallbackData,
|
||||
options?: ShowModalOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
public showModal(
|
||||
modal:
|
||||
| JSONEncodable<APIModalInteractionResponseCallbackData>
|
||||
@@ -703,14 +698,16 @@ export abstract class BaseGuild extends Base {
|
||||
|
||||
export class BaseGuildEmoji extends Emoji {
|
||||
protected constructor(client: Client<true>, data: RawGuildEmojiData, guild: Guild | GuildPreview);
|
||||
public imageURL(options?: BaseImageURLOptions): string;
|
||||
public imageURL(options?: EmojiURLOptions): string;
|
||||
public get url(): string;
|
||||
public available: boolean | null;
|
||||
public get createdAt(): Date;
|
||||
public get createdTimestamp(): number;
|
||||
public guild: Guild | GuildPreview;
|
||||
public id: Snowflake;
|
||||
public managed: boolean | null;
|
||||
public name: string;
|
||||
public animated: boolean;
|
||||
public managed: boolean;
|
||||
public requiresColons: boolean | null;
|
||||
}
|
||||
|
||||
@@ -1171,6 +1168,7 @@ export class ClientApplication extends Application {
|
||||
public flags: Readonly<ApplicationFlagsBitField>;
|
||||
public approximateGuildCount: number | null;
|
||||
public approximateUserInstallCount: number | null;
|
||||
public approximateUserAuthorizationCount: number | null;
|
||||
public tags: string[];
|
||||
public installParams: ClientApplicationInstallParams | null;
|
||||
public integrationTypesConfig: IntegrationTypesConfiguration | null;
|
||||
@@ -1439,6 +1437,23 @@ export class CommandInteractionOptionResolver<Cached extends CacheType = CacheTy
|
||||
}
|
||||
|
||||
export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType> extends CommandInteraction<Cached> {
|
||||
public options: Omit<
|
||||
CommandInteractionOptionResolver<Cached>,
|
||||
| 'getMessage'
|
||||
| 'getFocused'
|
||||
| 'getMentionable'
|
||||
| 'getRole'
|
||||
| 'getUser'
|
||||
| 'getMember'
|
||||
| 'getAttachment'
|
||||
| 'getNumber'
|
||||
| 'getInteger'
|
||||
| 'getString'
|
||||
| 'getChannel'
|
||||
| 'getBoolean'
|
||||
| 'getSubcommandGroup'
|
||||
| 'getSubcommand'
|
||||
>;
|
||||
public commandType: ApplicationCommandType.Message | ApplicationCommandType.User;
|
||||
public targetId: Snowflake;
|
||||
public inGuild(): this is ContextMenuCommandInteraction<'raw' | 'cached'>;
|
||||
@@ -1447,6 +1462,15 @@ export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType>
|
||||
private resolveContextMenuOptions(data: APIApplicationCommandInteractionData): CommandInteractionOption<Cached>[];
|
||||
}
|
||||
|
||||
export class PrimaryEntryPointCommandInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends CommandInteraction<Cached> {
|
||||
public commandType: ApplicationCommandType.PrimaryEntryPoint;
|
||||
public inGuild(): this is PrimaryEntryPointCommandInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is PrimaryEntryPointCommandInteraction<'cached'>;
|
||||
public inRawGuild(): this is PrimaryEntryPointCommandInteraction<'raw'>;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line no-empty-interface
|
||||
export interface DMChannel
|
||||
extends Omit<
|
||||
@@ -1471,7 +1495,7 @@ export class Emoji extends Base {
|
||||
public id: Snowflake | null;
|
||||
public name: string | null;
|
||||
public get identifier(): string;
|
||||
public imageURL(options?: BaseImageURLOptions): string | null;
|
||||
public imageURL(options?: EmojiURLOptions): string | null;
|
||||
public get url(): string | null;
|
||||
public toJSON(): unknown;
|
||||
public toString(): string;
|
||||
@@ -1490,10 +1514,16 @@ export class ApplicationEmoji extends Emoji {
|
||||
private constructor(client: Client<true>, data: RawApplicationEmojiData, application: ClientApplication);
|
||||
|
||||
public application: ClientApplication;
|
||||
public author: User | null;
|
||||
public author: User;
|
||||
public id: Snowflake;
|
||||
public managed: boolean | null;
|
||||
public requiresColons: boolean | null;
|
||||
public managed: false;
|
||||
public requiresColons: true;
|
||||
public name: string;
|
||||
public animated: boolean;
|
||||
public available: true;
|
||||
public get createdAt(): Date;
|
||||
public get createdTimestamp(): number;
|
||||
public imageURL(options?: EmojiURLOptions): string;
|
||||
public delete(): Promise<ApplicationEmoji>;
|
||||
public edit(options: ApplicationEmojiEditOptions): Promise<ApplicationEmoji>;
|
||||
public equals(other: ApplicationEmoji | unknown): boolean;
|
||||
@@ -1607,9 +1637,9 @@ export class Guild extends AnonymousGuild {
|
||||
public editOnboarding(options: GuildOnboardingEditOptions): Promise<GuildOnboarding>;
|
||||
public editWelcomeScreen(options: WelcomeScreenEditOptions): Promise<WelcomeScreen>;
|
||||
public equals(guild: Guild): boolean;
|
||||
public fetchAuditLogs<Event extends GuildAuditLogsResolvable = null>(
|
||||
public fetchAuditLogs<Event extends GuildAuditLogsResolvable = AuditLogEvent>(
|
||||
options?: GuildAuditLogsFetchOptions<Event>,
|
||||
): Promise<GuildAuditLogs<Event>>;
|
||||
): Promise<GuildAuditLogs<Event extends null ? AuditLogEvent : Event>>;
|
||||
public fetchIntegrations(): Promise<Collection<Snowflake | string, Integration>>;
|
||||
public fetchOnboarding(): Promise<GuildOnboarding>;
|
||||
public fetchOwner(options?: BaseFetchOptions): Promise<GuildMember>;
|
||||
@@ -1666,7 +1696,7 @@ export class FileComponent extends Component<APIFileComponent> {
|
||||
public get spoiler(): boolean;
|
||||
}
|
||||
|
||||
export class GuildAuditLogs<Event extends GuildAuditLogsResolvable = AuditLogEvent> {
|
||||
export class GuildAuditLogs<Event extends AuditLogEvent = AuditLogEvent> {
|
||||
private constructor(guild: Guild, data: RawGuildAuditLogData);
|
||||
private applicationCommands: Collection<Snowflake, ApplicationCommand>;
|
||||
private webhooks: Collection<Snowflake, Webhook<WebhookType.ChannelFollower | WebhookType.Incoming>>;
|
||||
@@ -1678,33 +1708,30 @@ export class GuildAuditLogs<Event extends GuildAuditLogsResolvable = AuditLogEve
|
||||
}
|
||||
|
||||
export class GuildAuditLogsEntry<
|
||||
TAction extends GuildAuditLogsResolvable = AuditLogEvent,
|
||||
TAction extends AuditLogEvent = AuditLogEvent,
|
||||
TActionType extends GuildAuditLogsActionType = TAction extends keyof GuildAuditLogsTypes
|
||||
? GuildAuditLogsTypes[TAction][1]
|
||||
: GuildAuditLogsActionType,
|
||||
: 'All',
|
||||
TTargetType extends GuildAuditLogsTargetType = TAction extends keyof GuildAuditLogsTypes
|
||||
? GuildAuditLogsTypes[TAction][0]
|
||||
: GuildAuditLogsTargetType,
|
||||
TResolvedType = TAction extends null ? AuditLogEvent : TAction,
|
||||
: 'Unknown',
|
||||
> {
|
||||
private constructor(guild: Guild, data: RawGuildAuditLogEntryData, logs?: GuildAuditLogs);
|
||||
public static Targets: GuildAuditLogsTargets;
|
||||
public action: TResolvedType;
|
||||
public action: TAction;
|
||||
public actionType: TActionType;
|
||||
public changes: AuditLogChange[];
|
||||
public get createdAt(): Date;
|
||||
public get createdTimestamp(): number;
|
||||
public executorId: Snowflake | null;
|
||||
public executor: User | null;
|
||||
public extra: TResolvedType extends keyof GuildAuditLogsEntryExtraField
|
||||
? GuildAuditLogsEntryExtraField[TResolvedType]
|
||||
: null;
|
||||
public executor: User | PartialUser | null;
|
||||
public extra: TAction extends keyof GuildAuditLogsEntryExtraField ? GuildAuditLogsEntryExtraField[TAction] : null;
|
||||
public id: Snowflake;
|
||||
public reason: string | null;
|
||||
public targetId: Snowflake | null;
|
||||
public target: TTargetType extends keyof GuildAuditLogsEntryTargetField<TActionType>
|
||||
? GuildAuditLogsEntryTargetField<TActionType>[TTargetType]
|
||||
: Role | GuildEmoji | { id: Snowflake } | null;
|
||||
public target: TTargetType extends keyof GuildAuditLogsEntryTargetField<TAction>
|
||||
? GuildAuditLogsEntryTargetField<TAction>[TTargetType]
|
||||
: { id: Snowflake | undefined; [x: string]: unknown } | null;
|
||||
public targetType: TTargetType;
|
||||
public static actionType(action: AuditLogEvent): GuildAuditLogsActionType;
|
||||
public static targetType(target: AuditLogEvent): GuildAuditLogsTargetType;
|
||||
@@ -1787,6 +1814,7 @@ export class GuildMember extends Base {
|
||||
private constructor(client: Client<true>, data: RawGuildMemberData, guild: Guild);
|
||||
private _roles: Snowflake[];
|
||||
public avatar: string | null;
|
||||
public avatarDecorationData: AvatarDecorationData | null;
|
||||
public banner: string | null;
|
||||
public get bannable(): boolean;
|
||||
public get dmChannel(): DMChannel | null;
|
||||
@@ -1814,6 +1842,7 @@ export class GuildMember extends Base {
|
||||
public user: User;
|
||||
public get voice(): VoiceState;
|
||||
public avatarURL(options?: ImageURLOptions): string | null;
|
||||
public avatarDecorationURL(): string | null;
|
||||
public bannerURL(options?: ImageURLOptions): string | null;
|
||||
public ban(options?: BanOptions): Promise<GuildMember>;
|
||||
public disableCommunicationUntil(timeout: DateResolvable | null, reason?: string): Promise<GuildMember>;
|
||||
@@ -1823,6 +1852,7 @@ export class GuildMember extends Base {
|
||||
public deleteDM(): Promise<DMChannel>;
|
||||
public displayAvatarURL(options?: ImageURLOptions): string;
|
||||
public displayBannerURL(options?: ImageURLOptions): string | null;
|
||||
public displayAvatarDecorationURL(): string | null;
|
||||
public edit(options: GuildMemberEditOptions): Promise<GuildMember>;
|
||||
public isCommunicationDisabled(): this is GuildMember & {
|
||||
communicationDisabledUntilTimestamp: number;
|
||||
@@ -2065,6 +2095,7 @@ export type Interaction<Cached extends CacheType = CacheType> =
|
||||
| ChatInputCommandInteraction<Cached>
|
||||
| MessageContextMenuCommandInteraction<Cached>
|
||||
| UserContextMenuCommandInteraction<Cached>
|
||||
| PrimaryEntryPointCommandInteraction<Cached>
|
||||
| AnySelectMenuInteraction<Cached>
|
||||
| ButtonInteraction<Cached>
|
||||
| AutocompleteInteraction<Cached>
|
||||
@@ -2105,6 +2136,7 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
|
||||
public locale: Locale;
|
||||
public guildLocale: CacheTypeReducer<Cached, Locale>;
|
||||
public entitlements: Collection<Snowflake, Entitlement>;
|
||||
public attachmentSizeLimit: number;
|
||||
public inGuild(): this is BaseInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is BaseInteraction<'cached'>;
|
||||
public inRawGuild(): this is BaseInteraction<'raw'>;
|
||||
@@ -2113,6 +2145,7 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
|
||||
public isChatInputCommand(): this is ChatInputCommandInteraction<Cached>;
|
||||
public isCommand(): this is CommandInteraction<Cached>;
|
||||
public isContextMenuCommand(): this is ContextMenuCommandInteraction<Cached>;
|
||||
public isPrimaryEntryPointCommand(): this is PrimaryEntryPointCommandInteraction<Cached>;
|
||||
public isMessageComponent(): this is MessageComponentInteraction<Cached>;
|
||||
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>;
|
||||
public isModalSubmit(): this is ModalSubmitInteraction<Cached>;
|
||||
@@ -2141,17 +2174,17 @@ export class InteractionCallback {
|
||||
public type: InteractionType;
|
||||
}
|
||||
|
||||
export class InteractionCallbackResponse {
|
||||
export class InteractionCallbackResponse<InGuild extends boolean = boolean> {
|
||||
private constructor(client: Client<true>, data: RESTPostAPIInteractionCallbackWithResponseResult);
|
||||
public readonly client: Client<true>;
|
||||
public interaction: InteractionCallback;
|
||||
public resource: InteractionCallbackResource | null;
|
||||
public resource: InteractionCallbackResource<InGuild> | null;
|
||||
}
|
||||
|
||||
export class InteractionCallbackResource {
|
||||
export class InteractionCallbackResource<InGuild extends boolean = boolean> {
|
||||
private constructor(client: Client<true>, data: RESTAPIInteractionCallbackResourceObject);
|
||||
public activityInstance: RESTAPIInteractionCallbackActivityInstanceResource | null;
|
||||
public message: Message | null;
|
||||
public message: Message<InGuild> | null;
|
||||
public type: InteractionResponseType;
|
||||
}
|
||||
|
||||
@@ -2222,8 +2255,8 @@ export class Invite extends Base {
|
||||
public inviterId: Snowflake | null;
|
||||
public maxAge: number | null;
|
||||
public maxUses: number | null;
|
||||
public memberCount: number;
|
||||
public presenceCount: number;
|
||||
public memberCount: number | null;
|
||||
public presenceCount: number | null;
|
||||
public targetApplication: IntegrationApplication | null;
|
||||
public targetUser: User | null;
|
||||
public targetType: InviteTargetType | null;
|
||||
@@ -2508,7 +2541,7 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
||||
public inRawGuild(): this is MessageComponentInteraction<'raw'>;
|
||||
public deferReply(
|
||||
options: InteractionDeferReplyOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public deferReply(
|
||||
options: InteractionDeferReplyOptions & { fetchReply: true },
|
||||
@@ -2516,7 +2549,7 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
||||
public deferReply(options?: InteractionDeferReplyOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
|
||||
public deferUpdate(
|
||||
options: InteractionDeferUpdateOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public deferUpdate(
|
||||
options: InteractionDeferUpdateOptions & { fetchReply: true },
|
||||
@@ -2528,25 +2561,36 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
||||
): Promise<Message<BooleanCache<Cached>>>;
|
||||
public fetchReply(message?: Snowflake | '@original'): Promise<Message<BooleanCache<Cached>>>;
|
||||
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<Message<BooleanCache<Cached>>>;
|
||||
public reply(options: InteractionReplyOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
|
||||
public reply(
|
||||
options: InteractionReplyOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<Message<BooleanCache<Cached>>>;
|
||||
public reply(
|
||||
options: string | MessagePayload | InteractionReplyOptions,
|
||||
): Promise<InteractionResponse<BooleanCache<Cached>>>;
|
||||
public update(options: InteractionUpdateOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
|
||||
public update(
|
||||
options: InteractionUpdateOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<Message<BooleanCache<Cached>>>;
|
||||
public update(
|
||||
options: string | MessagePayload | InteractionUpdateOptions,
|
||||
): Promise<InteractionResponse<BooleanCache<Cached>>>;
|
||||
public launchActivity(
|
||||
options: LaunchActivityOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise<undefined>;
|
||||
public launchActivity(
|
||||
options?: LaunchActivityOptions,
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>> | undefined>;
|
||||
public showModal(
|
||||
modal:
|
||||
| JSONEncodable<APIModalInteractionResponseCallbackData>
|
||||
| ModalComponentData
|
||||
| APIModalInteractionResponseCallbackData,
|
||||
options: ShowModalOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
public showModal(
|
||||
modal:
|
||||
| JSONEncodable<APIModalInteractionResponseCallbackData>
|
||||
@@ -2724,7 +2768,7 @@ export interface ActionRowModalData {
|
||||
export class ModalSubmitFields {
|
||||
private constructor(components: readonly (readonly ModalActionRowComponent[])[]);
|
||||
public components: ActionRowModalData[];
|
||||
public fields: Collection<string, ModalActionRowComponent>;
|
||||
public fields: Collection<string, TextInputModalData>;
|
||||
public getField<Type extends ComponentType>(customId: string, type: Type): { type: Type } & TextInputModalData;
|
||||
public getField(customId: string, type?: ComponentType): TextInputModalData;
|
||||
public getTextInputValue(customId: string): string;
|
||||
@@ -2734,7 +2778,9 @@ export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = C
|
||||
extends ModalSubmitInteraction<Cached> {
|
||||
message: Message<BooleanCache<Cached>>;
|
||||
channelId: Snowflake;
|
||||
update(options: InteractionUpdateOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
|
||||
update(
|
||||
options: InteractionUpdateOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<Message>;
|
||||
update(
|
||||
@@ -2756,7 +2802,9 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
|
||||
public message: Message<BooleanCache<Cached>> | null;
|
||||
public replied: boolean;
|
||||
public readonly webhook: InteractionWebhook;
|
||||
public reply(options: InteractionReplyOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
|
||||
public reply(
|
||||
options: InteractionReplyOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<Message<BooleanCache<Cached>>>;
|
||||
public reply(
|
||||
@@ -2768,7 +2816,7 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
|
||||
): Promise<Message<BooleanCache<Cached>>>;
|
||||
public deferReply(
|
||||
options: InteractionDeferReplyOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public deferReply(
|
||||
options: InteractionDeferReplyOptions & { fetchReply: true },
|
||||
@@ -2778,7 +2826,7 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
|
||||
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<Message<BooleanCache<Cached>>>;
|
||||
public deferUpdate(
|
||||
options: InteractionDeferUpdateOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse>;
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
|
||||
public deferUpdate(
|
||||
options: InteractionDeferUpdateOptions & { fetchReply: true },
|
||||
@@ -2786,6 +2834,13 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
|
||||
public deferUpdate(options?: InteractionDeferUpdateOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
|
||||
/** @deprecated Sending a premium-style button is the new Discord behaviour. */
|
||||
public sendPremiumRequired(): Promise<void>;
|
||||
public launchActivity(
|
||||
options: LaunchActivityOptions & { withResponse: true },
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>>>;
|
||||
public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise<undefined>;
|
||||
public launchActivity(
|
||||
options?: LaunchActivityOptions,
|
||||
): Promise<InteractionCallbackResponse<BooleanCache<Cached>> | undefined>;
|
||||
public inGuild(): this is ModalSubmitInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is ModalSubmitInteraction<'cached'>;
|
||||
public inRawGuild(): this is ModalSubmitInteraction<'raw'>;
|
||||
@@ -3034,9 +3089,23 @@ export class RichPresenceAssets {
|
||||
public smallImageURL(options?: ImageURLOptions): string | null;
|
||||
}
|
||||
|
||||
export interface RoleColors {
|
||||
primaryColor: number;
|
||||
secondaryColor: number | null;
|
||||
tertiaryColor: number | null;
|
||||
}
|
||||
|
||||
export interface RoleColorsResolvable {
|
||||
primaryColor: ColorResolvable;
|
||||
secondaryColor?: ColorResolvable;
|
||||
tertiaryColor?: ColorResolvable;
|
||||
}
|
||||
|
||||
export class Role extends Base {
|
||||
private constructor(client: Client<true>, data: RawRoleData, guild: Guild);
|
||||
/** @deprecated Use {@link Role.colors} instead. */
|
||||
public color: number;
|
||||
public colors: RoleColors;
|
||||
public get createdAt(): Date;
|
||||
public get createdTimestamp(): number;
|
||||
public get editable(): boolean;
|
||||
@@ -3064,7 +3133,9 @@ export class Role extends Base {
|
||||
channel: NonThreadGuildBasedChannel | Snowflake,
|
||||
checkAdmin?: boolean,
|
||||
): Readonly<PermissionsBitField>;
|
||||
/** @deprecated Use {@link Role.setColors} instead. */
|
||||
public setColor(color: ColorResolvable, reason?: string): Promise<Role>;
|
||||
public setColors(colors: RoleColorsResolvable, reason?: string): Promise<Role>;
|
||||
public setHoist(hoist?: boolean, reason?: string): Promise<Role>;
|
||||
public setMentionable(mentionable?: boolean, reason?: string): Promise<Role>;
|
||||
public setName(name: string, reason?: string): Promise<Role>;
|
||||
@@ -3222,7 +3293,7 @@ export type SelectMenuType = APISelectMenuComponent['type'];
|
||||
|
||||
export interface SeparatorComponentData extends BaseComponentData {
|
||||
spacing?: SeparatorSpacingSize;
|
||||
dividier?: boolean;
|
||||
divider?: boolean;
|
||||
}
|
||||
export class SeparatorComponent extends Component<APISeparatorComponent> {
|
||||
private constructor(data: APISeparatorComponent);
|
||||
@@ -3732,6 +3803,24 @@ export interface AvatarDecorationData {
|
||||
skuId: Snowflake;
|
||||
}
|
||||
|
||||
export interface Collectibles {
|
||||
nameplate: NameplateData | null;
|
||||
}
|
||||
|
||||
export interface UserPrimaryGuild {
|
||||
badge: string | null;
|
||||
identityEnabled: boolean | null;
|
||||
identityGuildId: Snowflake | null;
|
||||
tag: string | null;
|
||||
}
|
||||
|
||||
export interface NameplateData {
|
||||
asset: string;
|
||||
label: string;
|
||||
palette: NameplatePalette;
|
||||
skuId: Snowflake;
|
||||
}
|
||||
|
||||
export interface UnfurledMediaItemData {
|
||||
url: string;
|
||||
}
|
||||
@@ -3757,6 +3846,7 @@ export class User extends Base {
|
||||
public bot: boolean;
|
||||
public get createdAt(): Date;
|
||||
public get createdTimestamp(): number;
|
||||
public collectibles: Collectibles | null;
|
||||
public discriminator: string;
|
||||
public get displayName(): string;
|
||||
public get defaultAvatarURL(): string;
|
||||
@@ -3766,12 +3856,14 @@ export class User extends Base {
|
||||
public get hexAccentColor(): HexColorString | null | undefined;
|
||||
public id: Snowflake;
|
||||
public get partial(): false;
|
||||
public primaryGuild: UserPrimaryGuild | null;
|
||||
public system: boolean;
|
||||
public get tag(): string;
|
||||
public username: string;
|
||||
public avatarURL(options?: ImageURLOptions): string | null;
|
||||
public avatarDecorationURL(options?: BaseImageURLOptions): string | null;
|
||||
public bannerURL(options?: ImageURLOptions): string | null | undefined;
|
||||
public guildTagBadgeURL(options?: ImageURLOptions): string | null;
|
||||
public createDM(force?: boolean): Promise<DMChannel>;
|
||||
public deleteDM(): Promise<DMChannel>;
|
||||
public displayAvatarURL(options?: ImageURLOptions): string;
|
||||
@@ -4216,6 +4308,11 @@ export type DeletableMessageType =
|
||||
| MessageType.UserJoin;
|
||||
|
||||
export const Constants: {
|
||||
HolographicStyle: {
|
||||
Primary: 11_127_295;
|
||||
Secondary: 16_759_788;
|
||||
Tertiary: 16_761_760;
|
||||
};
|
||||
MaxBulkDeletableMessageAge: 1_209_600_000;
|
||||
SweeperKeys: SweeperKey[];
|
||||
NonSystemMessageTypes: NonSystemMessageType[];
|
||||
@@ -4860,8 +4957,15 @@ export interface GuildSoundboardSoundEditOptions {
|
||||
volume?: number | null;
|
||||
emojiId?: Snowflake | null;
|
||||
emojiName?: string | null;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface FetchGuildSoundboardSoundOptions extends BaseFetchOptions {
|
||||
soundboardSound: SoundboardSoundResolvable;
|
||||
}
|
||||
|
||||
export interface FetchGuildSoundboardSoundsOptions extends Pick<BaseFetchOptions, 'cache'> {}
|
||||
|
||||
export class GuildSoundboardSoundManager extends CachedManager<Snowflake, SoundboardSound, SoundboardSoundResolvable> {
|
||||
private constructor(guild: Guild, iterable?: Iterable<APISoundboardSound>);
|
||||
public guild: Guild;
|
||||
@@ -4871,8 +4975,8 @@ export class GuildSoundboardSoundManager extends CachedManager<Snowflake, Soundb
|
||||
options: GuildSoundboardSoundEditOptions,
|
||||
): Promise<GuildSoundboardSound>;
|
||||
public delete(soundboardSound: SoundboardSoundResolvable): Promise<void>;
|
||||
public fetch(id: Snowflake, options?: BaseFetchOptions): Promise<GuildSoundboardSound>;
|
||||
public fetch(options?: BaseFetchOptions): Promise<Collection<Snowflake, GuildSoundboardSound>>;
|
||||
public fetch(options: SoundboardSoundResolvable | FetchGuildSoundboardSoundOptions): Promise<GuildSoundboardSound>;
|
||||
public fetch(options?: FetchGuildSoundboardSoundsOptions): Promise<Collection<Snowflake, GuildSoundboardSound>>;
|
||||
}
|
||||
|
||||
export class GuildStickerManager extends CachedManager<Snowflake, Sticker, StickerResolvable> {
|
||||
@@ -4930,7 +5034,9 @@ export abstract class MessageManager<InGuild extends boolean = boolean> extends
|
||||
): Promise<Message<InGuild>>;
|
||||
public fetch(options: MessageResolvable | FetchMessageOptions): Promise<Message<InGuild>>;
|
||||
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message<InGuild>>>;
|
||||
/** @deprecated Use {@link MessageManager.fetchPins} instead. */
|
||||
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message<InGuild>>>;
|
||||
public fetchPins(options?: FetchPinnedMessagesOptions): Promise<FetchPinnedMessagesResponse<InGuild>>;
|
||||
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
|
||||
public pin(message: MessageResolvable, reason?: string): Promise<void>;
|
||||
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
|
||||
@@ -5266,10 +5372,18 @@ export interface ChatInputApplicationCommandData extends BaseApplicationCommandD
|
||||
options?: readonly ApplicationCommandOptionData[];
|
||||
}
|
||||
|
||||
export interface PrimaryEntryPointCommandData extends BaseApplicationCommandData {
|
||||
description?: string;
|
||||
descriptionLocalizations?: LocalizationMap;
|
||||
type: ApplicationCommandType.PrimaryEntryPoint;
|
||||
handler?: EntryPointCommandHandlerType;
|
||||
}
|
||||
|
||||
export type ApplicationCommandData =
|
||||
| UserApplicationCommandData
|
||||
| MessageApplicationCommandData
|
||||
| ChatInputApplicationCommandData;
|
||||
| ChatInputApplicationCommandData
|
||||
| PrimaryEntryPointCommandData;
|
||||
|
||||
export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData {
|
||||
type: CommandOptionChannelResolvableType;
|
||||
@@ -5729,6 +5843,7 @@ export interface ClientEvents {
|
||||
oldChannel: DMChannel | NonThreadGuildBasedChannel,
|
||||
newChannel: DMChannel | NonThreadGuildBasedChannel,
|
||||
];
|
||||
clientReady: [client: Client<true>];
|
||||
debug: [message: string];
|
||||
warn: [message: string];
|
||||
emojiCreate: [emoji: GuildEmoji];
|
||||
@@ -5752,9 +5867,13 @@ export interface ClientEvents {
|
||||
guildMembersChunk: [members: ReadonlyCollection<Snowflake, GuildMember>, guild: Guild, data: GuildMembersChunk];
|
||||
guildMemberUpdate: [oldMember: GuildMember | PartialGuildMember, newMember: GuildMember];
|
||||
guildUpdate: [oldGuild: Guild, newGuild: Guild];
|
||||
guildSoundboardSoundCreate: [soundboardSound: SoundboardSound];
|
||||
guildSoundboardSoundDelete: [soundboardSound: SoundboardSound | PartialSoundboardSound];
|
||||
guildSoundboardSoundUpdate: [oldSoundboardSound: SoundboardSound | null, newSoundboardSound: SoundboardSound];
|
||||
guildSoundboardSoundCreate: [soundboardSound: GuildSoundboardSound];
|
||||
guildSoundboardSoundDelete: [soundboardSound: GuildSoundboardSound | PartialSoundboardSound];
|
||||
guildSoundboardSoundUpdate: [
|
||||
oldSoundboardSound: GuildSoundboardSound | null,
|
||||
newSoundboardSound: GuildSoundboardSound,
|
||||
];
|
||||
guildSoundboardSoundsUpdate: [soundboardSounds: ReadonlyCollection<Snowflake, GuildSoundboardSound>, guild: Guild];
|
||||
inviteCreate: [invite: Invite];
|
||||
inviteDelete: [invite: Invite];
|
||||
messageCreate: [message: OmitPartialGroupDMChannel<Message>];
|
||||
@@ -5785,6 +5904,7 @@ export interface ClientEvents {
|
||||
newMessage: OmitPartialGroupDMChannel<Message>,
|
||||
];
|
||||
presenceUpdate: [oldPresence: Presence | null, newPresence: Presence];
|
||||
/** @deprecated Use {@link ClientEvents.ClientReady} instead. */
|
||||
ready: [client: Client<true>];
|
||||
invalidated: [];
|
||||
roleCreate: [role: Role];
|
||||
@@ -5830,7 +5950,7 @@ export interface ClientEvents {
|
||||
guildScheduledEventDelete: [guildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent];
|
||||
guildScheduledEventUserAdd: [guildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent, user: User];
|
||||
guildScheduledEventUserRemove: [guildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent, user: User];
|
||||
soundboardSounds: [soundboardSounds: ReadonlyCollection<Snowflake, SoundboardSound>, guild: Guild];
|
||||
soundboardSounds: [soundboardSounds: ReadonlyCollection<Snowflake, GuildSoundboardSound>, guild: Guild];
|
||||
}
|
||||
|
||||
export interface ClientFetchInviteOptions {
|
||||
@@ -5970,7 +6090,7 @@ export enum Events {
|
||||
AutoModerationRuleCreate = 'autoModerationRuleCreate',
|
||||
AutoModerationRuleDelete = 'autoModerationRuleDelete',
|
||||
AutoModerationRuleUpdate = 'autoModerationRuleUpdate',
|
||||
ClientReady = 'ready',
|
||||
ClientReady = 'clientReady',
|
||||
EntitlementCreate = 'entitlementCreate',
|
||||
EntitlementDelete = 'entitlementDelete',
|
||||
EntitlementUpdate = 'entitlementUpdate',
|
||||
@@ -6022,7 +6142,7 @@ export enum Events {
|
||||
VoiceServerUpdate = 'voiceServerUpdate',
|
||||
VoiceStateUpdate = 'voiceStateUpdate',
|
||||
TypingStart = 'typingStart',
|
||||
WebhooksUpdate = 'webhookUpdate',
|
||||
WebhooksUpdate = 'webhooksUpdate',
|
||||
InteractionCreate = 'interactionCreate',
|
||||
Error = 'error',
|
||||
Warn = 'warn',
|
||||
@@ -6240,6 +6360,23 @@ export interface FetchMessagesOptions {
|
||||
cache?: boolean;
|
||||
}
|
||||
|
||||
export interface FetchPinnedMessagesOptions {
|
||||
before?: DateResolvable;
|
||||
cache?: boolean;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface FetchPinnedMessagesResponse<InGuild extends boolean = boolean> {
|
||||
hasMore: boolean;
|
||||
items: readonly MessagePin<InGuild>[];
|
||||
}
|
||||
|
||||
export interface MessagePin<InGuild extends boolean = boolean> {
|
||||
message: Message<InGuild>;
|
||||
get pinnedAt(): Date;
|
||||
pinnedTimestamp: number;
|
||||
}
|
||||
|
||||
export interface FetchReactionUsersOptions {
|
||||
type?: ReactionType;
|
||||
limit?: number;
|
||||
@@ -6334,12 +6471,15 @@ interface GuildAuditLogsTypes {
|
||||
[AuditLogEvent.ThreadUpdate]: ['Thread', 'Update'];
|
||||
[AuditLogEvent.ThreadDelete]: ['Thread', 'Delete'];
|
||||
[AuditLogEvent.ApplicationCommandPermissionUpdate]: ['ApplicationCommand', 'Update'];
|
||||
[AuditLogEvent.SoundboardSoundCreate]: ['SoundboardSound', 'Create'];
|
||||
[AuditLogEvent.SoundboardSoundUpdate]: ['SoundboardSound', 'Update'];
|
||||
[AuditLogEvent.SoundboardSoundDelete]: ['SoundboardSound', 'Delete'];
|
||||
[AuditLogEvent.AutoModerationRuleCreate]: ['AutoModeration', 'Create'];
|
||||
[AuditLogEvent.AutoModerationRuleUpdate]: ['AutoModeration', 'Update'];
|
||||
[AuditLogEvent.AutoModerationRuleDelete]: ['AutoModeration', 'Delete'];
|
||||
[AuditLogEvent.AutoModerationBlockMessage]: ['AutoModeration', 'Create'];
|
||||
[AuditLogEvent.AutoModerationFlagToChannel]: ['AutoModeration', 'Create'];
|
||||
[AuditLogEvent.AutoModerationUserCommunicationDisabled]: ['AutoModeration', 'Create'];
|
||||
[AuditLogEvent.AutoModerationBlockMessage]: ['User', 'Update'];
|
||||
[AuditLogEvent.AutoModerationFlagToChannel]: ['User', 'Update'];
|
||||
[AuditLogEvent.AutoModerationUserCommunicationDisabled]: ['User', 'Update'];
|
||||
[AuditLogEvent.OnboardingPromptCreate]: ['GuildOnboardingPrompt', 'Create'];
|
||||
[AuditLogEvent.OnboardingPromptUpdate]: ['GuildOnboardingPrompt', 'Update'];
|
||||
[AuditLogEvent.OnboardingPromptDelete]: ['GuildOnboardingPrompt', 'Delete'];
|
||||
@@ -6355,7 +6495,7 @@ export interface GuildAuditLogsEntryExtraField {
|
||||
[AuditLogEvent.MemberPrune]: { removed: number; days: number };
|
||||
[AuditLogEvent.MemberMove]: { channel: VoiceBasedChannel | { id: Snowflake }; count: number };
|
||||
[AuditLogEvent.MessageDelete]: { channel: GuildTextBasedChannel | { id: Snowflake }; count: number };
|
||||
[AuditLogEvent.MessageBulkDelete]: { channel: GuildTextBasedChannel | { id: Snowflake }; count: number };
|
||||
[AuditLogEvent.MessageBulkDelete]: { count: number };
|
||||
[AuditLogEvent.MessagePin]: { channel: GuildTextBasedChannel | { id: Snowflake }; messageId: Snowflake };
|
||||
[AuditLogEvent.MessageUnpin]: { channel: GuildTextBasedChannel | { id: Snowflake }; messageId: Snowflake };
|
||||
[AuditLogEvent.MemberDisconnect]: { count: number };
|
||||
@@ -6395,12 +6535,14 @@ export interface GuildAuditLogsEntryExtraField {
|
||||
};
|
||||
}
|
||||
|
||||
export interface GuildAuditLogsEntryTargetField<TActionType extends GuildAuditLogsActionType> {
|
||||
User: User | null;
|
||||
export interface GuildAuditLogsEntryTargetField<TAction extends AuditLogEvent> {
|
||||
User: User | PartialUser | null;
|
||||
Guild: Guild;
|
||||
Webhook: Webhook<WebhookType.ChannelFollower | WebhookType.Incoming>;
|
||||
Invite: Invite;
|
||||
Message: TActionType extends AuditLogEvent.MessageBulkDelete ? Guild | { id: Snowflake } : User;
|
||||
Emoji: GuildEmoji | { id: Snowflake };
|
||||
Role: Role | { id: Snowflake };
|
||||
Message: TAction extends AuditLogEvent.MessageBulkDelete ? GuildTextBasedChannel | { id: Snowflake } : User | null;
|
||||
Integration: Integration;
|
||||
Channel: NonThreadGuildBasedChannel | { id: Snowflake; [x: string]: unknown };
|
||||
Thread: AnyThreadChannel | { id: Snowflake; [x: string]: unknown };
|
||||
@@ -6409,7 +6551,8 @@ export interface GuildAuditLogsEntryTargetField<TActionType extends GuildAuditLo
|
||||
GuildScheduledEvent: GuildScheduledEvent;
|
||||
ApplicationCommand: ApplicationCommand | { id: Snowflake };
|
||||
AutoModerationRule: AutoModerationRule;
|
||||
GuildOnboardingPrompt: GuildOnboardingPrompt;
|
||||
GuildOnboardingPrompt: GuildOnboardingPrompt | { id: Snowflake; [x: string]: unknown };
|
||||
SoundboardSound: SoundboardSound | { id: Snowflake };
|
||||
}
|
||||
|
||||
export interface GuildAuditLogsFetchOptions<Event extends GuildAuditLogsResolvable> {
|
||||
@@ -6422,10 +6565,10 @@ export interface GuildAuditLogsFetchOptions<Event extends GuildAuditLogsResolvab
|
||||
|
||||
export type GuildAuditLogsResolvable = AuditLogEvent | null;
|
||||
|
||||
export type GuildAuditLogsTargetType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][0] | 'All' | 'Unknown';
|
||||
export type GuildAuditLogsTargetType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][0] | 'Unknown';
|
||||
|
||||
export type GuildAuditLogsTargets = {
|
||||
[Key in GuildAuditLogsTargetType]: GuildAuditLogsTargetType;
|
||||
[Key in GuildAuditLogsTargetType]: Key;
|
||||
};
|
||||
|
||||
export type GuildBanResolvable = GuildBan | UserResolvable;
|
||||
@@ -7034,7 +7177,12 @@ export interface MessageEditAttachmentData {
|
||||
export interface MessageEditOptions extends Omit<BaseMessageOptions, 'content'> {
|
||||
content?: string | null;
|
||||
attachments?: readonly (Attachment | MessageEditAttachmentData)[];
|
||||
flags?: BitFieldResolvable<Extract<MessageFlagsString, 'SuppressEmbeds'>, MessageFlags.SuppressEmbeds> | undefined;
|
||||
flags?:
|
||||
| BitFieldResolvable<
|
||||
Extract<MessageFlagsString, 'SuppressEmbeds' | 'IsComponentsV2'>,
|
||||
MessageFlags.SuppressEmbeds | MessageFlags.IsComponentsV2
|
||||
>
|
||||
| undefined;
|
||||
}
|
||||
|
||||
export type MessageReactionResolvable = MessageReaction | Snowflake | string;
|
||||
@@ -7294,7 +7442,9 @@ export interface ResolvedOverwriteOptions {
|
||||
|
||||
export interface RoleData {
|
||||
name?: string;
|
||||
/** @deprecated Use {@link RoleData.colors} instead. */
|
||||
color?: ColorResolvable;
|
||||
colors?: RoleColorsResolvable;
|
||||
hoist?: boolean;
|
||||
position?: number;
|
||||
permissions?: PermissionResolvable;
|
||||
@@ -7360,6 +7510,10 @@ export interface ShowModalOptions {
|
||||
withResponse?: boolean;
|
||||
}
|
||||
|
||||
export interface LaunchActivityOptions {
|
||||
withResponse?: boolean;
|
||||
}
|
||||
|
||||
export { Snowflake };
|
||||
|
||||
export type StageInstanceResolvable = StageInstance | Snowflake;
|
||||
@@ -7550,6 +7704,7 @@ export interface WebhookEditOptions {
|
||||
|
||||
export interface WebhookMessageEditOptions extends MessageEditOptions {
|
||||
threadId?: Snowflake;
|
||||
withComponents?: boolean;
|
||||
}
|
||||
|
||||
export interface InteractionEditReplyOptions
|
||||
@@ -7569,6 +7724,7 @@ export interface WebhookMessageCreateOptions
|
||||
threadId?: Snowflake;
|
||||
threadName?: string;
|
||||
appliedTags?: readonly Snowflake[];
|
||||
withComponents?: boolean;
|
||||
}
|
||||
|
||||
export interface WebSocketOptions {
|
||||
|
||||
@@ -218,6 +218,7 @@ import {
|
||||
PollData,
|
||||
UserManager,
|
||||
InteractionCallbackResponse,
|
||||
PrimaryEntryPointCommandInteraction,
|
||||
GuildScheduledEventRecurrenceRuleOptions,
|
||||
ThreadOnlyChannel,
|
||||
SectionComponentData,
|
||||
@@ -229,6 +230,8 @@ import {
|
||||
SeparatorComponentData,
|
||||
FileComponentData,
|
||||
ContainerComponentData,
|
||||
InteractionResponse,
|
||||
FetchPinnedMessagesResponse,
|
||||
} from '.';
|
||||
import {
|
||||
expectAssignable,
|
||||
@@ -461,7 +464,7 @@ client.on('messageCreate', async message => {
|
||||
const component = await message.awaitMessageComponent({ componentType: ComponentType.Button });
|
||||
expectType<ButtonInteraction<'cached'>>(component);
|
||||
expectType<Message<true>>(await component.reply({ fetchReply: true }));
|
||||
expectType<InteractionCallbackResponse>(await component.reply({ withResponse: true }));
|
||||
expectType<InteractionCallbackResponse<true>>(await component.reply({ withResponse: true }));
|
||||
|
||||
const buttonCollector = message.createMessageComponentCollector({ componentType: ComponentType.Button });
|
||||
expectType<InteractionCollector<ButtonInteraction<'cached'>>>(buttonCollector);
|
||||
@@ -687,7 +690,7 @@ client.on('messageCreate', async message => {
|
||||
const rawSeparator: SeparatorComponentData = {
|
||||
type: ComponentType.Separator,
|
||||
spacing: 1,
|
||||
dividier: false,
|
||||
divider: false,
|
||||
};
|
||||
|
||||
const rawFile: FileComponentData = {
|
||||
@@ -1688,6 +1691,7 @@ declare const guildChannelManager: GuildChannelManager;
|
||||
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
|
||||
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
|
||||
expectType<Promise<Collection<Snowflake, Message<true>>>>(messages.fetchPinned());
|
||||
expectType<Promise<FetchPinnedMessagesResponse<true>>>(messages.fetchPins());
|
||||
expectType<Guild>(message.guild);
|
||||
expectType<Snowflake>(message.guildId);
|
||||
expectType<GuildTextBasedChannel>(message.channel.messages.channel);
|
||||
@@ -1701,6 +1705,7 @@ declare const guildChannelManager: GuildChannelManager;
|
||||
expectType<Promise<Message>>(messages.edit('1234567890', 'text'));
|
||||
expectType<Promise<Message>>(messages.fetch('1234567890'));
|
||||
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
|
||||
expectType<Promise<FetchPinnedMessagesResponse>>(messages.fetchPins());
|
||||
expectType<Guild | null>(message.guild);
|
||||
expectType<Snowflake | null>(message.guildId);
|
||||
expectType<DMChannel | PartialGroupDMChannel | GuildTextBasedChannel>(message.channel.messages.channel);
|
||||
@@ -1880,15 +1885,20 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Guild>(interaction.guild);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.deferReply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<true>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<true>>>(interaction.update({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.deferUpdate({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.update({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
expectType<Promise<InteractionCallbackResponse<true> | undefined>>(
|
||||
interaction.launchActivity({ withResponse: booleanValue }),
|
||||
);
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<MessageComponentInteraction>(interaction);
|
||||
expectType<APIButtonComponent | APISelectMenuComponent>(interaction.component);
|
||||
@@ -1896,15 +1906,20 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.deferReply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<false>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<false>>>(interaction.update({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.deferUpdate({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.update({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
expectType<Promise<InteractionCallbackResponse<false> | undefined>>(
|
||||
interaction.launchActivity({ withResponse: booleanValue }),
|
||||
);
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<MessageComponentInteraction>(interaction);
|
||||
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
|
||||
@@ -1921,6 +1936,11 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
expectType<Promise<InteractionCallbackResponse | undefined>>(
|
||||
interaction.launchActivity({ withResponse: booleanValue }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1955,21 +1975,31 @@ client.on('interactionCreate', async interaction => {
|
||||
expectAssignable<CommandInteraction<'cached'>>(interaction);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.deferReply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<true>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
expectType<Promise<InteractionCallbackResponse<true> | undefined>>(
|
||||
interaction.launchActivity({ withResponse: booleanValue }),
|
||||
);
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<ContextMenuCommandInteraction>(interaction);
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.deferReply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<false>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
expectType<Promise<InteractionCallbackResponse<false> | undefined>>(
|
||||
interaction.launchActivity({ withResponse: booleanValue }),
|
||||
);
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<ContextMenuCommandInteraction>(interaction);
|
||||
expectType<Guild | null>(interaction.guild);
|
||||
@@ -1980,6 +2010,11 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message>>(interaction.fetchReply());
|
||||
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
expectType<Promise<InteractionCallbackResponse | undefined>>(
|
||||
interaction.launchActivity({ withResponse: booleanValue }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2031,14 +2066,14 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Message<true>>(interaction.message);
|
||||
expectType<Guild>(interaction.guild);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ withResponse: true }));
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<ButtonInteraction>(interaction);
|
||||
expectType<APIButtonComponent>(interaction.component);
|
||||
expectType<Message<false>>(interaction.message);
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ withResponse: true }));
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<ButtonInteraction>(interaction);
|
||||
expectType<ButtonComponent | APIButtonComponent>(interaction.component);
|
||||
@@ -2062,14 +2097,14 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Message<true>>(interaction.message);
|
||||
expectType<Guild>(interaction.guild);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ withResponse: true }));
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||
expectType<APIStringSelectComponent>(interaction.component);
|
||||
expectType<Message<false>>(interaction.message);
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ withResponse: true }));
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||
expectType<SelectMenuComponent | APIStringSelectComponent>(interaction.component);
|
||||
@@ -2089,7 +2124,7 @@ client.on('interactionCreate', async interaction => {
|
||||
expectNotAssignable<Interaction<'cached'>>(interaction);
|
||||
expectAssignable<ChatInputCommandInteraction>(interaction);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ withResponse: true }));
|
||||
expectType<APIInteractionDataResolvedGuildMember | null>(interaction.options.getMember('test'));
|
||||
|
||||
expectType<APIInteractionDataResolvedChannel>(interaction.options.getChannel('test', true));
|
||||
@@ -2104,7 +2139,7 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<GuildMember | null>(interaction.options.getMember('test'));
|
||||
expectAssignable<ChatInputCommandInteraction>(interaction);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ withResponse: true }));
|
||||
|
||||
expectType<GuildBasedChannel>(interaction.options.getChannel('test', true));
|
||||
expectType<Role>(interaction.options.getRole('test', true));
|
||||
@@ -2164,6 +2199,57 @@ client.on('interactionCreate', async interaction => {
|
||||
interaction.options.getMessage('name');
|
||||
}
|
||||
|
||||
if (
|
||||
interaction.type === InteractionType.ApplicationCommand &&
|
||||
interaction.commandType === ApplicationCommandType.PrimaryEntryPoint
|
||||
) {
|
||||
expectType<PrimaryEntryPointCommandInteraction>(interaction);
|
||||
|
||||
// @ts-expect-error No options on primary entry point commands
|
||||
interaction.options;
|
||||
if (interaction.inCachedGuild()) {
|
||||
expectAssignable<PrimaryEntryPointCommandInteraction>(interaction);
|
||||
expectAssignable<Guild>(interaction.guild);
|
||||
expectAssignable<CommandInteraction<'cached'>>(interaction);
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionResponse<true>>>(interaction.deferReply());
|
||||
expectType<Promise<InteractionResponse<true>>>(interaction.reply({ content: 'a', withResponse: false }));
|
||||
expectType<Promise<InteractionResponse<true>>>(interaction.deferReply({ withResponse: false }));
|
||||
expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<true>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<PrimaryEntryPointCommandInteraction>(interaction);
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionResponse<false>>>(interaction.deferReply());
|
||||
expectType<Promise<InteractionResponse<false>>>(interaction.reply({ content: 'a', withResponse: false }));
|
||||
expectType<Promise<InteractionResponse<false>>>(interaction.deferReply({ withResponse: false }));
|
||||
expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<false>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<PrimaryEntryPointCommandInteraction>(interaction);
|
||||
expectType<Guild | null>(interaction.guild);
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionResponse>>(interaction.deferReply());
|
||||
expectType<Promise<InteractionResponse>>(interaction.reply({ content: 'a', withResponse: false }));
|
||||
expectType<Promise<InteractionResponse>>(interaction.deferReply({ withResponse: false }));
|
||||
expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message>>(interaction.fetchReply());
|
||||
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
|
||||
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
|
||||
}
|
||||
}
|
||||
|
||||
if (interaction.isRepliable()) {
|
||||
expectAssignable<RepliableInteraction>(interaction);
|
||||
interaction.reply('test');
|
||||
@@ -2185,25 +2271,27 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Guild>(interaction.guild);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.deferReply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<true>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<true>>>(interaction.deferUpdate({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<true>>>(interaction.launchActivity({ withResponse: true }));
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<ModalSubmitInteraction>(interaction);
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ content: 'a', fetchReply: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.deferReply({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.reply({ content: 'a', withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.deferReply({ withResponse: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' }));
|
||||
expectType<Promise<Message<false>>>(interaction.fetchReply());
|
||||
expectType<Promise<Message<false>>>(interaction.deferUpdate({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse<false>>>(interaction.launchActivity({ withResponse: true }));
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<ModalSubmitInteraction>(interaction);
|
||||
expectType<Guild | null>(interaction.guild);
|
||||
@@ -2216,6 +2304,7 @@ client.on('interactionCreate', async interaction => {
|
||||
expectType<Promise<Message>>(interaction.deferUpdate({ fetchReply: true }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
|
||||
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
|
||||
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2272,7 +2361,7 @@ expectType<Promise<GuildAuditLogs<AuditLogEvent.IntegrationUpdate>>>(
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.IntegrationUpdate }),
|
||||
);
|
||||
|
||||
expectType<Promise<GuildAuditLogs<null>>>(guild.fetchAuditLogs({ type: null }));
|
||||
expectType<Promise<GuildAuditLogs<AuditLogEvent>>>(guild.fetchAuditLogs({ type: null }));
|
||||
expectType<Promise<GuildAuditLogs<AuditLogEvent>>>(guild.fetchAuditLogs());
|
||||
|
||||
expectType<Promise<GuildAuditLogsEntry<AuditLogEvent.MemberKick, 'Delete', 'User'> | undefined>>(
|
||||
@@ -2282,10 +2371,10 @@ expectAssignable<Promise<GuildAuditLogsEntry<AuditLogEvent.MemberKick, 'Delete',
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick }).then(al => al.entries.first()),
|
||||
);
|
||||
|
||||
expectType<Promise<GuildAuditLogsEntry<null, GuildAuditLogsActionType, GuildAuditLogsTargetType> | undefined>>(
|
||||
expectType<Promise<GuildAuditLogsEntry<AuditLogEvent, GuildAuditLogsActionType, GuildAuditLogsTargetType> | undefined>>(
|
||||
guild.fetchAuditLogs({ type: null }).then(al => al.entries.first()),
|
||||
);
|
||||
expectType<Promise<GuildAuditLogsEntry<null, GuildAuditLogsActionType, GuildAuditLogsTargetType> | undefined>>(
|
||||
expectType<Promise<GuildAuditLogsEntry<AuditLogEvent, GuildAuditLogsActionType, GuildAuditLogsTargetType> | undefined>>(
|
||||
guild.fetchAuditLogs().then(al => al.entries.first()),
|
||||
);
|
||||
|
||||
@@ -2304,15 +2393,18 @@ expectType<Promise<{ channel: GuildTextBasedChannel | { id: Snowflake }; count:
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete }).then(al => al.entries.first()?.extra),
|
||||
);
|
||||
|
||||
expectType<Promise<User | null | undefined>>(
|
||||
expectType<Promise<User | PartialUser | null | undefined>>(
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick }).then(al => al.entries.first()?.target),
|
||||
);
|
||||
expectType<Promise<StageInstance | undefined>>(
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.StageInstanceCreate }).then(al => al.entries.first()?.target),
|
||||
);
|
||||
expectType<Promise<User | undefined>>(
|
||||
expectType<Promise<User | null | undefined>>(
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete }).then(al => al.entries.first()?.target),
|
||||
);
|
||||
expectType<Promise<GuildTextBasedChannel | { id: string } | undefined>>(
|
||||
guild.fetchAuditLogs({ type: AuditLogEvent.MessageBulkDelete }).then(al => al.entries.first()?.target),
|
||||
);
|
||||
|
||||
declare const AuditLogChange: AuditLogChange;
|
||||
// @ts-expect-error
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.37.119"
|
||||
"discord-api-types": "^0.38.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"@discordjs/rest": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@discordjs/ws": "workspace:^",
|
||||
"discord-api-types": "^0.37.119"
|
||||
"discord-api-types": "^0.38.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [@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
|
||||
|
||||
- Remove hardcoded locale from links (#10794) ([5be774d](https://github.com/discordjs/discord.js/commit/5be774db641b60669505645861d721200d335a7b))
|
||||
|
||||
## Features
|
||||
|
||||
- Support user guilds (#10995) ([baa08b8](https://github.com/discordjs/discord.js/commit/baa08b8fbb64abd8265890413c95f81e2c61303f))
|
||||
- Support animated WebP (#10987) ([cafe58b](https://github.com/discordjs/discord.js/commit/cafe58b3bd9defb5050a7a90bd07568f3b509c89))
|
||||
|
||||
# [@discordjs/rest@2.5.0](https://github.com/discordjs/discord.js/compare/@discordjs/rest@2.4.3...@discordjs/rest@2.5.0) - (2025-04-25)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -54,7 +54,7 @@ test('discoverySplash default', () => {
|
||||
expect(cdn.discoverySplash(id, hash)).toEqual(`${baseCDN}/discovery-splashes/${id}/${hash}.webp`);
|
||||
});
|
||||
|
||||
test('emoji default', () => {
|
||||
test('emoji', () => {
|
||||
expect(cdn.emoji(id)).toEqual(`${baseCDN}/emojis/${id}.webp`);
|
||||
});
|
||||
|
||||
@@ -62,6 +62,14 @@ test('emoji gif', () => {
|
||||
expect(cdn.emoji(id, 'gif')).toEqual(`${baseCDN}/emojis/${id}.gif`);
|
||||
});
|
||||
|
||||
test('emoji animated', () => {
|
||||
expect(cdn.emoji(id, { animated: true })).toEqual(`${baseCDN}/emojis/${id}.webp?animated=true`);
|
||||
});
|
||||
|
||||
test('emoji with GIF format', () => {
|
||||
expect(cdn.emoji(id, { extension: 'gif' })).toEqual(`${baseCDN}/emojis/${id}.gif`);
|
||||
});
|
||||
|
||||
test('guildMemberAvatar default', () => {
|
||||
expect(cdn.guildMemberAvatar(id, id, hash)).toEqual(`${baseCDN}/guilds/${id}/users/${id}/avatars/${hash}.webp`);
|
||||
});
|
||||
@@ -134,8 +142,11 @@ test('soundboardSound', () => {
|
||||
expect(cdn.soundboardSound(id)).toEqual(`${baseCDN}/soundboard-sounds/${id}`);
|
||||
});
|
||||
|
||||
test('guildTagBadge', () => {
|
||||
expect(cdn.guildTagBadge(id, hash)).toEqual(`${baseCDN}/guild-tag-badges/${id}/${hash}.webp`);
|
||||
});
|
||||
|
||||
test('makeURL throws on invalid size', () => {
|
||||
// @ts-expect-error: Invalid size
|
||||
expect(() => cdn.avatar(id, animatedHash, { size: 5 })).toThrow(RangeError);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/rest",
|
||||
"version": "2.5.0",
|
||||
"version": "2.6.0",
|
||||
"description": "The REST API for discord.js",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
@@ -88,10 +88,10 @@
|
||||
"@sapphire/async-queue": "^1.5.3",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.1",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.1"
|
||||
"undici": "6.21.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
@@ -14,27 +14,44 @@ import { deprecationWarning } from './utils/utils.js';
|
||||
let deprecationEmittedForEmoji = false;
|
||||
|
||||
/**
|
||||
* The options used for image URLs
|
||||
* The options used for image URLs.
|
||||
*/
|
||||
export interface BaseImageURLOptions {
|
||||
/**
|
||||
* The extension to use for the image URL
|
||||
* The extension to use for the image URL.
|
||||
*
|
||||
* @defaultValue `'webp'`
|
||||
*/
|
||||
extension?: ImageExtension;
|
||||
/**
|
||||
* The size specified in the image URL
|
||||
* The size specified in the image URL.
|
||||
*/
|
||||
size?: ImageSize;
|
||||
}
|
||||
|
||||
export interface EmojiURLOptionsWebp extends BaseImageURLOptions {
|
||||
/**
|
||||
* Whether to use the `animated` query parameter.
|
||||
*/
|
||||
animated?: boolean;
|
||||
extension?: 'webp';
|
||||
}
|
||||
|
||||
export interface EmojiURLOptionsNotWebp extends BaseImageURLOptions {
|
||||
extension: Exclude<ImageExtension, 'webp'>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The options used for image URLs with animated content
|
||||
* The options used for emoji URLs.
|
||||
*/
|
||||
export type EmojiURLOptions = EmojiURLOptionsNotWebp | EmojiURLOptionsWebp;
|
||||
|
||||
/**
|
||||
* The options used for image URLs that may be animated.
|
||||
*/
|
||||
export interface ImageURLOptions extends BaseImageURLOptions {
|
||||
/**
|
||||
* Whether or not to prefer the static version of an image asset.
|
||||
* Whether to prefer the static asset.
|
||||
*/
|
||||
forceStatic?: boolean;
|
||||
}
|
||||
@@ -47,6 +64,10 @@ export interface MakeURLOptions {
|
||||
* The allowed extensions that can be used
|
||||
*/
|
||||
allowedExtensions?: readonly string[];
|
||||
/**
|
||||
* Whether to use the `animated` query parameter
|
||||
*/
|
||||
animated?: boolean;
|
||||
/**
|
||||
* The base URL.
|
||||
*
|
||||
@@ -192,7 +213,7 @@ export class CDN {
|
||||
* @param emojiId - The emoji id
|
||||
* @param options - Optional options for the emoji
|
||||
*/
|
||||
public emoji(emojiId: string, options?: Readonly<BaseImageURLOptions>): string;
|
||||
public emoji(emojiId: string, options?: Readonly<EmojiURLOptions>): string;
|
||||
|
||||
/**
|
||||
* Generates an emoji's URL for an emoji.
|
||||
@@ -204,7 +225,7 @@ export class CDN {
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
public emoji(emojiId: string, extension?: ImageExtension): string;
|
||||
|
||||
public emoji(emojiId: string, options?: ImageExtension | Readonly<BaseImageURLOptions>): string {
|
||||
public emoji(emojiId: string, options?: ImageExtension | Readonly<EmojiURLOptions>): string {
|
||||
let resolvedOptions;
|
||||
|
||||
if (typeof options === 'string') {
|
||||
@@ -353,6 +374,17 @@ export class CDN {
|
||||
return `${this.cdn}${CDNRoutes.soundboardSound(soundId)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL for a guild tag badge.
|
||||
*
|
||||
* @param guildId - The guild id
|
||||
* @param badgeHash - The hash of the badge
|
||||
* @param options - Optional options for the badge
|
||||
*/
|
||||
public guildTagBadge(guildId: string, badgeHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/guild-tag-badges/${guildId}/${badgeHash}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`.
|
||||
*
|
||||
@@ -381,6 +413,7 @@ export class CDN {
|
||||
base = this.cdn,
|
||||
extension = 'webp',
|
||||
size,
|
||||
animated,
|
||||
}: Readonly<MakeURLOptions> = {},
|
||||
): string {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
@@ -396,6 +429,10 @@ export class CDN {
|
||||
|
||||
const url = new URL(`${base}${route}.${extension}`);
|
||||
|
||||
if (animated !== undefined) {
|
||||
url.searchParams.set('animated', String(animated));
|
||||
}
|
||||
|
||||
if (size) {
|
||||
url.searchParams.set('size', String(size));
|
||||
}
|
||||
|
||||
@@ -336,9 +336,9 @@ export class REST extends AsyncEventEmitter<RestEvents> {
|
||||
for (const [index, file] of request.files.entries()) {
|
||||
const fileKey = file.key ?? `files[${index}]`;
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/FormData/append#parameters
|
||||
// https://developer.mozilla.org/docs/Web/API/FormData/append#parameters
|
||||
// FormData.append only accepts a string or Blob.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#parameters
|
||||
// https://developer.mozilla.org/docs/Web/API/Blob/Blob#parameters
|
||||
// The Blob constructor accepts TypedArray/ArrayBuffer, strings, and Blobs.
|
||||
if (isBufferLike(file.data)) {
|
||||
// Try to infer the content type from the buffer if one isn't passed
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@types/ws": "^8.5.12",
|
||||
"discord-api-types": "^0.37.119",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"prism-media": "^1.3.5",
|
||||
"tslib": "^2.6.3",
|
||||
"ws": "^8.18.0"
|
||||
|
||||
@@ -2,6 +2,37 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [@discordjs/ws@2.0.3](https://github.com/discordjs/discord.js/compare/@discordjs/ws@2.0.2...@discordjs/ws@2.0.3) - (2025-06-16)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- Regression in allowedMentions when replying (#10866) ([2ebb5cb](https://github.com/discordjs/discord.js/commit/2ebb5cbd53d869a52cba4549e7acc417963741cd))
|
||||
|
||||
# [@discordjs/ws@2.0.0](https://github.com/discordjs/discord.js/compare/@discordjs/ws@1.1.1...@discordjs/ws@2.0.0) - (2024-09-02)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **WebSocketShard:** Buffer native zlib decompression payload (#10416) ([defb083](https://github.com/discordjs/discord.js/commit/defb083528ef31383778187a04ced8b00d886242)) by @didinele
|
||||
- **WebSocketManager:** Heartbeat event had outdated types (#10417) ([5eabec1](https://github.com/discordjs/discord.js/commit/5eabec14d45ef7bdd7f610e84234eb63e726eacd)) by @didinele
|
||||
- Retry for EAI_AGAIN I/O error (#10383) ([be04acd](https://github.com/discordjs/discord.js/commit/be04acd534d7d0c3fb7f6bd174e4a6482aae0d73)) by @didinele
|
||||
- Consistent debug log spacing (#10349) ([38c699b](https://github.com/discordjs/discord.js/commit/38c699bc8a2ca40f37f70c93e08067e00f12ee81)) by @Jiralite
|
||||
|
||||
## Features
|
||||
|
||||
- **WebsocketManager:** Retroactive token setting (#10418) ([de94eaf](https://github.com/discordjs/discord.js/commit/de94eaf351a69fab57ec766bd9e90e8c05e8c3d1)) by @didinele
|
||||
- **WebSocketShard:** Explicit time out network error handling (#10375) ([093ac92](https://github.com/discordjs/discord.js/commit/093ac924aef1bf328feadb49876bfbe26052fe1a)) by @didinele
|
||||
|
||||
## Refactor
|
||||
|
||||
- **WebSocketShard:** Error event handling (#10436) ([a6de270](https://github.com/discordjs/discord.js/commit/a6de2707fc1107262b12491f73b5b6887df91c67)) by @didinele
|
||||
- **ws:** Event layout (#10376) ([bf6761a](https://github.com/discordjs/discord.js/commit/bf6761a44adec1fe5017f6bf5d8bc0734916961f)) by @didinele
|
||||
- **BREAKING CHANGE:** All events now emit shard id as its own param
|
||||
|
||||
* fix: worker event forwarding
|
||||
|
||||
---------
|
||||
- Native zlib support (#10316) ([94cc02a](https://github.com/discordjs/discord.js/commit/94cc02a2580496774d75673abc0caabc765d9ee0)) by @sdanialraza
|
||||
|
||||
# [@discordjs/ws@2.0.0](https://github.com/discordjs/discord.js/compare/@discordjs/ws@1.1.1...@discordjs/ws@2.0.0) - (2024-09-02)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/ws",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"description": "Wrapper around Discord's gateway",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
@@ -79,7 +79,7 @@
|
||||
"@sapphire/async-queue": "^1.5.3",
|
||||
"@types/ws": "^8.5.12",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.1",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"tslib": "^2.6.3",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
@@ -100,9 +100,9 @@
|
||||
"tsup": "^8.2.4",
|
||||
"turbo": "^2.0.14",
|
||||
"typescript": "~5.5.4",
|
||||
"undici": "6.21.1",
|
||||
"undici": "6.21.3",
|
||||
"vitest": "^2.0.5",
|
||||
"zlib-sync": "^0.1.9"
|
||||
"zlib-sync": "^0.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
|
||||
3370
pnpm-lock.yaml
generated
3370
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user